From b6c07a5fa7fc5bb38e5e0b71669a6d422cdeea7d Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Fri, 31 May 2024 12:00:42 -0400 Subject: [PATCH 001/168] feat(minor-coordinator, minor-service-registry)!: add ready to unbond utility and connect service registry to coordinator (#358) * refactor(minor-service-registry)!: change service_contract to monitoring_contract * feat(minor-monitoring)!: add query message for check_unbond * fix: sort service registry cargo file * feat: service registry queries coordinator for can_unbond * fix: add initial setActiveWorkerSet for coordinator on integrations tests * fix: change the claim_stake test to include the first path of can_unbond * test: add two more integration tests for can_unbond feature * fix: add chains_of_worker map to coordinator and change structure of ready_to_unbond query * test: two more failure integration test paths for can_unbond * test: add stake claim when in unconfirmed next worker set integration test * feat: save next worker set of prover in coordinator and use for unbond check * fix: move the update next worker set message to update_worker_set on prover * chore: address merge conflicts with main * chore: remove add chain support message from coordinator * refactor: fix next verifier set map name * fix: rename remaining workers to verifiers * chore: remove v3 migrations, change todo comment on coordinator * feat: add .include method to verfierset * fix: add coordinator as lib feature for service registry * fix: sort service-registry cargo file and re-add entry_point for coordinator * fix: conditional import of entry_point for coordinator * refactor: use address for include method of verifier set --- Cargo.lock | 1 + contracts/coordinator/src/contract.rs | 21 +- contracts/coordinator/src/execute.rs | 13 +- contracts/coordinator/src/msg.rs | 6 + contracts/coordinator/src/query.rs | 59 +++- contracts/coordinator/src/state.rs | 8 + contracts/multisig-prover/src/execute.rs | 18 +- contracts/multisig/src/verifier_set.rs | 6 +- contracts/service-registry/Cargo.toml | 1 + contracts/service-registry/src/contract.rs | 84 +++--- .../service-registry/src/contract/execute.rs | 23 +- contracts/service-registry/src/lib.rs | 1 - .../service-registry/src/migrations/mod.rs | 1 - .../service-registry/src/migrations/v_0_3.rs | 250 ---------------- contracts/service-registry/src/msg.rs | 2 +- contracts/service-registry/src/state.rs | 2 +- doc/src/contracts/service_registry.md | 2 +- integration-tests/tests/bond_unbond.rs | 283 +++++++++++++++++- integration-tests/tests/test_utils/mod.rs | 81 ++++- 19 files changed, 518 insertions(+), 344 deletions(-) delete mode 100644 contracts/service-registry/src/migrations/mod.rs delete mode 100644 contracts/service-registry/src/migrations/v_0_3.rs diff --git a/Cargo.lock b/Cargo.lock index e2ea3c80a..4c6197bd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7598,6 +7598,7 @@ version = "0.3.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", + "coordinator", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 18a4d084e..2025cfaac 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -1,7 +1,8 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{Config, CONFIG}; -use cosmwasm_std::{entry_point, Empty}; -use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; use crate::error::ContractError; use crate::execute; @@ -59,6 +60,9 @@ pub fn execute( ExecuteMsg::SetActiveVerifiers { next_verifier_set } => { execute::set_active_verifier_set(deps, info, next_verifier_set) } + ExecuteMsg::SetNextVerifiers { next_verifier_set } => { + execute::set_next_verifier_set(deps, info, next_verifier_set) + } } .map_err(axelar_wasm_std::ContractError::from) } @@ -68,9 +72,12 @@ pub fn execute( pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::GetActiveVerifiers { chain_name } => { - to_json_binary(&query::get_active_verifier_set(deps, chain_name)?) - .map_err(|err| err.into()) + to_json_binary(&query::active_verifier_set(deps, chain_name)?).map_err(|err| err.into()) } + QueryMsg::ReadyToUnbond { worker_address } => to_json_binary( + &query::check_verifier_ready_to_unbond(deps, worker_address)?, + ) + .map_err(|err| err.into()), } } @@ -208,7 +215,7 @@ mod tests { .unwrap(); let chain_provers = - query::provers(test_setup.deps.as_ref(), test_setup.chain_name.clone()).unwrap(); + query::prover(test_setup.deps.as_ref(), test_setup.chain_name.clone()).unwrap(); assert_eq!(chain_provers, test_setup.prover); } @@ -267,7 +274,7 @@ mod tests { assert!(res.is_ok()); let eth_active_verifier_set = - query::get_active_verifier_set(test_setup.deps.as_ref(), test_setup.chain_name.clone()) + query::active_verifier_set(test_setup.deps.as_ref(), test_setup.chain_name.clone()) .unwrap(); assert_eq!(eth_active_verifier_set, Some(new_verifier_set)); @@ -289,7 +296,7 @@ mod tests { ); let query_result = - query::get_active_verifier_set(test_setup.deps.as_ref(), test_setup.chain_name.clone()) + query::active_verifier_set(test_setup.deps.as_ref(), test_setup.chain_name.clone()) .unwrap(); assert_eq!(query_result, None); diff --git a/contracts/coordinator/src/execute.rs b/contracts/coordinator/src/execute.rs index 72756cdb1..14bf95b00 100644 --- a/contracts/coordinator/src/execute.rs +++ b/contracts/coordinator/src/execute.rs @@ -4,7 +4,9 @@ use multisig::verifier_set::VerifierSet; use router_api::ChainName; use crate::error::ContractError; -use crate::state::{ACTIVE_VERIFIER_SET_FOR_PROVER, CONFIG, PROVER_PER_CHAIN}; +use crate::state::{ + ACTIVE_VERIFIER_SET_FOR_PROVER, CONFIG, NEXT_VERIFIER_SET_FOR_PROVER, PROVER_PER_CHAIN, +}; pub fn check_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { let config = CONFIG.load(deps.storage)?; @@ -31,3 +33,12 @@ pub fn set_active_verifier_set( ACTIVE_VERIFIER_SET_FOR_PROVER.save(deps.storage, info.sender, &(next_verifier_set))?; Ok(Response::new()) } + +pub fn set_next_verifier_set( + deps: DepsMut, + info: MessageInfo, + next_verifier_set: VerifierSet, +) -> Result { + NEXT_VERIFIER_SET_FOR_PROVER.save(deps.storage, info.sender, &(next_verifier_set))?; + Ok(Response::new()) +} diff --git a/contracts/coordinator/src/msg.rs b/contracts/coordinator/src/msg.rs index dfe908e14..b64e70a35 100644 --- a/contracts/coordinator/src/msg.rs +++ b/contracts/coordinator/src/msg.rs @@ -18,6 +18,9 @@ pub enum ExecuteMsg { SetActiveVerifiers { next_verifier_set: VerifierSet, }, + SetNextVerifiers { + next_verifier_set: VerifierSet, + }, } #[cw_serde] @@ -25,4 +28,7 @@ pub enum ExecuteMsg { pub enum QueryMsg { #[returns(VerifierSet)] GetActiveVerifiers { chain_name: ChainName }, + + #[returns(bool)] + ReadyToUnbond { worker_address: Addr }, } diff --git a/contracts/coordinator/src/query.rs b/contracts/coordinator/src/query.rs index 0842c83cf..54b9eedbc 100644 --- a/contracts/coordinator/src/query.rs +++ b/contracts/coordinator/src/query.rs @@ -1,23 +1,60 @@ use crate::error::ContractError; -use crate::state::{ACTIVE_VERIFIER_SET_FOR_PROVER, PROVER_PER_CHAIN}; +use crate::state::{ + ACTIVE_VERIFIER_SET_FOR_PROVER, NEXT_VERIFIER_SET_FOR_PROVER, PROVER_PER_CHAIN, +}; use cosmwasm_std::{Addr, Deps, StdResult}; use multisig::verifier_set::VerifierSet; use router_api::ChainName; -pub fn provers(deps: Deps, chain_name: ChainName) -> Result { +pub fn prover(deps: Deps, chain_name: ChainName) -> Result { PROVER_PER_CHAIN .may_load(deps.storage, chain_name.clone())? .ok_or(ContractError::NoProversRegisteredForChain(chain_name)) } -// For now, we consider only one prover per chain -pub fn get_active_verifier_set( - deps: Deps, - chain_name: ChainName, -) -> StdResult> { - let prover_address = provers(deps, chain_name).unwrap(); - let active_verifier_set = - ACTIVE_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address.clone())?; +pub fn active_verifier_set(deps: Deps, chain_name: ChainName) -> StdResult> { + match prover(deps, chain_name) { + Ok(prover_address) => { + let active_worker_set = + ACTIVE_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address)?; + Ok(active_worker_set) + } + Err(_err) => Ok(None), + } +} + +fn is_verifier_in_verifier_set(deps: Deps, verifier_address: &Addr) -> StdResult { + // TODO: Use map lookup for chain names to find out which provers to query (to have better performance). + let chain_names = PROVER_PER_CHAIN + .keys(deps.storage, None, None, cosmwasm_std::Order::Ascending) + .collect::>>()?; + + for chain_name in chain_names { + if let Ok(prover_address) = PROVER_PER_CHAIN.load(deps.storage, chain_name) { + if let Ok(Some(verifier_set)) = + ACTIVE_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address.clone()) + { + if verifier_set.includes(verifier_address) { + return Ok(true); + } + } + + if let Ok(Some(verifier_set)) = + NEXT_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address) + { + if verifier_set.includes(verifier_address) { + return Ok(true); + } + } + } + } + + Ok(false) +} - Ok(active_verifier_set) +pub fn check_verifier_ready_to_unbond(deps: Deps, verifier_address: Addr) -> StdResult { + if is_verifier_in_verifier_set(deps, &verifier_address)? { + return Ok(false); + } + Ok(true) } diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index ddd4f962d..27aa3d8f7 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -3,6 +3,7 @@ use cosmwasm_std::Addr; use cw_storage_plus::{Item, Map}; use multisig::verifier_set::VerifierSet; use router_api::ChainName; +use std::collections::HashSet; #[cw_serde] pub struct Config { @@ -18,3 +19,10 @@ pub const PROVER_PER_CHAIN: Map = Map::new("prover_per // TODO: migrate this? pub const ACTIVE_VERIFIER_SET_FOR_PROVER: Map = Map::new("active_prover_verifier_set"); + +type ChainNames = HashSet; +type VerifierAddress = Addr; +pub const CHAINS_OF_VERIFIER: Map = Map::new("chains_of_verifier"); + +pub const NEXT_VERIFIER_SET_FOR_PROVER: Map = + Map::new("next_prover_verifier"); diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index 04d913e26..3f8348c7f 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -226,7 +226,7 @@ pub fn update_verifier_set(deps: DepsMut, env: Env) -> Result Result bool { + self.signers.contains_key(signer.as_str()) + } } diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index f61d1f567..0727a2722 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -35,6 +35,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ [dependencies] axelar-wasm-std = { workspace = true } axelar-wasm-std-derive = { workspace = true } +coordinator = { workspace = true, features = ["library"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 67dc56a22..5283f3d36 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,12 +1,11 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, Order, - Response, Uint128, + to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Order, + QueryRequest, Response, Uint128, WasmQuery, }; use crate::error::ContractError; -use crate::migrations; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{AuthorizationState, BondingState, Config, Service, Verifier, CONFIG, SERVICES}; @@ -16,18 +15,6 @@ mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate( - deps: DepsMut, - _env: Env, - _msg: Empty, -) -> Result { - // any version checks should be done before here - - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_3::migrate(deps).map_err(axelar_wasm_std::ContractError::from) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, @@ -56,7 +43,7 @@ pub fn execute( match msg { ExecuteMsg::RegisterService { service_name, - service_contract, + coordinator_contract, min_num_verifiers, max_num_verifiers, min_verifier_bond, @@ -68,7 +55,7 @@ pub fn execute( execute::register_service( deps, service_name, - service_contract, + coordinator_contract, min_num_verifiers, max_num_verifiers, min_verifier_bond, @@ -186,6 +173,7 @@ mod test { const GOVERNANCE_ADDRESS: &str = "governance"; const UNAUTHORIZED_ADDRESS: &str = "unauthorized"; + const COORDINATOR_ADDRESS: &str = "coordinator_address"; const VERIFIER_ADDRESS: &str = "verifier"; const AXL_DENOMINATION: &str = "uaxl"; @@ -202,6 +190,13 @@ mod test { ) .unwrap(); + deps.querier.update_wasm(move |wq| match wq { + WasmQuery::Smart { contract_addr, .. } if contract_addr == COORDINATOR_ADDRESS => { + Ok(to_json_binary(&true).into()).into() + } + _ => panic!("no mock for this query"), + }); + deps } @@ -212,17 +207,6 @@ mod test { assert_eq!(actual.into().to_string(), expected.into().to_string()); } - #[test] - fn migrate_sets_contract_version() { - let mut deps = mock_dependencies(); - - migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); - - let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, "service-registry"); - assert_eq!(contract_version.version, CONTRACT_VERSION); - } - #[test] fn register_service() { let mut deps = setup(); @@ -233,7 +217,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: "validators".into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond: Uint128::zero(), @@ -250,7 +234,7 @@ mod test { mock_info(UNAUTHORIZED_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: "validators".into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond: Uint128::zero(), @@ -274,7 +258,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond: Uint128::zero(), @@ -321,7 +305,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -369,7 +353,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -472,7 +456,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -559,7 +543,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -653,7 +637,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -778,7 +762,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -880,7 +864,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -992,7 +976,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1068,7 +1052,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1142,7 +1126,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1216,7 +1200,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1300,7 +1284,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1339,7 +1323,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1402,7 +1386,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1476,7 +1460,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1563,7 +1547,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1672,7 +1656,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -1793,7 +1777,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers, max_num_verifiers: Some(100), min_verifier_bond, @@ -1904,7 +1888,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::RegisterService { service_name: service_name.into(), - service_contract: Addr::unchecked("service contract"), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, diff --git a/contracts/service-registry/src/contract/execute.rs b/contracts/service-registry/src/contract/execute.rs index 32e34a116..3b6068094 100644 --- a/contracts/service-registry/src/contract/execute.rs +++ b/contracts/service-registry/src/contract/execute.rs @@ -16,7 +16,7 @@ pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), Contr pub fn register_service( deps: DepsMut, service_name: String, - service_contract: Addr, + coordinator_contract: Addr, min_num_verifiers: u16, max_num_verifiers: Option, min_verifier_bond: Uint128, @@ -33,7 +33,7 @@ pub fn register_service( match service { None => Ok(Service { name: service_name, - service_contract, + coordinator_contract, min_num_verifiers, max_num_verifiers, min_verifier_bond, @@ -136,7 +136,12 @@ pub fn register_chains_support( .may_load(deps.storage, (&service_name, &info.sender))? .ok_or(ContractError::VerifierNotFound)?; - state::register_chains_support(deps.storage, service_name.clone(), chains, info.sender)?; + state::register_chains_support( + deps.storage, + service_name.clone(), + chains.clone(), + info.sender.clone(), + )?; Ok(Response::new()) } @@ -166,7 +171,7 @@ pub fn unbond_verifier( info: MessageInfo, service_name: String, ) -> Result { - SERVICES + let service = SERVICES .may_load(deps.storage, &service_name)? .ok_or(ContractError::ServiceNotFound)?; @@ -174,9 +179,15 @@ pub fn unbond_verifier( .may_load(deps.storage, (&service_name, &info.sender))? .ok_or(ContractError::VerifierNotFound)?; - let can_unbond = true; // TODO: actually query the service to determine this value + let query = coordinator::msg::QueryMsg::ReadyToUnbond { + worker_address: verifier.address.clone(), + }; + let ready_to_unbond = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: service.coordinator_contract.into(), + msg: to_json_binary(&query)?, + }))?; - let verifier = verifier.unbond(can_unbond, env.block.time)?; + let verifier = verifier.unbond(ready_to_unbond, env.block.time)?; VERIFIERS.save(deps.storage, (&service_name, &info.sender), &verifier)?; diff --git a/contracts/service-registry/src/lib.rs b/contracts/service-registry/src/lib.rs index f379c0cbc..98208b782 100644 --- a/contracts/service-registry/src/lib.rs +++ b/contracts/service-registry/src/lib.rs @@ -1,7 +1,6 @@ pub mod contract; pub mod error; pub mod helpers; -mod migrations; pub mod msg; pub mod state; diff --git a/contracts/service-registry/src/migrations/mod.rs b/contracts/service-registry/src/migrations/mod.rs deleted file mode 100644 index 194e2b5c7..000000000 --- a/contracts/service-registry/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v_0_3; diff --git a/contracts/service-registry/src/migrations/v_0_3.rs b/contracts/service-registry/src/migrations/v_0_3.rs deleted file mode 100644 index bc429b37d..000000000 --- a/contracts/service-registry/src/migrations/v_0_3.rs +++ /dev/null @@ -1,250 +0,0 @@ -//! Migrate includes: -//! - rename min_num_workers, max_num_workers and min_worker_bond fields in 'Service` struct -//! - rename WORKERS_PER_CHAIN to VERIFIERS_PER_CHAIN -//! - rename WORKERS to VERIFIERS - -use cosmwasm_std::{DepsMut, Order, Response, Storage}; - -use crate::error::ContractError; -use crate::state::{Service, Verifier, SERVICES, VERIFIERS, VERIFIERS_PER_CHAIN}; - -mod v0_2_state { - use cosmwasm_schema::cw_serde; - use cosmwasm_std::{Addr, Uint128}; - use cw_storage_plus::Map; - use router_api::ChainName; - - use crate::state::{AuthorizationState, BondingState}; - - #[cw_serde] - pub struct Service { - pub name: String, - pub service_contract: Addr, - pub min_num_workers: u16, - pub max_num_workers: Option, - pub min_worker_bond: Uint128, - pub bond_denom: String, - pub unbonding_period_days: u16, - pub description: String, - } - - #[cw_serde] - pub struct Worker { - pub address: Addr, - pub bonding_state: BondingState, - pub authorization_state: AuthorizationState, - pub service_name: String, - } - - type ServiceName = str; - type WorkerAddress = Addr; - - pub const SERVICES: Map<&ServiceName, Service> = Map::new("services"); - pub const WORKERS_PER_CHAIN: Map<(&ServiceName, &ChainName, &WorkerAddress), ()> = - Map::new("workers_per_chain"); - pub const WORKERS: Map<(&ServiceName, &WorkerAddress), Worker> = Map::new("workers"); -} - -pub fn migrate(deps: DepsMut) -> Result { - migrate_services(deps.storage)?; - migrate_workers_per_chain(deps.storage)?; - migrate_workers(deps.storage)?; - - Ok(Response::new()) -} - -fn migrate_services(store: &mut dyn Storage) -> Result<(), ContractError> { - let keys_and_services = v0_2_state::SERVICES - .range(store, None, None, Order::Ascending) - .map(|result| { - result.map(|(service_name, service)| { - ( - service_name, - Service { - name: service.name, - service_contract: service.service_contract, - min_num_verifiers: service.min_num_workers, - max_num_verifiers: service.max_num_workers, - min_verifier_bond: service.min_worker_bond, - bond_denom: service.bond_denom, - unbonding_period_days: service.unbonding_period_days, - description: service.description, - }, - ) - }) - }) - .collect::, _>>()?; - - for (service_name, new_service) in keys_and_services { - SERVICES.save(store, &service_name, &new_service)?; - } - - Ok(()) -} - -fn migrate_workers_per_chain(store: &mut dyn Storage) -> Result<(), ContractError> { - let keys_and_value_pairs = v0_2_state::WORKERS_PER_CHAIN - .range(store, None, None, Order::Ascending) - .collect::, _>>()?; - - for ((service_name, chain_name, verifier_address), _) in keys_and_value_pairs { - let key = (service_name.as_str(), &chain_name, &verifier_address); - VERIFIERS_PER_CHAIN.save(store, key, &())?; - v0_2_state::WORKERS_PER_CHAIN.remove(store, key); - } - - Ok(()) -} - -fn migrate_workers(store: &mut dyn Storage) -> Result<(), ContractError> { - let keys_and_workers = v0_2_state::WORKERS - .range(store, None, None, Order::Ascending) - .collect::, _>>()?; - - for ((service_name, verifier_address), worker) in keys_and_workers { - let key = (service_name.as_str(), &verifier_address); - let verifier = Verifier { - address: worker.address, - bonding_state: worker.bonding_state, - authorization_state: worker.authorization_state, - service_name: worker.service_name, - }; - VERIFIERS.save(store, key, &verifier)?; - v0_2_state::WORKERS.remove(store, key); - } - - Ok(()) -} - -#[cfg(test)] -mod test { - use cosmwasm_std::{testing::mock_dependencies, Addr, Storage, Uint128}; - - use router_api::ChainName; - - use crate::{ - migrations::v_0_3::{migrate, v0_2_state}, - state::{ - AuthorizationState, BondingState, Service, SERVICES, VERIFIERS, VERIFIERS_PER_CHAIN, - }, - }; - - #[test] - #[allow(clippy::arithmetic_side_effects)] - fn migration() { - let mut deps = mock_dependencies(); - - let service = v0_2_state::Service { - name: "service".to_string(), - service_contract: Addr::unchecked("service_contract"), - min_num_workers: 1, - max_num_workers: Some(2), - min_worker_bond: 100u128.into(), - bond_denom: "uaxl".to_string(), - unbonding_period_days: 10, - description: "description".to_string(), - }; - - let verifiers = vec![ - Addr::unchecked("verifier1"), - Addr::unchecked("verifier2"), - Addr::unchecked("verifier3"), - Addr::unchecked("verifier4"), - ]; - - let chains: Vec = vec![ - "chain1".parse().unwrap(), - "chain2".parse().unwrap(), - "chain3".parse().unwrap(), - "chain4".parse().unwrap(), - ]; - - set_up_v0_2_state( - &mut deps.storage, - service.clone(), - verifiers.clone(), - chains.clone(), - ); - - migrate(deps.as_mut()).unwrap(); - - // verify new state - assert_eq!( - SERVICES.load(&deps.storage, &service.name).unwrap(), - Service { - name: service.name, - service_contract: service.service_contract, - min_num_verifiers: service.min_num_workers, - max_num_verifiers: service.max_num_workers, - min_verifier_bond: service.min_worker_bond, - bond_denom: service.bond_denom, - unbonding_period_days: service.unbonding_period_days, - description: service.description, - } - ); - - assert_eq!( - VERIFIERS_PER_CHAIN - .range(&deps.storage, None, None, cosmwasm_std::Order::Ascending) - .count(), - chains.len() * verifiers.len() - ); - - assert_eq!( - VERIFIERS - .range(&deps.storage, None, None, cosmwasm_std::Order::Ascending) - .count(), - verifiers.len() - ); - } - - #[allow(clippy::arithmetic_side_effects)] - fn set_up_v0_2_state( - store: &mut dyn Storage, - service: v0_2_state::Service, - verifiers: Vec, - chains: Vec, - ) { - v0_2_state::SERVICES - .save(store, &service.name, &service) - .unwrap(); - - for verifier in verifiers.iter() { - for chain in chains.iter() { - v0_2_state::WORKERS_PER_CHAIN - .save(store, (&service.name, chain, &verifier), &()) - .unwrap(); - } - - let worker = v0_2_state::Worker { - address: verifier.clone(), - bonding_state: BondingState::Bonded { - amount: Uint128::from(1000000u128), - }, - authorization_state: AuthorizationState::Authorized, - service_name: service.name.clone(), - }; - v0_2_state::WORKERS - .save(store, (&service.name, verifier), &worker) - .unwrap(); - } - - // verify state set up correctly - assert_eq!( - v0_2_state::SERVICES.load(store, &service.name).unwrap(), - service - ); - assert_eq!( - v0_2_state::WORKERS_PER_CHAIN - .range(store, None, None, cosmwasm_std::Order::Ascending) - .count(), - chains.len() * verifiers.len() - ); - assert_eq!( - v0_2_state::WORKERS - .range(store, None, None, cosmwasm_std::Order::Ascending) - .count(), - verifiers.len() - ); - } -} diff --git a/contracts/service-registry/src/msg.rs b/contracts/service-registry/src/msg.rs index bf0e3a6b1..777ee0353 100644 --- a/contracts/service-registry/src/msg.rs +++ b/contracts/service-registry/src/msg.rs @@ -12,7 +12,7 @@ pub enum ExecuteMsg { // Can only be called by governance account RegisterService { service_name: String, - service_contract: Addr, + coordinator_contract: Addr, min_num_verifiers: u16, max_num_verifiers: Option, min_verifier_bond: Uint128, diff --git a/contracts/service-registry/src/state.rs b/contracts/service-registry/src/state.rs index 4004c556e..5dafe177b 100644 --- a/contracts/service-registry/src/state.rs +++ b/contracts/service-registry/src/state.rs @@ -20,7 +20,7 @@ use crate::ContractError; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct Service { pub name: String, - pub service_contract: Addr, + pub coordinator_contract: Addr, pub min_num_verifiers: u16, pub max_num_verifiers: Option, pub min_verifier_bond: Uint128, diff --git a/doc/src/contracts/service_registry.md b/doc/src/contracts/service_registry.md index 7fe2b84dd..60237bf55 100644 --- a/doc/src/contracts/service_registry.md +++ b/doc/src/contracts/service_registry.md @@ -26,7 +26,7 @@ pub enum ExecuteMsg { // Can only be called by governance account RegisterService { service_name: String, - service_contract: Addr, + coordinator_contract: Addr, min_num_verifiers: u16, max_num_verifiers: Option, min_verifier_bond: Uint128, diff --git a/integration-tests/tests/bond_unbond.rs b/integration-tests/tests/bond_unbond.rs index 16e2118a8..4ee8da440 100644 --- a/integration-tests/tests/bond_unbond.rs +++ b/integration-tests/tests/bond_unbond.rs @@ -1,11 +1,20 @@ use cosmwasm_std::BlockInfo; +use integration_tests::contract::Contract; +use service_registry::msg::ExecuteMsg; pub mod test_utils; #[test] -fn verifiers_can_claim_stake() { +fn claim_stake_after_rotation_success() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + let test_utils::TestCase { mut protocol, + chain1: ethereum, + chain2: polygon, verifiers, min_verifier_bond, unbonding_period_days, @@ -14,8 +23,29 @@ fn verifiers_can_claim_stake() { let before_balances = test_utils::query_balances(&protocol.app, &verifiers); + let new_verifiers = test_utils::create_new_verifiers_vec( + chains.clone(), + vec![("verifier3".to_string(), 3), ("verifier4".to_string(), 4)], + ); + + test_utils::register_verifiers(&mut protocol, &new_verifiers, min_verifier_bond); + test_utils::deregister_verifiers(&mut protocol, &verifiers); + test_utils::rotate_active_verifier_set(&mut protocol, ethereum, &verifiers, &new_verifiers); + test_utils::rotate_active_verifier_set(&mut protocol, polygon, &verifiers, &new_verifiers); + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::UnbondVerifier { + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + } + // balances don't change after deregistering assert_eq!( before_balances, @@ -33,10 +63,259 @@ fn verifiers_can_claim_stake() { ..block }); - test_utils::claim_stakes(&mut protocol, &verifiers); + let claim_results = test_utils::claim_stakes(&mut protocol, &verifiers); + for claim_result in claim_results { + assert!(claim_result.is_ok()); + } + let after_balances = test_utils::query_balances(&protocol.app, &verifiers); for (before_balance, after_balance) in before_balances.into_iter().zip(after_balances) { assert_eq!(after_balance, before_balance + min_verifier_bond); } } + +#[test] +fn claim_stake_when_in_all_active_verifier_sets_fails() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + + let test_utils::TestCase { + mut protocol, + verifiers, + min_verifier_bond, + .. + } = test_utils::setup_test_case(); + + let new_verifiers = test_utils::create_new_verifiers_vec( + chains.clone(), + vec![("verifier3".to_string(), 3), ("verifier4".to_string(), 4)], + ); + + test_utils::register_verifiers(&mut protocol, &new_verifiers, min_verifier_bond); + + test_utils::deregister_verifiers(&mut protocol, &verifiers); + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::UnbondVerifier { + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + } + + let claim_results = test_utils::claim_stakes(&mut protocol, &verifiers); + for claim_result in claim_results { + assert!(claim_result.is_err()); + } +} + +#[test] +fn claim_stake_when_in_some_active_verifier_sets_fails() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + + let test_utils::TestCase { + mut protocol, + chain1: ethereum, + verifiers, + min_verifier_bond, + .. + } = test_utils::setup_test_case(); + + let new_verifiers = test_utils::create_new_verifiers_vec( + chains.clone(), + vec![("verifier3".to_string(), 3), ("verifier4".to_string(), 4)], + ); + + test_utils::register_verifiers(&mut protocol, &new_verifiers, min_verifier_bond); + + test_utils::deregister_verifiers(&mut protocol, &verifiers); + + // Only rotate the first chain's verifier set + test_utils::rotate_active_verifier_set(&mut protocol, ethereum, &verifiers, &new_verifiers); + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::UnbondVerifier { + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + } + + let claim_results = test_utils::claim_stakes(&mut protocol, &verifiers); + for claim_result in claim_results { + assert!(claim_result.is_err()); + } +} + +#[test] +fn claim_stake_after_deregistering_before_rotation_fails() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + + let test_utils::TestCase { + mut protocol, + verifiers, + min_verifier_bond, + .. + } = test_utils::setup_test_case(); + + let new_verifiers = test_utils::create_new_verifiers_vec( + chains.clone(), + vec![("verifier3".to_string(), 3), ("verifier4".to_string(), 4)], + ); + + test_utils::register_verifiers(&mut protocol, &new_verifiers, min_verifier_bond); + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::DeregisterChainSupport { + service_name: protocol.service_name.to_string(), + chains: chains.clone(), + }, + ); + assert!(response.is_ok()); + } + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::UnbondVerifier { + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + } + + let claim_results = test_utils::claim_stakes(&mut protocol, &verifiers); + for claim_result in claim_results { + assert!(claim_result.is_err()); + } +} + +#[test] +fn claim_stake_when_jailed_fails() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + + let test_utils::TestCase { + mut protocol, + chain1: ethereum, + chain2: polygon, + verifiers, + min_verifier_bond, + .. + } = test_utils::setup_test_case(); + + let new_verifiers = test_utils::create_new_verifiers_vec( + chains.clone(), + vec![("verifier3".to_string(), 3), ("verifier4".to_string(), 4)], + ); + + test_utils::register_verifiers(&mut protocol, &new_verifiers, min_verifier_bond); + + test_utils::deregister_verifiers(&mut protocol, &verifiers); + + test_utils::rotate_active_verifier_set(&mut protocol, ethereum, &verifiers, &new_verifiers); + test_utils::rotate_active_verifier_set(&mut protocol, polygon, &verifiers, &new_verifiers); + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::UnbondVerifier { + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + } + + let response = protocol.service_registry.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &ExecuteMsg::JailVerifiers { + service_name: protocol.service_name.to_string(), + verifiers: vec!["verifier1".to_string(), "verifier2".to_string()], + }, + ); + assert!(response.is_ok()); + + let claim_results = test_utils::claim_stakes(&mut protocol, &verifiers); + for claim_result in claim_results { + assert!(claim_result.clone().is_err()); + } +} + +#[test] +fn claim_stake_when_in_next_verifier_sets_fails() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + + let test_utils::TestCase { + mut protocol, + chain1: ethereum, + chain2: polygon, + verifiers, + min_verifier_bond, + .. + } = test_utils::setup_test_case(); + + let new_verifiers = test_utils::create_new_verifiers_vec( + chains.clone(), + vec![("verifier3".to_string(), 3), ("verifier4".to_string(), 4)], + ); + + test_utils::register_verifiers(&mut protocol, &new_verifiers, min_verifier_bond); + + test_utils::deregister_verifiers(&mut protocol, &verifiers); + + let response = ethereum.multisig_prover.execute( + &mut protocol.app, + ethereum.multisig_prover.admin_addr.clone(), + &multisig_prover::msg::ExecuteMsg::UpdateVerifierSet, + ); + assert!(response.is_ok()); + + let response = polygon.multisig_prover.execute( + &mut protocol.app, + polygon.multisig_prover.admin_addr.clone(), + &multisig_prover::msg::ExecuteMsg::UpdateVerifierSet, + ); + assert!(response.is_ok()); + + for verifier in &verifiers { + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::UnbondVerifier { + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + } + + let claim_results = test_utils::claim_stakes(&mut protocol, &verifiers); + for claim_result in claim_results { + assert!(claim_result.is_err()); + } +} diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index fe0966818..86a5f05da 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -265,7 +265,7 @@ pub fn register_service( protocol.governance_address.clone(), &ExecuteMsg::RegisterService { service_name: protocol.service_name.to_string(), - service_contract: Addr::unchecked("nowhere"), + coordinator_contract: protocol.coordinator.contract_addr.clone(), min_num_verifiers: 0, max_num_verifiers: Some(100), min_verifier_bond, @@ -538,7 +538,12 @@ pub fn deregister_verifiers(protocol: &mut Protocol, verifiers: &Vec) } } -pub fn claim_stakes(protocol: &mut Protocol, verifiers: &Vec) { +pub fn claim_stakes( + protocol: &mut Protocol, + verifiers: &Vec, +) -> Vec> { + let mut responses = Vec::new(); + for verifier in verifiers { let response = protocol.service_registry.execute( &mut protocol.app, @@ -547,8 +552,11 @@ pub fn claim_stakes(protocol: &mut Protocol, verifiers: &Vec) { service_name: protocol.service_name.to_string(), }, ); - assert!(response.is_ok()); + + responses.push(response.map_err(|e| e.to_string())); } + + responses } pub fn confirm_verifier_set( @@ -712,7 +720,11 @@ pub struct Chain { pub chain_name: ChainName, } -pub fn setup_chain(protocol: &mut Protocol, chain_name: ChainName) -> Chain { +pub fn setup_chain( + protocol: &mut Protocol, + chain_name: ChainName, + verifiers: &Vec, +) -> Chain { let voting_verifier = VotingVerifierContract::instantiate_contract( protocol, "doesn't matter".to_string().try_into().unwrap(), @@ -798,6 +810,16 @@ pub fn setup_chain(protocol: &mut Protocol, chain_name: ChainName) -> Chain { ); assert!(response.is_ok()); + let verifier_set = verifiers_to_verifier_set(protocol, verifiers); + let response = protocol.coordinator.execute( + &mut protocol.app, + multisig_prover.contract_addr.clone(), + &coordinator::msg::ExecuteMsg::SetActiveVerifiers { + next_verifier_set: verifier_set, + }, + ); + assert!(response.is_ok()); + Chain { gateway, voting_verifier, @@ -822,6 +844,53 @@ pub fn query_balances(app: &App, verifiers: &Vec) -> Vec { balances } +pub fn rotate_active_verifier_set( + protocol: &mut Protocol, + chain: Chain, + previous_verifiers: &Vec, + new_verifiers: &Vec, +) { + let response = chain.multisig_prover.execute( + &mut protocol.app, + chain.multisig_prover.admin_addr.clone(), + &multisig_prover::msg::ExecuteMsg::UpdateVerifierSet, + ); + assert!(response.is_ok()); + + let session_id = sign_proof(protocol, previous_verifiers, response.unwrap()); + + let proof = get_proof(&mut protocol.app, &chain.multisig_prover, &session_id); + assert!(matches!( + proof.status, + multisig_prover::msg::ProofStatus::Completed { .. } + )); + assert_eq!(proof.message_ids.len(), 0); + + let new_verifier_set = verifiers_to_verifier_set(protocol, new_verifiers); + let (poll_id, expiry) = create_verifier_set_poll( + &mut protocol.app, + Addr::unchecked("relayer"), + &chain.voting_verifier, + new_verifier_set.clone(), + ); + + vote_true_for_verifier_set( + &mut protocol.app, + &chain.voting_verifier, + new_verifiers, + poll_id, + ); + + advance_at_least_to_height(&mut protocol.app, expiry); + end_poll(&mut protocol.app, &chain.voting_verifier, poll_id); + + confirm_verifier_set( + &mut protocol.app, + Addr::unchecked("relayer"), + &chain.multisig_prover, + ); +} + pub struct TestCase { pub protocol: Protocol, pub chain1: Chain, @@ -855,8 +924,8 @@ pub fn setup_test_case() -> TestCase { register_service(&mut protocol, min_verifier_bond, unbonding_period_days); register_verifiers(&mut protocol, &verifiers, min_verifier_bond); - let chain1 = setup_chain(&mut protocol, chains.first().unwrap().clone()); - let chain2 = setup_chain(&mut protocol, chains.get(1).unwrap().clone()); + let chain1 = setup_chain(&mut protocol, chains.first().unwrap().clone(), &verifiers); + let chain2 = setup_chain(&mut protocol, chains.get(1).unwrap().clone(), &verifiers); TestCase { protocol, chain1, From 4a9f31f830a078597c1b7e5a97dcf648875ca89e Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Fri, 31 May 2024 15:19:57 -0400 Subject: [PATCH 002/168] docs: add compatibility matrix to readme (#441) --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index 788c1f9d4..a994108d5 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,23 @@ The basic rules are as follows: - if no changes are detected in the watched directories, the release will not bump the version. For example, if since last release for the gateway contract no changes were made in the `contracts/gateway` or `packages/` directory. A new release will not bump the version. + +### Compatibility + +For the amplifier preview with version numbers < 1.0.0, please refer to the following compatibility table to select versions of +contracts and `ampd` that work well together. + +| Binary | Version | +|-------------|---------| +| ampd | 0.4.0 | +| coordinator | 0.1.2 | +| gateway | 0.2.2 | +| multisig-prover | 0.5.0 | +| multisig | 0.3.0 | +| nexus-gateway | 0.2.3 | +| rewards | 0.2.0 | +| router | 0.3.2 | +| service-registry | 0.3.0 | +| voting-verifier | 0.4.0 | +| [tofnd](https://github.com/axelarnetwork/tofnd) | TBD | +| [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | From cb8c5d3be80d30be4fc0069696e59e6f87b57303 Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 3 Jun 2024 14:51:09 -0400 Subject: [PATCH 003/168] refactor(ampd): merge tofnd MultisigClient and SharableEcdsaClient (#442) --- ampd/src/broadcaster.rs | 41 ++--- ampd/src/commands/mod.rs | 26 ++- ampd/src/commands/register_public_key.rs | 14 +- ampd/src/handlers/multisig.rs | 53 ++++--- ampd/src/lib.rs | 19 ++- ampd/src/tofnd/grpc.rs | 191 +++-------------------- 6 files changed, 92 insertions(+), 252 deletions(-) diff --git a/ampd/src/broadcaster.rs b/ampd/src/broadcaster.rs index 5348a3930..3d646e078 100644 --- a/ampd/src/broadcaster.rs +++ b/ampd/src/broadcaster.rs @@ -29,7 +29,7 @@ use dec_coin::DecCoin; use report::LoggableError; use tx::Tx; -use crate::tofnd::grpc::SharableEcdsaClient; +use crate::tofnd::grpc::Multisig; use crate::types::{PublicKey, TMAddress}; pub mod accounts; @@ -92,9 +92,9 @@ pub trait Broadcaster { } #[derive(TypedBuilder)] -pub struct BroadcastClient { +pub struct BroadcastClient { client: T, - signer: SharableEcdsaClient, + signer: S, query_client: Q, address: TMAddress, #[builder(default, setter(skip))] @@ -104,9 +104,10 @@ pub struct BroadcastClient { } #[async_trait] -impl Broadcaster for BroadcastClient +impl Broadcaster for BroadcastClient where T: clients::BroadcastClient + Send, + S: Multisig + Send + Sync, Q: clients::AccountQueryClient + Send, { async fn broadcast(&mut self, msgs: Vec) -> Result { @@ -168,7 +169,7 @@ where } } -impl BroadcastClient +impl BroadcastClient where T: clients::BroadcastClient, Q: clients::AccountQueryClient, @@ -310,7 +311,7 @@ mod tests { use crate::broadcaster::clients::{MockAccountQueryClient, MockBroadcastClient}; use crate::broadcaster::{BroadcastClient, Broadcaster, Config, Error}; - use crate::tofnd::grpc::{MockEcdsaClient, SharableEcdsaClient}; + use crate::tofnd::grpc::MockMultisig; use crate::types::{PublicKey, TMAddress}; use crate::PREFIX; @@ -335,7 +336,7 @@ mod tests { .expect_simulate() .returning(|_| Err(Status::unavailable("unavailable service").into())); - let signer = MockEcdsaClient::new(); + let signer = MockMultisig::default(); let mut query_client = MockAccountQueryClient::new(); query_client.expect_account().returning(move |_| { @@ -346,7 +347,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) @@ -388,7 +389,7 @@ mod tests { }) }); - let signer = MockEcdsaClient::new(); + let signer = MockMultisig::default(); let mut query_client = MockAccountQueryClient::new(); query_client.expect_account().returning(move |_| { @@ -399,7 +400,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) @@ -447,7 +448,7 @@ mod tests { .expect_broadcast_tx() .returning(|_| Err(Status::aborted("failed").into())); - let mut signer = MockEcdsaClient::new(); + let mut signer = MockMultisig::default(); signer .expect_sign() .once() @@ -471,7 +472,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) @@ -523,7 +524,7 @@ mod tests { .times((Config::default().tx_fetch_max_retries + 1) as usize) .returning(|_| Err(Status::deadline_exceeded("time out").into())); - let mut signer = MockEcdsaClient::new(); + let mut signer = MockMultisig::default(); signer .expect_sign() .once() @@ -547,7 +548,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) @@ -604,7 +605,7 @@ mod tests { }) }); - let mut signer = MockEcdsaClient::new(); + let mut signer = MockMultisig::default(); signer .expect_sign() .once() @@ -628,7 +629,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) @@ -687,7 +688,7 @@ mod tests { }) }); - let mut signer = MockEcdsaClient::new(); + let mut signer = MockMultisig::default(); signer .expect_sign() .once() @@ -711,7 +712,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) @@ -763,7 +764,7 @@ mod tests { }) }); - let mut signer = MockEcdsaClient::new(); + let mut signer = MockMultisig::default(); signer .expect_sign() .times(3) @@ -802,7 +803,7 @@ mod tests { let mut broadcaster = BroadcastClient::builder() .client(client) - .signer(SharableEcdsaClient::new(signer)) + .signer(signer) .query_client(query_client) .address(address) .pub_key((key_id.to_string(), pub_key)) diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 10b600ade..9135e4ccf 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -15,7 +15,7 @@ use valuable::Valuable; use crate::broadcaster::Broadcaster; use crate::config::Config as AmpdConfig; use crate::state; -use crate::tofnd::grpc::{MultisigClient, SharableEcdsaClient}; +use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::{PublicKey, TMAddress}; use crate::{broadcaster, Error}; use crate::{tofnd, PREFIX}; @@ -61,14 +61,12 @@ async fn verifier_pub_key(state_path: &Path, config: tofnd::Config) -> Result Ok(pub_key), - None => SharableEcdsaClient::new( - MultisigClient::connect(config.party_uid, config.url) - .await - .change_context(Error::Connection)?, - ) - .keygen(&config.key_uid) - .await - .change_context(Error::Tofnd), + None => MultisigClient::new(config.party_uid, config.url) + .await + .change_context(Error::Connection)? + .keygen(&config.key_uid) + .await + .change_context(Error::Tofnd), } } @@ -90,11 +88,9 @@ async fn broadcast_tx( let query_client = QueryClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection)?; - let ecdsa_client = SharableEcdsaClient::new( - MultisigClient::connect(tofnd_config.party_uid, tofnd_config.url) - .await - .change_context(Error::Connection)?, - ); + let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) + .await + .change_context(Error::Connection)?; let address = pub_key .account_id(PREFIX) .expect("failed to convert to account identifier") @@ -102,7 +98,7 @@ async fn broadcast_tx( broadcaster::BroadcastClient::builder() .client(service_client) - .signer(ecdsa_client) + .signer(multisig_client) .query_client(query_client) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast) diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index e0d6c22fe..1afd4960b 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -14,7 +14,7 @@ use tracing::info; use crate::commands::{broadcast_tx, verifier_pub_key}; use crate::config::Config; -use crate::tofnd::grpc::{MultisigClient, SharableEcdsaClient}; +use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::TMAddress; use crate::{handlers, Error, PREFIX}; @@ -25,12 +25,10 @@ pub async fn run(config: Config, state_path: &Path) -> Result, Er let tofnd_config = config.tofnd_config.clone(); - let ecdsa_client = SharableEcdsaClient::new( - MultisigClient::connect(tofnd_config.party_uid, tofnd_config.url) - .await - .change_context(Error::Connection)?, - ); - let multisig_key = ecdsa_client + let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) + .await + .change_context(Error::Connection)?; + let multisig_key = multisig_client .keygen(&multisig_address.to_string()) .await .change_context(Error::Tofnd)?; @@ -43,7 +41,7 @@ pub async fn run(config: Config, state_path: &Path) -> Result, Er .try_into() .expect("wrong length"); - let signed_sender_address = ecdsa_client + let signed_sender_address = multisig_client .sign( &multisig_address.to_string(), address_hash.into(), diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 290a99602..bd5b699f3 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -20,7 +20,7 @@ use multisig::msg::ExecuteMsg; use crate::event_processor::EventHandler; use crate::handlers::errors::Error::{self, DeserializeEvent}; -use crate::tofnd::grpc::SharableEcdsaClient; +use crate::tofnd::grpc::Multisig; use crate::tofnd::MessageDigest; use crate::types::PublicKey; use crate::types::TMAddress; @@ -66,18 +66,21 @@ where .collect() } -pub struct Handler { +pub struct Handler { verifier: TMAddress, multisig: TMAddress, - signer: SharableEcdsaClient, + signer: S, latest_block_height: Receiver, } -impl Handler { +impl Handler +where + S: Multisig, +{ pub fn new( verifier: TMAddress, multisig: TMAddress, - signer: SharableEcdsaClient, + signer: S, latest_block_height: Receiver, ) -> Self { Self { @@ -107,7 +110,10 @@ impl Handler { } #[async_trait] -impl EventHandler for Handler { +impl EventHandler for Handler +where + S: Multisig + Sync, +{ type Err = Error; async fn handle(&self, event: &events::Event) -> error_stack::Result, Error> { @@ -191,7 +197,7 @@ mod test { use crate::broadcaster::MockBroadcaster; use crate::tofnd; - use crate::tofnd::grpc::{MockEcdsaClient, SharableEcdsaClient}; + use crate::tofnd::grpc::MockMultisig; use crate::types; use super::*; @@ -291,9 +297,9 @@ mod test { fn get_handler( verifier: TMAddress, multisig: TMAddress, - signer: SharableEcdsaClient, + signer: MockMultisig, latest_block_height: u64, - ) -> Handler { + ) -> Handler { let mut broadcaster = MockBroadcaster::new(); broadcaster .expect_broadcast() @@ -361,12 +367,12 @@ mod test { #[tokio::test] async fn should_not_handle_event_with_missing_fields_if_multisig_address_does_not_match() { - let client = MockEcdsaClient::new(); + let client = MockMultisig::default(); let handler = get_handler( rand_account(), TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), - SharableEcdsaClient::new(client), + client, 100u64, ); @@ -383,12 +389,12 @@ mod test { #[tokio::test] async fn should_error_on_event_with_missing_fields_if_multisig_address_does_match() { - let client = MockEcdsaClient::new(); + let client = MockMultisig::default(); let handler = get_handler( rand_account(), TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), - SharableEcdsaClient::new(client), + client, 100u64, ); @@ -400,14 +406,9 @@ mod test { #[tokio::test] async fn should_not_handle_event_if_multisig_address_does_not_match() { - let client = MockEcdsaClient::new(); + let client = MockMultisig::default(); - let handler = get_handler( - rand_account(), - rand_account(), - SharableEcdsaClient::new(client), - 100u64, - ); + let handler = get_handler(rand_account(), rand_account(), client, 100u64); assert_eq!( handler.handle(&signing_started_event()).await.unwrap(), @@ -417,7 +418,7 @@ mod test { #[tokio::test] async fn should_not_handle_event_if_verifier_is_not_a_participant() { - let mut client = MockEcdsaClient::new(); + let mut client = MockMultisig::default(); client .expect_sign() .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); @@ -425,7 +426,7 @@ mod test { let handler = get_handler( rand_account(), TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), - SharableEcdsaClient::new(client), + client, 100u64, ); @@ -437,7 +438,7 @@ mod test { #[tokio::test] async fn should_not_handle_event_if_sign_failed() { - let mut client = MockEcdsaClient::new(); + let mut client = MockMultisig::default(); client .expect_sign() .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); @@ -448,7 +449,7 @@ mod test { let handler = get_handler( verifier, TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), - SharableEcdsaClient::new(client), + client, 99u64, ); @@ -460,7 +461,7 @@ mod test { #[tokio::test] async fn should_not_handle_event_if_session_expired() { - let mut client = MockEcdsaClient::new(); + let mut client = MockMultisig::default(); client .expect_sign() .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); @@ -471,7 +472,7 @@ mod test { let handler = get_handler( verifier, TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), - SharableEcdsaClient::new(client), + client, 101u64, ); diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 4e70c1550..395e0a159 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -23,7 +23,7 @@ use event_sub::EventSub; use events::Event; use queue::queued_broadcaster::{QueuedBroadcaster, QueuedBroadcasterDriver}; use state::StateUpdater; -use tofnd::grpc::{MultisigClient, SharableEcdsaClient}; +use tofnd::grpc::{Multisig, MultisigClient}; use types::TMAddress; use crate::config::Config; @@ -85,10 +85,9 @@ async fn prepare_app(cfg: Config, state: State) -> Result, let query_client = QueryClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection)?; - let multisig_client = MultisigClient::connect(tofnd_config.party_uid, tofnd_config.url) + let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) .await .change_context(Error::Connection)?; - let ecdsa_client = SharableEcdsaClient::new(multisig_client); let block_height_monitor = BlockHeightMonitor::connect(tm_client.clone()) .await @@ -98,7 +97,7 @@ async fn prepare_app(cfg: Config, state: State) -> Result, let pub_key = match state_updater.state().pub_key { Some(pub_key) => pub_key, None => { - let pub_key = ecdsa_client + let pub_key = multisig_client .keygen(&tofnd_config.key_uid) .await .change_context(Error::Tofnd)?; @@ -117,7 +116,7 @@ async fn prepare_app(cfg: Config, state: State) -> Result, .query_client(query_client) .address(verifier.clone()) .client(service_client) - .signer(ecdsa_client.clone()) + .signer(multisig_client.clone()) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast.clone()) .build(); @@ -128,7 +127,7 @@ async fn prepare_app(cfg: Config, state: State) -> Result, tm_client, broadcaster, state_updater, - ecdsa_client, + multisig_client, broadcast, event_buffer_cap, block_height_monitor, @@ -165,7 +164,7 @@ where #[allow(dead_code)] broadcaster_driver: QueuedBroadcasterDriver, state_updater: StateUpdater, - ecdsa_client: SharableEcdsaClient, + multisig_client: MultisigClient, block_height_monitor: BlockHeightMonitor, health_check_server: health_check::Server, token: CancellationToken, @@ -180,7 +179,7 @@ where tm_client: tendermint_rpc::HttpClient, broadcaster: T, state_updater: StateUpdater, - ecdsa_client: SharableEcdsaClient, + multisig_client: MultisigClient, broadcast_cfg: broadcaster::Config, event_buffer_cap: usize, block_height_monitor: BlockHeightMonitor, @@ -210,7 +209,7 @@ where broadcaster, broadcaster_driver, state_updater, - ecdsa_client, + multisig_client, block_height_monitor, health_check_server, token, @@ -289,7 +288,7 @@ where handlers::multisig::Handler::new( verifier.clone(), cosmwasm_contract, - self.ecdsa_client.clone(), + self.multisig_client.clone(), self.block_height_monitor.latest_block_height(), ), stream_timeout, diff --git a/ampd/src/tofnd/grpc.rs b/ampd/src/tofnd/grpc.rs index 2907f621b..0c08d7182 100644 --- a/ampd/src/tofnd/grpc.rs +++ b/ampd/src/tofnd/grpc.rs @@ -20,41 +20,46 @@ type Result = error_stack::Result; #[automock] #[async_trait] -pub trait EcdsaClient: Send { - async fn keygen(&mut self, key_uid: &str) -> Result; +pub trait Multisig { + async fn keygen(&self, key_uid: &str) -> Result; async fn sign( - &mut self, + &self, key_uid: &str, data: MessageDigest, pub_key: &PublicKey, ) -> Result; } +#[derive(Clone)] pub struct MultisigClient { - client: multisig_client::MultisigClient, party_uid: String, + client: Arc>>, } impl MultisigClient { - pub async fn connect(party_uid: String, url: Url) -> Result { + pub async fn new(party_uid: String, url: Url) -> Result { Ok(Self { party_uid, - client: multisig_client::MultisigClient::connect(url.to_string()) - .await - .change_context(Error::Grpc)?, + client: Arc::new(Mutex::new( + multisig_client::MultisigClient::connect(url.to_string()) + .await + .change_context(Error::Grpc)?, + )), }) } } #[async_trait] -impl EcdsaClient for MultisigClient { - async fn keygen(&mut self, key_uid: &str) -> Result { +impl Multisig for MultisigClient { + async fn keygen(&self, key_uid: &str) -> Result { let request = KeygenRequest { key_uid: key_uid.to_string(), party_uid: self.party_uid.to_string(), }; self.client + .lock() + .await .keygen(request) .await .and_then(|response| { @@ -78,7 +83,7 @@ impl EcdsaClient for MultisigClient { } async fn sign( - &mut self, + &self, key_uid: &str, data: MessageDigest, pub_key: &PublicKey, @@ -91,6 +96,8 @@ impl EcdsaClient for MultisigClient { }; self.client + .lock() + .await .sign(request) .await .and_then(|response| { @@ -113,165 +120,3 @@ impl EcdsaClient for MultisigClient { }) } } - -#[derive(Clone)] -pub struct SharableEcdsaClient(Arc>); - -impl SharableEcdsaClient { - pub fn new(client: impl EcdsaClient + 'static) -> Self { - Self(Arc::new(Mutex::new(client))) - } - - pub async fn keygen(&self, key_uid: &str) -> Result { - self.0.lock().await.keygen(key_uid).await - } - - pub async fn sign( - &self, - key_uid: &str, - data: MessageDigest, - pub_key: &PublicKey, - ) -> Result { - self.0.lock().await.sign(key_uid, data, pub_key).await - } -} - -#[cfg(test)] -mod tests { - use ecdsa::SigningKey; - use error_stack::Report; - use futures::future::join_all; - use k256::Secp256k1; - use rand::rngs::OsRng; - use rand::{thread_rng, RngCore}; - use tokio::test; - - use crate::tofnd::{ - error::Error, - grpc::{MockEcdsaClient, SharableEcdsaClient}, - MessageDigest, Signature, - }; - - const KEY_UID: &str = "key_1"; - - #[test] - async fn keygen_error_response() { - let mut client = MockEcdsaClient::new(); - client - .expect_keygen() - .returning(|_| Err(Report::from(Error::KeygenFailed))); - - assert!(matches!( - SharableEcdsaClient::new(client) - .keygen(KEY_UID) - .await - .unwrap_err() - .current_context(), - Error::KeygenFailed - )); - } - - #[test] - async fn keygen_succeeded() { - let rand_pub_key = SigningKey::random(&mut OsRng).verifying_key().into(); - - let mut client = MockEcdsaClient::new(); - client.expect_keygen().returning(move |_| Ok(rand_pub_key)); - - assert_eq!( - SharableEcdsaClient::new(client) - .keygen(KEY_UID) - .await - .unwrap(), - rand_pub_key - ); - } - - #[test] - async fn sign_error_response() { - let mut client = MockEcdsaClient::new(); - client - .expect_sign() - .returning(move |_, _, _| Err(Report::from(Error::SignFailed))); - - let digest: MessageDigest = rand::random::<[u8; 32]>().into(); - assert!(matches!( - SharableEcdsaClient::new(client) - .sign( - KEY_UID, - digest, - &SigningKey::random(&mut OsRng).verifying_key().into() - ) - .await - .unwrap_err() - .current_context(), - Error::SignFailed - )); - } - - #[test] - async fn sign_succeeded() { - let mut hash = [0u8; 64]; - thread_rng().fill_bytes(&mut hash); - - let priv_key = SigningKey::::random(&mut OsRng); - let (signature, _) = priv_key.sign_prehash_recoverable(hash.as_ref()).unwrap(); - - let mut client = MockEcdsaClient::new(); - client - .expect_sign() - .returning(move |_, _, _| Ok(signature.to_vec())); - - let digest: MessageDigest = rand::random::<[u8; 32]>().into(); - - assert_eq!( - SharableEcdsaClient::new(client) - .sign( - KEY_UID, - digest, - &SigningKey::random(&mut OsRng).verifying_key().into(), - ) - .await - .unwrap(), - Signature::from(signature.to_vec()), - ); - } - - #[test] - async fn share_across_threads() { - let mut hash = [0u8; 64]; - thread_rng().fill_bytes(&mut hash); - - let priv_key = SigningKey::::random(&mut OsRng); - let (signature, _) = priv_key.sign_prehash_recoverable(&hash).unwrap(); - - let mut client = MockEcdsaClient::new(); - client - .expect_sign() - .returning(move |_, _, _| Ok(signature.to_vec())); - - let client = SharableEcdsaClient::new(client); - - let mut handles = Vec::new(); - for _ in 0..5 { - let cloned = client.clone(); - let handle = tokio::spawn(async move { - let digest: MessageDigest = rand::random::<[u8; 32]>().into(); - assert_eq!( - cloned - .sign( - KEY_UID, - digest, - &SigningKey::random(&mut OsRng).verifying_key().into() - ) - .await - .unwrap(), - Signature::from(signature.to_vec()), - ) - }); - handles.push(handle); - } - - join_all(handles).await; - } -} From fe08c00e11974223ceb2c61c28ea75df826ec99e Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 3 Jun 2024 16:52:39 -0400 Subject: [PATCH 004/168] feat(ampd): add tofnd grpc server support (#443) --- ampd/proto/ampd.proto | 25 +++ ampd/proto/tofnd/common.proto | 27 ++- ampd/proto/tofnd/multisig.proto | 41 ++--- ampd/src/broadcaster.rs | 19 ++- ampd/src/commands/mod.rs | 2 +- ampd/src/commands/register_public_key.rs | 4 +- ampd/src/grpc/ampd.rs | 5 +- ampd/src/grpc/crypto.rs | 200 +++++++++++++++++++++++ ampd/src/grpc/mod.rs | 20 ++- ampd/src/handlers/multisig.rs | 15 +- ampd/src/lib.rs | 2 +- ampd/src/tofnd/grpc.rs | 12 +- ampd/src/tofnd/mod.rs | 4 +- 13 files changed, 320 insertions(+), 56 deletions(-) create mode 100644 ampd/src/grpc/crypto.rs diff --git a/ampd/proto/ampd.proto b/ampd/proto/ampd.proto index 1da3612b5..59bb0ebe6 100644 --- a/ampd/proto/ampd.proto +++ b/ampd/proto/ampd.proto @@ -4,6 +4,11 @@ import "google/protobuf/any.proto"; package ampd; +enum Algorithm { + ALGORITHM_ECDSA = 0; + ALGORITHM_ED25519 = 1; +} + message SubscribeRequest { // the subscription will return all events that match ANY of these filters repeated Event event_filters = 1; @@ -35,3 +40,23 @@ service Ampd { rpc Subscribe(SubscribeRequest) returns (stream SubscribeResponse) {} rpc Broadcast(BroadcastRequest) returns (BroadcastResponse) {} } + +message SignRequest { + string key_id = 1; + bytes msg = 2; + Algorithm algorithm = 3; +} + +message SignResponse { bytes signature = 1; } + +message GetKeyRequest { + string key_id = 1; + Algorithm algorithm = 2; +} + +message GetKeyResponse { bytes pub_key = 1; } + +service Crypto { + rpc Sign(SignRequest) returns (SignResponse) {} + rpc GetKey(GetKeyRequest) returns (GetKeyResponse) {} +} diff --git a/ampd/proto/tofnd/common.proto b/ampd/proto/tofnd/common.proto index 0ddf272e2..12793c106 100644 --- a/ampd/proto/tofnd/common.proto +++ b/ampd/proto/tofnd/common.proto @@ -1,20 +1,29 @@ syntax = "proto3"; +option go_package = "tofnd;tofnd"; + package tofnd; +enum Algorithm { + ALGORITHM_ECDSA = 0; + ALGORITHM_ED25519 = 1; +} + // Key presence check types message KeyPresenceRequest { - string key_uid = 1; - bytes pub_key = 2; // SEC1-encoded compressed pub key bytes to find the right mnemonic. Latest is used, if empty. + string key_uid = 1; + bytes pub_key = 2; // SEC1-encoded compressed pub key bytes to find the right + // mnemonic. Latest is used, if empty. + Algorithm algorithm = 3; } message KeyPresenceResponse { - enum Response { - RESPONSE_UNSPECIFIED = 0; - RESPONSE_PRESENT = 1; - RESPONSE_ABSENT = 2; - RESPONSE_FAIL = 3; - } + enum Response { + RESPONSE_UNSPECIFIED = 0; + RESPONSE_PRESENT = 1; + RESPONSE_ABSENT = 2; + RESPONSE_FAIL = 3; + } - Response response = 1; + Response response = 1; } diff --git a/ampd/proto/tofnd/multisig.proto b/ampd/proto/tofnd/multisig.proto index c7ce22977..f6b4cc0b8 100644 --- a/ampd/proto/tofnd/multisig.proto +++ b/ampd/proto/tofnd/multisig.proto @@ -5,33 +5,36 @@ package tofnd; import "common.proto"; // import key presence request/response service Multisig { - rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); - rpc Keygen(KeygenRequest) returns (KeygenResponse); - rpc Sign(SignRequest) returns (SignResponse); + rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); + rpc Keygen(KeygenRequest) returns (KeygenResponse); + rpc Sign(SignRequest) returns (SignResponse); } message KeygenRequest { - string key_uid = 1; - string party_uid = 2; // used only for logging + string key_uid = 1; + string party_uid = 2; // used only for logging + Algorithm algorithm = 3; } -message KeygenResponse { - oneof keygen_response { - bytes pub_key = 1; // SEC1-encoded compressed curve point - string error = 2; // reply with an error message if keygen fails - } +message KeygenResponse { + oneof keygen_response { + bytes pub_key = 1; // SEC1-encoded compressed curve point + string error = 2; // reply with an error message if keygen fails + } } message SignRequest { - string key_uid = 1; - bytes msg_to_sign = 2; // 32-byte pre-hashed message digest - string party_uid = 3; // used only for logging - bytes pub_key = 4; // SEC1-encoded compressed pub key bytes to find the right mnemonic. Latest is used, if empty. + string key_uid = 1; + bytes msg_to_sign = 2; // 32-byte pre-hashed message digest + string party_uid = 3; // used only for logging + bytes pub_key = 4; // SEC1-encoded compressed pub key bytes to find the right + // mnemonic. Latest is used, if empty. + Algorithm algorithm = 5; } -message SignResponse { - oneof sign_response { - bytes signature = 1; // ASN.1 DER-encoded ECDSA signature - string error = 2; // reply with an error message if sign fails - } +message SignResponse { + oneof sign_response { + bytes signature = 1; // ASN.1 DER-encoded ECDSA signature + string error = 2; // reply with an error message if sign fails + } } diff --git a/ampd/src/broadcaster.rs b/ampd/src/broadcaster.rs index 3d646e078..4e1b4bddd 100644 --- a/ampd/src/broadcaster.rs +++ b/ampd/src/broadcaster.rs @@ -29,6 +29,7 @@ use dec_coin::DecCoin; use report::LoggableError; use tx::Tx; +use crate::tofnd; use crate::tofnd::grpc::Multisig; use crate::types::{PublicKey, TMAddress}; @@ -128,8 +129,12 @@ where .try_into() .expect("hash size must be 32"); - self.signer - .sign(self.pub_key.0.as_str(), sign_digest.into(), &self.pub_key.1) + self.signer.sign( + self.pub_key.0.as_str(), + sign_digest.into(), + &self.pub_key.1, + tofnd::Algorithm::Ecdsa, + ) }) .await .change_context(Error::TxBuilding)?; @@ -452,7 +457,7 @@ mod tests { signer .expect_sign() .once() - .returning(move |actual_key_uid, data, actual_pub_key| { + .returning(move |actual_key_uid, data, actual_pub_key, _| { assert_eq!(actual_key_uid, key_id); assert_eq!(actual_pub_key, &pub_key); @@ -528,7 +533,7 @@ mod tests { signer .expect_sign() .once() - .returning(move |actual_key_uid, data, actual_pub_key| { + .returning(move |actual_key_uid, data, actual_pub_key, _| { assert_eq!(actual_key_uid, key_id); assert_eq!(actual_pub_key, &pub_key); @@ -609,7 +614,7 @@ mod tests { signer .expect_sign() .once() - .returning(move |actual_key_uid, data, actual_pub_key| { + .returning(move |actual_key_uid, data, actual_pub_key, _| { assert_eq!(actual_key_uid, key_id); assert_eq!(actual_pub_key, &pub_key); @@ -692,7 +697,7 @@ mod tests { signer .expect_sign() .once() - .returning(move |actual_key_uid, data, actual_pub_key| { + .returning(move |actual_key_uid, data, actual_pub_key, _| { assert_eq!(actual_key_uid, key_id); assert_eq!(actual_pub_key, &pub_key); @@ -768,7 +773,7 @@ mod tests { signer .expect_sign() .times(3) - .returning(move |actual_key_uid, data, actual_pub_key| { + .returning(move |actual_key_uid, data, actual_pub_key, _| { assert_eq!(actual_key_uid, key_id); assert_eq!(actual_pub_key, &pub_key); diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 9135e4ccf..e98b66689 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -64,7 +64,7 @@ async fn verifier_pub_key(state_path: &Path, config: tofnd::Config) -> Result MultisigClient::new(config.party_uid, config.url) .await .change_context(Error::Connection)? - .keygen(&config.key_uid) + .keygen(&config.key_uid, tofnd::Algorithm::Ecdsa) .await .change_context(Error::Tofnd), } diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index 1afd4960b..eb89fe072 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -14,6 +14,7 @@ use tracing::info; use crate::commands::{broadcast_tx, verifier_pub_key}; use crate::config::Config; +use crate::tofnd; use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::TMAddress; use crate::{handlers, Error, PREFIX}; @@ -29,7 +30,7 @@ pub async fn run(config: Config, state_path: &Path) -> Result, Er .await .change_context(Error::Connection)?; let multisig_key = multisig_client - .keygen(&multisig_address.to_string()) + .keygen(&multisig_address.to_string(), tofnd::Algorithm::Ecdsa) .await .change_context(Error::Tofnd)?; info!(key_id = multisig_address.to_string(), "keygen successful"); @@ -46,6 +47,7 @@ pub async fn run(config: Config, state_path: &Path) -> Result, Er &multisig_address.to_string(), address_hash.into(), &multisig_key, + tofnd::Algorithm::Ecdsa, ) .await .change_context(Error::Tofnd)? diff --git a/ampd/src/grpc/ampd.rs b/ampd/src/grpc/ampd.rs index 8123e1d28..2d1549606 100644 --- a/ampd/src/grpc/ampd.rs +++ b/ampd/src/grpc/ampd.rs @@ -5,12 +5,9 @@ use events::Event; use futures::{Stream, StreamExt, TryStreamExt}; use tonic::{Request, Response, Status}; +use super::proto; use crate::{event_sub::EventSub, queue::queued_broadcaster::BroadcasterClient}; -pub mod proto { - tonic::include_proto!("ampd"); -} - impl From for proto::subscribe_response::Event { fn from(event: Event) -> Self { match event { diff --git a/ampd/src/grpc/crypto.rs b/ampd/src/grpc/crypto.rs new file mode 100644 index 000000000..a53ac3e63 --- /dev/null +++ b/ampd/src/grpc/crypto.rs @@ -0,0 +1,200 @@ +use async_trait::async_trait; +use k256::sha2::{Digest, Sha256}; +use tonic::{Request, Response, Status}; + +use crate::tofnd::{self, grpc::Multisig}; +use crate::types::PublicKey; + +use super::proto; + +impl From for tofnd::Algorithm { + fn from(algorithm: proto::Algorithm) -> Self { + match algorithm { + proto::Algorithm::Ed25519 => Self::Ed25519, + proto::Algorithm::Ecdsa => Self::Ecdsa, + } + } +} + +pub struct Server { + multisig_client: M, +} + +impl Server +where + M: Multisig, +{ + pub fn new(multisig_client: M) -> Self { + Self { multisig_client } + } + + async fn key(&self, key_id: &str, algorithm: proto::Algorithm) -> Result { + self.multisig_client + .keygen(key_id, algorithm.into()) + .await + .map_err(|err| Status::internal(err.to_string())) + } +} + +#[async_trait] +impl proto::crypto_server::Crypto for Server +where + M: Multisig + Send + Sync + 'static, +{ + async fn sign( + &self, + req: Request, + ) -> Result, Status> { + let req = req.into_inner(); + + let mut hasher = Sha256::new(); + hasher.update(req.msg); + let sign_digest: [u8; 32] = hasher + .finalize() + .to_vec() + .try_into() + .expect("hash size must be 32"); + + let algorithm = proto::Algorithm::from_i32(req.algorithm) + .ok_or(Status::invalid_argument("invalid algorithm"))?; + let key = self.key(&req.key_id, algorithm).await?; + let signature = self + .multisig_client + .sign(&req.key_id, sign_digest.into(), &key, algorithm.into()) + .await + .map_err(|err| Status::internal(err.to_string()))?; + + Ok(Response::new(proto::SignResponse { signature })) + } + + async fn get_key( + &self, + req: Request, + ) -> Result, Status> { + let req = req.into_inner(); + + let algorithm = proto::Algorithm::from_i32(req.algorithm) + .ok_or(Status::invalid_argument("invalid algorithm"))?; + let key = self.key(&req.key_id, algorithm).await?; + + Ok(Response::new(proto::GetKeyResponse { + pub_key: key.to_bytes(), + })) + } +} + +#[cfg(test)] +mod tests { + use ecdsa::SigningKey; + use k256::sha2::{Digest, Sha256}; + use mockall::predicate; + use rand::rngs::OsRng; + use tokio::test; + use tonic::Code; + + use crate::tofnd; + use crate::tofnd::grpc::MockMultisig; + use crate::types::PublicKey; + + use super::proto::{self, crypto_server::Crypto}; + use super::Server; + + #[test] + async fn sign_should_return_correct_signature() { + let key_id = "key_id"; + let algorithm = proto::Algorithm::Ecdsa; + let key: PublicKey = SigningKey::random(&mut OsRng).verifying_key().into(); + let msg = b"message"; + let mut hasher = Sha256::new(); + hasher.update(msg); + let sign_digest: [u8; 32] = hasher.finalize().to_vec().try_into().unwrap(); + + let mut multisig_client = MockMultisig::default(); + multisig_client + .expect_keygen() + .with( + predicate::eq(key_id), + predicate::eq(tofnd::Algorithm::from(algorithm)), + ) + .return_once(move |_, _| Ok(key)); + multisig_client + .expect_sign() + .with( + predicate::eq(key_id), + predicate::eq(tofnd::MessageDigest::from(sign_digest)), + predicate::function(move |actual: &PublicKey| actual == &key), + predicate::eq(tofnd::Algorithm::from(algorithm)), + ) + .return_once(|_, _, _, _| Ok(vec![1; 64])); + let server = Server::new(multisig_client); + + let req = tonic::Request::new(proto::SignRequest { + key_id: key_id.to_string(), + msg: msg.to_vec(), + algorithm: algorithm.into(), + }); + let res = server.sign(req).await.unwrap().into_inner(); + + assert_eq!(res.signature, vec![1; 64]); + } + + #[test] + async fn sign_should_return_error_when_algorithm_is_invalid() { + let key_id = "key_id"; + let algorithm = 2; + let msg = b"message"; + + let multisig_client = MockMultisig::default(); + let server = Server::new(multisig_client); + + let req = tonic::Request::new(proto::SignRequest { + key_id: key_id.to_string(), + msg: msg.to_vec(), + algorithm, + }); + let res = server.sign(req).await.unwrap_err(); + + assert_eq!(res.code(), Code::InvalidArgument); + } + + #[test] + async fn get_key_should_return_correct_key() { + let key_id = "key_id"; + let algorithm = proto::Algorithm::Ecdsa; + let key: PublicKey = SigningKey::random(&mut OsRng).verifying_key().into(); + + let mut multisig_client = MockMultisig::default(); + multisig_client + .expect_keygen() + .with( + predicate::eq(key_id), + predicate::eq(tofnd::Algorithm::from(algorithm)), + ) + .return_once(move |_, _| Ok(key)); + let server = Server::new(multisig_client); + + let req = tonic::Request::new(proto::GetKeyRequest { + key_id: key_id.to_string(), + algorithm: algorithm.into(), + }); + let res = server.get_key(req).await.unwrap().into_inner(); + + assert_eq!(res.pub_key, key.to_bytes()); + } + + #[test] + async fn get_key_should_return_error_when_algorithm_is_invalid() { + let key_id = "key_id"; + + let multisig_client = MockMultisig::default(); + let server = Server::new(multisig_client); + + let req = tonic::Request::new(proto::GetKeyRequest { + key_id: key_id.to_string(), + algorithm: 2, + }); + let res = server.get_key(req).await.unwrap_err(); + + assert_eq!(res.code(), Code::InvalidArgument); + } +} diff --git a/ampd/src/grpc/mod.rs b/ampd/src/grpc/mod.rs index 1912a314a..55764473e 100644 --- a/ampd/src/grpc/mod.rs +++ b/ampd/src/grpc/mod.rs @@ -1,15 +1,27 @@ use tonic::transport::{server::Router, Server}; -use crate::{event_sub::EventSubscriber, queue::queued_broadcaster::QueuedBroadcasterClient}; +use crate::event_sub::EventSubscriber; +use crate::queue::queued_broadcaster::QueuedBroadcasterClient; +use crate::tofnd::grpc::MultisigClient; +mod proto { + tonic::include_proto!("ampd"); +} mod ampd; +mod crypto; #[allow(dead_code)] pub fn new_server( event_subscriber: EventSubscriber, broadcaster: QueuedBroadcasterClient, + multisig_client: MultisigClient, ) -> Router { - Server::builder().add_service(ampd::proto::ampd_server::AmpdServer::new( - ampd::Server::new(event_subscriber, broadcaster), - )) + Server::builder() + .add_service(proto::ampd_server::AmpdServer::new(ampd::Server::new( + event_subscriber, + broadcaster, + ))) + .add_service(proto::crypto_server::CryptoServer::new( + crypto::Server::new(multisig_client), + )) } diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index bd5b699f3..abb1aef74 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -21,7 +21,7 @@ use multisig::msg::ExecuteMsg; use crate::event_processor::EventHandler; use crate::handlers::errors::Error::{self, DeserializeEvent}; use crate::tofnd::grpc::Multisig; -use crate::tofnd::MessageDigest; +use crate::tofnd::{self, MessageDigest}; use crate::types::PublicKey; use crate::types::TMAddress; @@ -152,7 +152,12 @@ where Some(pub_key) => { let signature = self .signer - .sign(self.multisig.to_string().as_str(), msg.clone(), pub_key) + .sign( + self.multisig.to_string().as_str(), + msg.clone(), + pub_key, + tofnd::Algorithm::Ecdsa, + ) .await .change_context(Error::Sign)?; @@ -421,7 +426,7 @@ mod test { let mut client = MockMultisig::default(); client .expect_sign() - .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + .returning(move |_, _, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); let handler = get_handler( rand_account(), @@ -441,7 +446,7 @@ mod test { let mut client = MockMultisig::default(); client .expect_sign() - .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + .returning(move |_, _, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); let event = signing_started_event(); let signing_started: SigningStartedEvent = ((&event).try_into() as Result<_, _>).unwrap(); @@ -464,7 +469,7 @@ mod test { let mut client = MockMultisig::default(); client .expect_sign() - .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + .returning(move |_, _, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); let event = signing_started_event(); let signing_started: SigningStartedEvent = ((&event).try_into() as Result<_, _>).unwrap(); diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 395e0a159..8ba2b17d0 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -98,7 +98,7 @@ async fn prepare_app(cfg: Config, state: State) -> Result, Some(pub_key) => pub_key, None => { let pub_key = multisig_client - .keygen(&tofnd_config.key_uid) + .keygen(&tofnd_config.key_uid, tofnd::Algorithm::Ecdsa) .await .change_context(Error::Tofnd)?; state_updater.as_mut().pub_key = Some(pub_key); diff --git a/ampd/src/tofnd/grpc.rs b/ampd/src/tofnd/grpc.rs index 0c08d7182..98260b99a 100644 --- a/ampd/src/tofnd/grpc.rs +++ b/ampd/src/tofnd/grpc.rs @@ -11,8 +11,8 @@ use tonic::{transport::Channel, Status}; use crate::{types::PublicKey, url::Url}; use super::proto::{ - keygen_response::KeygenResponse, multisig_client, sign_response::SignResponse, KeygenRequest, - SignRequest, + keygen_response::KeygenResponse, multisig_client, sign_response::SignResponse, Algorithm, + KeygenRequest, SignRequest, }; use super::{error::Error, error::TofndError, MessageDigest, Signature}; @@ -21,12 +21,13 @@ type Result = error_stack::Result; #[automock] #[async_trait] pub trait Multisig { - async fn keygen(&self, key_uid: &str) -> Result; + async fn keygen(&self, key_uid: &str, algorithm: Algorithm) -> Result; async fn sign( &self, key_uid: &str, data: MessageDigest, pub_key: &PublicKey, + algorithm: Algorithm, ) -> Result; } @@ -51,10 +52,11 @@ impl MultisigClient { #[async_trait] impl Multisig for MultisigClient { - async fn keygen(&self, key_uid: &str) -> Result { + async fn keygen(&self, key_uid: &str, algorithm: Algorithm) -> Result { let request = KeygenRequest { key_uid: key_uid.to_string(), party_uid: self.party_uid.to_string(), + algorithm: algorithm.into(), }; self.client @@ -87,12 +89,14 @@ impl Multisig for MultisigClient { key_uid: &str, data: MessageDigest, pub_key: &PublicKey, + algorithm: Algorithm, ) -> Result { let request = SignRequest { key_uid: key_uid.to_string(), msg_to_sign: data.into(), party_uid: self.party_uid.to_string(), pub_key: pub_key.to_bytes(), + algorithm: algorithm.into(), }; self.client diff --git a/ampd/src/tofnd/mod.rs b/ampd/src/tofnd/mod.rs index 110cc152e..3ae656b22 100644 --- a/ampd/src/tofnd/mod.rs +++ b/ampd/src/tofnd/mod.rs @@ -11,6 +11,8 @@ mod proto { tonic::include_proto!("tofnd"); } +pub use proto::Algorithm; + #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] pub struct Config { pub url: Url, @@ -31,7 +33,7 @@ impl Default for Config { // Signature is an alias for signature in raw bytes pub type Signature = Vec; -#[derive(Clone, Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq)] pub struct MessageDigest([u8; 32]); impl FromHex for MessageDigest { From bf6750b7d077702a1ff1dd0f2b7e61aebd2baaab Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 5 Jun 2024 16:33:24 -0400 Subject: [PATCH 005/168] chore: simplify cosmos proto dependencies (#445) --- Cargo.lock | 46 ++++------------------------ ampd/Cargo.toml | 5 ++- ampd/src/broadcaster.rs | 37 ++++++++++------------ ampd/src/broadcaster/accounts.rs | 10 +++--- ampd/src/broadcaster/clients.rs | 10 +++--- ampd/src/broadcaster/tx.rs | 2 +- ampd/src/commands/mod.rs | 6 ++-- ampd/src/grpc/ampd.rs | 2 +- ampd/src/handlers/multisig.rs | 2 +- ampd/src/lib.rs | 2 +- ampd/src/queue/msg_queue.rs | 2 +- ampd/src/queue/queued_broadcaster.rs | 2 +- 12 files changed, 44 insertions(+), 82 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c6197bd1..86f4f019f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,7 +235,6 @@ dependencies = [ "bcs", "clap", "config", - "cosmos-sdk-proto 0.16.0", "cosmrs", "cosmwasm-std", "deref-derive", @@ -279,7 +278,7 @@ dependencies = [ "tokio-stream", "tokio-util 0.7.9", "toml 0.5.11", - "tonic 0.8.3", + "tonic 0.9.2", "tonic-build", "tracing", "tracing-core", @@ -1715,18 +1714,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "cosmos-sdk-proto" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" -dependencies = [ - "prost 0.11.9", - "prost-types", - "tendermint-proto 0.27.0", - "tonic 0.8.3", -] - [[package]] name = "cosmos-sdk-proto" version = "0.19.0" @@ -1736,6 +1723,7 @@ dependencies = [ "prost 0.11.9", "prost-types", "tendermint-proto 0.32.2", + "tonic 0.9.2", ] [[package]] @@ -1745,7 +1733,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" dependencies = [ "bip32", - "cosmos-sdk-proto 0.19.0", + "cosmos-sdk-proto", "ecdsa", "eyre", "getrandom", @@ -8446,24 +8434,6 @@ dependencies = [ "url", ] -[[package]] -name = "tendermint-proto" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost 0.11.9", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - [[package]] name = "tendermint-proto" version = "0.32.2" @@ -8858,14 +8828,13 @@ dependencies = [ [[package]] name = "tonic" -version = "0.8.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ - "async-stream", "async-trait", "axum 0.6.20", - "base64 0.13.1", + "base64 0.21.4", "bytes", "futures-core", "futures-util", @@ -8877,15 +8846,12 @@ dependencies = [ "percent-encoding", "pin-project", "prost 0.11.9", - "prost-derive 0.11.9", "tokio", "tokio-stream", - "tokio-util 0.7.9", "tower", "tower-layer", "tower-service", "tracing", - "tracing-futures", ] [[package]] diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index d9fa5e2fc..a2dce5e2f 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -13,8 +13,7 @@ base64 = "0.21.2" bcs = "0.1.5" clap = { version = "4.2.7", features = ["derive", "cargo"] } config = "0.13.2" -cosmos-sdk-proto = "0.16.0" -cosmrs = { version = "0.14.0", features = ["cosmwasm"] } +cosmrs = { version = "0.14.0", features = ["cosmwasm", "grpc"] } cosmwasm-std = { workspace = true, features = ["stargate"] } deref-derive = "0.1.0" dirs = "5.0.1" @@ -58,7 +57,7 @@ tokio = { version = "1.22.0", features = ["signal"] } tokio-stream = { version = "0.1.11", features = ["sync"] } tokio-util = "0.7.8" toml = "0.5.9" -tonic = "0.8.3" +tonic = "0.9.2" tracing = { version = "0.1.37", features = ["valuable", "log"] } tracing-core = { version = "0.1.30", features = ["valuable"] } tracing-subscriber = { version = "0.3.16", features = ["json", "valuable"] } diff --git a/ampd/src/broadcaster.rs b/ampd/src/broadcaster.rs index 4e1b4bddd..7ac230e1a 100644 --- a/ampd/src/broadcaster.rs +++ b/ampd/src/broadcaster.rs @@ -4,11 +4,11 @@ use std::time::Duration; use std::{cmp, thread}; use async_trait::async_trait; -use cosmos_sdk_proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmos_sdk_proto::cosmos::tx::v1beta1::{ +use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; +use cosmrs::proto::cosmos::tx::v1beta1::{ BroadcastMode, BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, }; -use cosmos_sdk_proto::traits::MessageExt; +use cosmrs::proto::traits::MessageExt; use cosmrs::tendermint::chain::Id; use cosmrs::tx::Fee; use cosmrs::{Coin, Gas}; @@ -51,7 +51,7 @@ pub enum Error { #[error("failed to confirm tx inclusion in block")] TxConfirmation, #[error("failed to execute tx")] - Execution { response: TxResponse }, + Execution { response: Box }, #[error("failed to query account information for address {address}")] QueryAccount { address: TMAddress }, } @@ -290,7 +290,9 @@ fn evaluate_response(response: Result) -> ConfirmationRes .. }) => match response { TxResponse { code: 0, .. } => ConfirmationResult::Success, - _ => ConfirmationResult::Critical(Error::Execution { response }), + _ => ConfirmationResult::Critical(Error::Execution { + response: Box::new(response), + }), }, } } @@ -303,11 +305,11 @@ enum ConfirmationResult { #[cfg(test)] mod tests { - use cosmos_sdk_proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountResponse}; - use cosmos_sdk_proto::cosmos::base::abci::v1beta1::{GasInfo, TxResponse}; - use cosmos_sdk_proto::cosmos::tx::v1beta1::{GetTxResponse, SimulateResponse}; - use cosmos_sdk_proto::traits::MessageExt; - use cosmos_sdk_proto::Any; + use cosmrs::proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountResponse}; + use cosmrs::proto::cosmos::base::abci::v1beta1::{GasInfo, TxResponse}; + use cosmrs::proto::cosmos::tx::v1beta1::{GetTxResponse, SimulateResponse}; + use cosmrs::proto::traits::MessageExt; + use cosmrs::proto::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use ecdsa::SigningKey; use rand::rngs::OsRng; @@ -642,16 +644,11 @@ mod tests { .build(); let msgs = vec![dummy_msg()]; - assert!(matches!( - broadcaster - .broadcast(msgs) - .await - .unwrap_err() - .current_context(), - Error::Execution { - response: TxResponse { code: 32, .. } - } - )); + let report = broadcaster.broadcast(msgs).await.unwrap_err(); + assert!(matches!(report.current_context(), Error::Execution { .. })); + if let Error::Execution { response } = report.current_context() { + assert_eq!(response.code, 32); + } } #[test] diff --git a/ampd/src/broadcaster/accounts.rs b/ampd/src/broadcaster/accounts.rs index 93b3e4734..56901c8f1 100644 --- a/ampd/src/broadcaster/accounts.rs +++ b/ampd/src/broadcaster/accounts.rs @@ -1,5 +1,5 @@ -use cosmos_sdk_proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountRequest}; -use cosmos_sdk_proto::traits::Message; +use cosmrs::proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountRequest}; +use cosmrs::proto::traits::Message; use error_stack::{Result, ResultExt}; use thiserror::Error; @@ -54,9 +54,9 @@ where #[cfg(test)] mod tests { - use cosmos_sdk_proto::cosmos::auth::v1beta1::BaseAccount; - use cosmos_sdk_proto::cosmos::auth::v1beta1::QueryAccountResponse; - use cosmos_sdk_proto::traits::MessageExt; + use cosmrs::proto::cosmos::auth::v1beta1::BaseAccount; + use cosmrs::proto::cosmos::auth::v1beta1::QueryAccountResponse; + use cosmrs::proto::traits::MessageExt; use cosmrs::Any; use ecdsa::SigningKey; use rand::rngs::OsRng; diff --git a/ampd/src/broadcaster/clients.rs b/ampd/src/broadcaster/clients.rs index a453dd2c9..58deac16a 100644 --- a/ampd/src/broadcaster/clients.rs +++ b/ampd/src/broadcaster/clients.rs @@ -1,9 +1,9 @@ use async_trait::async_trait; -use cosmos_sdk_proto::cosmos::auth::v1beta1::query_client::QueryClient; -use cosmos_sdk_proto::cosmos::auth::v1beta1::{QueryAccountRequest, QueryAccountResponse}; -use cosmos_sdk_proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmos_sdk_proto::cosmos::tx::v1beta1::service_client::ServiceClient; -use cosmos_sdk_proto::cosmos::tx::v1beta1::{ +use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient; +use cosmrs::proto::cosmos::auth::v1beta1::{QueryAccountRequest, QueryAccountResponse}; +use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; +use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; +use cosmrs::proto::cosmos::tx::v1beta1::{ BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, SimulateResponse, }; use error_stack::{Report, Result}; diff --git a/ampd/src/broadcaster/tx.rs b/ampd/src/broadcaster/tx.rs index 077a27330..48fee8f98 100644 --- a/ampd/src/broadcaster/tx.rs +++ b/ampd/src/broadcaster/tx.rs @@ -98,7 +98,7 @@ where #[cfg(test)] mod tests { - use cosmos_sdk_proto::Any; + use cosmrs::proto::Any; use cosmrs::{ bank::MsgSend, bip32::secp256k1::elliptic_curve::rand_core::OsRng, diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index e98b66689..9252324f5 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -1,11 +1,11 @@ use std::path::Path; use clap::Subcommand; -use cosmos_sdk_proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmos_sdk_proto::cosmos::{ +use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; +use cosmrs::proto::cosmos::{ auth::v1beta1::query_client::QueryClient, tx::v1beta1::service_client::ServiceClient, }; -use cosmos_sdk_proto::Any; +use cosmrs::proto::Any; use cosmrs::AccountId; use error_stack::Result; use error_stack::ResultExt; diff --git a/ampd/src/grpc/ampd.rs b/ampd/src/grpc/ampd.rs index 2d1549606..50defd3e4 100644 --- a/ampd/src/grpc/ampd.rs +++ b/ampd/src/grpc/ampd.rs @@ -127,7 +127,7 @@ mod tests { use std::collections::HashMap; use std::time::Duration; - use cosmos_sdk_proto::Any; + use cosmrs::proto::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use error_stack::Report; use events::Event; diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index abb1aef74..1540ab235 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -184,7 +184,7 @@ mod test { use base64::engine::general_purpose::STANDARD; use base64::Engine; - use cosmos_sdk_proto::cosmos::base::abci::v1beta1::TxResponse; + use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::AccountId; use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::SigningKey; diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 8ba2b17d0..7ef425556 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -2,7 +2,7 @@ use std::pin::Pin; use std::time::Duration; use block_height_monitor::BlockHeightMonitor; -use cosmos_sdk_proto::cosmos::{ +use cosmrs::proto::cosmos::{ auth::v1beta1::query_client::QueryClient, tx::v1beta1::service_client::ServiceClient, }; use error_stack::{report, FutureExt, Result, ResultExt}; diff --git a/ampd/src/queue/msg_queue.rs b/ampd/src/queue/msg_queue.rs index b9d98a51d..67bc48b94 100644 --- a/ampd/src/queue/msg_queue.rs +++ b/ampd/src/queue/msg_queue.rs @@ -44,7 +44,7 @@ impl MsgQueue { #[cfg(test)] mod test { - use cosmos_sdk_proto::Any; + use cosmrs::proto::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use super::MsgQueue; diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index dd7638463..a414ac60a 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -174,7 +174,7 @@ where #[cfg(test)] mod test { - use cosmos_sdk_proto::cosmos::base::abci::v1beta1::TxResponse; + use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::tx::Fee; use cosmrs::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; From 0bab15820c25e4950b2c92c71528e931b34445a2 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 5 Jun 2024 17:08:35 -0400 Subject: [PATCH 006/168] refactor: move main broadcaster file into broadcaster module (#449) --- ampd/src/{broadcaster.rs => broadcaster/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ampd/src/{broadcaster.rs => broadcaster/mod.rs} (100%) diff --git a/ampd/src/broadcaster.rs b/ampd/src/broadcaster/mod.rs similarity index 100% rename from ampd/src/broadcaster.rs rename to ampd/src/broadcaster/mod.rs From 04b1b5db8fbea2d42d6bfad74e8c97770970b7c1 Mon Sep 17 00:00:00 2001 From: Sammy Date: Mon, 10 Jun 2024 11:50:07 -0400 Subject: [PATCH 007/168] feat(ampd): create the ampd gRPC client (#447) * feat(ampd): create the ampd gRPC client * fix imports --- ampd/src/grpc/client.rs | 275 +++++++++++++++++++++++++++ ampd/src/grpc/mod.rs | 27 +-- ampd/src/grpc/{ => server}/ampd.rs | 2 +- ampd/src/grpc/{ => server}/crypto.rs | 0 ampd/src/grpc/server/mod.rs | 27 +++ ampd/src/lib.rs | 2 + ampd/src/queue/msg_queue.rs | 2 +- 7 files changed, 309 insertions(+), 26 deletions(-) create mode 100644 ampd/src/grpc/client.rs rename ampd/src/grpc/{ => server}/ampd.rs (99%) rename ampd/src/grpc/{ => server}/crypto.rs (100%) create mode 100644 ampd/src/grpc/server/mod.rs diff --git a/ampd/src/grpc/client.rs b/ampd/src/grpc/client.rs new file mode 100644 index 000000000..8cff0c2b3 --- /dev/null +++ b/ampd/src/grpc/client.rs @@ -0,0 +1,275 @@ +use error_stack::{Report, Result}; +use tonic::{codegen, transport}; + +use super::proto::{ampd_client::AmpdClient, crypto_client::CryptoClient}; + +pub struct Client { + pub ampd: AmpdClient, + pub crypto: CryptoClient, +} + +pub async fn new(dst: D) -> Result +where + D: TryInto, + D::Error: Into, +{ + let conn = transport::Endpoint::new(dst) + .map_err(Report::new)? + .connect() + .await + .map_err(Report::new)?; + + let ampd = AmpdClient::new(conn.clone()); + let crypto = CryptoClient::new(conn); + + Ok(Client { ampd, crypto }) +} + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use cosmrs::Any; + use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use error_stack::Report; + use events::Event; + use futures::StreamExt; + use k256::ecdsa::SigningKey; + use k256::sha2::{Digest, Sha256}; + use mockall::predicate; + use rand::rngs::OsRng; + use tokio::net::TcpListener; + use tokio::sync::mpsc; + use tokio::{sync::oneshot, test, time}; + use tokio_stream::wrappers::errors::BroadcastStreamRecvError; + use tokio_stream::wrappers::{ReceiverStream, TcpListenerStream}; + use tonic::Code; + use url::Url; + + use crate::proto::{ + Algorithm, BroadcastRequest, BroadcastResponse, GetKeyRequest, GetKeyResponse, SignRequest, + SignResponse, SubscribeRequest, + }; + use crate::types::PublicKey; + use crate::{ + event_sub::MockEventSub, + grpc, + queue::queued_broadcaster::MockBroadcasterClient, + tofnd::{self, grpc::MockMultisig}, + }; + + async fn start_server( + event_sub: MockEventSub, + broadcaster: MockBroadcasterClient, + multisig_client: MockMultisig, + ) -> (Url, oneshot::Sender<()>) { + let (tx, rx) = oneshot::channel::<()>(); + let server = grpc::server::new(event_sub, broadcaster, multisig_client); + let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); + let addr = listener.local_addr().unwrap(); + + tokio::spawn( + server.serve_with_incoming_shutdown(TcpListenerStream::new(listener), async { + drop(rx.await) + }), + ); + time::sleep(Duration::from_millis(100)).await; + + (format!("http://{addr}").parse().unwrap(), tx) + } + + #[test] + async fn get_key_should_work() { + let key_id = "key_id"; + let key: PublicKey = SigningKey::random(&mut OsRng).verifying_key().into(); + let algorithm = Algorithm::Ed25519; + + let mut multisig_client = MockMultisig::new(); + multisig_client + .expect_keygen() + .with( + predicate::eq(key_id), + predicate::eq(tofnd::Algorithm::from(algorithm)), + ) + .return_once(move |_, _| Ok(key)); + + let (url, tx) = start_server( + MockEventSub::new(), + MockBroadcasterClient::new(), + multisig_client, + ) + .await; + assert_eq!( + grpc::client::new(url.to_string()) + .await + .unwrap() + .crypto + .get_key(GetKeyRequest { + key_id: key_id.to_string(), + algorithm: algorithm.into(), + }) + .await + .unwrap() + .into_inner(), + GetKeyResponse { + pub_key: key.to_bytes() + } + ); + + tx.send(()).unwrap(); + } + + #[test] + async fn sign_should_work() { + let key_id = "key_id"; + let algorithm = Algorithm::Ed25519; + let key: PublicKey = SigningKey::random(&mut OsRng).verifying_key().into(); + let msg = b"message"; + let mut hasher = Sha256::new(); + hasher.update(msg); + let sign_digest: [u8; 32] = hasher.finalize().to_vec().try_into().unwrap(); + + let mut multisig_client = MockMultisig::new(); + multisig_client + .expect_keygen() + .with( + predicate::eq(key_id), + predicate::eq(tofnd::Algorithm::from(algorithm)), + ) + .return_once(move |_, _| Ok(key)); + multisig_client + .expect_sign() + .with( + predicate::eq(key_id), + predicate::eq(tofnd::MessageDigest::from(sign_digest)), + predicate::function(move |actual: &PublicKey| actual == &key), + predicate::eq(tofnd::Algorithm::from(algorithm)), + ) + .return_once(|_, _, _, _| Ok(vec![1; 64])); + + let (url, tx) = start_server( + MockEventSub::new(), + MockBroadcasterClient::new(), + multisig_client, + ) + .await; + assert_eq!( + grpc::client::new(url.to_string()) + .await + .unwrap() + .crypto + .sign(SignRequest { + key_id: key_id.to_string(), + msg: msg.to_vec(), + algorithm: algorithm.into(), + }) + .await + .unwrap() + .into_inner(), + SignResponse { + signature: vec![1; 64] + } + ); + + tx.send(()).unwrap(); + } + + #[test] + async fn broadcast_should_work() { + let msg = dummy_msg(); + + let mut broadcaster = MockBroadcasterClient::new(); + broadcaster + .expect_broadcast() + .with(predicate::eq(msg.clone())) + .return_once(|_| Ok(())); + + let (url, tx) = start_server(MockEventSub::new(), broadcaster, MockMultisig::new()).await; + assert_eq!( + grpc::client::new(url.to_string()) + .await + .unwrap() + .ampd + .broadcast(BroadcastRequest { msg: Some(msg) }) + .await + .unwrap() + .into_inner(), + BroadcastResponse {} + ); + + tx.send(()).unwrap(); + } + + #[test] + async fn subscribe_should_work() { + let mut event_sub = MockEventSub::new(); + let (event_tx, event_rx) = mpsc::channel(1); + event_sub + .expect_subscribe() + .return_once(|| Box::pin(ReceiverStream::new(event_rx))); + + let (url, tx) = + start_server(event_sub, MockBroadcasterClient::new(), MockMultisig::new()).await; + let mut stream = grpc::client::new(url.to_string()) + .await + .unwrap() + .ampd + .subscribe(SubscribeRequest { + event_filters: vec![], + include_block_begin_end: true, + }) + .await + .unwrap() + .into_inner(); + + let event = Event::BlockBegin(1u32.into()); + event_tx.send(Ok(event.clone())).await.unwrap(); + assert_eq!( + stream.next().await.unwrap().unwrap().event, + Some(event.into()) + ); + + let event = Event::Abci { + event_type: "some_event".into(), + attributes: serde_json::from_str("{\"key_1\":\"value_1\",\"key_2\":\"value_2\"}") + .unwrap(), + }; + event_tx.send(Ok(event.clone())).await.unwrap(); + assert_eq!( + stream.next().await.unwrap().unwrap().event, + Some(event.into()) + ); + + let event = Event::BlockEnd(1u32.into()); + event_tx.send(Ok(event.clone())).await.unwrap(); + assert_eq!( + stream.next().await.unwrap().unwrap().event, + Some(event.into()) + ); + + event_tx + .send(Err(Report::new(BroadcastStreamRecvError::Lagged(10)))) + .await + .unwrap(); + assert_eq!( + stream.next().await.unwrap().unwrap_err().code(), + Code::Internal + ); + + let event = Event::BlockBegin(2u32.into()); + assert!(event_tx.send(Ok(event.clone())).await.is_err()); + + drop(stream); + tx.send(()).unwrap(); + } + + fn dummy_msg() -> Any { + MsgSend { + from_address: AccountId::new("", &[1, 2, 3]).unwrap(), + to_address: AccountId::new("", &[4, 5, 6]).unwrap(), + amount: vec![], + } + .to_any() + .unwrap() + } +} diff --git a/ampd/src/grpc/mod.rs b/ampd/src/grpc/mod.rs index 55764473e..26bd4efa2 100644 --- a/ampd/src/grpc/mod.rs +++ b/ampd/src/grpc/mod.rs @@ -1,27 +1,6 @@ -use tonic::transport::{server::Router, Server}; - -use crate::event_sub::EventSubscriber; -use crate::queue::queued_broadcaster::QueuedBroadcasterClient; -use crate::tofnd::grpc::MultisigClient; - -mod proto { +pub mod proto { tonic::include_proto!("ampd"); } -mod ampd; -mod crypto; -#[allow(dead_code)] -pub fn new_server( - event_subscriber: EventSubscriber, - broadcaster: QueuedBroadcasterClient, - multisig_client: MultisigClient, -) -> Router { - Server::builder() - .add_service(proto::ampd_server::AmpdServer::new(ampd::Server::new( - event_subscriber, - broadcaster, - ))) - .add_service(proto::crypto_server::CryptoServer::new( - crypto::Server::new(multisig_client), - )) -} +pub mod client; +pub mod server; diff --git a/ampd/src/grpc/ampd.rs b/ampd/src/grpc/server/ampd.rs similarity index 99% rename from ampd/src/grpc/ampd.rs rename to ampd/src/grpc/server/ampd.rs index 50defd3e4..24f2e3048 100644 --- a/ampd/src/grpc/ampd.rs +++ b/ampd/src/grpc/server/ampd.rs @@ -127,7 +127,7 @@ mod tests { use std::collections::HashMap; use std::time::Duration; - use cosmrs::proto::Any; + use cosmrs::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use error_stack::Report; use events::Event; diff --git a/ampd/src/grpc/crypto.rs b/ampd/src/grpc/server/crypto.rs similarity index 100% rename from ampd/src/grpc/crypto.rs rename to ampd/src/grpc/server/crypto.rs diff --git a/ampd/src/grpc/server/mod.rs b/ampd/src/grpc/server/mod.rs new file mode 100644 index 000000000..e5695026d --- /dev/null +++ b/ampd/src/grpc/server/mod.rs @@ -0,0 +1,27 @@ +use tonic::transport::{server::Router, Server}; + +use crate::{ + event_sub::EventSub, queue::queued_broadcaster::BroadcasterClient, tofnd::grpc::Multisig, +}; + +use super::proto; + +mod ampd; +mod crypto; + +#[allow(dead_code)] +pub fn new(event_subscriber: S, broadcaster: B, multisig_client: M) -> Router +where + S: EventSub + Send + Sync + 'static, + B: BroadcasterClient + Send + Sync + 'static, + M: Multisig + Send + Sync + 'static, +{ + Server::builder() + .add_service(proto::ampd_server::AmpdServer::new(ampd::Server::new( + event_subscriber, + broadcaster, + ))) + .add_service(proto::crypto_server::CryptoServer::new( + crypto::Server::new(multisig_client), + )) +} diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 7ef425556..4f8ffc0c8 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -50,6 +50,8 @@ mod tofnd; mod types; mod url; +pub use grpc::{client, proto}; + const PREFIX: &str = "axelar"; const DEFAULT_RPC_TIMEOUT: Duration = Duration::from_secs(3); diff --git a/ampd/src/queue/msg_queue.rs b/ampd/src/queue/msg_queue.rs index 67bc48b94..5f4460da5 100644 --- a/ampd/src/queue/msg_queue.rs +++ b/ampd/src/queue/msg_queue.rs @@ -44,7 +44,7 @@ impl MsgQueue { #[cfg(test)] mod test { - use cosmrs::proto::Any; + use cosmrs::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use super::MsgQueue; From 6108934862a908a1d25747878eb77c3b6a01ec18 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:05:53 +0300 Subject: [PATCH 008/168] feat(minor-rewards): add query for verifier participation (#439) * feat(minor-rewards): add query for verifier participation --- contracts/rewards/src/contract.rs | 6 ++ contracts/rewards/src/contract/query.rs | 85 +++++++++++++++++++++++++ contracts/rewards/src/msg.rs | 22 ++++++- contracts/rewards/src/state.rs | 7 ++ 4 files changed, 118 insertions(+), 2 deletions(-) diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index d1ef6ede3..41f6f24b0 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -157,6 +157,12 @@ pub fn query( .change_context(ContractError::SerializeResponse) .map_err(axelar_wasm_std::ContractError::from) } + QueryMsg::VerifierParticipation { pool_id, epoch_num } => { + let tally = query::participation(deps.storage, pool_id, epoch_num, env.block.height)?; + to_json_binary(&tally) + .change_context(ContractError::SerializeResponse) + .map_err(axelar_wasm_std::ContractError::from) + } } } diff --git a/contracts/rewards/src/contract/query.rs b/contracts/rewards/src/contract/query.rs index 2a01fdc15..0bfbdafcc 100644 --- a/contracts/rewards/src/contract/query.rs +++ b/contracts/rewards/src/contract/query.rs @@ -35,9 +35,38 @@ pub fn rewards_pool( }) } +pub fn participation( + storage: &dyn Storage, + pool_id: PoolId, + epoch_num: Option, + block_height: u64, +) -> Result, ContractError> { + let epoch_num = match epoch_num { + Some(num) => num, + None => { + let current_params = state::load_params(storage); + Epoch::current(¤t_params, block_height)?.epoch_num + } + }; + + let tally = state::load_epoch_tally(storage, pool_id, epoch_num)?; + + match tally { + None => Ok(None), + Some(tally) => Ok(Some(msg::Participation { + event_count: tally.event_count, + participation: tally.verifier_participation(), + rewards_by_verifier: tally.rewards_by_verifier(), + epoch: tally.epoch, + params: tally.params, + })), + } +} + #[cfg(test)] mod tests { use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128, Uint64}; + use msg::Participation; use crate::{ msg::Params, @@ -234,4 +263,60 @@ mod tests { &ContractError::RewardsPoolNotFound ); } + + #[test] + fn should_get_participation() { + let mut deps = mock_dependencies(); + let balance = Uint128::from(1000u128); + let (current_params, pool_id) = setup(deps.as_mut().storage, balance); + + let block_height = 1000; + let epoch = Epoch::current(¤t_params, block_height).unwrap(); + + let mut tally = EpochTally::new( + pool_id.clone(), + epoch.clone(), + current_params.params.clone(), + ); + tally = tally.record_participation(Addr::unchecked("verifier_1")); + tally = tally.record_participation(Addr::unchecked("verifier_2")); + tally.event_count = tally.event_count.saturating_add(1); + state::save_epoch_tally(deps.as_mut().storage, &tally).unwrap(); + + let expected = Participation { + event_count: tally.event_count, + participation: tally.verifier_participation(), + rewards_by_verifier: tally.rewards_by_verifier(), + epoch: Epoch::current(¤t_params.clone(), block_height).unwrap(), + params: current_params.params.clone(), + }; + + // get participation for current epoch + let res = + participation(deps.as_mut().storage, pool_id.clone(), None, block_height).unwrap(); + assert_eq!(res.unwrap(), expected); + + // get participation for past epoch + let res = participation( + deps.as_mut().storage, + pool_id.clone(), + Some(epoch.epoch_num), + block_height + u64::from(current_params.params.epoch_duration), + ) + .unwrap(); + assert_eq!(res.unwrap(), expected); + } + + #[test] + fn participation_should_return_none_when_no_participation() { + let mut deps = mock_dependencies(); + let balance = Uint128::from(1000u128); + let (_, pool_id) = setup(deps.as_mut().storage, balance); + + let block_height = 1000; + + let res = + participation(deps.as_mut().storage, pool_id.clone(), None, block_height).unwrap(); + assert!(res.is_none()); + } } diff --git a/contracts/rewards/src/msg.rs b/contracts/rewards/src/msg.rs index ea7ce45dc..cf2c596ac 100644 --- a/contracts/rewards/src/msg.rs +++ b/contracts/rewards/src/msg.rs @@ -1,9 +1,11 @@ +use std::collections::HashMap; + use axelar_wasm_std::{nonempty, Threshold}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Uint128, Uint64}; +use cosmwasm_std::{Addr, Uint128, Uint64}; use router_api::ChainName; -use crate::state::PoolId; +use crate::state::{Epoch, PoolId}; #[cw_serde] pub struct InstantiateMsg { @@ -65,6 +67,13 @@ pub enum QueryMsg { /// Gets the rewards pool details for the given `pool_id`` #[returns(RewardsPool)] RewardsPool { pool_id: PoolId }, + + /// Gets verifier participation info for a given epoch (or the current epoch if unspecified) and pool. If no participation was recorded, returns None + #[returns(Option)] + VerifierParticipation { + pool_id: PoolId, + epoch_num: Option, + }, } #[cw_serde] @@ -75,3 +84,12 @@ pub struct RewardsPool { pub current_epoch_num: Uint64, pub last_distribution_epoch: Option, } + +#[cw_serde] +pub struct Participation { + pub event_count: u64, + pub participation: HashMap, // maps a verifier address to participation count + pub rewards_by_verifier: HashMap, // maps a verifier address to amount of rewards + pub epoch: Epoch, + pub params: Params, +} diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index 072301271..070216bc0 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -161,6 +161,13 @@ impl EpochTally { }) .collect() } + + pub fn verifier_participation(&self) -> HashMap { + self.participation + .iter() + .map(|(verifier, participation)| (Addr::unchecked(verifier), *participation)) // Ok to convert unchecked here, since we only store valid addresses + .collect() + } } #[cw_serde] From afa1390dae87e1a0ee1b24ca5aa0d58889298821 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:21:24 +0300 Subject: [PATCH 009/168] feat(minor-voting-verifier)!: emit event when quorum is reached (#440) * feat(minor-voting-verifier)!: emit event when quorum is reached --- contracts/voting-verifier/src/contract.rs | 104 +++++++++++++++++++ contracts/voting-verifier/src/error.rs | 3 + contracts/voting-verifier/src/events.rs | 24 ++++- contracts/voting-verifier/src/execute.rs | 109 ++++++++++++++++---- contracts/voting-verifier/src/query.rs | 17 ++-- contracts/voting-verifier/src/state.rs | 119 +++++++++++++++++++++- packages/axelar-wasm-std/src/voting.rs | 45 +++++++- 7 files changed, 382 insertions(+), 39 deletions(-) diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 17ab9a429..d982581ab 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1312,4 +1312,108 @@ mod test { )] ); } + + #[test] + fn should_emit_event_when_verification_succeeds() { + let msg_id_format = MessageIdFormat::HexTxHashAndEventIndex; + let verifiers = verifiers(3); + let mut deps = setup(verifiers.clone(), &msg_id_format); + let threshold = initial_voting_threshold(); + // this test depends on the threshold being 2/3 + assert_eq!( + threshold, + Threshold::try_from((2, 3)).unwrap().try_into().unwrap() + ); + let votes_to_reach_quorum = 2; + + let messages = messages(2, &msg_id_format); + + // 1. First verification + + let msg_verify = ExecuteMsg::VerifyMessages { + messages: messages.clone(), + }; + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(SENDER, &[]), + msg_verify.clone(), + ); + assert!(res.is_ok()); + + // 2. Verifiers cast votes, but only reach consensus on the first three messages + verifiers.iter().enumerate().for_each(|(i, verifier)| { + let msg = ExecuteMsg::Vote { + poll_id: 1u64.into(), + votes: vec![Vote::SucceededOnChain, Vote::NotFound], + }; + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(verifier.address.as_str(), &[]), + msg, + ) + .unwrap(); + + // should emit event when vote causes quorum to be reached + assert_eq!( + res.events.iter().any(|event| event.ty == "quorum_reached"), + i == votes_to_reach_quorum - 1 + ); + + if i == votes_to_reach_quorum - 1 { + let mut iter = res.events.iter(); + + let first_event = iter.find(|event| event.ty == "quorum_reached").unwrap(); + + let msg: Message = serde_json::from_str( + &first_event + .attributes + .iter() + .find(|attr| attr.key == "content") + .unwrap() + .value, + ) + .unwrap(); + assert_eq!(msg, messages[0]); + + let status: VerificationStatus = serde_json::from_str( + &first_event + .attributes + .iter() + .find(|attr| attr.key == "status") + .unwrap() + .value, + ) + .unwrap(); + assert_eq!(status, VerificationStatus::SucceededOnSourceChain); + + let second_event = iter.find(|event| event.ty == "quorum_reached").unwrap(); + + let msg: Message = serde_json::from_str( + &second_event + .attributes + .iter() + .find(|attr| attr.key == "content") + .unwrap() + .value, + ) + .unwrap(); + assert_eq!(msg, messages[1]); + + let status: VerificationStatus = serde_json::from_str( + &second_event + .attributes + .iter() + .find(|attr| attr.key == "status") + .unwrap() + .value, + ) + .unwrap(); + assert_eq!(status, VerificationStatus::NotFoundOnSourceChain); + } + }); + } } diff --git a/contracts/voting-verifier/src/error.rs b/contracts/voting-verifier/src/error.rs index cee961235..1aec7e088 100644 --- a/contracts/voting-verifier/src/error.rs +++ b/contracts/voting-verifier/src/error.rs @@ -39,6 +39,9 @@ pub enum ContractError { #[error("unauthorized")] Unauthorized, + + #[error("poll results have different length")] + PollResultsLengthUnequal, } impl From for StdError { diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 3bd523c91..c2d0a9436 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -7,8 +7,8 @@ use axelar_wasm_std::msg_id::MessageIdFormat; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Attribute, Event}; -use axelar_wasm_std::nonempty; use axelar_wasm_std::voting::{PollId, Vote}; +use axelar_wasm_std::{nonempty, VerificationStatus}; use multisig::verifier_set::VerifierSet; use router_api::{Address, ChainName, Message}; @@ -221,6 +221,28 @@ impl From for Event { } } +pub struct QuorumReached { + pub content: T, + pub status: VerificationStatus, +} + +impl From> for Event +where + T: cosmwasm_schema::serde::Serialize, +{ + fn from(value: QuorumReached) -> Self { + Event::new("quorum_reached") + .add_attribute( + "content", + serde_json::to_string(&value.content).expect("failed to serialize content"), + ) + .add_attribute( + "status", + serde_json::to_string(&value.status).expect("failed to serialize status"), + ) + } +} + #[cfg(test)] mod test { use std::collections::BTreeMap; diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 6e4924af0..6e5e5e90f 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -1,11 +1,11 @@ use cosmwasm_std::{ - to_json_binary, Addr, Deps, DepsMut, Env, MessageInfo, OverflowError, OverflowOperation, + to_json_binary, Addr, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, }; use axelar_wasm_std::{ nonempty, snapshot, - voting::{PollId, Vote, WeightedPoll}, + voting::{PollId, PollResults, Vote, WeightedPoll}, MajorityThreshold, VerificationStatus, }; @@ -13,13 +13,16 @@ use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; use service_registry::{msg::QueryMsg, state::WeightedVerifier}; -use crate::events::{ - PollEnded, PollMetadata, PollStarted, TxEventConfirmation, VerifierSetConfirmation, Voted, -}; -use crate::query::verifier_set_status; -use crate::state::{self, Poll, PollContent, POLL_MESSAGES, POLL_VERIFIER_SETS}; +use crate::state::{self, Poll, PollContent}; use crate::state::{CONFIG, POLLS, POLL_ID}; use crate::{error::ContractError, query::message_status}; +use crate::{events::QuorumReached, query::verifier_set_status, state::poll_verifier_sets}; +use crate::{ + events::{ + PollEnded, PollMetadata, PollStarted, TxEventConfirmation, VerifierSetConfirmation, Voted, + }, + state::poll_messages, +}; // TODO: this type of function exists in many contracts. Would be better to implement this // in one place, and then just include it @@ -60,7 +63,7 @@ pub fn verify_verifier_set( let poll_id = create_verifier_set_poll(deps.storage, expires_at, snapshot)?; - POLL_VERIFIER_SETS.save( + poll_verifier_sets().save( deps.storage, &new_verifier_set.hash().as_slice().try_into().unwrap(), &PollContent::::new(new_verifier_set.clone(), poll_id), @@ -134,7 +137,7 @@ pub fn verify_messages( let id = create_messages_poll(deps.storage, expires_at, snapshot, msgs_to_verify.len())?; for (idx, message) in msgs_to_verify.iter().enumerate() { - POLL_MESSAGES.save( + poll_messages().save( deps.storage, &message.hash(), &state::PollContent::::new(message.clone(), id, idx), @@ -162,6 +165,51 @@ pub fn verify_messages( )) } +fn get_poll_results(poll: &Poll) -> PollResults { + match poll { + Poll::Messages(weighted_poll) => weighted_poll.state().results, + Poll::ConfirmVerifierSet(weighted_poll) => weighted_poll.state().results, + } +} + +fn make_quorum_event( + vote: &Vote, + index_in_poll: u32, + poll_id: &PollId, + poll: &Poll, + deps: &DepsMut, +) -> Result { + let status = match vote { + Vote::SucceededOnChain => VerificationStatus::SucceededOnSourceChain, + Vote::FailedOnChain => VerificationStatus::FailedOnSourceChain, + Vote::NotFound => VerificationStatus::NotFoundOnSourceChain, + }; + + match poll { + Poll::Messages(_) => { + let msg = poll_messages() + .idx + .load_message(deps.storage, *poll_id, index_in_poll)? + .expect("message not found in poll"); + Ok(QuorumReached { + content: msg, + status, + } + .into()) + } + Poll::ConfirmVerifierSet(_) => { + let verifier_set = poll_verifier_sets() + .idx + .load_verifier_set(deps.storage, *poll_id)? + .expect("verifier set not found in poll"); + Ok(QuorumReached { + content: verifier_set, + status, + } + .into()) + } + } +} pub fn vote( deps: DepsMut, env: Env, @@ -171,21 +219,38 @@ pub fn vote( ) -> Result { let poll = POLLS .may_load(deps.storage, poll_id)? - .ok_or(ContractError::PollNotFound)? - .try_map(|poll| { - poll.cast_vote(env.block.height, &info.sender, votes) - .map_err(ContractError::from) - })?; + .ok_or(ContractError::PollNotFound)?; + let results_before_voting = get_poll_results(&poll); + + let poll = poll.try_map(|poll| { + poll.cast_vote(env.block.height, &info.sender, votes) + .map_err(ContractError::from) + })?; POLLS.save(deps.storage, poll_id, &poll)?; - Ok(Response::new().add_event( - Voted { - poll_id, - voter: info.sender, - } - .into(), - )) + let results_after_voting = get_poll_results(&poll); + + let quorum_events = (results_after_voting.difference(results_before_voting)) + .expect("failed to substract poll results") + .0 + .into_iter() + .enumerate() + .filter_map(|(idx, vote)| vote.map(|vote| (idx, vote))) + .map(|(index_in_poll, vote)| { + make_quorum_event(&vote, index_in_poll as u32, &poll_id, &poll, &deps) + }) + .collect::, _>>()?; + + Ok(Response::new() + .add_event( + Voted { + poll_id, + voter: info.sender, + } + .into(), + ) + .add_events(quorum_events)) } pub fn end_poll(deps: DepsMut, env: Env, poll_id: PollId) -> Result { @@ -223,7 +288,7 @@ pub fn end_poll(deps: DepsMut, env: Env, poll_id: PollId) -> Result Result { @@ -30,7 +33,7 @@ pub fn messages_status( } pub fn message_status(deps: Deps, message: &Message) -> Result { - let loaded_poll_content = POLL_MESSAGES.may_load(deps.storage, &message.hash())?; + let loaded_poll_content = poll_messages().may_load(deps.storage, &message.hash())?; Ok(verification_status(deps, loaded_poll_content, message)) } @@ -39,7 +42,7 @@ pub fn verifier_set_status( deps: Deps, verifier_set: &VerifierSet, ) -> Result { - let loaded_poll_content = POLL_VERIFIER_SETS.may_load( + let loaded_poll_content = poll_verifier_sets().may_load( deps.storage, &verifier_set.hash().as_slice().try_into().unwrap(), )?; @@ -119,7 +122,7 @@ mod tests { .unwrap(); let msg = message(1); - POLL_MESSAGES + poll_messages() .save( deps.as_mut().storage, &msg.hash(), @@ -154,7 +157,7 @@ mod tests { .unwrap(); let msg = message(1); - POLL_MESSAGES + poll_messages() .save( deps.as_mut().storage, &msg.hash(), @@ -188,7 +191,7 @@ mod tests { .unwrap(); let msg = message(1); - POLL_MESSAGES + poll_messages() .save( deps.as_mut().storage, &msg.hash(), diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index b88160765..d6785ea2f 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; -use cw_storage_plus::{Item, Map}; +use cosmwasm_std::{Addr, Order, StdResult, Storage}; +use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; use axelar_wasm_std::{ counter, @@ -79,8 +79,117 @@ pub const POLL_ID: counter::Counter = counter::Counter::new("poll_id"); pub const POLLS: Map = Map::new("polls"); -pub const POLL_MESSAGES: Map<&Hash, PollContent> = Map::new("poll_messages"); - pub const CONFIG: Item = Item::new("config"); -pub const POLL_VERIFIER_SETS: Map<&Hash, PollContent> = Map::new("poll_verifier_sets"); +/// A multi-index that indexes a message by (PollID, index in poll) pair. The primary key of the underlying +/// map is the hash of the message (typed as Hash). This allows looking up a Message by it's hash, +/// or by a (PollID, index in poll) pair. The PollID is stored as a String +pub struct PollMessagesIndex<'a>(MultiIndex<'a, (String, u32), PollContent, &'a Hash>); + +impl<'a> PollMessagesIndex<'a> { + fn new( + idx_fn: fn(&[u8], &PollContent) -> (String, u32), + pk_namespace: &'a str, + idx_namespace: &'a str, + ) -> Self { + PollMessagesIndex(MultiIndex::new(idx_fn, pk_namespace, idx_namespace)) + } + + pub fn load_message( + &self, + storage: &dyn Storage, + poll_id: PollId, + index_in_poll: u32, + ) -> StdResult> { + match self + .0 + .prefix((poll_id.to_string(), index_in_poll)) + .range(storage, None, None, Order::Ascending) + .collect::)>, _>>()? + .as_slice() + { + [] => Ok(None), + [(_, content)] => Ok(Some(content.content.to_owned())), + _ => panic!("More than one message for poll_id and index_in_poll"), + } + } +} + +const POLL_MESSAGES_PKEY_NAMESPACE: &str = "poll_messages"; +const POLL_MESSAGES_IDX_NAMESPACE: &str = "poll_messages_idx"; + +pub fn poll_messages<'a>() -> IndexedMap<'a, &'a Hash, PollContent, PollMessagesIndex<'a>> +{ + IndexedMap::new( + POLL_MESSAGES_PKEY_NAMESPACE, + PollMessagesIndex::new( + |_pk: &[u8], d: &PollContent| (d.poll_id.to_string(), d.index_in_poll), + POLL_MESSAGES_PKEY_NAMESPACE, + POLL_MESSAGES_IDX_NAMESPACE, + ), + ) +} + +impl<'a> IndexList> for PollMessagesIndex<'a> { + fn get_indexes(&'_ self) -> Box>> + '_> { + let v: Vec<&dyn Index>> = vec![&self.0]; + Box::new(v.into_iter()) + } +} + +/// A multi-index that indexes a verifier set by PollID. The primary key of the underlying +/// map is the hash of the verifier set (typed as Hash). This allows looking up a VerifierSet by it's hash, +/// or by a PollID. PollIDs are stored as String. +pub struct PollVerifierSetsIndex<'a>(MultiIndex<'a, String, PollContent, &'a Hash>); + +impl<'a> PollVerifierSetsIndex<'a> { + fn new( + idx_fn: fn(&[u8], &PollContent) -> String, + pk_namespace: &'a str, + idx_namespace: &'a str, + ) -> Self { + PollVerifierSetsIndex(MultiIndex::new(idx_fn, pk_namespace, idx_namespace)) + } + + pub fn load_verifier_set( + &self, + storage: &dyn Storage, + poll_id: PollId, + ) -> StdResult> { + match self + .0 + .prefix(poll_id.to_string()) + .range(storage, None, None, Order::Ascending) + .collect::)>, _>>()? + .as_slice() + { + [] => Ok(None), + [(_, content)] => Ok(Some(content.content.to_owned())), + _ => panic!("More than one verifier_set for poll_id"), + } + } +} + +const POLL_VERIFIER_SETS_PKEY_NAMESPACE: &str = "poll_verifier_sets"; +const POLL_VERIFIER_SETS_IDX_NAMESPACE: &str = "poll_verifier_sets_idx"; + +pub fn poll_verifier_sets<'a>( +) -> IndexedMap<'a, &'a Hash, PollContent, PollVerifierSetsIndex<'a>> { + IndexedMap::new( + POLL_VERIFIER_SETS_PKEY_NAMESPACE, + PollVerifierSetsIndex::new( + |_pk: &[u8], d: &PollContent| d.poll_id.to_string(), + POLL_VERIFIER_SETS_PKEY_NAMESPACE, + POLL_VERIFIER_SETS_IDX_NAMESPACE, + ), + ) +} + +impl<'a> IndexList> for PollVerifierSetsIndex<'a> { + fn get_indexes( + &'_ self, + ) -> Box>> + '_> { + let v: Vec<&dyn Index>> = vec![&self.0]; + Box::new(v.into_iter()) + } +} diff --git a/packages/axelar-wasm-std/src/voting.rs b/packages/axelar-wasm-std/src/voting.rs index 4a5d5aed6..ee591f5e8 100644 --- a/packages/axelar-wasm-std/src/voting.rs +++ b/packages/axelar-wasm-std/src/voting.rs @@ -56,6 +56,9 @@ pub enum Error { #[error("message index out of bounds")] MessageIndexOutOfBounds, + + #[error("poll results have different length")] + PollResultsLengthUnequal, } #[cw_serde] @@ -204,10 +207,38 @@ impl Tallies { } } +#[cw_serde] +pub struct PollResults(pub Vec>); + +// would be better to implement the Sub trait, but clippy is configured to not allow arithmetic operators +impl PollResults { + /// Returns the elements in self that are Some, but in rhs are None. All other elements are converted to None. + /// This is used to determine which elements have quorum in self, but do not have quorum in rhs. + /// Vectors must be equal length. + pub fn difference(self, rhs: Self) -> Result { + if self.0.len() != rhs.0.len() { + return Err(Error::PollResultsLengthUnequal); + } + Ok(PollResults( + self.0 + .into_iter() + .zip(rhs.0) + .filter_map(|(lhs, rhs)| { + if lhs.is_some() && rhs.is_none() { + Some(lhs) + } else { + None + } + }) + .collect(), + )) + } +} + #[cw_serde] pub struct PollState { pub poll_id: PollId, - pub results: Vec>, + pub results: PollResults, /// List of participants who voted for the winning result pub consensus_participants: Vec, } @@ -306,7 +337,7 @@ impl WeightedPoll { PollState { poll_id: self.poll_id, - results, + results: PollResults(results), consensus_participants, } } @@ -483,7 +514,10 @@ mod tests { result, PollState { poll_id: PollId::from(Uint64::one()), - results: vec![Some(Vote::SucceededOnChain), Some(Vote::SucceededOnChain)], + results: PollResults(vec![ + Some(Vote::SucceededOnChain), + Some(Vote::SucceededOnChain) + ]), consensus_participants: vec!["addr1".to_string(), "addr2".to_string(),], } ); @@ -509,7 +543,10 @@ mod tests { result, PollState { poll_id: PollId::from(Uint64::one()), - results: vec![Some(Vote::SucceededOnChain), Some(Vote::SucceededOnChain)], + results: PollResults(vec![ + Some(Vote::SucceededOnChain), + Some(Vote::SucceededOnChain) + ]), consensus_participants: vec!["addr1".to_string(), "addr3".to_string(),], } ); From e7aa2c5404d315f8ca576a6757ed69ed6267b510 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Mon, 10 Jun 2024 12:27:58 -0400 Subject: [PATCH 010/168] refactor(multisig-prover): use evm-gateway package (#444) * refactor: use evm-gateway package * fix actions * remove auto fetch abi so contracts can build * remove ethers from ampd --- .cargo/config | 4 - Cargo.lock | 1082 +--- Cargo.toml | 2 + ampd/Cargo.lock | 5672 ----------------- ampd/Cargo.toml | 5 +- ampd/src/evm/finalizer.rs | 4 +- ampd/src/evm/json_rpc.rs | 8 +- ampd/src/evm/verifier.rs | 8 +- ampd/src/handlers/evm_verify_msg.rs | 4 +- ampd/src/handlers/evm_verify_verifier_set.rs | 4 +- ampd/src/handlers/sui_verify_msg.rs | 2 +- ampd/src/handlers/sui_verify_verifier_set.rs | 2 +- ampd/src/json_rpc.rs | 2 +- ampd/src/sui/json_rpc.rs | 2 +- ampd/src/sui/verifier.rs | 2 +- ampd/src/types.rs | 2 +- contracts/multisig-prover/Cargo.toml | 7 +- contracts/multisig-prover/src/contract.rs | 9 +- .../src/encoding/abi/execute_data.rs | 130 +- .../multisig-prover/src/encoding/abi/mod.rs | 175 +- .../abi/solidity/AmplifierGatewayTypes.sol | 27 - .../abi/solidity/WeightedMultisigTypes.sol | 36 - contracts/multisig-prover/src/error.rs | 15 +- contracts/multisig-prover/src/execute.rs | 88 +- contracts/multisig-prover/src/payload.rs | 2 + contracts/multisig-prover/src/query.rs | 24 +- packages/evm-gateway/.gitignore | 2 - packages/evm-gateway/Cargo.toml | 12 +- packages/evm-gateway/build.rs | 90 - .../src/abi}/IAxelarAmplifierGateway.json | 0 packages/evm-gateway/src/error.rs | 13 + packages/evm-gateway/src/lib.rs | 134 +- 32 files changed, 351 insertions(+), 7218 deletions(-) delete mode 100644 ampd/Cargo.lock delete mode 100644 contracts/multisig-prover/src/encoding/abi/solidity/AmplifierGatewayTypes.sol delete mode 100644 contracts/multisig-prover/src/encoding/abi/solidity/WeightedMultisigTypes.sol delete mode 100644 packages/evm-gateway/.gitignore delete mode 100644 packages/evm-gateway/build.rs rename {contracts/multisig-prover/src/encoding/abi/solidity => packages/evm-gateway/src/abi}/IAxelarAmplifierGateway.json (100%) create mode 100644 packages/evm-gateway/src/error.rs diff --git a/.cargo/config b/.cargo/config index b9f0cd28e..e61e7526b 100644 --- a/.cargo/config +++ b/.cargo/config @@ -4,7 +4,3 @@ unit-test = "test --lib" [build] rustflags = ["--cfg", "tracing_unstable"] - -[env] -SOLIDITY_GATEWAY_VERSION = "v5.9.0" -SOLIDITY_RELEASES_URL = "https://github.com/axelarnetwork/axelar-gmp-sdk-solidity/releases/download" diff --git a/Cargo.lock b/Cargo.lock index 86f4f019f..83a155a0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,105 +125,6 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "alloy-json-abi" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30946aa6173020259055a44971f5cf40a7d76c931d209caeb51b333263df4f" -dependencies = [ - "alloy-primitives", - "alloy-sol-type-parser", - "serde", -] - -[[package]] -name = "alloy-primitives" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" -dependencies = [ - "bytes", - "cfg-if", - "const-hex", - "derive_more", - "hex-literal", - "itoa", - "ruint", - "serde", - "tiny-keccak", -] - -[[package]] -name = "alloy-sol-macro" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dbd17d67f3e89478c8a634416358e539e577899666c927bc3d2b1328ee9b6ca" -dependencies = [ - "alloy-sol-macro-expander", - "alloy-sol-macro-input", - "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", -] - -[[package]] -name = "alloy-sol-macro-expander" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6da95adcf4760bb4b108fefa51d50096c5e5fdd29ee72fed3e86ee414f2e34" -dependencies = [ - "alloy-json-abi", - "alloy-sol-macro-input", - "const-hex", - "heck 0.4.1", - "indexmap 2.0.0", - "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", - "syn-solidity", - "tiny-keccak", -] - -[[package]] -name = "alloy-sol-macro-input" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c8da04c1343871fb6ce5a489218f9c85323c8340a36e9106b5fc98d4dd59d5" -dependencies = [ - "alloy-json-abi", - "const-hex", - "dunce", - "heck 0.5.0", - "proc-macro2 1.0.67", - "quote 1.0.33", - "serde_json", - "syn 2.0.37", - "syn-solidity", -] - -[[package]] -name = "alloy-sol-type-parser" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368cae4dc052cad1d8f72eb2ae0c38027116933eeb49213c200a9e9875f208d7" -dependencies = [ - "winnow", -] - -[[package]] -name = "alloy-sol-types" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a64d2d2395c1ac636b62419a7b17ec39031d6b2367e66e9acbf566e6055e9c" -dependencies = [ - "alloy-json-abi", - "alloy-primitives", - "alloy-sol-macro", - "const-hex", -] - [[package]] name = "ampd" version = "0.4.0" @@ -243,7 +144,9 @@ dependencies = [ "elliptic-curve", "enum-display-derive", "error-stack", - "ethers", + "ethers-contract", + "ethers-core", + "ethers-providers", "events", "events-derive", "evm-gateway", @@ -262,7 +165,7 @@ dependencies = [ "rand", "random-string", "report", - "reqwest 0.11.25", + "reqwest", "router-api", "serde", "serde_json", @@ -394,15 +297,6 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" -dependencies = [ - "derive_arbitrary", -] - [[package]] name = "ark-bls12-381" version = "0.4.0" @@ -611,15 +505,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "ascii-canvas" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] - [[package]] name = "asn1-rs" version = "0.5.2" @@ -931,12 +816,6 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "base64ct" version = "1.6.0" @@ -1023,7 +902,7 @@ dependencies = [ "hmac", "k256", "once_cell", - "pbkdf2 0.12.2", + "pbkdf2", "rand_core 0.6.4", "ripemd", "sha2 0.10.7", @@ -1123,7 +1002,7 @@ checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.3.0", + "constant_time_eq", ] [[package]] @@ -1134,7 +1013,7 @@ checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.3.0", + "constant_time_eq", ] [[package]] @@ -1147,7 +1026,7 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq 0.3.0", + "constant_time_eq", "digest 0.10.7", ] @@ -1316,16 +1195,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - [[package]] name = "bzip2-sys" version = "0.1.11+1.0.8" @@ -1517,58 +1386,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "coins-bip32" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" -dependencies = [ - "bs58 0.5.1", - "coins-core", - "digest 0.10.7", - "hmac", - "k256", - "serde", - "sha2 0.10.7", - "thiserror", -] - -[[package]] -name = "coins-bip39" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" -dependencies = [ - "bitvec 1.0.1", - "coins-bip32", - "hmac", - "once_cell", - "pbkdf2 0.12.2", - "rand", - "sha2 0.10.7", - "thiserror", -] - -[[package]] -name = "coins-core" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" -dependencies = [ - "base64 0.21.4", - "bech32", - "bs58 0.5.1", - "digest 0.10.7", - "generic-array", - "hex", - "ripemd", - "serde", - "serde_derive", - "sha2 0.10.7", - "sha3 0.10.8", - "thiserror", -] - [[package]] name = "collectable" version = "0.0.2" @@ -1642,12 +1459,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "constant_time_eq" version = "0.3.0" @@ -1834,21 +1645,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc" -version = "3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - [[package]] name = "crc32fast" version = "1.4.0" @@ -1868,30 +1664,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -2207,12 +1979,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "deflate64" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ace6c86376be0b6cdcf3fb41882e81d94b31587573d1cfa9d01cd06bba210d" - [[package]] name = "der" version = "0.6.1" @@ -2293,17 +2059,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" -dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -2317,12 +2072,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "difference" version = "2.0.0" @@ -2552,15 +2301,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ena" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" -dependencies = [ - "log", -] - [[package]] name = "encode_unicode" version = "0.3.6" @@ -2673,28 +2413,6 @@ dependencies = [ "rustc_version", ] -[[package]] -name = "eth-keystore" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes", - "ctr", - "digest 0.10.7", - "hex", - "hmac", - "pbkdf2 0.11.0", - "rand", - "scrypt", - "serde", - "serde_json", - "sha2 0.10.7", - "sha3 0.10.8", - "thiserror", - "uuid 0.8.2", -] - [[package]] name = "ethabi" version = "18.0.0" @@ -2743,34 +2461,6 @@ dependencies = [ "uint", ] -[[package]] -name = "ethers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" -dependencies = [ - "ethers-addressbook", - "ethers-contract", - "ethers-core", - "ethers-etherscan", - "ethers-middleware", - "ethers-providers", - "ethers-signers", - "ethers-solc", -] - -[[package]] -name = "ethers-addressbook" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" -dependencies = [ - "ethers-core", - "once_cell", - "serde", - "serde_json", -] - [[package]] name = "ethers-contract" version = "2.0.14" @@ -2781,7 +2471,6 @@ dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", "ethers-core", - "ethers-providers", "futures-util", "once_cell", "pin-project", @@ -2800,13 +2489,11 @@ dependencies = [ "const-hex", "dunce", "ethers-core", - "ethers-etherscan", "eyre", "prettyplease 0.2.15", "proc-macro2 1.0.67", "quote 1.0.33", "regex", - "reqwest 0.11.25", "serde", "serde_json", "syn 2.0.37", @@ -2860,49 +2547,6 @@ dependencies = [ "unicode-xid 0.2.4", ] -[[package]] -name = "ethers-etherscan" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" -dependencies = [ - "chrono", - "ethers-core", - "reqwest 0.11.25", - "semver", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "ethers-middleware" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" -dependencies = [ - "async-trait", - "auto_impl", - "ethers-contract", - "ethers-core", - "ethers-etherscan", - "ethers-providers", - "ethers-signers", - "futures-channel", - "futures-locks", - "futures-util", - "instant", - "reqwest 0.11.25", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "url", -] - [[package]] name = "ethers-providers" version = "2.0.14" @@ -2925,7 +2569,7 @@ dependencies = [ "jsonwebtoken", "once_cell", "pin-project", - "reqwest 0.11.25", + "reqwest", "serde", "serde_json", "thiserror", @@ -2940,57 +2584,6 @@ dependencies = [ "ws_stream_wasm", ] -[[package]] -name = "ethers-signers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" -dependencies = [ - "async-trait", - "coins-bip32", - "coins-bip39", - "const-hex", - "elliptic-curve", - "eth-keystore", - "ethers-core", - "rand", - "sha2 0.10.7", - "thiserror", - "tracing", -] - -[[package]] -name = "ethers-solc" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" -dependencies = [ - "cfg-if", - "const-hex", - "dirs", - "dunce", - "ethers-core", - "glob", - "home", - "md-5", - "num_cpus", - "once_cell", - "path-slash", - "rayon", - "regex", - "semver", - "serde", - "serde_json", - "solang-parser", - "svm-rs", - "thiserror", - "tiny-keccak", - "tokio", - "tracing", - "walkdir", - "yansi", -] - [[package]] name = "ethnum" version = "1.4.0" @@ -3029,15 +2622,13 @@ dependencies = [ "axelar-wasm-std", "cosmwasm-std", "error-stack", - "ethers", + "ethers-contract", + "ethers-core", "k256", "multisig", - "reqwest 0.12.4", - "serde", - "serde_json", + "router-api", "sha3 0.10.8", "thiserror", - "zip 2.0.0", ] [[package]] @@ -3163,7 +2754,7 @@ dependencies = [ "num-bigint 0.4.4", "once_cell", "regex", - "reqwest 0.11.25", + "reqwest", "rustls-webpki 0.101.5", "schemars", "serde", @@ -3310,21 +2901,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.0" @@ -3346,16 +2922,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "funty" version = "1.1.0" @@ -3416,16 +2982,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" -[[package]] -name = "futures-locks" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" -dependencies = [ - "futures-channel", - "futures-task", -] - [[package]] name = "futures-macro" version = "0.3.28" @@ -3608,25 +3164,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "h2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 1.1.0", - "indexmap 2.0.0", - "slab", - "tokio", - "tokio-util 0.7.9", - "tracing", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -3713,12 +3250,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hermit-abi" version = "0.3.3" @@ -3734,12 +3265,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hkdf" version = "0.12.3" @@ -3867,7 +3392,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.24", + "h2", "http 0.2.9", "http-body 0.4.5", "httparse", @@ -3890,7 +3415,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.4", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -3899,7 +3423,6 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", - "want", ] [[package]] @@ -3965,22 +3488,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.3.1", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.3" @@ -3988,7 +3495,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", - "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.0", @@ -3996,9 +3502,6 @@ dependencies = [ "pin-project-lite", "socket2 0.5.4", "tokio", - "tower", - "tower-service", - "tracing", ] [[package]] @@ -4338,34 +3841,6 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "lalrpop" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" -dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools 0.10.5", - "lalrpop-util", - "petgraph 0.6.4", - "regex", - "regex-syntax 0.7.5", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid 0.2.4", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" - [[package]] name = "lazy_static" version = "1.4.0" @@ -4452,12 +3927,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "lockfree-object-pool" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" - [[package]] name = "log" version = "0.4.21" @@ -4477,16 +3946,6 @@ dependencies = [ "libc", ] -[[package]] -name = "lzma-rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" -dependencies = [ - "byteorder", - "crc", -] - [[package]] name = "match_opt" version = "0.1.2" @@ -4505,30 +3964,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" -[[package]] -name = "md-5" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "memchr" version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "merlin" version = "3.0.0" @@ -5114,8 +4555,6 @@ dependencies = [ name = "multisig-prover" version = "0.5.0" dependencies = [ - "alloy-primitives", - "alloy-sol-types", "anyhow", "axelar-wasm-std", "axelar-wasm-std-derive", @@ -5129,8 +4568,9 @@ dependencies = [ "cw2 1.1.0", "elliptic-curve", "error-stack", - "ethabi", - "ethers", + "ethers-contract", + "ethers-core", + "evm-gateway", "gateway", "gateway-api", "generic-array", @@ -5276,24 +4716,6 @@ dependencies = [ "workspace-hack", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "neptune" version = "13.0.0" @@ -5313,12 +4735,6 @@ dependencies = [ "trait-set", ] -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - [[package]] name = "nexus-gateway" version = "0.2.3" @@ -5575,50 +4991,12 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags 2.4.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -5772,17 +5150,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "pasta_curves" version = "0.5.1" @@ -5807,30 +5174,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "path-slash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" - [[package]] name = "pathdiff" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", - "hmac", - "password-hash", - "sha2 0.10.7", -] - [[package]] name = "pbkdf2" version = "0.12.2" @@ -5989,7 +5338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ "phf_macros", - "phf_shared 0.11.2", + "phf_shared", ] [[package]] @@ -5998,7 +5347,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared 0.11.2", + "phf_shared", "rand", ] @@ -6009,21 +5358,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", - "phf_shared 0.11.2", + "phf_shared", "proc-macro2 1.0.67", "quote 1.0.33", "syn 2.0.37", ] -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - [[package]] name = "phf_shared" version = "0.11.2" @@ -6133,12 +5473,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "predicates" version = "2.1.5" @@ -6316,7 +5650,7 @@ dependencies = [ "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.2", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -6589,28 +5923,6 @@ dependencies = [ "fastrand 1.9.0", ] -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - [[package]] name = "rcgen" version = "0.9.3" @@ -6710,7 +6022,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] @@ -6721,15 +6033,9 @@ checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - [[package]] name = "regex-syntax" version = "0.8.2" @@ -6758,7 +6064,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.24", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", @@ -6771,12 +6077,12 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.7", - "rustls-pemfile 1.0.3", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration 0.6.0", + "system-configuration", "tokio", "tokio-rustls 0.24.1", "tower-service", @@ -6785,50 +6091,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots 0.25.2", - "winreg 0.50.0", -] - -[[package]] -name = "reqwest" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" -dependencies = [ - "base64 0.22.1", - "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.4.4", - "http 1.1.0", - "http-body 1.0.0", - "http-body-util", - "hyper 1.3.1", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile 2.1.2", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg 0.52.0", + "winreg", ] [[package]] @@ -7010,26 +6273,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ruint" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" -dependencies = [ - "proptest", - "rand", - "ruint-macro", - "serde", - "valuable", - "zeroize", -] - -[[package]] -name = "ruint-macro" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" - [[package]] name = "rust-ini" version = "0.18.0" @@ -7135,22 +6378,6 @@ dependencies = [ "base64 0.21.4", ] -[[package]] -name = "rustls-pemfile" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" -dependencies = [ - "base64 0.22.1", - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - [[package]] name = "rustls-webpki" version = "0.100.3" @@ -7195,15 +6422,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - [[package]] name = "same-file" version = "1.0.6" @@ -7277,18 +6495,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac", - "pbkdf2 0.11.0", - "salsa20", - "sha2 0.10.7", -] - [[package]] name = "sct" version = "0.6.1" @@ -7731,12 +6937,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "similar" version = "2.2.1" @@ -7812,20 +7012,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "solang-parser" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" -dependencies = [ - "itertools 0.11.0", - "lalrpop", - "lalrpop-util", - "phf", - "thiserror", - "unicode-xid 0.2.4", -] - [[package]] name = "spin" version = "0.5.2" @@ -7858,19 +7044,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", -] - [[package]] name = "strsim" version = "0.10.0" @@ -8188,26 +7361,6 @@ dependencies = [ "workspace-hack", ] -[[package]] -name = "svm-rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597e3a746727984cb7ea2487b6a40726cad0dbe86628e7d429aa6b8c4c153db4" -dependencies = [ - "dirs", - "fs2", - "hex", - "once_cell", - "reqwest 0.11.25", - "semver", - "serde", - "serde_json", - "sha2 0.10.7", - "thiserror", - "url", - "zip 0.6.6", -] - [[package]] name = "syn" version = "0.15.44" @@ -8241,18 +7394,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn-solidity" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8db114c44cf843a8bacd37a146e37987a0b823a0e8bc4fdc610c9c72ab397a5" -dependencies = [ - "paste", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", -] - [[package]] name = "sync_wrapper" version = "0.1.2" @@ -8277,17 +7418,6 @@ dependencies = [ "unicode-xid 0.2.4", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys 0.5.0", -] - [[package]] name = "system-configuration" version = "0.6.0" @@ -8296,17 +7426,7 @@ checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" dependencies = [ "bitflags 2.4.0", "core-foundation", - "system-configuration-sys 0.6.0", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "system-configuration-sys", ] [[package]] @@ -8503,17 +7623,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "term" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] - [[package]] name = "termcolor" version = "1.1.3" @@ -8694,16 +7803,6 @@ dependencies = [ "syn 2.0.37", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.22.0" @@ -8838,7 +7937,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2 0.3.24", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", @@ -8865,7 +7964,7 @@ dependencies = [ "axum 0.6.20", "base64 0.21.4", "bytes", - "h2 0.3.24", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", @@ -8874,7 +7973,7 @@ dependencies = [ "pin-project", "prost 0.12.6", "rustls 0.21.7", - "rustls-pemfile 1.0.3", + "rustls-pemfile", "tokio", "tokio-rustls 0.24.1", "tokio-stream", @@ -9284,10 +8383,6 @@ name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom", - "serde", -] [[package]] name = "uuid" @@ -9739,16 +8834,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "workspace-hack" version = "0.1.0" @@ -9816,12 +8901,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "yasna" version = "0.5.2" @@ -9851,105 +8930,6 @@ dependencies = [ "syn 2.0.37", ] -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq 0.1.5", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2 0.11.0", - "sha1", - "time", - "zstd 0.11.2+zstd.1.5.2", -] - -[[package]] -name = "zip" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fccb210625924ecbbe92f9bb497d04b167b64fe5540cec75f10b16e0c51ee92b" -dependencies = [ - "aes", - "arbitrary", - "bzip2", - "constant_time_eq 0.3.0", - "crc32fast", - "crossbeam-utils", - "deflate64", - "displaydoc", - "flate2", - "hmac", - "indexmap 2.0.0", - "lzma-rs", - "pbkdf2 0.12.2", - "rand", - "sha1", - "thiserror", - "time", - "zeroize", - "zopfli", - "zstd 0.13.1", -] - -[[package]] -name = "zopfli" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" -dependencies = [ - "bumpalo", - "crc32fast", - "lockfree-object-pool", - "log", - "once_cell", - "simd-adler32", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" -dependencies = [ - "zstd-safe 7.1.0", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-safe" -version = "7.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" -dependencies = [ - "zstd-sys", -] - [[package]] name = "zstd-sys" version = "2.0.10+zstd.1.5.6" diff --git a/Cargo.toml b/Cargo.toml index 01387b218..9ddacf8a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,8 @@ serde_json = "1.0.89" schemars = "0.8.10" sha3 = { version = "0.10.8", default-features = false, features = [] } signature-verifier-api = { version = "^0.1.0", path = "packages/signature-verifier-api" } +ethers-contract = { version = "2.0.13", default-features = false, features = ["abigen"] } +ethers-core = "2.0.13" [workspace.lints.clippy] arithmetic_side_effects = "deny" diff --git a/ampd/Cargo.lock b/ampd/Cargo.lock deleted file mode 100644 index cd74ae803..000000000 --- a/ampd/Cargo.lock +++ /dev/null @@ -1,5672 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "addr2line" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aes" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" -dependencies = [ - "memchr", -] - -[[package]] -name = "ampd" -version = "0.1.0" -dependencies = [ - "async-trait", - "axelar-wasm-std", - "base64 0.21.2", - "clap", - "config", - "router", - "cosmos-sdk-proto 0.16.0", - "cosmrs", - "cosmwasm-std", - "deref-derive", - "ecdsa 0.16.7", - "enum-display-derive", - "error-stack", - "ethers", - "futures", - "hex", - "humantime-serde", - "k256 0.13.1", - "mockall", - "multisig", - "prost", - "rand", - "random-string", - "serde", - "serde_json", - "serde_with", - "tendermint 0.33.0", - "tendermint-rpc", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "toml 0.5.11", - "tonic", - "tonic-build", - "tracing", - "tracing-core", - "tracing-subscriber", - "url", - "valuable", - "voting-verifier", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is-terminal", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" - -[[package]] -name = "anstyle-parse" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" -dependencies = [ - "anstyle", - "windows-sys 0.48.0", -] - -[[package]] -name = "anyhow" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" - -[[package]] -name = "arrayvec" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[package]] -name = "ascii-canvas" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" -dependencies = [ - "term", -] - -[[package]] -name = "async-stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "async-trait" -version = "0.1.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "async_io_stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" -dependencies = [ - "futures", - "pharos", - "rustc_version", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "auto_impl" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "axelar-wasm-std" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "flagset", - "num-traits", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "axum" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d8068b6ccb8b34db9de397c7043f91db8b4c66414952c6db944f238c4d3db3" -dependencies = [ - "async-trait", - "axum-core", - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" - -[[package]] -name = "base64ct" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" - -[[package]] -name = "bech32" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bip32" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e40748d60a3296653e45e87e64c6989aebfad607bccce59cc4156c5d81b2f70" -dependencies = [ - "bs58", - "hmac", - "k256 0.13.1", - "once_cell", - "pbkdf2 0.12.1", - "rand_core 0.6.4", - "ripemd", - "sha2 0.10.6", - "subtle", - "zeroize", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitvec" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" -dependencies = [ - "either", - "radium 0.3.0", -] - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium 0.7.0", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" - -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" -dependencies = [ - "sha2 0.9.9", -] - -[[package]] -name = "bumpalo" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -dependencies = [ - "serde", -] - -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "camino" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "4.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" -dependencies = [ - "clap_builder", - "clap_derive", - "once_cell", -] - -[[package]] -name = "clap_builder" -version = "4.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" -dependencies = [ - "anstream", - "anstyle", - "bitflags", - "clap_lex", - "once_cell", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "clap_lex" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" - -[[package]] -name = "coins-bip32" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30a84aab436fcb256a2ab3c80663d8aec686e6bae12827bb05fef3e1e439c9f" -dependencies = [ - "bincode", - "bs58", - "coins-core", - "digest 0.10.6", - "getrandom", - "hmac", - "k256 0.13.1", - "lazy_static", - "serde", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "coins-bip39" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f4d04ee18e58356accd644896aeb2094ddeafb6a713e056cef0c0a8e468c15" -dependencies = [ - "bitvec 0.17.4", - "coins-bip32", - "getrandom", - "hmac", - "once_cell", - "pbkdf2 0.12.1", - "rand", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "coins-core" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b949a1c63fb7eb591eb7ba438746326aedf0ae843e51ec92ba6bec5bb382c4f" -dependencies = [ - "base64 0.21.2", - "bech32", - "bs58", - "digest 0.10.6", - "generic-array", - "hex", - "ripemd", - "serde", - "serde_derive", - "sha2 0.10.6", - "sha3", - "thiserror", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "config" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" -dependencies = [ - "async-trait", - "json5", - "lazy_static", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml 0.5.11", - "yaml-rust", -] - -[[package]] -name = "router" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2", - "flagset", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "const-oid" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cosmos-sdk-proto" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" -dependencies = [ - "prost", - "prost-types", - "tendermint-proto 0.27.0", - "tonic", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" -dependencies = [ - "prost", - "prost-types", - "tendermint-proto 0.32.0", -] - -[[package]] -name = "cosmrs" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.19.0", - "ecdsa 0.16.7", - "eyre", - "getrandom", - "k256 0.13.1", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.32.0", - "thiserror", -] - -[[package]] -name = "cosmwasm-crypto" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" -dependencies = [ - "digest 0.10.6", - "ed25519-zebra", - "k256 0.11.6", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" -dependencies = [ - "syn 1.0.107", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" -dependencies = [ - "cosmwasm-schema-derive", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "cosmwasm-std" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" -dependencies = [ - "base64 0.13.1", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18b4c99c6479e554ef1516950f1fa3d88bd7d0a8fc2367321c07ca0a33997dfc" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct 0.6.1", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - -[[package]] -name = "cw-storage-plus" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6cf70ef7686e2da9ad7b067c5942cd3e88dd9453f7af42f54557f8af300fb0" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw0" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae676b6cced78a3d38ad4b01ab4ed66fc78ac191c3c0d6bfd5372cb2efd473b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5abb8ecea72e09afff830252963cb60faf945ce6cef2c20a43814516082653da" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.15.1", - "schemars", - "serde", -] - -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.27", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "der" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "deref-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4255bb7dd538590188bd0aea52e48bd699b19bd90b0d069ec2ced8461fe23273" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer 0.10.3", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - -[[package]] -name = "dyn-clone" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - -[[package]] -name = "ecdsa" -version = "0.16.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" -dependencies = [ - "der 0.7.5", - "digest 0.10.6", - "elliptic-curve 0.13.4", - "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", -] - -[[package]] -name = "ed25519" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.1.0", -] - -[[package]] -name = "ed25519-consensus" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" -dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.6", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" -dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.2", - "digest 0.10.6", - "ff 0.13.0", - "generic-array", - "group 0.13.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", - "sec1 0.7.1", - "subtle", - "zeroize", -] - -[[package]] -name = "ena" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" -dependencies = [ - "log", -] - -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "enr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf56acd72bb22d2824e66ae8e9e5ada4d0de17a69c7fd35569dde2ada8ec9116" -dependencies = [ - "base64 0.13.1", - "bytes", - "hex", - "k256 0.13.1", - "log", - "rand", - "rlp", - "serde", - "sha3", - "zeroize", -] - -[[package]] -name = "enum-display-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "error-stack" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d224e04b2d93d974c08e375dac9b8d1a513846e44c6666450a57b1ed963f9" -dependencies = [ - "anyhow", - "eyre", - "owo-colors", - "rustc_version", -] - -[[package]] -name = "eth-keystore" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes", - "ctr", - "digest 0.10.6", - "hex", - "hmac", - "pbkdf2 0.11.0", - "rand", - "scrypt", - "serde", - "serde_json", - "sha2 0.10.6", - "sha3", - "thiserror", - "uuid", -] - -[[package]] -name = "ethabi" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "primitive-types", - "scale-info", - "uint", -] - -[[package]] -name = "ethers" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b4026b97da8281276744741fac7eb385da905f6093c583331fa2953fdd4253" -dependencies = [ - "ethers-addressbook", - "ethers-contract", - "ethers-core", - "ethers-etherscan", - "ethers-middleware", - "ethers-providers", - "ethers-signers", - "ethers-solc", -] - -[[package]] -name = "ethers-addressbook" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcb6ffefc230d8c42874c51b28dc11dbb8de50b27a8fdf92648439d6baa68dc" -dependencies = [ - "ethers-core", - "once_cell", - "serde", - "serde_json", -] - -[[package]] -name = "ethers-contract" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4719a44c3d37ab07c6dea99ab174068d8c35e441b60b6c20ce4e48357273e8" -dependencies = [ - "ethers-contract-abigen", - "ethers-contract-derive", - "ethers-core", - "ethers-providers", - "ethers-signers", - "futures-util", - "hex", - "once_cell", - "pin-project", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "ethers-contract-abigen" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155ea1b84d169d231317ed86e307af6f2bed6b40dd17e5e94bc84da21cadb21c" -dependencies = [ - "Inflector", - "dunce", - "ethers-core", - "ethers-etherscan", - "eyre", - "hex", - "prettyplease 0.2.12", - "proc-macro2", - "quote", - "regex", - "reqwest", - "serde", - "serde_json", - "syn 2.0.27", - "toml 0.7.6", - "walkdir", -] - -[[package]] -name = "ethers-contract-derive" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8567ff196c4a37c1a8c90ec73bda0ad2062e191e4f0a6dc4d943e2ec4830fc88" -dependencies = [ - "Inflector", - "ethers-contract-abigen", - "ethers-core", - "hex", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.27", -] - -[[package]] -name = "ethers-core" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60ca2514feb98918a0a31de7e1983c29f2267ebf61b2dc5d4294f91e5b866623" -dependencies = [ - "arrayvec", - "bytes", - "cargo_metadata", - "chrono", - "elliptic-curve 0.13.4", - "ethabi", - "generic-array", - "hex", - "k256 0.13.1", - "num_enum", - "once_cell", - "open-fastrlp", - "rand", - "rlp", - "serde", - "serde_json", - "strum", - "syn 2.0.27", - "tempfile", - "thiserror", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "ethers-etherscan" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22b3a8269d3df0ed6364bc05b4735b95f4bf830ce3aef87d5e760fb0e93e5b91" -dependencies = [ - "ethers-core", - "reqwest", - "semver", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "ethers-middleware" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c339aad74ae5c451d27e0e49c7a3c7d22620b119b4f9291d7aa21f72d7f366" -dependencies = [ - "async-trait", - "auto_impl", - "ethers-contract", - "ethers-core", - "ethers-etherscan", - "ethers-providers", - "ethers-signers", - "futures-channel", - "futures-locks", - "futures-util", - "instant", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "url", -] - -[[package]] -name = "ethers-providers" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b411b119f1cf0efb69e2190883dee731251882bb21270f893ee9513b3a697c48" -dependencies = [ - "async-trait", - "auto_impl", - "base64 0.21.2", - "bytes", - "enr", - "ethers-core", - "futures-core", - "futures-timer", - "futures-util", - "hashers", - "hex", - "http", - "instant", - "once_cell", - "pin-project", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-tungstenite", - "tracing", - "tracing-futures", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "ws_stream_wasm", -] - -[[package]] -name = "ethers-signers" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4864d387456a9c09a1157fa10e1528b29d90f1d859443acf06a1b23365fb518c" -dependencies = [ - "async-trait", - "coins-bip32", - "coins-bip39", - "elliptic-curve 0.13.4", - "eth-keystore", - "ethers-core", - "hex", - "rand", - "sha2 0.10.6", - "thiserror", - "tracing", -] - -[[package]] -name = "ethers-solc" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6c2b9625a2c639d46625f88acc2092a3cb35786c37f7c2128b3ca20f639b3c" -dependencies = [ - "cfg-if", - "dunce", - "ethers-core", - "glob", - "hex", - "home", - "md-5", - "num_cpus", - "once_cell", - "path-slash", - "rayon", - "regex", - "semver", - "serde", - "serde_json", - "solang-parser", - "svm-rs", - "thiserror", - "tiny-keccak", - "tokio", - "tracing", - "walkdir", - "yansi", -] - -[[package]] -name = "eyre" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "flagset" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499" -dependencies = [ - "serde", -] - -[[package]] -name = "flate2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "eyre", - "paste", -] - -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-executor" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-locks" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" -dependencies = [ - "futures-channel", - "futures-task", -] - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" -dependencies = [ - "gloo-timers", - "send_wrapper 0.4.0", -] - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.0", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.2", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" - -[[package]] -name = "hashers" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" -dependencies = [ - "fxhash", -] - -[[package]] -name = "headers" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" -dependencies = [ - "base64 0.13.1", - "bitflags", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "http" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "humantime-serde" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" -dependencies = [ - "humantime", - "serde", -] - -[[package]] -name = "hyper" -version = "0.14.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-proxy" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "hyper-rustls 0.22.1", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.22.0", - "tower-service", - "webpki 0.21.4", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper", - "log", - "rustls 0.19.1", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.22.0", - "webpki 0.21.4", - "webpki-roots 0.21.1", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls 0.21.5", - "tokio", - "tokio-rustls 0.24.1", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", - "serde", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" -dependencies = [ - "libc", - "windows-sys 0.42.0", -] - -[[package]] -name = "ipnet" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" - -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "is_ci" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" - -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" -dependencies = [ - "pest", - "pest_derive", - "serde", -] - -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.6", -] - -[[package]] -name = "k256" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" -dependencies = [ - "cfg-if", - "ecdsa 0.16.7", - "elliptic-curve 0.13.4", - "once_cell", - "sha2 0.10.6", - "signature 2.1.0", -] - -[[package]] -name = "keccak" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lalrpop" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" -dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matchit" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" - -[[package]] -name = "md-5" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" -dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "mockall" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "lazy_static", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "multisig" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "cosmwasm-crypto", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2", - "getrandom", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", - "ethereum-types", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -dependencies = [ - "supports-color", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" -dependencies = [ - "arrayvec", - "bitvec 1.0.1", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "windows-sys 0.42.0", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" - -[[package]] -name = "path-slash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.6", - "hmac", - "password-hash", - "sha2 0.10.6", -] - -[[package]] -name = "pbkdf2" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31" -dependencies = [ - "digest 0.10.6", - "hmac", -] - -[[package]] -name = "peg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" - -[[package]] -name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - -[[package]] -name = "pest" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" -dependencies = [ - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "pest_meta" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" -dependencies = [ - "once_cell", - "pest", - "sha2 0.10.6", -] - -[[package]] -name = "petgraph" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" -dependencies = [ - "fixedbitset", - "indexmap 1.9.2", -] - -[[package]] -name = "pharos" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" -dependencies = [ - "futures", - "rustc_version", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared 0.11.2", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.5", - "spki 0.7.2", -] - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "predicates" -version = "2.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" -dependencies = [ - "difflib", - "float-cmp", - "itertools", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates-core" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" - -[[package]] -name = "predicates-tree" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "prettyplease" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" -dependencies = [ - "proc-macro2", - "syn 1.0.107", -] - -[[package]] -name = "prettyplease" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" -dependencies = [ - "proc-macro2", - "syn 2.0.27", -] - -[[package]] -name = "primitive-types" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" -dependencies = [ - "once_cell", - "toml_edit 0.18.1", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.107", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" -dependencies = [ - "bytes", - "heck", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prettyplease 0.1.25", - "prost", - "prost-types", - "regex", - "syn 1.0.107", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", -] - -[[package]] -name = "quote" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "random-string" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e63111ec5292d8af9c220f06fe3bb87991cc78b6f1f7e291d1ae6b8a60817" -dependencies = [ - "fastrand", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall 0.2.16", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" - -[[package]] -name = "reqwest" -version = "0.11.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" -dependencies = [ - "base64 0.21.2", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls 0.24.1", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.5", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.22.6", - "winreg", -] - -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rlp-derive", - "rustc-hex", -] - -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "ron" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" -dependencies = [ - "base64 0.13.1", - "bitflags", - "serde", -] - -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys 0.45.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct 0.6.1", - "webpki 0.21.4", -] - -[[package]] -name = "rustls" -version = "0.21.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.1", - "sct 0.7.0", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls 0.19.1", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.2", -] - -[[package]] -name = "rustls-webpki" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" - -[[package]] -name = "ryu" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scale-info" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "schannel" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" -dependencies = [ - "windows-sys 0.42.0", -] - -[[package]] -name = "schemars" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 1.0.107", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac", - "pbkdf2 0.11.0", - "salsa20", - "sha2 0.10.6", -] - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - -[[package]] -name = "sec1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" -dependencies = [ - "base16ct 0.2.0", - "der 0.7.5", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" -dependencies = [ - "serde", -] - -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - -[[package]] -name = "serde" -version = "1.0.174" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.174" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "serde_json" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "serde_spanned" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" -dependencies = [ - "base64 0.21.2", - "chrono", - "hex", - "indexmap 1.9.2", - "indexmap 2.0.0", - "serde", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "service-registry" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.15.1", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "sha1" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" -dependencies = [ - "digest 0.10.6", - "keccak", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.6", - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" -dependencies = [ - "digest 0.10.6", - "rand_core 0.6.4", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "solang-parser" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c792fe9fae2a2f716846f214ca10d5a1e21133e0bf36cef34bcc4a852467b21" -dependencies = [ - "itertools", - "lalrpop", - "lalrpop-util", - "phf", - "thiserror", - "unicode-xid", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" -dependencies = [ - "base64ct", - "der 0.7.5", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.27", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - -[[package]] -name = "supports-color" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba6faf2ca7ee42fdd458f4347ae0a9bd6bcc445ad7cb57ad82b383f18870d6f" -dependencies = [ - "atty", - "is_ci", -] - -[[package]] -name = "svm-rs" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a04fc4f5cd35c700153b233f5575ccb3237e0f941fa5049d9e98254d10bf2fe" -dependencies = [ - "fs2", - "hex", - "home", - "once_cell", - "reqwest", - "semver", - "serde", - "serde_json", - "sha2 0.10.6", - "thiserror", - "url", - "zip", -] - -[[package]] -name = "syn" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "unicode-xid", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.3.5", - "rustix", - "windows-sys 0.45.0", -] - -[[package]] -name = "tendermint" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46ec6b25b028097ab682ffae11d09d64fe1e2535833b902f26a278a0f88a705" -dependencies = [ - "bytes", - "digest 0.10.6", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "k256 0.13.1", - "num-traits", - "once_cell", - "prost", - "prost-types", - "ripemd", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.6", - "signature 2.1.0", - "subtle", - "subtle-encoding", - "tendermint-proto 0.32.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "bytes", - "digest 0.10.6", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "num-traits", - "once_cell", - "prost", - "prost-types", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.6", - "signature 2.1.0", - "subtle", - "subtle-encoding", - "tendermint-proto 0.33.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-config" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.33.0", - "toml 0.5.11", - "url", -] - -[[package]] -name = "tendermint-proto" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23c8ff0e6634eb4c3c4aeed45076dc97dac91aac5501a905a67fa222e165b" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-rpc" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls 0.22.1", - "peg", - "pin-project", - "semver", - "serde", - "serde_bytes", - "serde_json", - "subtle", - "subtle-encoding", - "tendermint 0.33.0", - "tendermint-config", - "tendermint-proto 0.33.0", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "term" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" -dependencies = [ - "dirs-next", - "rustversion", - "winapi", -] - -[[package]] -name = "termtree" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" - -[[package]] -name = "thiserror" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" - -[[package]] -name = "time-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" -dependencies = [ - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" -dependencies = [ - "autocfg", - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls 0.19.1", - "tokio", - "webpki 0.21.4", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.5", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" -dependencies = [ - "futures-util", - "log", - "rustls 0.21.5", - "tokio", - "tokio-rustls 0.24.1", - "tungstenite", - "webpki-roots 0.23.1", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime 0.6.3", - "toml_edit 0.19.14", -] - -[[package]] -name = "toml_datetime" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" -dependencies = [ - "indexmap 1.9.2", - "nom8", - "toml_datetime 0.5.1", -] - -[[package]] -name = "toml_edit" -version = "0.19.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" -dependencies = [ - "indexmap 2.0.0", - "serde", - "serde_spanned", - "toml_datetime 0.6.3", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.13.1", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "prost-derive", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic-build" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" -dependencies = [ - "prettyplease 0.1.25", - "proc-macro2", - "prost-build", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.2", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "tracing-core" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", - "valuable", - "valuable-serde", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "nu-ansi-term", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", - "tracing-serde", - "valuable", - "valuable-serde", -] - -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "tungstenite" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "rustls 0.21.5", - "sha1", - "thiserror", - "url", - "utf-8", - "webpki 0.22.0", -] - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "ucd-trie" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" - -[[package]] -name = "unicode-ident" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom", - "serde", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -dependencies = [ - "valuable-derive", -] - -[[package]] -name = "valuable-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d44690c645190cfce32f91a1582281654b2338c6073fa250b0949fd25c55b32" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "valuable-serde" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5285cfff30cdabe26626736a54d989687dd9cab84f51f4048b61d6d0ae8b0907" -dependencies = [ - "serde", - "valuable", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "voting-verifier" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "router", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw0", - "cw2", - "either", - "schemars", - "serde", - "serde_json", - "service-registry", - "thiserror", -] - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.107", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" - -[[package]] -name = "web-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki 0.21.4", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki 0.22.0", -] - -[[package]] -name = "webpki-roots" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.1", -] - -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.1", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", -] - -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "winnow" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "ws_stream_wasm" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" -dependencies = [ - "async_io_stream", - "futures", - "js-sys", - "log", - "pharos", - "rustc_version", - "send_wrapper 0.6.0", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - -[[package]] -name = "zeroize" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "synstructure", -] - -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "aes", - "byteorder", - "bzip2", - "constant_time_eq", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "pbkdf2 0.11.0", - "sha1", - "time", - "zstd", -] - -[[package]] -name = "zstd" -version = "0.11.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" -dependencies = [ - "cc", - "libc", - "pkg-config", -] \ No newline at end of file diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index a2dce5e2f..f9b849790 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -20,7 +20,9 @@ dirs = "5.0.1" ecdsa = { version = "0.16.6" } enum-display-derive = "0.1.1" error-stack = { workspace = true } -ethers = { version = "2.0.8", features = ["rustls"] } +ethers-contract = { workspace = true } +ethers-core = { workspace = true } +ethers-providers = { version = "2.0.13", default-features = false, features = ["rustls"] } events = { workspace = true } events-derive = { workspace = true } evm-gateway = { workspace = true } @@ -75,7 +77,6 @@ rand = "0.8.5" random-string = "1.0.0" [build-dependencies] -ethers = "2.0.8" tonic-build = "0.8.3" [lints] diff --git a/ampd/src/evm/finalizer.rs b/ampd/src/evm/finalizer.rs index 9e0551a2f..b5dedda23 100644 --- a/ampd/src/evm/finalizer.rs +++ b/ampd/src/evm/finalizer.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; use error_stack::{self, Report, ResultExt}; -use ethers::types::U64; +use ethers_core::types::U64; use mockall::automock; use serde::{Deserialize, Serialize}; @@ -118,7 +118,7 @@ where mod tests { use crate::evm::finalizer::{pick, ConfirmationHeightFinalizer, Finalization, Finalizer}; use crate::evm::json_rpc::MockEthereumClient; - use ethers::{ + use ethers_core::{ abi::Hash, types::{Block, U64}, }; diff --git a/ampd/src/evm/json_rpc.rs b/ampd/src/evm/json_rpc.rs index 845c0c824..5e59600c6 100644 --- a/ampd/src/evm/json_rpc.rs +++ b/ampd/src/evm/json_rpc.rs @@ -1,7 +1,9 @@ use async_trait::async_trait; -use ethers::providers::{JsonRpcClient, ProviderError}; -use ethers::types::{Block, BlockNumber, TransactionReceipt, H256, U64}; -use ethers::utils::serialize; +use ethers_core::{ + types::{Block, BlockNumber, TransactionReceipt, H256, U64}, + utils::serialize, +}; +use ethers_providers::{JsonRpcClient, ProviderError}; use mockall::automock; use crate::json_rpc::Client; diff --git a/ampd/src/evm/verifier.rs b/ampd/src/evm/verifier.rs index ee79606d6..e14722b7e 100644 --- a/ampd/src/evm/verifier.rs +++ b/ampd/src/evm/verifier.rs @@ -1,5 +1,5 @@ -use ethers::contract::EthLogDecode; -use ethers::types::{Log, TransactionReceipt, H256}; +use ethers_contract::EthLogDecode; +use ethers_core::types::{Log, TransactionReceipt, H256}; use num_traits::cast; use axelar_wasm_std::voting::Vote; @@ -120,9 +120,9 @@ pub fn verify_verifier_set( mod tests { use axelar_wasm_std::voting::Vote; use cosmwasm_std::Uint128; - use ethers::{ + use ethers_contract::EthEvent; + use ethers_core::{ abi::{encode, Token}, - contract::EthEvent, types::{Log, TransactionReceipt, H256}, }; use evm_gateway::{ diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 6825ef71d..5a8fc859a 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -5,7 +5,7 @@ use async_trait::async_trait; use cosmrs::cosmwasm::MsgExecuteContract; use cosmrs::{tx::Msg, Any}; use error_stack::ResultExt; -use ethers::types::{TransactionReceipt, U64}; +use ethers_core::types::{TransactionReceipt, U64}; use futures::future::join_all; use serde::Deserialize; use tokio::sync::watch::Receiver; @@ -230,7 +230,7 @@ mod tests { use base64::Engine; use cosmwasm_std; use error_stack::{Report, Result}; - use ethers::providers::ProviderError; + use ethers_providers::ProviderError; use tendermint::abci; use tokio::sync::watch; use tokio::test as async_test; diff --git a/ampd/src/handlers/evm_verify_verifier_set.rs b/ampd/src/handlers/evm_verify_verifier_set.rs index 577a50bc5..72c2cd563 100644 --- a/ampd/src/handlers/evm_verify_verifier_set.rs +++ b/ampd/src/handlers/evm_verify_verifier_set.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use cosmrs::cosmwasm::MsgExecuteContract; use cosmrs::{tx::Msg, Any}; use error_stack::ResultExt; -use ethers::types::{TransactionReceipt, U64}; +use ethers_core::types::{TransactionReceipt, U64}; use multisig::verifier_set::VerifierSet; use serde::Deserialize; use tokio::sync::watch::Receiver; @@ -204,7 +204,7 @@ mod tests { use base64::engine::general_purpose::STANDARD; use base64::Engine; use error_stack::{Report, Result}; - use ethers::providers::ProviderError; + use ethers_providers::ProviderError; use tendermint::abci; use tokio::{sync::watch, test as async_test}; diff --git a/ampd/src/handlers/sui_verify_msg.rs b/ampd/src/handlers/sui_verify_msg.rs index 477514d09..86fd3838f 100644 --- a/ampd/src/handlers/sui_verify_msg.rs +++ b/ampd/src/handlers/sui_verify_msg.rs @@ -154,7 +154,7 @@ mod tests { use cosmrs::tx::Msg; use cosmwasm_std; use error_stack::{Report, Result}; - use ethers::providers::ProviderError; + use ethers_providers::ProviderError; use sui_types::base_types::{SuiAddress, TransactionDigest}; use tokio::sync::watch; use tokio::test as async_test; diff --git a/ampd/src/handlers/sui_verify_verifier_set.rs b/ampd/src/handlers/sui_verify_verifier_set.rs index c00c8ea25..b2645e5ca 100644 --- a/ampd/src/handlers/sui_verify_verifier_set.rs +++ b/ampd/src/handlers/sui_verify_verifier_set.rs @@ -163,7 +163,7 @@ mod tests { use std::convert::TryInto; use error_stack::{Report, Result}; - use ethers::providers::ProviderError; + use ethers_providers::ProviderError; use sui_types::base_types::{SuiAddress, TransactionDigest}; use tokio::sync::watch; use tokio::test as async_test; diff --git a/ampd/src/json_rpc.rs b/ampd/src/json_rpc.rs index 7665dd8d2..20a76f69e 100644 --- a/ampd/src/json_rpc.rs +++ b/ampd/src/json_rpc.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use error_stack::Report; -use ethers::providers::{Http, JsonRpcClient, ProviderError}; +use ethers_providers::{Http, JsonRpcClient, ProviderError}; use serde::{de::DeserializeOwned, Serialize}; use crate::url::Url; diff --git a/ampd/src/sui/json_rpc.rs b/ampd/src/sui/json_rpc.rs index fdae009c2..ca7897c91 100644 --- a/ampd/src/sui/json_rpc.rs +++ b/ampd/src/sui/json_rpc.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, HashSet}; use async_trait::async_trait; -use ethers::providers::{JsonRpcClient, ProviderError}; +use ethers_providers::{JsonRpcClient, ProviderError}; use mockall::automock; use sui_json_rpc_types::{SuiTransactionBlockResponse, SuiTransactionBlockResponseOptions}; use sui_types::digests::TransactionDigest; diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index 434ee7b5f..b31634685 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -124,7 +124,7 @@ mod tests { use std::collections::BTreeMap; use cosmwasm_std::Uint128; - use ethers::abi::AbiEncode; + use ethers_core::abi::AbiEncode; use move_core_types::language_storage::StructTag; use random_string::generate; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockEvents, SuiTransactionBlockResponse}; diff --git a/ampd/src/types.rs b/ampd/src/types.rs index cde390033..4801b30ba 100644 --- a/ampd/src/types.rs +++ b/ampd/src/types.rs @@ -3,7 +3,7 @@ use std::hash::{Hash as StdHash, Hasher}; use cosmrs::crypto; use cosmrs::AccountId; -use ethers::types::{Address, H256}; +use ethers_core::types::{Address, H256}; use serde::{Deserialize, Serialize}; pub type EVMAddress = Address; diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index e50323090..5e2ae13cc 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -33,8 +33,6 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -alloy-primitives = { version = "0.7.0", default-features = false } -alloy-sol-types = { version = "0.7.0", default-features = false, features = ["json"] } axelar-wasm-std = { workspace = true } axelar-wasm-std-derive = { workspace = true } bcs = "0.1.5" @@ -45,7 +43,9 @@ cw-storage-plus = { workspace = true } cw-utils = "1.0.1" cw2 = { workspace = true } error-stack = { workspace = true } -ethabi = { version = "18.0.0", default-features = false, features = [] } +ethers-contract = { workspace = true } +ethers-core = { workspace = true } +evm-gateway = { workspace = true } gateway = { workspace = true } gateway-api = { workspace = true } hex = { version = "0.4.3", default-features = false, features = [] } @@ -64,7 +64,6 @@ voting-verifier = { workspace = true, features = ["library"] } anyhow = "1.0" cw-multi-test = "0.15.1" elliptic-curve = "0.13.5" -ethers = "2.0.8" generic-array = "0.14.7" prost = "0.12.4" diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 2bfbd92a8..31f6ce2f0 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -80,16 +80,19 @@ pub fn execute( .or_else(|_| execute::require_governance(&deps, info))?; execute::update_verifier_set(deps, env) } - ExecuteMsg::ConfirmVerifierSet {} => execute::confirm_verifier_set(deps, info.sender), + ExecuteMsg::ConfirmVerifierSet {} => Ok(execute::confirm_verifier_set(deps, info.sender)?), ExecuteMsg::UpdateSigningThreshold { new_signing_threshold, } => { execute::require_governance(&deps, info)?; - execute::update_signing_threshold(deps, new_signing_threshold) + Ok(execute::update_signing_threshold( + deps, + new_signing_threshold, + )?) } ExecuteMsg::UpdateAdmin { new_admin_address } => { execute::require_governance(&deps, info)?; - execute::update_admin(deps, new_admin_address) + Ok(execute::update_admin(deps, new_admin_address)?) } } .map_err(axelar_wasm_std::ContractError::from) diff --git a/contracts/multisig-prover/src/encoding/abi/execute_data.rs b/contracts/multisig-prover/src/encoding/abi/execute_data.rs index 792589315..1f3ed470d 100644 --- a/contracts/multisig-prover/src/encoding/abi/execute_data.rs +++ b/contracts/multisig-prover/src/encoding/abi/execute_data.rs @@ -1,109 +1,53 @@ -use alloy_primitives::Bytes; -use alloy_sol_types::{sol, SolCall}; use cosmwasm_std::HexBinary; +use error_stack::ResultExt; +use ethers_contract::contract::EthCall; +use ethers_core::abi::{encode as abi_encode, Tokenize}; use axelar_wasm_std::hash::Hash; +use evm_gateway::{ApproveMessagesCall, Message, Proof, RotateSignersCall, WeightedSigners}; use multisig::{key::Signature, msg::SignerWithSig, verifier_set::VerifierSet}; -use crate::{ - encoding::abi::{evm_address, Message, Proof, WeightedSigners}, - error::ContractError, - payload::Payload, -}; - -sol!( - IAxelarAmplifierGateway, - "src/encoding/abi/solidity/IAxelarAmplifierGateway.json" -); - -impl From for IAxelarAmplifierGateway::WeightedSigners { - fn from(signers: WeightedSigners) -> Self { - IAxelarAmplifierGateway::WeightedSigners { - signers: signers - .signers - .iter() - .map(|signer| IAxelarAmplifierGateway::WeightedSigner { - signer: signer.signer, - weight: signer.weight, - }) - .collect(), - threshold: signers.threshold, - nonce: signers.nonce, - } - } -} - -impl From for IAxelarAmplifierGateway::Proof { - fn from(proof: Proof) -> Self { - IAxelarAmplifierGateway::Proof { - signers: proof.signers.into(), - signatures: proof.signatures, - } - } -} - -impl From for IAxelarAmplifierGateway::Message { - fn from(message: Message) -> Self { - IAxelarAmplifierGateway::Message { - messageId: message.messageId, - sourceChain: message.sourceChain, - sourceAddress: message.sourceAddress, - contractAddress: message.contractAddress, - payloadHash: message.payloadHash, - } - } -} - -impl Proof { - /// Proof contains the entire verifier set and optimized signatures. Signatures are sorted in ascending order based on the signer's address. - pub fn new(verifier_set: &VerifierSet, mut signers_with_sigs: Vec) -> Self { - signers_with_sigs.sort_by_key(|signer| { - evm_address(&signer.signer.pub_key).expect("failed to convert pub key to evm address") - }); - - let signatures = signers_with_sigs - .into_iter() - .map(|signer| Bytes::copy_from_slice(signer.signature.as_ref())) - .collect(); - - Proof { - signers: WeightedSigners::from(verifier_set), - signatures, - } - } -} +use crate::{error::ContractError, payload::Payload}; pub fn encode( verifier_set: &VerifierSet, signers: Vec, payload_digest: &Hash, payload: &Payload, -) -> Result { +) -> error_stack::Result { let signers = to_recoverable(payload_digest.as_slice(), signers); - let proof = Proof::new(verifier_set, signers); + let proof = Proof::new(verifier_set, signers).change_context(ContractError::Proof)?; - let data = match payload { + let (selector, encoded) = match payload { Payload::Messages(messages) => { let messages: Vec<_> = messages .iter() - .map(|msg| Message::try_from(msg).map(IAxelarAmplifierGateway::Message::from)) - .collect::, _>>()?; - - IAxelarAmplifierGateway::approveMessagesCall::new((messages, proof.into())) - .abi_encode() - .into() + .map(Message::try_from) + .collect::>() + .change_context(ContractError::InvalidMessage)?; + + ( + ApproveMessagesCall::selector(), + abi_encode(&ApproveMessagesCall { messages, proof }.into_tokens()), + ) } Payload::VerifierSet(new_verifier_set) => { - let new_verifier_set = WeightedSigners::from(new_verifier_set); + let new_signers = WeightedSigners::try_from(new_verifier_set) + .change_context(ContractError::InvalidVerifierSet)?; - IAxelarAmplifierGateway::rotateSignersCall::new((new_verifier_set.into(), proof.into())) - .abi_encode() - .into() + ( + RotateSignersCall::selector(), + abi_encode(&RotateSignersCall { new_signers, proof }.into_tokens()), + ) } }; - Ok(data) + Ok(selector + .into_iter() + .chain(encoded) + .collect::>() + .into()) } // Convert non-recoverable ECDSA signatures to recoverable ones. @@ -134,9 +78,9 @@ pub fn add27(recovery_byte: k256::ecdsa::RecoveryId) -> u8 { mod tests { use std::str::FromStr; - use alloy_primitives::Signature as EcdsaSignature; use cosmwasm_std::HexBinary; use elliptic_curve::consts::U32; + use ethers_core::types::Signature as EthersSignature; use generic_array::GenericArray; use hex::FromHex; use itertools::Itertools; @@ -144,12 +88,14 @@ mod tests { use sha3::{Digest, Keccak256}; use axelar_wasm_std::hash::Hash; - use multisig::key::{KeyType, KeyTyped, Signature}; - use multisig::msg::{Signer, SignerWithSig}; + use evm_gateway::evm_address; + use multisig::{ + key::{KeyType, KeyTyped, Signature}, + msg::{Signer, SignerWithSig}, + }; use crate::{ encoding::abi::{ - evm_address, execute_data::{add27, encode}, payload_hash_to_sign, }, @@ -204,7 +150,7 @@ mod tests { #[test] fn should_convert_signature_to_recoverable() { - let ecdsa_signature = EcdsaSignature::from_str("74ab5ec395cdafd861dec309c30f6cf8884fc9905eb861171e636d9797478adb60b2bfceb7db0a08769ed7a60006096d3e0f6d3783d125600ac6306180ecbc6f1b").unwrap(); + let ecdsa_signature = EthersSignature::from_str("74ab5ec395cdafd861dec309c30f6cf8884fc9905eb861171e636d9797478adb60b2bfceb7db0a08769ed7a60006096d3e0f6d3783d125600ac6306180ecbc6f1b").unwrap(); let pub_key = Vec::from_hex("03571a2dcec96eecc7950c9f36367fd459b8d334bac01ac153b7ed3dcf4025fc22") .unwrap(); @@ -212,8 +158,10 @@ mod tests { let digest = "6ac52b00f4256d98d53c256949288135c14242a39001d5fdfa564ea003ccaf92"; let signature = { - let r_bytes: [u8; 32] = ecdsa_signature.r().to_be_bytes(); - let s_bytes: [u8; 32] = ecdsa_signature.s().to_be_bytes(); + let mut r_bytes = [0u8; 32]; + let mut s_bytes = [0u8; 32]; + ecdsa_signature.r.to_big_endian(&mut r_bytes); + ecdsa_signature.s.to_big_endian(&mut s_bytes); let gar: &GenericArray = GenericArray::from_slice(&r_bytes); let gas: &GenericArray = GenericArray::from_slice(&s_bytes); @@ -233,7 +181,7 @@ mod tests { ) .unwrap(); - assert_eq!(recoverable.as_ref(), ecdsa_signature.as_bytes().as_slice()); + assert_eq!(recoverable.as_ref(), ecdsa_signature.to_vec().as_slice()); } else { panic!("Invalid signature type") } diff --git a/contracts/multisig-prover/src/encoding/abi/mod.rs b/contracts/multisig-prover/src/encoding/abi/mod.rs index c07eb223e..c2135a065 100644 --- a/contracts/multisig-prover/src/encoding/abi/mod.rs +++ b/contracts/multisig-prover/src/encoding/abi/mod.rs @@ -1,24 +1,16 @@ -// TODO: remove this, use evm-gateway package for solidity type conversion and encoding - pub mod execute_data; -use std::str::FromStr; - -use alloy_primitives::{Address, FixedBytes}; -use alloy_sol_types::{sol, SolValue}; -use cosmwasm_std::Uint256; -use k256::{elliptic_curve::sec1::ToEncodedPoint, PublicKey}; +use error_stack::{Result, ResultExt}; +use ethers_core::abi::{encode as abi_encode, Token, Tokenize}; +use itertools::Itertools; use sha3::{Digest, Keccak256}; use axelar_wasm_std::hash::Hash; -use multisig::{key::PublicKey as MultisigPublicKey, msg::Signer, verifier_set::VerifierSet}; -use router_api::Message as RouterMessage; +use evm_gateway::{CommandType, Message, WeightedSigners}; +use multisig::verifier_set::VerifierSet; use crate::{error::ContractError, payload::Payload}; -sol!("src/encoding/abi/solidity/AmplifierGatewayTypes.sol"); -sol!("src/encoding/abi/solidity/WeightedMultisigTypes.sol"); - impl From<&Payload> for CommandType { fn from(payload: &Payload) -> Self { match payload { @@ -28,68 +20,15 @@ impl From<&Payload> for CommandType { } } -impl WeightedSigners { - pub fn hash(&self) -> Hash { - Keccak256::digest(self.abi_encode()).into() - } -} - -impl From<&Signer> for WeightedSigner { - fn from(signer: &Signer) -> Self { - WeightedSigner { - signer: evm_address(&signer.pub_key).expect("failed to convert pub key to evm address"), - weight: signer.weight.u128(), - } - } -} - -impl From<&VerifierSet> for WeightedSigners { - fn from(verifier_set: &VerifierSet) -> Self { - let mut signers = verifier_set - .signers - .values() - .map(WeightedSigner::from) - .collect::>(); - - signers.sort_by_key(|weighted_signer| weighted_signer.signer); - - WeightedSigners { - signers, - threshold: verifier_set.threshold.u128(), - nonce: Uint256::from(verifier_set.created_at).to_be_bytes().into(), - } - } -} - -impl TryFrom<&RouterMessage> for Message { - type Error = ContractError; - - fn try_from(msg: &RouterMessage) -> Result { - let contract_address = - Address::from_str(msg.destination_address.as_str()).map_err(|err| { - ContractError::InvalidMessage { - reason: format!("destination_address is not a valid EVM address: {}", err), - } - })?; - - let payload_hash = FixedBytes::<32>::from_slice(msg.payload_hash.as_slice()); - - Ok(Message { - sourceChain: msg.cc_id.chain.to_string(), - messageId: msg.cc_id.id.to_string(), - sourceAddress: msg.source_address.to_string(), - contractAddress: contract_address, - payloadHash: payload_hash, - }) - } -} - pub fn payload_hash_to_sign( domain_separator: &Hash, signer: &VerifierSet, payload: &Payload, ) -> Result { - let signer_hash = WeightedSigners::from(signer).hash(); + let signer_hash = WeightedSigners::try_from(signer) + .map(|signers| signers.hash()) + .change_context(ContractError::InvalidVerifierSet)?; + let data_hash = Keccak256::digest(encode(payload)?); // Prefix for standard EVM signed data https://eips.ethereum.org/EIPS/eip-191 @@ -105,34 +44,27 @@ pub fn payload_hash_to_sign( } pub fn encode(payload: &Payload) -> Result, ContractError> { - let command_type = CommandType::from(payload); + let command_type = CommandType::from(payload).into(); match payload { Payload::Messages(messages) => { - let messages: Vec<_> = messages + let messages = messages .iter() .map(Message::try_from) - .collect::>()?; + .map_ok(|m| Token::Tuple(m.into_tokens())) + .collect::, _>>() + .change_context(ContractError::InvalidMessage)?; - Ok((command_type, messages).abi_encode_sequence()) + Ok(abi_encode(&[command_type, Token::Array(messages)])) } - Payload::VerifierSet(verifier_set) => { - Ok((command_type, WeightedSigners::from(verifier_set)).abi_encode_sequence()) - } - } -} - -fn evm_address(pub_key: &MultisigPublicKey) -> Result { - match pub_key { - MultisigPublicKey::Ecdsa(pub_key) => PublicKey::from_sec1_bytes(pub_key) - .map(|pub_key| pub_key.to_encoded_point(false)) - .map(|pub_key| Address::from_raw_public_key(&pub_key.as_bytes()[1..])) - .map_err(|err| ContractError::InvalidPublicKey { - reason: err.to_string(), - }), - _ => Err(ContractError::InvalidPublicKey { - reason: "expect ECDSA public key".to_string(), - }), + Payload::VerifierSet(verifier_set) => Ok(abi_encode(&[ + command_type, + Token::Tuple( + WeightedSigners::try_from(verifier_set) + .change_context(ContractError::InvalidVerifierSet)? + .into_tokens(), + ), + ])), } } @@ -140,10 +72,8 @@ fn evm_address(pub_key: &MultisigPublicKey) -> Result { mod tests { use cosmwasm_std::HexBinary; - use router_api::{CrossChainId, Message as RouterMessage}; - use crate::{ - encoding::abi::{payload_hash_to_sign, CommandType, Message, WeightedSigners}, + encoding::abi::{payload_hash_to_sign, CommandType}, payload::Payload, test::test_data::{ curr_verifier_set, domain_separator, messages, new_verifier_set, @@ -154,26 +84,10 @@ mod tests { #[test] fn command_type_from_payload() { let payload = Payload::Messages(vec![]); - assert_eq!( - CommandType::from(&payload).as_u8(), - CommandType::ApproveMessages.as_u8() - ); + assert_eq!(CommandType::from(&payload), CommandType::ApproveMessages); let payload = Payload::VerifierSet(new_verifier_set()); - assert_eq!( - CommandType::from(&payload).as_u8(), - CommandType::RotateSigners.as_u8() - ); - } - - #[test] - fn weight_signers_hash() { - let expected_hash = - HexBinary::from_hex("e490c7e55a46b0e1e39a3034973b676eed044fed387f80f4e6377305313f8762") - .unwrap(); - let verifier_set = curr_verifier_set(); - - assert_eq!(WeightedSigners::from(&verifier_set).hash(), expected_hash); + assert_eq!(CommandType::from(&payload), CommandType::RotateSigners); } #[test] @@ -202,43 +116,6 @@ mod tests { assert_eq!(msg_to_sign, expected_hash); } - #[test] - fn router_message_to_gateway_message() { - let source_chain = "chain0"; - let message_id = "0xff822c88807859ff226b58e24f24974a70f04b9442501ae38fd665b3c68f3834-0"; - let source_address = "0x52444f1835Adc02086c37Cb226561605e2E1699b"; - let destination_chain = "chain1"; - let destination_address = "0xA4f10f76B86E01B98daF66A3d02a65e14adb0767"; - let payload_hash = "8c3685dc41c2eca11426f8035742fb97ea9f14931152670a5703f18fe8b392f0"; - - let router_messages = RouterMessage { - cc_id: CrossChainId { - chain: source_chain.parse().unwrap(), - id: message_id.parse().unwrap(), - }, - source_address: source_address.parse().unwrap(), - destination_address: destination_address.parse().unwrap(), - destination_chain: destination_chain.parse().unwrap(), - payload_hash: HexBinary::from_hex(payload_hash) - .unwrap() - .to_array::<32>() - .unwrap(), - }; - - let gateway_message = Message::try_from(&router_messages).unwrap(); - assert_eq!(gateway_message.sourceChain, source_chain); - assert_eq!(gateway_message.messageId, message_id); - assert_eq!(gateway_message.sourceAddress, source_address); - assert_eq!( - gateway_message.contractAddress.to_string(), - destination_address - ); - assert_eq!( - gateway_message.payloadHash.to_string()[2..], - payload_hash.to_string() - ); - } - #[test] fn approve_messages_hash() { // generated by axelar-gmp-sdk-solidity unit tests diff --git a/contracts/multisig-prover/src/encoding/abi/solidity/AmplifierGatewayTypes.sol b/contracts/multisig-prover/src/encoding/abi/solidity/AmplifierGatewayTypes.sol deleted file mode 100644 index 6fd019e09..000000000 --- a/contracts/multisig-prover/src/encoding/abi/solidity/AmplifierGatewayTypes.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @notice This enum represents the different types of commands that can be processed by the Axelar Amplifier Gateway - */ -enum CommandType { - ApproveMessages, - RotateSigners -} - -/** - * @notice This struct represents a message that is to be processed by the Amplifier Gateway - * @param sourceChain The chain from which the message originated - * @param messageId The unique identifier for the message - * @param sourceAddress The address from which the message originated - * @param contractAddress The address of the contract that the message is intended for - * @param payloadHash The hash of the payload that is to be processed - */ -struct Message { - string sourceChain; - string messageId; - string sourceAddress; - address contractAddress; - bytes32 payloadHash; -} diff --git a/contracts/multisig-prover/src/encoding/abi/solidity/WeightedMultisigTypes.sol b/contracts/multisig-prover/src/encoding/abi/solidity/WeightedMultisigTypes.sol deleted file mode 100644 index 63578e177..000000000 --- a/contracts/multisig-prover/src/encoding/abi/solidity/WeightedMultisigTypes.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -/** - * @notice This struct represents the weighted signers payload - * @param signers The list of signers - * @param weights The list of weights - * @param threshold The threshold for the signers - */ -struct WeightedSigner { - address signer; - uint128 weight; -} - -/** - * @notice This struct represents the weighted signers payload - * @param signers The list of weighted signers - * @param threshold The threshold for the weighted signers - * @param nonce The nonce to distinguish different weighted signer sets - */ -struct WeightedSigners { - WeightedSigner[] signers; - uint128 threshold; - bytes32 nonce; -} - -/** - * @notice This struct represents a proof for a message from the weighted signers - * @param signers The weighted signers - * @param signatures The list of signatures - */ -struct Proof { - WeightedSigners signers; - bytes[] signatures; -} diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index d95d0e1fd..142ecb03f 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -1,8 +1,9 @@ -use axelar_wasm_std::nonempty; -use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::StdError; use thiserror::Error; +use axelar_wasm_std::nonempty; +use axelar_wasm_std_derive::IntoContractError; + #[derive(Error, Debug, PartialEq, IntoContractError)] pub enum ContractError { #[error(transparent)] @@ -11,8 +12,8 @@ pub enum ContractError { #[error("caller is not authorized")] Unauthorized, - #[error("message is invalid: {reason}")] - InvalidMessage { reason: String }, + #[error("message is invalid")] + InvalidMessage, #[error("public key is invalid: {reason}")] InvalidPublicKey { reason: String }, @@ -55,4 +56,10 @@ pub enum ContractError { #[error("failed to serialize the response")] SerializeResponse, + + #[error("failed to create proof")] + Proof, + + #[error("invalid verifier set")] + InvalidVerifierSet, } diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index 3f8348c7f..853c157a3 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -4,11 +4,10 @@ use cosmwasm_std::{ to_json_binary, wasm_execute, Addr, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, WasmQuery, }; - use itertools::Itertools; -use multisig::{key::PublicKey, msg::Signer, verifier_set::VerifierSet}; use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; +use multisig::{key::PublicKey, msg::Signer, verifier_set::VerifierSet}; use router_api::{ChainName, CrossChainId, Message}; use service_registry::state::WeightedVerifier; @@ -37,8 +36,8 @@ pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), Contr pub fn construct_proof( deps: DepsMut, message_ids: Vec, -) -> Result { - let config = CONFIG.load(deps.storage)?; +) -> error_stack::Result { + let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; let payload_id = (&message_ids).into(); let messages = get_messages( @@ -48,21 +47,29 @@ pub fn construct_proof( config.chain_name.clone(), )?; - let payload = match PAYLOAD.may_load(deps.storage, &payload_id)? { + let payload = match PAYLOAD + .may_load(deps.storage, &payload_id) + .map_err(ContractError::from)? + { Some(payload) => payload, None => { let payload = Payload::Messages(messages); - PAYLOAD.save(deps.storage, &payload_id, &payload)?; + PAYLOAD + .save(deps.storage, &payload_id, &payload) + .map_err(ContractError::from)?; payload } }; // keep track of the payload id to use during submessage reply - REPLY_TRACKER.save(deps.storage, &payload_id)?; + REPLY_TRACKER + .save(deps.storage, &payload_id) + .map_err(ContractError::from)?; let verifier_set = CURRENT_VERIFIER_SET - .may_load(deps.storage)? + .may_load(deps.storage) + .map_err(ContractError::from)? .ok_or(ContractError::NoVerifierSet)?; let digest = payload.digest(config.encoder, &config.domain_separator, &verifier_set)?; @@ -74,7 +81,8 @@ pub fn construct_proof( sig_verifier: None, }; - let wasm_msg = wasm_execute(config.multisig, &start_sig_msg, vec![])?; + let wasm_msg = + wasm_execute(config.multisig, &start_sig_msg, vec![]).map_err(ContractError::from)?; Ok(Response::new().add_submessage(SubMsg::reply_on_success(wasm_msg, START_MULTISIG_REPLY_ID))) } @@ -202,23 +210,33 @@ fn save_next_verifier_set( Ok(()) } -pub fn update_verifier_set(deps: DepsMut, env: Env) -> Result { - let config = CONFIG.load(deps.storage)?; - let cur_verifier_set = CURRENT_VERIFIER_SET.may_load(deps.storage)?; +pub fn update_verifier_set( + deps: DepsMut, + env: Env, +) -> error_stack::Result { + let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; + let cur_verifier_set = CURRENT_VERIFIER_SET + .may_load(deps.storage) + .map_err(ContractError::from)?; match cur_verifier_set { None => { // if no verifier set, just store it and return let new_verifier_set = make_verifier_set(&deps, &env, &config)?; - CURRENT_VERIFIER_SET.save(deps.storage, &new_verifier_set)?; - - Ok(Response::new().add_message(wasm_execute( - config.multisig, - &multisig::msg::ExecuteMsg::RegisterVerifierSet { - verifier_set: new_verifier_set, - }, - vec![], - )?)) + CURRENT_VERIFIER_SET + .save(deps.storage, &new_verifier_set) + .map_err(ContractError::from)?; + + Ok(Response::new().add_message( + wasm_execute( + config.multisig, + &multisig::msg::ExecuteMsg::RegisterVerifierSet { + verifier_set: new_verifier_set, + }, + vec![], + ) + .map_err(ContractError::from)?, + )) } Some(cur_verifier_set) => { let new_verifier_set = get_next_verifier_set(&deps, &env, &config)? @@ -228,8 +246,12 @@ pub fn update_verifier_set(deps: DepsMut, env: Env) -> Result Result None, } } + pub fn execute_data( &self, encoder: Encoder, diff --git a/contracts/multisig-prover/src/query.rs b/contracts/multisig-prover/src/query.rs index dc4a4e218..c997aa5d0 100644 --- a/contracts/multisig-prover/src/query.rs +++ b/contracts/multisig-prover/src/query.rs @@ -1,4 +1,5 @@ use cosmwasm_std::{to_json_binary, Deps, QueryRequest, StdResult, Uint64, WasmQuery}; +use error_stack::Result; use multisig::{multisig::Multisig, types::MultisigState, verifier_set::VerifierSet}; @@ -12,20 +13,27 @@ pub fn get_proof( deps: Deps, multisig_session_id: Uint64, ) -> Result { - let config = CONFIG.load(deps.storage)?; + let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; - let payload_id = MULTISIG_SESSION_PAYLOAD.load(deps.storage, multisig_session_id.u64())?; + let payload_id = MULTISIG_SESSION_PAYLOAD + .load(deps.storage, multisig_session_id.u64()) + .map_err(ContractError::from)?; let query_msg = multisig::msg::QueryMsg::GetMultisig { session_id: multisig_session_id, }; - let multisig: Multisig = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: config.multisig.to_string(), - msg: to_json_binary(&query_msg)?, - }))?; - - let payload = PAYLOAD.load(deps.storage, &payload_id)?; + let multisig: Multisig = deps + .querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: config.multisig.to_string(), + msg: to_json_binary(&query_msg).map_err(ContractError::from)?, + })) + .map_err(ContractError::from)?; + + let payload = PAYLOAD + .load(deps.storage, &payload_id) + .map_err(ContractError::from)?; let status = match multisig.state { MultisigState::Pending => ProofStatus::Pending, diff --git a/packages/evm-gateway/.gitignore b/packages/evm-gateway/.gitignore deleted file mode 100644 index 8b806e780..000000000 --- a/packages/evm-gateway/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# EVM gateway artifacts -src/abi/ diff --git a/packages/evm-gateway/Cargo.toml b/packages/evm-gateway/Cargo.toml index c2fb32ee1..6d3916050 100644 --- a/packages/evm-gateway/Cargo.toml +++ b/packages/evm-gateway/Cargo.toml @@ -9,17 +9,13 @@ edition = "2021" axelar-wasm-std = { workspace = true } cosmwasm-std = { workspace = true } error-stack = { workspace = true } -ethers = { version = "2.0.14", features = ["abigen"] } +ethers-contract = { workspace = true } +ethers-core = { workspace = true } k256 = { version = "0.13.1", features = ["ecdsa"] } multisig = { workspace = true } -sha3 ={ workspace = true } +router-api = { workspace = true } +sha3 = { workspace = true } thiserror = { workspace = true } -[build-dependencies] -reqwest = { version = "0.12.4", features = ["blocking", "json"] } -serde = { workspace = true } -serde_json = { workspace = true } -zip = "2.0.0" - [lints] workspace = true diff --git a/packages/evm-gateway/build.rs b/packages/evm-gateway/build.rs deleted file mode 100644 index 080dc4b79..000000000 --- a/packages/evm-gateway/build.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::env; -use std::fs::{self, File}; -use std::io; -use std::path::{Path, PathBuf}; - -use reqwest::blocking::Client; -use zip::ZipArchive; - -const ABI_FILES: [&str; 1] = ["IAxelarAmplifierGateway.json"]; -const OUTPUT_DIR_BASE: &str = "src/abi"; // Base output directory - -const VERSION: &str = env!( - "SOLIDITY_GATEWAY_VERSION", - "environment variable SOLIDITY_GATEWAY_VERSION is not set" -); -const URL: &str = env!( - "SOLIDITY_RELEASES_URL", - "environment variable SOLIDITY_RELEASES_URL is not set" -); - -fn main() -> Result<(), Box> { - // Append version to output directory - let output_dir = format!("{}/{}/", OUTPUT_DIR_BASE, VERSION); - - // Skip if files already exist - if files_exist(&output_dir, &ABI_FILES) { - return Ok(()); - } - - let zipfile_name = format!("Bytecode-{}.zip", VERSION); - let url = format!("{}/{}/{}", URL, VERSION, &zipfile_name); - let zipfile_path = PathBuf::from(&zipfile_name); - - let mut zip_archive = download(&url, &zipfile_path)?; - - extract(&mut zip_archive, &output_dir)?; - - fs::remove_file(zipfile_path)?; - - Ok(()) -} - -fn files_exist(output_dir: &str, files: &[&str]) -> bool { - let output_path = Path::new(output_dir); - files.iter().all(|file| output_path.join(file).exists()) -} - -fn download(url: &str, zip_path: &Path) -> Result, Box> { - let client = Client::new(); - let mut response = client.get(url).send()?; - if !response.status().is_success() { - return Err(Box::new(io::Error::new( - io::ErrorKind::Other, - format!("failed to download {}", url), - ))); - } - - let mut zipfile = File::create(zip_path)?; - io::copy(&mut response, &mut zipfile)?; - - let zipfile = File::open(zip_path)?; - Ok(ZipArchive::new(zipfile)?) -} - -fn extract(archive: &mut ZipArchive, output_dir: &str) -> io::Result<()> { - let abi_output = Path::new(output_dir); - - fs::create_dir_all(abi_output)?; - - for abi in ABI_FILES.iter() { - let file_path = format!( - "contracts/interfaces/{}.sol/{}", - abi.trim_end_matches(".json"), - abi - ); - let output_path = abi_output.join(abi); - - let mut file = archive.by_name(&file_path).map_err(|_| { - io::Error::new( - io::ErrorKind::NotFound, - format!("file not found in archive: {}", file_path), - ) - })?; - - let mut output_file = File::create(output_path)?; - io::copy(&mut file, &mut output_file)?; - } - - Ok(()) -} diff --git a/contracts/multisig-prover/src/encoding/abi/solidity/IAxelarAmplifierGateway.json b/packages/evm-gateway/src/abi/IAxelarAmplifierGateway.json similarity index 100% rename from contracts/multisig-prover/src/encoding/abi/solidity/IAxelarAmplifierGateway.json rename to packages/evm-gateway/src/abi/IAxelarAmplifierGateway.json diff --git a/packages/evm-gateway/src/error.rs b/packages/evm-gateway/src/error.rs new file mode 100644 index 000000000..261f7c6db --- /dev/null +++ b/packages/evm-gateway/src/error.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("invalid public key")] + InvalidPublicKey, + + #[error("invalid address")] + InvalidAddress, + + #[error("invalid signature")] + InvalidSignature, +} diff --git a/packages/evm-gateway/src/lib.rs b/packages/evm-gateway/src/lib.rs index 777337ba3..177d50eb9 100644 --- a/packages/evm-gateway/src/lib.rs +++ b/packages/evm-gateway/src/lib.rs @@ -1,31 +1,37 @@ +pub mod error; + use cosmwasm_std::Uint256; use error_stack::{Report, ResultExt}; -use ethers::{ - abi::{encode, Token::Tuple, Tokenize}, - prelude::abigen, - types::Address, - utils::public_key_to_address, +use ethers_contract::abigen; +use ethers_core::{ + abi::{ + encode, + Token::{self, Tuple, Uint}, + Tokenize, + }, + types::{Address, Bytes, U256}, + utils::{parse_checksummed, public_key_to_address}, }; use k256::ecdsa::VerifyingKey; use sha3::{Digest, Keccak256}; -use thiserror::Error; use axelar_wasm_std::hash::Hash; -use multisig::{key::PublicKey, msg::Signer, verifier_set::VerifierSet}; +use multisig::{ + key::PublicKey, + msg::{Signer, SignerWithSig}, + verifier_set::VerifierSet, +}; +use router_api::Message as RouterMessage; + +use crate::error::Error; // Generates the bindings for the Axelar Amplifier Gateway contract. // This includes the defined structs: Messages, WeightedSigners, WeightedSigner, and Proofs. abigen!( IAxelarAmplifierGateway, - "src/abi/$SOLIDITY_GATEWAY_VERSION/IAxelarAmplifierGateway.json" + "src/abi/IAxelarAmplifierGateway.json" ); -#[derive(Error, Debug)] -pub enum Error { - #[error("invalid public key")] - InvalidPublicKey, -} - impl TryFrom<&VerifierSet> for WeightedSigners { type Error = Report; @@ -69,23 +75,83 @@ impl WeightedSigners { } } -fn evm_address(pub_key: &PublicKey) -> Result> { +impl TryFrom<&RouterMessage> for Message { + type Error = Report; + + fn try_from(msg: &RouterMessage) -> Result { + let contract_address = parse_checksummed(msg.destination_address.as_str(), None) + .change_context(Error::InvalidAddress)?; + + Ok(Message { + source_chain: msg.cc_id.chain.to_string(), + message_id: msg.cc_id.id.to_string(), + source_address: msg.source_address.to_string(), + contract_address, + payload_hash: msg.payload_hash, + }) + } +} + +impl Proof { + /// Proof contains the entire verifier set and optimized signatures. Signatures are sorted in ascending order based on the signer's address. + pub fn new( + verifier_set: &VerifierSet, + mut signers_with_sigs: Vec, + ) -> Result> { + let signers = WeightedSigners::try_from(verifier_set)?; + + // The conversion from the public key to the EVM address must be successful, + // otherwise WeightedSigners::try_from would have returned an error. + signers_with_sigs.sort_by_key(|signer| { + evm_address(&signer.signer.pub_key).expect("failed to convert pub key to evm address") + }); + + let signatures = signers_with_sigs + .into_iter() + .map(|signer| Bytes::from(signer.signature.as_ref().to_vec())) + .collect::>(); + + Ok(Proof { + signers, + signatures, + }) + } +} + +#[derive(PartialEq, Debug)] +pub enum CommandType { + ApproveMessages, + RotateSigners, +} + +impl From for Token { + fn from(command_type: CommandType) -> Self { + match command_type { + CommandType::ApproveMessages => Uint(U256::zero()), + CommandType::RotateSigners => Uint(U256::one()), + } + } +} + +pub fn evm_address(pub_key: &PublicKey) -> Result> { match pub_key { PublicKey::Ecdsa(pub_key) => VerifyingKey::from_sec1_bytes(pub_key) .map(|v| public_key_to_address(&v)) .change_context(Error::InvalidPublicKey), - _ => Err(Report::new(Error::InvalidPublicKey).attach_printable("expect ECDSA public key")), + _ => Err(Error::InvalidPublicKey).attach_printable("expect ECDSA public key"), } } #[cfg(test)] mod test { use cosmwasm_std::{Addr, HexBinary, Uint128}; + use ethers_core::utils::to_checksum; use axelar_wasm_std::{nonempty, snapshot::Participant}; use multisig::{key::PublicKey, verifier_set::VerifierSet}; + use router_api::{CrossChainId, Message as RouterMessage}; - use crate::WeightedSigners; + use crate::{Message, WeightedSigners}; #[test] fn weight_signers_hash() { @@ -100,6 +166,40 @@ mod test { ); } + #[test] + fn router_message_to_gateway_message() { + let source_chain = "chain0"; + let message_id = "0xff822c88807859ff226b58e24f24974a70f04b9442501ae38fd665b3c68f3834-0"; + let source_address = "0x52444f1835Adc02086c37Cb226561605e2E1699b"; + let destination_chain = "chain1"; + let destination_address = "0xA4f10f76B86E01B98daF66A3d02a65e14adb0767"; + let payload_hash = "8c3685dc41c2eca11426f8035742fb97ea9f14931152670a5703f18fe8b392f0"; + + let router_messages = RouterMessage { + cc_id: CrossChainId { + chain: source_chain.parse().unwrap(), + id: message_id.parse().unwrap(), + }, + source_address: source_address.parse().unwrap(), + destination_address: destination_address.parse().unwrap(), + destination_chain: destination_chain.parse().unwrap(), + payload_hash: HexBinary::from_hex(payload_hash) + .unwrap() + .to_array::<32>() + .unwrap(), + }; + + let gateway_message = Message::try_from(&router_messages).unwrap(); + assert_eq!(gateway_message.source_chain, source_chain); + assert_eq!(gateway_message.message_id, message_id); + assert_eq!(gateway_message.source_address, source_address); + assert_eq!( + to_checksum(&gateway_message.contract_address, None), + destination_address + ); + assert_eq!(gateway_message.payload_hash, router_messages.payload_hash); + } + // Generate a worker set matches axelar-gmp-sdk-solidity repo test data pub fn curr_verifier_set() -> VerifierSet { let pub_keys = vec![ From b44318141daf70df89df83f20bd1a1e979ef8286 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Mon, 10 Jun 2024 14:23:40 -0400 Subject: [PATCH 011/168] refactor(minor-coordinator)!: single map for active and next verifier sets (#448) * feat: add coordinator IndexedMap, execute message, and call from prover * feat: add first union set update to integration tests, use IndexedMap for ReadyToUnbond * refactor: remove active and next verifier maps from coordinator alongside their messages * refactor: address comments on SetVerifiers message, use of index for readyToUnbond check, and error handling * refactor: map_err for VERIFIER_PROVER_INDEXED_MAP removal, reduce check_ready_to_unbond checks to one, improve all_active_verifiers calculation * refactor: address PR comments * fix: bring back error mapping to update_verifier_set in prover * refactor: improve all_active_verifiers in prover --- contracts/coordinator/src/contract.rs | 129 +------------------ contracts/coordinator/src/execute.rs | 19 +-- contracts/coordinator/src/msg.rs | 10 +- contracts/coordinator/src/query.rs | 62 ++------- contracts/coordinator/src/state.rs | 85 ++++++++++-- contracts/multisig-prover/src/execute.rs | 35 ++++- integration-tests/tests/test_utils/mod.rs | 22 +--- integration-tests/tests/update_worker_set.rs | 7 - 8 files changed, 130 insertions(+), 239 deletions(-) diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 2025cfaac..6da163524 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -57,11 +57,8 @@ pub fn execute( execute::check_governance(&deps, info)?; execute::register_prover(deps, chain_name, new_prover_addr) } - ExecuteMsg::SetActiveVerifiers { next_verifier_set } => { - execute::set_active_verifier_set(deps, info, next_verifier_set) - } - ExecuteMsg::SetNextVerifiers { next_verifier_set } => { - execute::set_next_verifier_set(deps, info, next_verifier_set) + ExecuteMsg::SetActiveVerifiers { verifiers } => { + execute::set_active_verifier_set(deps, info, verifiers) } } .map_err(axelar_wasm_std::ContractError::from) @@ -71,9 +68,6 @@ pub fn execute( #[allow(dead_code)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::GetActiveVerifiers { chain_name } => { - to_json_binary(&query::active_verifier_set(deps, chain_name)?).map_err(|err| err.into()) - } QueryMsg::ReadyToUnbond { worker_address } => to_json_binary( &query::check_verifier_ready_to_unbond(deps, worker_address)?, ) @@ -85,15 +79,11 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result, - pub key_pair: KeyPair, - } - - fn create_verifier( - keypair_seed: u32, - verifier_address: Addr, - supported_chains: Vec, - ) -> Verifier { - let seed_bytes = keypair_seed.to_be_bytes(); - let mut result = [0; 64]; - result[0..seed_bytes.len()].copy_from_slice(seed_bytes.as_slice()); - let secret_recovery_key = result.as_slice().try_into().unwrap(); - - Verifier { - addr: verifier_address, - supported_chains, - key_pair: tofn::ecdsa::keygen(&secret_recovery_key, b"tofn nonce").unwrap(), - } - } - - fn create_verifier_set_from_verifiers( - verifiers: &Vec, - block_height: u64, - ) -> VerifierSet { - let mut pub_keys = vec![]; - for verifier in verifiers { - let encoded_verifying_key = - HexBinary::from(verifier.key_pair.encoded_verifying_key().to_vec()); - let pub_key = PublicKey::try_from((KeyType::Ecdsa, encoded_verifying_key)).unwrap(); - pub_keys.push(pub_key); - } - - let participants: Vec = verifiers - .iter() - .map(|verifier| Participant { - address: verifier.addr.clone(), - weight: Uint128::one().try_into().unwrap(), - }) - .collect(); - - VerifierSet::new( - participants.clone().into_iter().zip(pub_keys).collect(), - Uint128::from(participants.len() as u128).mul_ceil((2u64, 3u64)), - block_height, - ) - } - #[test] #[allow(clippy::arithmetic_side_effects)] fn test_instantiation() { @@ -238,67 +178,4 @@ mod tests { axelar_wasm_std::ContractError::from(ContractError::Unauthorized).to_string() ); } - - #[test] - fn set_and_get_populated_active_verifier_set_success() { - let governance = "governance_for_coordinator"; - let mut test_setup = setup(governance); - - let new_verifier = create_verifier( - 1, - Addr::unchecked("verifier1"), - vec![test_setup.chain_name.clone()], - ); - let new_verifier_set = - create_verifier_set_from_verifiers(&vec![new_verifier], test_setup.env.block.height); - - let res = execute( - test_setup.deps.as_mut(), - test_setup.env.clone(), - mock_info(governance, &[]), - ExecuteMsg::RegisterProverContract { - chain_name: test_setup.chain_name.clone(), - new_prover_addr: test_setup.prover.clone(), - }, - ); - assert!(res.is_ok()); - - let res = execute( - test_setup.deps.as_mut(), - test_setup.env.clone(), - mock_info(test_setup.prover.as_ref(), &[]), - ExecuteMsg::SetActiveVerifiers { - next_verifier_set: new_verifier_set.clone(), - }, - ); - assert!(res.is_ok()); - - let eth_active_verifier_set = - query::active_verifier_set(test_setup.deps.as_ref(), test_setup.chain_name.clone()) - .unwrap(); - - assert_eq!(eth_active_verifier_set, Some(new_verifier_set)); - } - - #[test] - fn set_and_get_empty_active_verifier_set_success() { - let governance = "governance_for_coordinator"; - let mut test_setup = setup(governance); - - let _response = execute( - test_setup.deps.as_mut(), - test_setup.env, - mock_info(governance, &[]), - ExecuteMsg::RegisterProverContract { - chain_name: test_setup.chain_name.clone(), - new_prover_addr: test_setup.prover.clone(), - }, - ); - - let query_result = - query::active_verifier_set(test_setup.deps.as_ref(), test_setup.chain_name.clone()) - .unwrap(); - - assert_eq!(query_result, None); - } } diff --git a/contracts/coordinator/src/execute.rs b/contracts/coordinator/src/execute.rs index 14bf95b00..d96277058 100644 --- a/contracts/coordinator/src/execute.rs +++ b/contracts/coordinator/src/execute.rs @@ -1,12 +1,10 @@ use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response}; +use std::collections::HashSet; -use multisig::verifier_set::VerifierSet; use router_api::ChainName; use crate::error::ContractError; -use crate::state::{ - ACTIVE_VERIFIER_SET_FOR_PROVER, CONFIG, NEXT_VERIFIER_SET_FOR_PROVER, PROVER_PER_CHAIN, -}; +use crate::state::{update_verifier_set_for_prover, CONFIG, PROVER_PER_CHAIN}; pub fn check_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { let config = CONFIG.load(deps.storage)?; @@ -28,17 +26,8 @@ pub fn register_prover( pub fn set_active_verifier_set( deps: DepsMut, info: MessageInfo, - next_verifier_set: VerifierSet, + verifiers: HashSet, ) -> Result { - ACTIVE_VERIFIER_SET_FOR_PROVER.save(deps.storage, info.sender, &(next_verifier_set))?; - Ok(Response::new()) -} - -pub fn set_next_verifier_set( - deps: DepsMut, - info: MessageInfo, - next_verifier_set: VerifierSet, -) -> Result { - NEXT_VERIFIER_SET_FOR_PROVER.save(deps.storage, info.sender, &(next_verifier_set))?; + update_verifier_set_for_prover(deps.storage, info.sender, verifiers)?; Ok(Response::new()) } diff --git a/contracts/coordinator/src/msg.rs b/contracts/coordinator/src/msg.rs index b64e70a35..af75e4d0e 100644 --- a/contracts/coordinator/src/msg.rs +++ b/contracts/coordinator/src/msg.rs @@ -1,7 +1,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Addr; -use multisig::verifier_set::VerifierSet; use router_api::ChainName; +use std::collections::HashSet; #[cw_serde] pub struct InstantiateMsg { @@ -16,19 +16,13 @@ pub enum ExecuteMsg { new_prover_addr: Addr, }, SetActiveVerifiers { - next_verifier_set: VerifierSet, - }, - SetNextVerifiers { - next_verifier_set: VerifierSet, + verifiers: HashSet, }, } #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(VerifierSet)] - GetActiveVerifiers { chain_name: ChainName }, - #[returns(bool)] ReadyToUnbond { worker_address: Addr }, } diff --git a/contracts/coordinator/src/query.rs b/contracts/coordinator/src/query.rs index 54b9eedbc..c7241d3d0 100644 --- a/contracts/coordinator/src/query.rs +++ b/contracts/coordinator/src/query.rs @@ -1,9 +1,6 @@ use crate::error::ContractError; -use crate::state::{ - ACTIVE_VERIFIER_SET_FOR_PROVER, NEXT_VERIFIER_SET_FOR_PROVER, PROVER_PER_CHAIN, -}; -use cosmwasm_std::{Addr, Deps, StdResult}; -use multisig::verifier_set::VerifierSet; +use crate::state::{VerifierAddress, PROVER_PER_CHAIN, VERIFIER_PROVER_INDEXED_MAP}; +use cosmwasm_std::{Addr, Deps, Order, StdResult}; use router_api::ChainName; pub fn prover(deps: Deps, chain_name: ChainName) -> Result { @@ -12,49 +9,18 @@ pub fn prover(deps: Deps, chain_name: ChainName) -> Result .ok_or(ContractError::NoProversRegisteredForChain(chain_name)) } -pub fn active_verifier_set(deps: Deps, chain_name: ChainName) -> StdResult> { - match prover(deps, chain_name) { - Ok(prover_address) => { - let active_worker_set = - ACTIVE_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address)?; - Ok(active_worker_set) - } - Err(_err) => Ok(None), - } +fn is_verifier_in_any_verifier_set(deps: Deps, verifier_address: &VerifierAddress) -> bool { + VERIFIER_PROVER_INDEXED_MAP + .idx + .by_verifier + .prefix(verifier_address.clone()) + .range(deps.storage, None, None, Order::Ascending) + .any(|_| true) } -fn is_verifier_in_verifier_set(deps: Deps, verifier_address: &Addr) -> StdResult { - // TODO: Use map lookup for chain names to find out which provers to query (to have better performance). - let chain_names = PROVER_PER_CHAIN - .keys(deps.storage, None, None, cosmwasm_std::Order::Ascending) - .collect::>>()?; - - for chain_name in chain_names { - if let Ok(prover_address) = PROVER_PER_CHAIN.load(deps.storage, chain_name) { - if let Ok(Some(verifier_set)) = - ACTIVE_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address.clone()) - { - if verifier_set.includes(verifier_address) { - return Ok(true); - } - } - - if let Ok(Some(verifier_set)) = - NEXT_VERIFIER_SET_FOR_PROVER.may_load(deps.storage, prover_address) - { - if verifier_set.includes(verifier_address) { - return Ok(true); - } - } - } - } - - Ok(false) -} - -pub fn check_verifier_ready_to_unbond(deps: Deps, verifier_address: Addr) -> StdResult { - if is_verifier_in_verifier_set(deps, &verifier_address)? { - return Ok(false); - } - Ok(true) +pub fn check_verifier_ready_to_unbond( + deps: Deps, + verifier_address: VerifierAddress, +) -> StdResult { + Ok(!is_verifier_in_any_verifier_set(deps, &verifier_address)) } diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index 27aa3d8f7..631387162 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -1,7 +1,7 @@ +use crate::error::ContractError; use cosmwasm_schema::cw_serde; -use cosmwasm_std::Addr; -use cw_storage_plus::{Item, Map}; -use multisig::verifier_set::VerifierSet; +use cosmwasm_std::{Addr, Order, Storage}; +use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; use router_api::ChainName; use std::collections::HashSet; @@ -12,17 +12,78 @@ pub struct Config { pub const CONFIG: Item = Item::new("config"); -type ProverAddress = Addr; +pub type ProverAddress = Addr; pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); -// TODO: migrate this? -pub const ACTIVE_VERIFIER_SET_FOR_PROVER: Map = - Map::new("active_prover_verifier_set"); - -type ChainNames = HashSet; -type VerifierAddress = Addr; +pub type ChainNames = HashSet; +pub type VerifierAddress = Addr; pub const CHAINS_OF_VERIFIER: Map = Map::new("chains_of_verifier"); -pub const NEXT_VERIFIER_SET_FOR_PROVER: Map = - Map::new("next_prover_verifier"); +pub struct VerifierSetIndex<'a> { + pub by_verifier: MultiIndex<'a, Addr, VerifierProverRecord, (Addr, Addr)>, +} + +impl<'a> IndexList for VerifierSetIndex<'a> { + fn get_indexes(&self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.by_verifier]; + Box::new(v.into_iter()) + } +} + +#[cw_serde] +pub struct VerifierProverRecord { + pub prover: ProverAddress, + pub verifier: VerifierAddress, +} + +pub const VERIFIER_PROVER_INDEXED_MAP: IndexedMap< + (Addr, Addr), + VerifierProverRecord, + VerifierSetIndex, +> = IndexedMap::new( + "verifier_prover_map", + VerifierSetIndex { + by_verifier: MultiIndex::new( + |_pk: &[u8], d| d.verifier.clone(), + "verifier_prover_map", + "verifier_prover_map_by_verifier", + ), + }, +); + +pub fn update_verifier_set_for_prover( + storage: &mut dyn Storage, + prover_address: ProverAddress, + new_verifiers: HashSet, +) -> Result<(), ContractError> { + let existing_verifiers = VERIFIER_PROVER_INDEXED_MAP + .prefix(prover_address.clone()) + .keys(storage, None, None, Order::Ascending) + .filter_map(Result::ok) + .collect::>(); + + for verifier in existing_verifiers.difference(&new_verifiers) { + VERIFIER_PROVER_INDEXED_MAP + .remove(storage, (prover_address.clone(), verifier.clone())) + .unwrap_or_else(|_| { + panic!( + "Failed to remove verifier {:?} for prover {:?}", + verifier, prover_address + ) + }); + } + + for verifier in new_verifiers.difference(&existing_verifiers) { + VERIFIER_PROVER_INDEXED_MAP.save( + storage, + (prover_address.clone(), verifier.clone()), + &VerifierProverRecord { + prover: prover_address.clone(), + verifier: verifier.clone(), + }, + )?; + } + + Ok(()) +} diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index 853c157a3..e2061fb27 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use cosmwasm_std::{ to_json_binary, wasm_execute, Addr, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, @@ -6,7 +6,7 @@ use cosmwasm_std::{ }; use itertools::Itertools; -use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; +use axelar_wasm_std::{snapshot, FnExt, MajorityThreshold, VerificationStatus}; use multisig::{key::PublicKey, msg::Signer, verifier_set::VerifierSet}; use router_api::{ChainName, CrossChainId, Message}; use service_registry::state::WeightedVerifier; @@ -263,6 +263,8 @@ pub fn update_verifier_set( chain_name: config.chain_name, }; + let verifier_union_set = all_active_verifiers(&deps)?; + Ok(Response::new() .add_submessage(SubMsg::reply_on_success( wasm_execute(config.multisig, &start_sig_msg, vec![]) @@ -271,9 +273,9 @@ pub fn update_verifier_set( )) .add_message( wasm_execute( - config.coordinator.clone(), - &coordinator::msg::ExecuteMsg::SetNextVerifiers { - next_verifier_set: new_verifier_set, + config.coordinator, + &coordinator::msg::ExecuteMsg::SetActiveVerifiers { + verifiers: verifier_union_set, }, vec![], ) @@ -316,6 +318,8 @@ pub fn confirm_verifier_set(deps: DepsMut, sender: Addr) -> Result Result Result, ContractError> { + let current_signers = CURRENT_VERIFIER_SET + .may_load(deps.storage)? + .map(|verifier_set| verifier_set.signers) + .unwrap_or_default(); + + let next_signers = NEXT_VERIFIER_SET + .may_load(deps.storage)? + .map(|verifier_set| verifier_set.signers) + .unwrap_or_default(); + + current_signers + .values() + .chain(next_signers.values()) + .map(|signer| signer.address.clone()) + .collect::>() + .then(Ok) +} + pub fn should_update_verifier_set( new_verifiers: &VerifierSet, cur_verifiers: &VerifierSet, diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 86a5f05da..84299a30a 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -9,6 +9,7 @@ use cosmwasm_std::{ }; use cw_multi_test::{App, AppResponse, Executor}; use router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; +use std::collections::HashSet; use integration_tests::contract::Contract; use integration_tests::coordinator_contract::CoordinatorContract; @@ -321,20 +322,6 @@ pub fn get_verifier_set_from_prover( query_response.unwrap() } -pub fn get_verifier_set_from_coordinator( - app: &mut App, - coordinator_contract: &CoordinatorContract, - chain_name: ChainName, -) -> VerifierSet { - let query_response: Result = coordinator_contract.query( - app, - &coordinator::msg::QueryMsg::GetActiveVerifiers { chain_name }, - ); - assert!(query_response.is_ok()); - - query_response.unwrap() -} - #[allow(clippy::arithmetic_side_effects)] pub fn advance_height(app: &mut App, increment: u64) { let cur_block = app.block_info(); @@ -723,7 +710,7 @@ pub struct Chain { pub fn setup_chain( protocol: &mut Protocol, chain_name: ChainName, - verifiers: &Vec, + verifiers: &[Verifier], ) -> Chain { let voting_verifier = VotingVerifierContract::instantiate_contract( protocol, @@ -810,12 +797,13 @@ pub fn setup_chain( ); assert!(response.is_ok()); - let verifier_set = verifiers_to_verifier_set(protocol, verifiers); + let mut verifier_union_set = HashSet::new(); + verifier_union_set.extend(verifiers.iter().map(|verifier| verifier.addr.clone())); let response = protocol.coordinator.execute( &mut protocol.app, multisig_prover.contract_addr.clone(), &coordinator::msg::ExecuteMsg::SetActiveVerifiers { - next_verifier_set: verifier_set, + verifiers: verifier_union_set, }, ); assert!(response.is_ok()); diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index 002f2421a..67ab77d74 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -104,13 +104,6 @@ fn verifier_set_can_be_initialized_and_then_manually_updated() { let new_verifier_set = test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(new_verifier_set, expected_new_verifier_set); - - let coordinator_verifier_set = test_utils::get_verifier_set_from_coordinator( - &mut protocol.app, - &protocol.coordinator, - ethereum.chain_name, - ); - assert_eq!(coordinator_verifier_set, expected_new_verifier_set); } #[test] From 550fb8fe91e3616926bbf319f895f05708616631 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:17:13 +0300 Subject: [PATCH 012/168] feat(minor-nexus-gateway)!: pass msg id between amplifier and core (#437) * feat(minor-nexus-gateway)!: pass msg id between amplifier and core --- .../nexus-gateway/src/contract/execute.rs | 21 ++++++++-- contracts/nexus-gateway/src/nexus.rs | 39 +++++++------------ 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index c602c6b42..d25cb6762 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -67,6 +67,7 @@ where #[cfg(test)] mod test { + use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; use cosmwasm_std::{from_json, CosmosMsg}; use hex::decode; @@ -122,6 +123,16 @@ mod test { .returning(move || Ok(config.clone())); let contract = Contract::new(store); + let msg_ids = vec![ + HexTxHashAndEventIndex { + tx_hash: vec![0x2f; 32].try_into().unwrap(), + event_index: 100, + }, + HexTxHashAndEventIndex { + tx_hash: vec![0x23; 32].try_into().unwrap(), + event_index: 1000, + }, + ]; let msgs = vec![ nexus::Message { source_chain: "sourceChain".parse().unwrap(), @@ -134,8 +145,9 @@ mod test { .unwrap() .try_into() .unwrap(), - source_tx_id: vec![0x2f; 32].try_into().unwrap(), - source_tx_index: 100, + source_tx_id: msg_ids[0].tx_hash.to_vec().try_into().unwrap(), + source_tx_index: msg_ids[0].event_index as u64, + id: msg_ids[0].to_string(), }, nexus::Message { source_chain: "sourceChain".parse().unwrap(), @@ -148,8 +160,9 @@ mod test { .unwrap() .try_into() .unwrap(), - source_tx_id: vec![0x23; 32].try_into().unwrap(), - source_tx_index: 1000, + source_tx_id: msg_ids[1].tx_hash.to_vec().try_into().unwrap(), + source_tx_index: msg_ids[1].event_index as u64, + id: msg_ids[1].to_string(), }, ]; let res = contract.route_to_router(Addr::unchecked("nexus"), msgs); diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 7e3f751d2..9cd1a9030 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -3,7 +3,6 @@ use std::str::FromStr; use axelar_wasm_std::{msg_id::tx_hash_event_index::HexTxHashAndEventIndex, nonempty}; use cosmwasm_std::{CosmosMsg, CustomMsg}; use error_stack::{Report, Result, ResultExt}; -use hex::ToHex; use router_api::{Address, ChainName, CrossChainId}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -21,6 +20,7 @@ pub struct Message { pub payload_hash: [u8; 32], pub source_tx_id: nonempty::Vec, pub source_tx_index: u64, + pub id: String, } impl CustomMsg for Message {} @@ -40,16 +40,17 @@ impl From for Message { fn from(msg: router_api::Message) -> Self { // fallback to using the message ID as the tx ID if it's not in the expected format let (source_tx_id, source_tx_index) = - parse_message_id(&msg.cc_id.id).unwrap_or((msg.cc_id.id.into(), u64::MAX)); + parse_message_id(&msg.cc_id.id).unwrap_or((msg.cc_id.id.clone().into(), u64::MAX)); Self { - source_chain: msg.cc_id.chain, + source_chain: msg.cc_id.chain.clone(), source_address: msg.source_address, destination_chain: msg.destination_chain, destination_address: msg.destination_address, payload_hash: msg.payload_hash, source_tx_id, source_tx_index, + id: msg.cc_id.id.to_string(), } } } @@ -58,19 +59,11 @@ impl TryFrom for router_api::Message { type Error = Report; fn try_from(msg: Message) -> Result { - let msg_id = HexTxHashAndEventIndex { - tx_hash: <[u8; 32]>::try_from(msg.source_tx_id.as_ref().as_slice()).map_err(|_| { - ContractError::InvalidSourceTxId(msg.source_tx_id.as_ref().encode_hex::()) - })?, - event_index: u32::try_from(msg.source_tx_index) - .map_err(|_| ContractError::InvalidEventIndex(msg.source_tx_index))?, - }; - Ok(Self { cc_id: CrossChainId { chain: msg.source_chain, - id: nonempty::String::try_from(msg_id.to_string()) - .change_context(ContractError::InvalidMessageId(msg_id.to_string()))?, + id: nonempty::String::try_from(msg.id.clone()) + .change_context(ContractError::InvalidMessageId(msg.id.to_string()))?, }, source_address: msg.source_address, destination_chain: msg.destination_chain, @@ -90,33 +83,31 @@ impl From for CosmosMsg { mod test { use std::vec; - use cosmwasm_std::HexBinary; + use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; use super::Message; #[test] fn should_convert_nexus_message_to_router_message() { + let msg_id = HexTxHashAndEventIndex { + tx_hash: vec![2; 32].try_into().unwrap(), + event_index: 1, + }; let msg = Message { source_chain: "ethereum".parse().unwrap(), source_address: "something".parse().unwrap(), destination_chain: "polygon".parse().unwrap(), destination_address: "something else".parse().unwrap(), payload_hash: [1; 32], - source_tx_id: vec![2; 32].try_into().unwrap(), - source_tx_index: 1, + source_tx_id: msg_id.tx_hash.to_vec().try_into().unwrap(), + source_tx_index: msg_id.event_index as u64, + id: msg_id.to_string(), }; let router_msg = router_api::Message::try_from(msg.clone()); assert!(router_msg.is_ok()); let router_msg = router_msg.unwrap(); assert_eq!(router_msg.cc_id.chain, msg.source_chain); - assert_eq!( - router_msg.cc_id.id.to_string(), - format!( - "0x{}-{}", - HexBinary::from(msg.source_tx_id.as_ref().clone()).to_hex(), - msg.source_tx_index - ) - ); + assert_eq!(router_msg.cc_id.id.to_string(), msg.id); } } From 47cc8f6bbf570a530ea364320b737a98c48a734d Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:19:46 +0200 Subject: [PATCH 013/168] feat(minor-nexus-gateway): set source tx id 0 when parsing fails (#453) * feat(minor-nexus-gateway): set source tx id to 0 when parsing fails --- contracts/nexus-gateway/src/nexus.rs | 71 ++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 9cd1a9030..26baad411 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -38,9 +38,9 @@ fn parse_message_id(message_id: &str) -> Result<(nonempty::Vec, u64), Contra impl From for Message { fn from(msg: router_api::Message) -> Self { - // fallback to using the message ID as the tx ID if it's not in the expected format + // fallback to using all 0's as the tx ID if it's not in the expected format let (source_tx_id, source_tx_index) = - parse_message_id(&msg.cc_id.id).unwrap_or((msg.cc_id.id.clone().into(), u64::MAX)); + parse_message_id(&msg.cc_id.id).unwrap_or((vec![0; 32].try_into().unwrap(), 0)); Self { source_chain: msg.cc_id.chain.clone(), @@ -83,7 +83,11 @@ impl From for CosmosMsg { mod test { use std::vec; - use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use axelar_wasm_std::msg_id::{ + base_58_event_index::Base58TxDigestAndEventIndex, + tx_hash_event_index::HexTxHashAndEventIndex, + }; + use router_api::CrossChainId; use super::Message; @@ -110,4 +114,65 @@ mod test { assert_eq!(router_msg.cc_id.chain, msg.source_chain); assert_eq!(router_msg.cc_id.id.to_string(), msg.id); } + + #[test] + fn should_convert_router_message_to_nexus_message() { + let msg = router_api::Message { + cc_id: CrossChainId { + chain: "ethereum".parse().unwrap(), + id: HexTxHashAndEventIndex { + tx_hash: [2; 32], + event_index: 1, + } + .to_string() + .try_into() + .unwrap(), + }, + source_address: "something".parse().unwrap(), + destination_chain: "polygon".parse().unwrap(), + destination_address: "something else".parse().unwrap(), + payload_hash: [1; 32], + }; + + let nexus_msg = Message::from(msg.clone()); + + assert_eq!(nexus_msg.id, msg.cc_id.id.to_string()); + assert_eq!(nexus_msg.destination_address, msg.destination_address); + assert_eq!(nexus_msg.destination_chain, msg.destination_chain); + assert_eq!(nexus_msg.source_address, msg.source_address); + assert_eq!(nexus_msg.source_chain, msg.cc_id.chain); + assert_eq!(nexus_msg.source_tx_id, vec![2; 32].try_into().unwrap()); + assert_eq!(nexus_msg.source_tx_index, 1); + } + + #[test] + fn should_convert_router_message_with_non_hex_msg_id_to_nexus_message() { + let msg = router_api::Message { + cc_id: CrossChainId { + chain: "ethereum".parse().unwrap(), + id: Base58TxDigestAndEventIndex { + tx_digest: [2; 32], + event_index: 1, + } + .to_string() + .try_into() + .unwrap(), + }, + source_address: "something".parse().unwrap(), + destination_chain: "polygon".parse().unwrap(), + destination_address: "something else".parse().unwrap(), + payload_hash: [1; 32], + }; + + let nexus_msg = Message::from(msg.clone()); + + assert_eq!(nexus_msg.id, msg.cc_id.id.to_string()); + assert_eq!(nexus_msg.source_tx_id, vec![0; 32].try_into().unwrap()); + assert_eq!(nexus_msg.source_tx_index, 0); + + assert_eq!(nexus_msg.destination_address, msg.destination_address); + assert_eq!(nexus_msg.destination_chain, msg.destination_chain); + assert_eq!(nexus_msg.source_address, msg.source_address); + assert_eq!(nexus_msg.source_chain, msg.cc_id.chain); + } } From 6fd3612716fc6cf3b421ebe53939a71341731047 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Thu, 13 Jun 2024 09:19:26 -0400 Subject: [PATCH 014/168] feat(minor-multisig-prover): next verifier set query (#452) * feat(minor-multisig-prover): next verifier set query * rename GetVerifierSet to CurrentVerifierSet --- contracts/multisig-prover/src/contract.rs | 5 ++-- contracts/multisig-prover/src/msg.rs | 5 +++- contracts/multisig-prover/src/query.rs | 31 +++++++++++++++++++++-- integration-tests/tests/test_utils/mod.rs | 2 +- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 31f6ce2f0..d40a098e2 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -121,7 +121,8 @@ pub fn query( QueryMsg::GetProof { multisig_session_id, } => to_json_binary(&query::get_proof(deps, multisig_session_id)?), - QueryMsg::GetVerifierSet {} => to_json_binary(&query::get_verifier_set(deps)?), + QueryMsg::CurrentVerifierSet {} => to_json_binary(&query::current_verifier_set(deps)?), + QueryMsg::NextVerifierSet {} => to_json_binary(&query::next_verifier_set(deps)?), } .change_context(ContractError::SerializeResponse) .map_err(axelar_wasm_std::ContractError::from) @@ -299,7 +300,7 @@ mod tests { fn query_get_verifier_set( deps: Deps, ) -> Result, axelar_wasm_std::ContractError> { - query(deps, mock_env(), QueryMsg::GetVerifierSet {}).map(|res| from_json(res).unwrap()) + query(deps, mock_env(), QueryMsg::CurrentVerifierSet {}).map(|res| from_json(res).unwrap()) } #[test] diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index b80a8d486..197031586 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -78,7 +78,10 @@ pub enum QueryMsg { GetProof { multisig_session_id: Uint64 }, #[returns(Option)] - GetVerifierSet, + CurrentVerifierSet, + + #[returns(Option)] + NextVerifierSet, } #[cw_serde] diff --git a/contracts/multisig-prover/src/query.rs b/contracts/multisig-prover/src/query.rs index c997aa5d0..d7723bf55 100644 --- a/contracts/multisig-prover/src/query.rs +++ b/contracts/multisig-prover/src/query.rs @@ -6,7 +6,7 @@ use multisig::{multisig::Multisig, types::MultisigState, verifier_set::VerifierS use crate::{ error::ContractError, msg::{GetProofResponse, ProofStatus}, - state::{CONFIG, CURRENT_VERIFIER_SET, MULTISIG_SESSION_PAYLOAD, PAYLOAD}, + state::{CONFIG, CURRENT_VERIFIER_SET, MULTISIG_SESSION_PAYLOAD, NEXT_VERIFIER_SET, PAYLOAD}, }; pub fn get_proof( @@ -57,6 +57,33 @@ pub fn get_proof( }) } -pub fn get_verifier_set(deps: Deps) -> StdResult> { +pub fn current_verifier_set(deps: Deps) -> StdResult> { CURRENT_VERIFIER_SET.may_load(deps.storage) } + +pub fn next_verifier_set(deps: Deps) -> StdResult> { + NEXT_VERIFIER_SET.may_load(deps.storage) +} + +#[cfg(test)] +mod test { + use cosmwasm_std::testing::mock_dependencies; + + use crate::{state, test::test_data::new_verifier_set}; + + #[test] + fn next_verifier_set() { + let mut deps = mock_dependencies(); + + assert_eq!(None, super::next_verifier_set(deps.as_ref()).unwrap()); + + state::NEXT_VERIFIER_SET + .save(deps.as_mut().storage, &new_verifier_set()) + .unwrap(); + + assert_eq!( + Some(new_verifier_set()), + super::next_verifier_set(deps.as_ref()).unwrap() + ); + } +} diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 84299a30a..71d69f31b 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -316,7 +316,7 @@ pub fn get_verifier_set_from_prover( multisig_prover_contract: &MultisigProverContract, ) -> VerifierSet { let query_response: Result = - multisig_prover_contract.query(app, &multisig_prover::msg::QueryMsg::GetVerifierSet); + multisig_prover_contract.query(app, &multisig_prover::msg::QueryMsg::CurrentVerifierSet); assert!(query_response.is_ok()); query_response.unwrap() From eadf44b8148183d52b18235e5557293c0001bafc Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 17 Jun 2024 13:54:36 -0400 Subject: [PATCH 015/168] feat(minor-ampd): check if configured fee denomination can be paid at startup (#456) --- ampd/src/broadcaster/accounts.rs | 158 ------- ampd/src/broadcaster/clients.rs | 72 --- ampd/src/broadcaster/cosmos.rs | 87 ++++ ampd/src/broadcaster/dec_coin.rs | 18 +- ampd/src/broadcaster/mod.rs | 784 +++++++++++++++++-------------- ampd/src/commands/mod.rs | 23 +- ampd/src/lib.rs | 31 +- 7 files changed, 561 insertions(+), 612 deletions(-) delete mode 100644 ampd/src/broadcaster/accounts.rs delete mode 100644 ampd/src/broadcaster/clients.rs create mode 100644 ampd/src/broadcaster/cosmos.rs diff --git a/ampd/src/broadcaster/accounts.rs b/ampd/src/broadcaster/accounts.rs deleted file mode 100644 index 56901c8f1..000000000 --- a/ampd/src/broadcaster/accounts.rs +++ /dev/null @@ -1,158 +0,0 @@ -use cosmrs::proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountRequest}; -use cosmrs::proto::traits::Message; -use error_stack::{Result, ResultExt}; -use thiserror::Error; - -use crate::broadcaster::clients::AccountQueryClient; -use crate::types::TMAddress; - -#[derive(Error, Debug)] -pub enum Error { - #[error("failed to retrieve the account information for address {address}")] - ResponseFailed { address: TMAddress }, - #[error("address {address} is unknown")] - AccountNotFound { address: TMAddress }, - #[error("received response could not be decoded")] - MalformedResponse, -} - -pub async fn account(client: &mut T, address: &TMAddress) -> Result -where - T: AccountQueryClient, -{ - let response = client - .account(QueryAccountRequest { - address: address.to_string(), - }) - .await - .map_err(|report| match report.current_context().code() { - tonic::Code::NotFound => { - report.attach_printable("to proceed, please ensure the account is funded") - } - _ => report, - }) - .change_context_lazy(|| Error::ResponseFailed { - address: address.clone(), - })?; - - let account = response - .account - .ok_or_else(|| { - Error::AccountNotFound { - address: address.clone(), - } - .into() - }) - .and_then(|account| { - BaseAccount::decode(&account.value[..]) - .change_context(Error::MalformedResponse) - .attach_printable_lazy(|| format!("{{ value = {:?} }}", account.value)) - })?; - - Ok(account) -} - -#[cfg(test)] -mod tests { - use cosmrs::proto::cosmos::auth::v1beta1::BaseAccount; - use cosmrs::proto::cosmos::auth::v1beta1::QueryAccountResponse; - use cosmrs::proto::traits::MessageExt; - use cosmrs::Any; - use ecdsa::SigningKey; - use rand::rngs::OsRng; - use tokio::test; - use tonic::Status; - - use crate::broadcaster::accounts::account; - use crate::broadcaster::accounts::Error::*; - use crate::broadcaster::clients::MockAccountQueryClient; - use crate::types::PublicKey; - use crate::types::TMAddress; - - #[test] - async fn response_failed() { - let mut client = MockAccountQueryClient::new(); - client - .expect_account() - .returning(|_| Err(Status::aborted("aborted").into())); - - let address = rand_tm_address(); - - assert!(matches!( - account(&mut client, &address) - .await - .unwrap_err() - .current_context(), - ResponseFailed { address: _ } - )); - } - - #[test] - async fn account_not_found() { - let mut client = MockAccountQueryClient::new(); - client - .expect_account() - .returning(|_| Ok(QueryAccountResponse { account: None })); - - let address = rand_tm_address(); - - assert!(matches!( - account(&mut client, &address) - .await - .unwrap_err() - .current_context(), - AccountNotFound { address: _ } - )); - } - - #[test] - async fn malformed_response() { - let mut client = MockAccountQueryClient::new(); - client.expect_account().returning(|_| { - Ok(QueryAccountResponse { - account: Some(Any { - type_url: "wrong_type".to_string(), - value: vec![1, 2, 3, 4, 5], - }), - }) - }); - - let address = rand_tm_address(); - - assert!(matches!( - account(&mut client, &address) - .await - .unwrap_err() - .current_context(), - MalformedResponse - )); - } - - #[test] - async fn get_existing_account() { - let address = rand_tm_address(); - let acc = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 20, - }; - let any = acc.clone().to_any().unwrap(); - - let mut client = MockAccountQueryClient::new(); - client.expect_account().returning(move |_| { - Ok(QueryAccountResponse { - account: Some(any.to_owned()), - }) - }); - - assert_eq!(account(&mut client, &address).await.unwrap(), acc); - } - - fn rand_tm_address() -> TMAddress { - PublicKey::from(SigningKey::random(&mut OsRng).verifying_key()) - .account_id("axelar") - .unwrap() - .into() - } -} diff --git a/ampd/src/broadcaster/clients.rs b/ampd/src/broadcaster/clients.rs deleted file mode 100644 index 58deac16a..000000000 --- a/ampd/src/broadcaster/clients.rs +++ /dev/null @@ -1,72 +0,0 @@ -use async_trait::async_trait; -use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient; -use cosmrs::proto::cosmos::auth::v1beta1::{QueryAccountRequest, QueryAccountResponse}; -use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; -use cosmrs::proto::cosmos::tx::v1beta1::{ - BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, SimulateResponse, -}; -use error_stack::{Report, Result}; -use mockall::automock; -use tonic::transport::Channel; - -use tonic::{Response, Status}; - -#[automock] -#[async_trait] -pub trait BroadcastClient { - async fn broadcast_tx(&mut self, request: BroadcastTxRequest) -> Result; - async fn simulate(&mut self, request: SimulateRequest) -> Result; - async fn get_tx(&mut self, request: GetTxRequest) -> Result; -} - -#[async_trait] -impl BroadcastClient for ServiceClient { - async fn broadcast_tx(&mut self, request: BroadcastTxRequest) -> Result { - self.broadcast_tx(request) - .await - .and_then(|response| { - response - .into_inner() - .tx_response - .ok_or_else(|| Status::not_found("tx not found")) - }) - .map_err(Report::from) - } - - async fn simulate(&mut self, request: SimulateRequest) -> Result { - self.simulate(request) - .await - .map(Response::into_inner) - .map_err(Report::from) - } - - async fn get_tx(&mut self, request: GetTxRequest) -> Result { - self.get_tx(request) - .await - .map(Response::into_inner) - .map_err(Report::from) - } -} - -#[automock] -#[async_trait] -pub trait AccountQueryClient { - async fn account( - &mut self, - request: QueryAccountRequest, - ) -> Result; -} - -#[async_trait] -impl AccountQueryClient for QueryClient { - async fn account( - &mut self, - request: QueryAccountRequest, - ) -> Result { - self.account(request) - .await - .map(Response::into_inner) - .map_err(Report::from) - } -} diff --git a/ampd/src/broadcaster/cosmos.rs b/ampd/src/broadcaster/cosmos.rs new file mode 100644 index 000000000..9f4f8569e --- /dev/null +++ b/ampd/src/broadcaster/cosmos.rs @@ -0,0 +1,87 @@ +//! Abstractions that decouple the broadcaster from the explicit clients of the cosmrs crate. +//! +//! In this module, new traits are defined and implemented for several cosmrs clients, +//! so the broadcaster only needs to depend on the traits that it owns itself. This makes it less +//! vulnerable to unexpected changes in the external crate and helps with unit testing, +//! because the client traits also provide auto-mocks. + +use async_trait::async_trait; +use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient as AuthQueryClient; +use cosmrs::proto::cosmos::auth::v1beta1::{QueryAccountRequest, QueryAccountResponse}; +use cosmrs::proto::cosmos::bank::v1beta1::query_client::QueryClient as BankQueryClient; +use cosmrs::proto::cosmos::bank::v1beta1::{QueryBalanceRequest, QueryBalanceResponse}; +use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; +use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; +use cosmrs::proto::cosmos::tx::v1beta1::{ + BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, SimulateResponse, +}; + +use mockall::automock; +use tonic::transport::Channel; +use tonic::{Response, Status}; + +#[automock] +#[async_trait] +pub trait BroadcastClient { + async fn broadcast_tx(&mut self, request: BroadcastTxRequest) -> Result; + async fn simulate(&mut self, request: SimulateRequest) -> Result; + async fn get_tx(&mut self, request: GetTxRequest) -> Result; +} + +#[async_trait] +impl BroadcastClient for ServiceClient { + async fn broadcast_tx(&mut self, request: BroadcastTxRequest) -> Result { + self.broadcast_tx(request).await.and_then(|response| { + response + .into_inner() + .tx_response + .ok_or_else(|| Status::not_found("tx not found")) + }) + } + + async fn simulate(&mut self, request: SimulateRequest) -> Result { + self.simulate(request).await.map(Response::into_inner) + } + + async fn get_tx(&mut self, request: GetTxRequest) -> Result { + self.get_tx(request).await.map(Response::into_inner) + } +} + +#[automock] +#[async_trait] +pub trait AccountQueryClient { + async fn account( + &mut self, + address: QueryAccountRequest, + ) -> Result; +} + +#[async_trait] +impl AccountQueryClient for AuthQueryClient { + async fn account( + &mut self, + request: QueryAccountRequest, + ) -> Result { + self.account(request).await.map(Response::into_inner) + } +} + +#[automock] +#[async_trait] +pub trait BalanceQueryClient { + async fn balance( + &mut self, + request: QueryBalanceRequest, + ) -> Result; +} + +#[async_trait] +impl BalanceQueryClient for BankQueryClient { + async fn balance( + &mut self, + request: QueryBalanceRequest, + ) -> Result { + self.balance(request).await.map(Response::into_inner) + } +} diff --git a/ampd/src/broadcaster/dec_coin.rs b/ampd/src/broadcaster/dec_coin.rs index 664bb7f6a..ca2da4fff 100644 --- a/ampd/src/broadcaster/dec_coin.rs +++ b/ampd/src/broadcaster/dec_coin.rs @@ -64,6 +64,15 @@ impl From for proto::cosmos::base::v1beta1::DecCoin { } } +impl From<&DecCoin> for proto::cosmos::base::v1beta1::DecCoin { + fn from(coin: &DecCoin) -> proto::cosmos::base::v1beta1::DecCoin { + proto::cosmos::base::v1beta1::DecCoin { + denom: coin.denom.to_string(), + amount: coin.amount.to_string(), + } + } +} + impl TryFrom for DecCoin { type Error = Report; @@ -92,15 +101,6 @@ impl TryFrom<&str> for DecCoin { } } -impl From<&DecCoin> for proto::cosmos::base::v1beta1::DecCoin { - fn from(coin: &DecCoin) -> proto::cosmos::base::v1beta1::DecCoin { - proto::cosmos::base::v1beta1::DecCoin { - denom: coin.denom.to_string(), - amount: coin.amount.to_string(), - } - } -} - impl Display for DecCoin { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { // See: https://github.com/cosmos/cosmos-sdk/blob/c4864e9f85011b3e971885ea995a0021c01a885d/types/dec_coin.go#L134 diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index 7ac230e1a..53380f0f5 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -4,6 +4,10 @@ use std::time::Duration; use std::{cmp, thread}; use async_trait::async_trait; +use cosmrs::proto::cosmos::auth::v1beta1::{ + BaseAccount, QueryAccountRequest, QueryAccountResponse, +}; +use cosmrs::proto::cosmos::bank::v1beta1::QueryBalanceRequest; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::proto::cosmos::tx::v1beta1::{ BroadcastMode, BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, @@ -11,30 +15,32 @@ use cosmrs::proto::cosmos::tx::v1beta1::{ use cosmrs::proto::traits::MessageExt; use cosmrs::tendermint::chain::Id; use cosmrs::tx::Fee; -use cosmrs::{Coin, Gas}; -use error_stack::{FutureExt, Report, Result, ResultExt}; +use cosmrs::{Amount, Coin, Denom, Gas}; +use error_stack::{ensure, report, FutureExt, Report, Result, ResultExt}; use futures::TryFutureExt; use k256::sha2::{Digest, Sha256}; use mockall::automock; -use num_traits::cast; +use num_traits::{cast, Zero}; +use prost::Message; +use prost_types::Any; use serde::{Deserialize, Serialize}; use thiserror::Error; -use tonic::Status; +use tonic::{Code, Status}; use tracing::debug; use tracing::info; use typed_builder::TypedBuilder; use valuable::Valuable; +use axelar_wasm_std::FnExt; use dec_coin::DecCoin; -use report::LoggableError; +use report::{LoggableError, ResultCompatExt}; use tx::Tx; use crate::tofnd; use crate::tofnd::grpc::Multisig; use crate::types::{PublicKey, TMAddress}; -pub mod accounts; -pub mod clients; +mod cosmos; mod dec_coin; mod tx; @@ -48,12 +54,22 @@ pub enum Error { FeeEstimation, #[error("broadcast failed")] Broadcast, - #[error("failed to confirm tx inclusion in block")] - TxConfirmation, + #[error("failed to confirm inclusion in block for tx with hash '{tx_hash}'")] + TxConfirmation { tx_hash: String }, #[error("failed to execute tx")] Execution { response: Box }, - #[error("failed to query account information for address {address}")] + #[error("failed to query balance for address '{address}' and denomination '{denom}'")] + QueryBalance { address: TMAddress, denom: Denom }, + #[error("failed to query account for address '{address}'")] QueryAccount { address: TMAddress }, + #[error("address '{address}' controls no tokens of denomination '{denom}' that are required to pay broadcast fees")] + NoTokensOfFeeDenom { address: TMAddress, denom: Denom }, + #[error("failed to encode broadcaster address from public key")] + AddressEncoding, + #[error("received response for query '{query}' could not be decoded")] + MalformedResponse { query: String }, + #[error("address {address} is unknown, please make sure it is funded")] + AccountNotFound { address: TMAddress }, } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] @@ -88,30 +104,120 @@ impl Default for Config { #[automock] #[async_trait] pub trait Broadcaster { - async fn broadcast(&mut self, msgs: Vec) -> Result; - async fn estimate_fee(&mut self, msgs: Vec) -> Result; + async fn broadcast(&mut self, msgs: Vec) -> Result; + async fn estimate_fee(&mut self, msgs: Vec) -> Result; } #[derive(TypedBuilder)] -pub struct BroadcastClient { +pub struct UnvalidatedBasicBroadcaster +where + T: cosmos::BroadcastClient + Send, + S: Multisig + Send + Sync, + A: cosmos::AccountQueryClient + Send, + B: cosmos::BalanceQueryClient, +{ client: T, signer: S, - query_client: Q, - address: TMAddress, + auth_query_client: A, + bank_query_client: B, + address_prefix: String, #[builder(default, setter(skip))] acc_sequence: Option, pub_key: (String, PublicKey), config: Config, } +impl UnvalidatedBasicBroadcaster +where + T: cosmos::BroadcastClient + Send, + S: Multisig + Send + Sync, + A: cosmos::AccountQueryClient + Send, + B: cosmos::BalanceQueryClient, +{ + pub async fn validate_fee_denomination(mut self) -> Result, Error> { + let denom: Denom = self.config.gas_price.denom.clone().into(); + let address: TMAddress = self.derive_address()?; + + ensure!( + self.balance(address.clone(), denom.clone()) + .await? + .then(extract_non_zero_amount) + .is_some(), + Error::NoTokensOfFeeDenom { denom, address } + ); + + Ok(BasicBroadcaster { + client: self.client, + signer: self.signer, + auth_query_client: self.auth_query_client, + address: address.clone(), + acc_sequence: self.acc_sequence, + pub_key: self.pub_key, + config: self.config, + }) + } + + fn derive_address(&mut self) -> Result { + Ok(self + .pub_key + .1 + .account_id(&self.address_prefix) + .change_context(Error::AddressEncoding)? + .into()) + } + + async fn balance(&mut self, address: TMAddress, denom: Denom) -> Result { + let coin = self + .bank_query_client + .balance(QueryBalanceRequest { + address: address.to_string(), + denom: denom.to_string(), + }) + .await + .and_then(|response| { + response + .balance + .ok_or(Status::not_found("balance not found")) + }) + .change_context(Error::QueryBalance { address, denom })?; + + ResultCompatExt::change_context( + coin.try_into(), + Error::MalformedResponse { + query: "balance".to_string(), + }, + ) + } +} + +fn extract_non_zero_amount(coin: Coin) -> Option { + Some(coin.amount).filter(|amount| !amount.is_zero()) +} + +#[derive(Debug)] +pub struct BasicBroadcaster +where + T: cosmos::BroadcastClient + Send, + S: Multisig + Send + Sync, + Q: cosmos::AccountQueryClient + Send, +{ + client: T, + signer: S, + auth_query_client: Q, + address: TMAddress, + acc_sequence: Option, + pub_key: (String, PublicKey), + config: Config, +} + #[async_trait] -impl Broadcaster for BroadcastClient +impl Broadcaster for BasicBroadcaster where - T: clients::BroadcastClient + Send, + T: cosmos::BroadcastClient + Send, S: Multisig + Send + Sync, - Q: clients::AccountQueryClient + Send, + Q: cosmos::AccountQueryClient + Send, { - async fn broadcast(&mut self, msgs: Vec) -> Result { + async fn broadcast(&mut self, msgs: Vec) -> Result { let (acc_number, acc_sequence) = self.acc_number_and_sequence().await?; let tx = Tx::builder() .msgs(msgs.clone()) @@ -167,25 +273,40 @@ where Ok(response) } - async fn estimate_fee(&mut self, msgs: Vec) -> Result { + async fn estimate_fee(&mut self, msgs: Vec) -> Result { let (_, acc_sequence) = self.acc_number_and_sequence().await?; self.estimate_fee(msgs, acc_sequence).await } } -impl BroadcastClient +impl BasicBroadcaster where - T: clients::BroadcastClient, - Q: clients::AccountQueryClient, + T: cosmos::BroadcastClient + Send, + S: Multisig + Send + Sync, + Q: cosmos::AccountQueryClient + Send, { async fn acc_number_and_sequence(&mut self) -> Result<(u64, u64), Error> { - let account = accounts::account(&mut self.query_client, &self.address) + let request = QueryAccountRequest { + address: self.address.to_string(), + }; + + let response = self + .auth_query_client + .account(request) .await - .change_context_lazy(|| Error::QueryAccount { + .then(remap_account_not_found_error) + .change_context(Error::QueryAccount { address: self.address.clone(), })?; + let account = response.account.map_or( + Err(report!(Error::AccountNotFound { + address: self.address.clone() + })), + decode_base_account, + )?; + let acc_sequence = self.acc_sequence.insert(cmp::max( account.sequence, self.acc_sequence.unwrap_or_default(), @@ -194,11 +315,7 @@ where Ok((account.account_number, *acc_sequence)) } - async fn estimate_fee( - &mut self, - msgs: Vec, - acc_sequence: u64, - ) -> Result { + async fn estimate_fee(&mut self, msgs: Vec, acc_sequence: u64) -> Result { let sim_tx = Tx::builder() .msgs(msgs) .pub_key(self.pub_key.1) @@ -253,7 +370,7 @@ where }) .await; - match evaluate_response(response) { + match evaluate_tx_response(response) { ConfirmationResult::Success => { if let Err(report) = result { debug!( @@ -275,13 +392,25 @@ where }; } - result.change_context(Error::TxConfirmation) + result.change_context(Error::TxConfirmation { + tx_hash: tx_hash.to_string(), + }) } } -fn evaluate_response(response: Result) -> ConfirmationResult { +fn decode_base_account(account: Any) -> Result { + BaseAccount::decode(&account.value[..]) + .change_context(Error::MalformedResponse { + query: "account".to_string(), + }) + .attach_printable_lazy(|| format!("{{ value = {:?} }}", account.value)) +} + +fn evaluate_tx_response( + response: core::result::Result, +) -> ConfirmationResult { match response { - Err(err) => ConfirmationResult::Retriable(err), + Err(err) => ConfirmationResult::Retriable(report!(err)), Ok(GetTxResponse { tx_response: None, .. }) => ConfirmationResult::Retriable(Report::new(Status::not_found("tx not found"))), @@ -297,6 +426,16 @@ fn evaluate_response(response: Result) -> ConfirmationRes } } +fn remap_account_not_found_error( + response: core::result::Result, +) -> core::result::Result { + if matches!(response.clone(), Err(status) if status.code() == Code::NotFound) { + Ok(QueryAccountResponse { account: None }) + } else { + response + } +} + enum ConfirmationResult { Success, Retriable(Report), @@ -305,61 +444,61 @@ enum ConfirmationResult { #[cfg(test)] mod tests { + use cosmrs::crypto::PublicKey; use cosmrs::proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountResponse}; + use cosmrs::proto::cosmos::bank::v1beta1::QueryBalanceResponse; use cosmrs::proto::cosmos::base::abci::v1beta1::{GasInfo, TxResponse}; use cosmrs::proto::cosmos::tx::v1beta1::{GetTxResponse, SimulateResponse}; use cosmrs::proto::traits::MessageExt; use cosmrs::proto::Any; - use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use cosmrs::{bank::MsgSend, tx::Msg, AccountId, Coin, Denom}; use ecdsa::SigningKey; + use k256::Secp256k1; use rand::rngs::OsRng; use tokio::test; use tonic::Status; - use crate::broadcaster::clients::{MockAccountQueryClient, MockBroadcastClient}; - use crate::broadcaster::{BroadcastClient, Broadcaster, Config, Error}; + use crate::broadcaster::cosmos::{ + MockAccountQueryClient, MockBalanceQueryClient, MockBroadcastClient, + }; + use crate::broadcaster::{ + BasicBroadcaster, Broadcaster, Config, Error, UnvalidatedBasicBroadcaster, + }; use crate::tofnd::grpc::MockMultisig; - use crate::types::{PublicKey, TMAddress}; + use crate::types::TMAddress; use crate::PREFIX; #[test] - async fn gas_estimation_call_failed() { - let key_id = "key_uid"; - let priv_key = SigningKey::random(&mut OsRng); - let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let account = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 0, - }; + async fn broadcaster_has_incorrect_fee_denomination_return_error() { + let known_denom = "some/other/denom".parse().unwrap(); + + let broadcaster = + init_unvalidated_broadcaster(Some(init_mock_balance_client(known_denom)), None, None); + + let report = broadcaster.validate_fee_denomination().await.unwrap_err(); + assert!(matches!( + report.current_context(), + Error::NoTokensOfFeeDenom { .. } + )); + } + + #[test] + async fn broadcaster_has_correct_fee_denomination_return_validated_broadcaster() { + let broadcaster = init_unvalidated_broadcaster(None, None, None); + + let result = broadcaster.validate_fee_denomination().await; + assert!(result.is_ok()); + } + #[test] + async fn gas_estimation_call_failed() { let mut client = MockBroadcastClient::new(); client .expect_simulate() - .returning(|_| Err(Status::unavailable("unavailable service").into())); + .returning(|_| Err(Status::unavailable("unavailable service"))); - let signer = MockMultisig::default(); + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; - let mut query_client = MockAccountQueryClient::new(); - query_client.expect_account().returning(move |_| { - Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), - }) - }); - - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); let msgs = vec![dummy_msg()]; assert!(matches!( @@ -374,20 +513,6 @@ mod tests { #[test] async fn gas_estimation_none_response() { - let key_id = "key_uid"; - let priv_key = SigningKey::random(&mut OsRng); - let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let account = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 0, - }; - let mut client = MockBroadcastClient::new(); client.expect_simulate().returning(|_| { Ok(SimulateResponse { @@ -396,23 +521,7 @@ mod tests { }) }); - let signer = MockMultisig::default(); - - let mut query_client = MockAccountQueryClient::new(); - query_client.expect_account().returning(move |_| { - Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), - }) - }); - - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; let msgs = vec![dummy_msg()]; assert!(matches!( @@ -427,20 +536,6 @@ mod tests { #[test] async fn broadcast_failed() { - let key_id = "key_uid"; - let priv_key = SigningKey::random(&mut OsRng); - let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let account = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 0, - }; - let mut client = MockBroadcastClient::new(); client.expect_simulate().returning(|_| { Ok(SimulateResponse { @@ -453,38 +548,9 @@ mod tests { }); client .expect_broadcast_tx() - .returning(|_| Err(Status::aborted("failed").into())); - - let mut signer = MockMultisig::default(); - signer - .expect_sign() - .once() - .returning(move |actual_key_uid, data, actual_pub_key, _| { - assert_eq!(actual_key_uid, key_id); - assert_eq!(actual_pub_key, &pub_key); - - let (signature, _) = priv_key - .sign_prehash_recoverable(>::from(data).as_slice()) - .unwrap(); + .returning(|_| Err(Status::aborted("failed"))); - Ok(signature.to_vec()) - }); - - let mut query_client = MockAccountQueryClient::new(); - query_client.expect_account().returning(move |_| { - Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), - }) - }); - - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; let msgs = vec![dummy_msg()]; assert!(matches!( @@ -499,20 +565,6 @@ mod tests { #[test] async fn tx_confirmation_failed() { - let key_id = "key_uid"; - let priv_key = SigningKey::random(&mut OsRng); - let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let account = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 0, - }; - let mut client = MockBroadcastClient::new(); client.expect_simulate().returning(|_| { Ok(SimulateResponse { @@ -529,38 +581,9 @@ mod tests { client .expect_get_tx() .times((Config::default().tx_fetch_max_retries + 1) as usize) - .returning(|_| Err(Status::deadline_exceeded("time out").into())); - - let mut signer = MockMultisig::default(); - signer - .expect_sign() - .once() - .returning(move |actual_key_uid, data, actual_pub_key, _| { - assert_eq!(actual_key_uid, key_id); - assert_eq!(actual_pub_key, &pub_key); - - let (signature, _) = priv_key - .sign_prehash_recoverable(>::from(data).as_slice()) - .unwrap(); - - Ok(signature.to_vec()) - }); + .returning(|_| Err(Status::deadline_exceeded("time out"))); - let mut query_client = MockAccountQueryClient::new(); - query_client.expect_account().returning(move |_| { - Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), - }) - }); - - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; let msgs = vec![dummy_msg()]; assert!(matches!( @@ -569,26 +592,12 @@ mod tests { .await .unwrap_err() .current_context(), - Error::TxConfirmation + Error::TxConfirmation { .. } )); } #[test] async fn tx_execution_failed() { - let key_id = "key_uid"; - let priv_key = SigningKey::random(&mut OsRng); - let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let account = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 0, - }; - let mut client = MockBroadcastClient::new(); client.expect_simulate().returning(|_| { Ok(SimulateResponse { @@ -612,67 +621,187 @@ mod tests { }) }); - let mut signer = MockMultisig::default(); - signer - .expect_sign() - .once() - .returning(move |actual_key_uid, data, actual_pub_key, _| { - assert_eq!(actual_key_uid, key_id); - assert_eq!(actual_pub_key, &pub_key); + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; + let msgs = vec![dummy_msg()]; - let (signature, _) = priv_key - .sign_prehash_recoverable(>::from(data).as_slice()) - .unwrap(); + let report = broadcaster.broadcast(msgs).await.unwrap_err(); - Ok(signature.to_vec()) + assert!( + matches!(report.current_context(), Error::Execution { response } if response.code == 32) + ); + } + + #[test] + async fn broadcast_confirmed() { + let mut broadcaster = init_validated_broadcaster(None, None, None).await; + let msgs = vec![dummy_msg()]; + + assert_eq!(broadcaster.acc_sequence, None); + assert!(broadcaster.broadcast(msgs).await.is_ok()); + assert_eq!(broadcaster.acc_sequence, Some(1)); + } + + #[test] + async fn broadcast_confirmed_in_mem_acc_sequence_mismatch_with_on_chain() { + let mut auth_query_client = MockAccountQueryClient::new(); + let mut call_count = 0; + auth_query_client + .expect_account() + .returning(move |request| { + let mut account = BaseAccount { + address: request.address, + pub_key: None, + account_number: 7, + sequence: 0, + }; + + call_count += 1; + + account.sequence = match call_count { + 1 => 0, + 2 => 10, + _ => 0, + }; + + Ok(QueryAccountResponse { + account: Some(account.to_any().unwrap()), + }) }); - let mut query_client = MockAccountQueryClient::new(); - query_client.expect_account().returning(move |_| { + let mut broadcaster = init_validated_broadcaster(None, Some(auth_query_client), None).await; + + assert_eq!(broadcaster.acc_sequence, None); + assert!(broadcaster.broadcast(vec![dummy_msg()]).await.is_ok()); + assert_eq!(broadcaster.acc_sequence, Some(1)); + assert!(broadcaster.broadcast(vec![dummy_msg()]).await.is_ok()); + assert_eq!(broadcaster.acc_sequence, Some(11)); + assert!(broadcaster.broadcast(vec![dummy_msg()]).await.is_ok()); + assert_eq!(broadcaster.acc_sequence, Some(12)); + } + + #[test] + async fn account_query_failed_return_error() { + let mut client = MockAccountQueryClient::new(); + client + .expect_account() + .returning(|_| Err(Status::aborted("aborted"))); + + let mut broadcaster = init_validated_broadcaster(None, Some(client), None).await; + + for report in [ + broadcaster.broadcast(vec![dummy_msg()]).await.unwrap_err(), + Broadcaster::estimate_fee(&mut broadcaster, vec![dummy_msg()]) + .await + .unwrap_err(), + ] { + assert!(matches!( + report.current_context(), + Error::QueryAccount { .. } + )); + } + } + + #[test] + async fn account_not_found_returns_error() { + let mut client = MockAccountQueryClient::new(); + client + .expect_account() + .returning(|_| Ok(QueryAccountResponse { account: None })); + + let mut broadcaster = init_validated_broadcaster(None, Some(client), None).await; + + for report in [ + broadcaster.broadcast(vec![dummy_msg()]).await.unwrap_err(), + Broadcaster::estimate_fee(&mut broadcaster, vec![dummy_msg()]) + .await + .unwrap_err(), + ] { + assert!(matches!( + report.current_context(), + Error::AccountNotFound { .. } + )); + } + } + + #[test] + async fn malformed_account_query_response_return_error() { + let mut client = MockAccountQueryClient::new(); + client.expect_account().returning(|_| { Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), + account: Some(Any { + type_url: "wrong_type".to_string(), + value: vec![1, 2, 3, 4, 5], + }), }) }); - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); - let msgs = vec![dummy_msg()]; + let mut broadcaster = init_validated_broadcaster(None, Some(client), None).await; - let report = broadcaster.broadcast(msgs).await.unwrap_err(); - assert!(matches!(report.current_context(), Error::Execution { .. })); - if let Error::Execution { response } = report.current_context() { - assert_eq!(response.code, 32); + for report in [ + broadcaster.broadcast(vec![dummy_msg()]).await.unwrap_err(), + Broadcaster::estimate_fee(&mut broadcaster, vec![dummy_msg()]) + .await + .unwrap_err(), + ] { + assert!(matches!( + report.current_context(), + Error::MalformedResponse { .. } + )); } } - #[test] - async fn broadcast_confirmed() { - let key_id = "key_uid"; + fn init_unvalidated_broadcaster( + balance_client_override: Option, + auth_client_override: Option, + broadcast_client_override: Option, + ) -> UnvalidatedBasicBroadcaster< + MockBroadcastClient, + MockMultisig, + MockAccountQueryClient, + MockBalanceQueryClient, + > { + let key_id = "key_uid".to_string(); let priv_key = SigningKey::random(&mut OsRng); let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let account = BaseAccount { - address: address.to_string(), - pub_key: None, - account_number: 7, - sequence: 0, - }; + let known_denom: Denom = Config::default().gas_price.denom.clone().into(); + + UnvalidatedBasicBroadcaster::builder() + .client(broadcast_client_override.unwrap_or_else(init_mock_broadcaster_client)) + .signer(init_mock_signer(key_id.clone(), priv_key)) + .auth_query_client( + auth_client_override.unwrap_or_else(|| init_mock_account_client(pub_key)), + ) + .bank_query_client( + balance_client_override.unwrap_or(init_mock_balance_client(known_denom)), + ) + .address_prefix(PREFIX.to_string()) + .pub_key((key_id, pub_key)) + .config(Config::default()) + .build() + } + async fn init_validated_broadcaster( + balance_client_override: Option, + auth_client_override: Option, + broadcast_client_override: Option, + ) -> BasicBroadcaster { + init_unvalidated_broadcaster( + balance_client_override, + auth_client_override, + broadcast_client_override, + ) + .validate_fee_denomination() + .await + .unwrap() + } + + fn init_mock_broadcaster_client() -> MockBroadcastClient { let mut client = MockBroadcastClient::new(); client.expect_simulate().returning(|_| { Ok(SimulateResponse { gas_info: Some(GasInfo { - gas_wanted: 0, - gas_used: 0, + gas_wanted: 1000, + gas_used: 500, }), result: None, }) @@ -690,88 +819,75 @@ mod tests { }) }); - let mut signer = MockMultisig::default(); - signer - .expect_sign() - .once() - .returning(move |actual_key_uid, data, actual_pub_key, _| { - assert_eq!(actual_key_uid, key_id); - assert_eq!(actual_pub_key, &pub_key); - - let (signature, _) = priv_key - .sign_prehash_recoverable(>::from(data).as_slice()) - .unwrap(); + client + } - Ok(signature.to_vec()) + // returns a non-zero balance if the denom in the request is known, a zero balance otherwise + fn init_mock_balance_client(known_denom: Denom) -> MockBalanceQueryClient { + let mut bank_query_client = MockBalanceQueryClient::new(); + bank_query_client + .expect_balance() + .returning(move |request| { + if request.denom.eq(known_denom.as_ref()) { + Ok(QueryBalanceResponse { + balance: Some( + Coin { + amount: 1, + denom: known_denom.clone(), + } + .into(), + ), + }) + } else { + Ok(QueryBalanceResponse { + balance: Some( + Coin { + amount: 0, + denom: request.denom.parse().unwrap(), + } + .into(), + ), + }) + } }); - - let mut query_client = MockAccountQueryClient::new(); - query_client.expect_account().returning(move |_| { - Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), - }) - }); - - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); - let msgs = vec![dummy_msg()]; - - assert_eq!(broadcaster.acc_sequence, None); - assert!(broadcaster.broadcast(msgs).await.is_ok()); - assert_eq!(broadcaster.acc_sequence, Some(1)); + bank_query_client } - #[test] - async fn broadcast_confirmed_in_mem_acc_sequence_mismatch_with_on_chain() { - let key_id = "key_uid"; - let priv_key = SigningKey::random(&mut OsRng); - let pub_key: PublicKey = priv_key.verifying_key().into(); - let address: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - let mut account = BaseAccount { + // returns an account for the address corresponding to the given public key if that address is queried + fn init_mock_account_client(pub_key: PublicKey) -> MockAccountQueryClient { + let address: TMAddress = pub_key.account_id(PREFIX).unwrap().into(); + let account = BaseAccount { address: address.to_string(), pub_key: None, account_number: 7, sequence: 0, }; - let mut client = MockBroadcastClient::new(); - client.expect_simulate().returning(|_| { - Ok(SimulateResponse { - gas_info: Some(GasInfo { - gas_wanted: 0, - gas_used: 0, - }), - result: None, - }) - }); - client - .expect_broadcast_tx() - .returning(|_| Ok(TxResponse::default())); - client.expect_get_tx().returning(|_| { - Ok(GetTxResponse { - tx_response: Some(TxResponse { - code: 0, - ..TxResponse::default() - }), - ..GetTxResponse::default() - }) - }); + let mut auth_query_client = MockAccountQueryClient::new(); + auth_query_client + .expect_account() + .returning(move |request| { + if request.address == address.to_string() { + Ok(QueryAccountResponse { + account: Some(account.to_any().unwrap()), + }) + } else { + Ok(QueryAccountResponse { account: None }) + } + }); + + auth_query_client + } + + // signs a digest if the public key matches the given private key + fn init_mock_signer(key_id: String, priv_key: SigningKey) -> MockMultisig { + let pub_key: PublicKey = priv_key.verifying_key().into(); let mut signer = MockMultisig::default(); signer .expect_sign() - .times(3) .returning(move |actual_key_uid, data, actual_pub_key, _| { - assert_eq!(actual_key_uid, key_id); + assert_eq!(actual_key_uid, &key_id); assert_eq!(actual_pub_key, &pub_key); let (signature, _) = priv_key @@ -780,45 +896,7 @@ mod tests { Ok(signature.to_vec()) }); - - let mut query_client = MockAccountQueryClient::new(); - let mut call_count = 0; - query_client.expect_account().returning(move |_| { - call_count += 1; - - match call_count { - 1 => { - account.sequence = 0; - } - 2 => { - account.sequence = 10; - } - _ => { - account.sequence = 0; - } - } - - Ok(QueryAccountResponse { - account: Some(account.to_any().unwrap()), - }) - }); - - let mut broadcaster = BroadcastClient::builder() - .client(client) - .signer(signer) - .query_client(query_client) - .address(address) - .pub_key((key_id.to_string(), pub_key)) - .config(Config::default()) - .build(); - - assert_eq!(broadcaster.acc_sequence, None); - assert!(broadcaster.broadcast(vec![dummy_msg()]).await.is_ok()); - assert_eq!(broadcaster.acc_sequence, Some(1)); - assert!(broadcaster.broadcast(vec![dummy_msg()]).await.is_ok()); - assert_eq!(broadcaster.acc_sequence, Some(11)); - assert!(broadcaster.broadcast(vec![dummy_msg()]).await.is_ok()); - assert_eq!(broadcaster.acc_sequence, Some(12)); + signer } fn dummy_msg() -> Any { diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 9252324f5..7ca535c3c 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -3,7 +3,9 @@ use std::path::Path; use clap::Subcommand; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::proto::cosmos::{ - auth::v1beta1::query_client::QueryClient, tx::v1beta1::service_client::ServiceClient, + auth::v1beta1::query_client::QueryClient as AuthQueryClient, + bank::v1beta1::query_client::QueryClient as BankQueryClient, + tx::v1beta1::service_client::ServiceClient, }; use cosmrs::proto::Any; use cosmrs::AccountId; @@ -85,25 +87,28 @@ async fn broadcast_tx( let service_client = ServiceClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection)?; - let query_client = QueryClient::connect(tm_grpc.to_string()) + let auth_query_client = AuthQueryClient::connect(tm_grpc.to_string()) + .await + .change_context(Error::Connection)?; + let bank_query_client = BankQueryClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection)?; let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) .await .change_context(Error::Connection)?; - let address = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - broadcaster::BroadcastClient::builder() + broadcaster::UnvalidatedBasicBroadcaster::builder() .client(service_client) .signer(multisig_client) - .query_client(query_client) + .auth_query_client(auth_query_client) + .bank_query_client(bank_query_client) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast) - .address(address) + .address_prefix(PREFIX.to_string()) .build() + .validate_fee_denomination() + .await + .change_context(Error::Broadcaster)? .broadcast(vec![tx]) .await .change_context(Error::Broadcaster) diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 4f8ffc0c8..5bbfa0ba7 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -3,7 +3,9 @@ use std::time::Duration; use block_height_monitor::BlockHeightMonitor; use cosmrs::proto::cosmos::{ - auth::v1beta1::query_client::QueryClient, tx::v1beta1::service_client::ServiceClient, + auth::v1beta1::query_client::QueryClient as AuthQueryClient, + bank::v1beta1::query_client::QueryClient as BankQueryClient, + tx::v1beta1::service_client::ServiceClient, }; use error_stack::{report, FutureExt, Result, ResultExt}; use evm::finalizer::{pick, Finalization}; @@ -84,7 +86,10 @@ async fn prepare_app(cfg: Config, state: State) -> Result, let service_client = ServiceClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection)?; - let query_client = QueryClient::connect(tm_grpc.to_string()) + let auth_query_client = AuthQueryClient::connect(tm_grpc.to_string()) + .await + .change_context(Error::Connection)?; + let bank_query_client = BankQueryClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection)?; let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) @@ -109,22 +114,26 @@ async fn prepare_app(cfg: Config, state: State) -> Result, } }; - let verifier: TMAddress = pub_key - .account_id(PREFIX) - .expect("failed to convert to account identifier") - .into(); - - let broadcaster = broadcaster::BroadcastClient::builder() - .query_client(query_client) - .address(verifier.clone()) + let broadcaster = broadcaster::UnvalidatedBasicBroadcaster::builder() + .auth_query_client(auth_query_client) + .bank_query_client(bank_query_client) + .address_prefix(PREFIX.to_string()) .client(service_client) .signer(multisig_client.clone()) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast.clone()) - .build(); + .build() + .validate_fee_denomination() + .await + .change_context(Error::Broadcaster)?; let health_check_server = health_check::Server::new(health_check_bind_addr); + let verifier: TMAddress = pub_key + .account_id(PREFIX) + .expect("failed to convert to account identifier") + .into(); + App::new( tm_client, broadcaster, From e07b3c3db297dcaaf41a82a0dc2aada1067c2ac3 Mon Sep 17 00:00:00 2001 From: jcs47 <11947034+jcs47@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:28:41 +0100 Subject: [PATCH 016/168] fix: remove ampd/Cargo.lock from Dockerfile (#458) --- .dockerignore | 1 - ampd/Dockerfile | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index 977dbf345..883057c49 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,7 +4,6 @@ # For more help, visit the .dockerignore file reference guide at # https://docs.docker.com/engine/reference/builder/#dockerignore-file -Cargo.lock **/.DS_Store **/.dockerignore **/.git diff --git a/ampd/Dockerfile b/ampd/Dockerfile index 305cbfca1..9fa27e088 100644 --- a/ampd/Dockerfile +++ b/ampd/Dockerfile @@ -3,8 +3,8 @@ RUN apt-get update && apt-get install -y clang protobuf-compiler cmake WORKDIR /ampd COPY ./Cargo.toml ./Cargo.toml +COPY ./Cargo.lock ./Cargo.lock COPY ./ampd/Cargo.toml ./ampd/Cargo.toml -COPY ./ampd/Cargo.lock ./ampd/Cargo.lock COPY ./packages ./packages COPY ./contracts ./contracts COPY ./integration-tests ./integration-tests From ada2dbeb0b0807e573443e42190088957169752d Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 17 Jun 2024 17:38:06 -0400 Subject: [PATCH 017/168] chore: update dependencies (#460) --- Cargo.lock | 3499 ++++++++++++++++++++++++----------------------- Cargo.toml | 7 +- ampd/Cargo.toml | 13 +- 3 files changed, 1818 insertions(+), 1701 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83a155a0c..2233c3d74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", "aes", @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -86,20 +86,21 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -132,7 +133,7 @@ dependencies = [ "async-trait", "axelar-wasm-std", "axum 0.7.5", - "base64 0.21.4", + "base64 0.21.7", "bcs", "clap", "config", @@ -169,9 +170,9 @@ dependencies = [ "router-api", "serde", "serde_json", - "serde_with 3.3.0", + "serde_with 3.8.1", "service-registry", - "sha3 0.10.8", + "sha3", "sui-json-rpc-types", "sui-types", "tendermint 0.33.0", @@ -179,7 +180,7 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", - "tokio-util 0.7.9", + "tokio-util", "toml 0.5.11", "tonic 0.9.2", "tonic-build", @@ -211,7 +212,7 @@ dependencies = [ [[package]] name = "anemo" version = "0.0.0" -source = "git+https://github.com/mystenlabs/anemo.git?rev=1169850e6af127397068cd86764c29b1d49dbe35#1169850e6af127397068cd86764c29b1d49dbe35" +source = "git+https://github.com/mystenlabs/anemo.git?rev=26d415eb9aa6a2417be3c03c57d6e93c30bd1ad7#26d415eb9aa6a2417be3c03c57d6e93c30bd1ad7" dependencies = [ "anyhow", "async-trait", @@ -220,7 +221,7 @@ dependencies = [ "ed25519 1.5.3", "futures", "hex", - "http 0.2.9", + "http 0.2.12", "matchit 0.5.0", "pin-project-lite", "pkcs8 0.9.0", @@ -228,16 +229,16 @@ dependencies = [ "quinn-proto", "rand", "rcgen", - "ring", - "rustls 0.21.7", - "rustls-webpki 0.101.5", + "ring 0.16.20", + "rustls 0.21.12", + "rustls-webpki", "serde", "serde_json", - "socket2 0.5.4", + "socket2", "tap", "thiserror", "tokio", - "tokio-util 0.7.9", + "tokio-util", "tower", "tracing", "x509-parser", @@ -245,57 +246,58 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "ark-bls12-381" @@ -335,7 +337,7 @@ dependencies = [ "blake2", "derivative", "digest 0.10.7", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -368,7 +370,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools 0.10.5", - "num-bigint 0.4.4", + "num-bigint 0.4.5", "num-traits", "paste", "rustc_version", @@ -381,7 +383,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] @@ -391,10 +393,10 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.5", "num-traits", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -457,7 +459,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.4", + "num-bigint 0.4.5", ] [[package]] @@ -466,8 +468,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -527,10 +529,10 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -539,8 +541,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -558,6 +560,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -575,25 +586,20 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] -[[package]] -name = "async-task" -version = "4.3.0" -source = "git+https://github.com/mystenmark/async-task?rev=4e45b26e11126b191701b9b2ce5e2346b8d7682f#4e45b26e11126b191701b9b2ce5e2346b8d7682f" - [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -609,14 +615,13 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 1.0.109", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -627,9 +632,9 @@ checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axelar-wasm-std" @@ -651,7 +656,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sha3 0.10.8", + "sha3", "strum 0.25.0", "thiserror", "valuable", @@ -663,9 +668,9 @@ version = "0.1.0" dependencies = [ "axelar-wasm-std", "error-stack", - "quote 1.0.33", + "quote 1.0.36", "report", - "syn 2.0.37", + "syn 2.0.66", "thiserror", ] @@ -677,16 +682,16 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core 0.3.4", - "base64 0.21.4", + "base64 0.21.7", "bitflags 1.3.2", "bytes", "futures-util", "headers", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.29", "itoa", - "matchit 0.7.2", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", @@ -721,7 +726,7 @@ dependencies = [ "hyper 1.3.1", "hyper-util", "itoa", - "matchit 0.7.2", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", @@ -748,8 +753,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -779,9 +784,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -812,9 +817,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -824,9 +835,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bcs" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd3ffe8b19a604421a5d461d4a70346223e535903fbc3067138bddbebddcf77" +checksum = "85b6598a2f5d564fb7855dc6b06fd1c38cff5a72bd8b863a4d021938497b440a" dependencies = [ "serde", "thiserror", @@ -838,6 +849,15 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + [[package]] name = "bellpepper" version = "0.4.1" @@ -863,33 +883,32 @@ dependencies = [ ] [[package]] -name = "bincode" -version = "1.3.3" +name = "better_any" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "b359aebd937c17c725e19efcb661200883f04c49c53e7132224dac26da39d4a0" dependencies = [ - "serde", + "better_typeid_derive", ] [[package]] -name = "bindgen" -version = "0.65.1" +name = "better_typeid_derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +checksum = "3deeecb812ca5300b7d3f66f730cc2ebd3511c3d36c691dd79c165d5b19a26e3" dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "prettyplease 0.2.15", - "proc-macro2 1.0.67", - "quote 1.0.33", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 1.0.109", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", ] [[package]] @@ -905,7 +924,7 @@ dependencies = [ "pbkdf2", "rand_core 0.6.4", "ripemd", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", "zeroize", ] @@ -948,9 +967,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitmaps" @@ -1016,27 +1035,12 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "blake3" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "digest 0.10.7", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding 0.2.1", "generic-array", ] @@ -1049,12 +1053,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "block-padding" version = "0.3.3" @@ -1066,9 +1064,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +checksum = "62dc83a094a71d43eeadd254b1ec2d24cb6a0bb6cadce00df51f0db594711a32" dependencies = [ "cc", "glob", @@ -1084,7 +1082,6 @@ checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" dependencies = [ "blst", "byte-slice-cast", - "ec-gpu", "ff", "group", "pairing", @@ -1101,9 +1098,9 @@ checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" [[package]] name = "brotli" -version = "3.3.4" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1112,9 +1109,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.4" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1132,28 +1129,18 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.7", + "sha2 0.10.8", "tinyvec", ] [[package]] -name = "bulletproofs" -version = "4.0.0" +name = "bstr" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40e698f1df446cc6246afd823afbe2d121134d089c9102c1dd26d1264991ba32" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ - "byteorder", - "clear_on_drop", - "curve25519-dalek-ng", - "digest 0.9.0", - "merlin", - "rand", - "rand_core 0.6.4", + "memchr", "serde", - "serde_derive", - "sha3 0.9.1", - "subtle-ng", - "thiserror", ] [[package]] @@ -1170,56 +1157,45 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -1249,22 +1225,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -1274,15 +1237,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", - "windows-targets 0.48.5", + "wasm-bindgen", + "windows-targets 0.52.5", ] [[package]] @@ -1295,22 +1260,11 @@ dependencies = [ "inout", ] -[[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" -version = "4.4.4" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -1318,42 +1272,34 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", + "terminal_size", ] [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ - "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "heck 0.5.0", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" - -[[package]] -name = "clear_on_drop" -version = "0.2.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" -dependencies = [ - "cc", -] +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "client" @@ -1386,34 +1332,27 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "collectable" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08abddbaad209601e53c7dd4308d8c04c06f17bb7df006434e586a22b83be45a" - [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "json5", @@ -1428,23 +1367,35 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "consensus-config" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" +dependencies = [ + "fastcrypto", + "mysten-network", + "rand", + "serde", + "shared-crypto", +] + [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] name = "const-hex" -version = "1.11.4" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ff96486ccc291d36a958107caf2c0af8c78c0af7d31ae2f35ce055130de1a6" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" dependencies = [ "cfg-if", "cpufeatures", @@ -1455,9 +1406,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" @@ -1471,15 +1422,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "coordinator" version = "0.1.2" @@ -1490,7 +1432,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "integration-tests", "multisig", @@ -1502,9 +1444,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1512,9 +1454,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -1599,8 +1541,8 @@ version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb57855fbfc83327f8445ae0d413b1a05ac0d68c396ab4d122b2abd7bb82cb6" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -1610,7 +1552,7 @@ version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bech32", "bnum", "cosmwasm-crypto", @@ -1621,16 +1563,16 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", - "sha2 0.10.7", + "sha2 0.10.8", "static_assertions", "thiserror", ] [[package]] name = "cosmwasm-storage" -version = "1.3.4" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fc6766006aef09dea5db0c0728446e8c0e22b26eeb33c83ae70a500894ff3" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -1638,38 +1580,22 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", - "crossbeam-utils", ] -[[package]] -name = "crossbeam-utils" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" - [[package]] name = "crunchy" version = "0.2.2" @@ -1678,9 +1604,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1732,9 +1658,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -1753,9 +1679,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -1767,7 +1693,6 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.6.4", - "serde", "subtle-ng", "zeroize", ] @@ -1830,13 +1755,13 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.0", + "cw2 1.1.2", "schemars", "semver", "serde", @@ -1858,14 +1783,15 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", "schemars", + "semver", "serde", "thiserror", ] @@ -1882,12 +1808,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.9", + "darling_macro 0.20.9", ] [[package]] @@ -1898,24 +1824,24 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.67", - "quote 1.0.33", - "strsim", + "proc-macro2 1.0.85", + "quote 1.0.36", + "strsim 0.10.0", "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.67", - "quote 1.0.33", - "strsim", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "strsim 0.11.1", + "syn 2.0.66", ] [[package]] @@ -1925,19 +1851,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core 0.14.4", - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ - "darling_core 0.20.3", - "quote 1.0.33", - "syn 2.0.37", + "darling_core 0.20.9", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -1947,7 +1873,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.0", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1955,15 +1881,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-encoding-macro" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1971,9 +1897,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" dependencies = [ "data-encoding", "syn 1.0.109", @@ -1992,9 +1918,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "der_derive", @@ -2011,7 +1937,7 @@ dependencies = [ "asn1-rs", "displaydoc", "nom", - "num-bigint 0.4.4", + "num-bigint 0.4.5", "num-traits", "rusticata-macros", ] @@ -2022,9 +1948,9 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -2043,8 +1969,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4255bb7dd538590188bd0aea52e48bd699b19bd90b0d069ec2ced8461fe23273" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -2054,22 +1980,22 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ - "convert_case 0.4.0", - "proc-macro2 1.0.67", - "quote 1.0.33", + "convert_case", + "proc-macro2 1.0.85", + "quote 1.0.36", "rustc_version", - "syn 1.0.109", + "syn 2.0.66", ] [[package]] @@ -2153,9 +2079,9 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -2170,12 +2096,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - [[package]] name = "dunce" version = "1.0.4" @@ -2184,28 +2104,22 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dyn-clone" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" - -[[package]] -name = "ec-gpu" -version = "0.2.0" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd63582de2b59ea1aa48d7c1941b5d87618d95484397521b3acdfa0e1e9f5e45" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der 0.7.9", "digest 0.10.7", "elliptic-curve", "rfc6979", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2221,12 +2135,12 @@ dependencies = [ [[package]] name = "ed25519" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8 0.10.2", - "signature 2.1.0", + "signature 2.2.0", ] [[package]] @@ -2250,12 +2164,12 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519 2.2.2", + "curve25519-dalek 4.1.2", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "zeroize", ] @@ -2277,15 +2191,15 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -2309,9 +2223,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -2322,7 +2236,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "hex", "k256", @@ -2330,14 +2244,14 @@ dependencies = [ "rand", "rlp", "serde", - "sha3 0.10.8", + "sha3", "zeroize", ] [[package]] name = "enum-compat-util" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "serde_yaml", ] @@ -2348,21 +2262,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "enum_dispatch" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ "once_cell", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -2371,35 +2285,14 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erasable" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f11890ce181d47a64e5d1eb4b6caba0e7bae911a356723740d058a5d0340b7d" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -2425,7 +2318,7 @@ dependencies = [ "regex", "serde", "serde_json", - "sha3 0.10.8", + "sha3", "thiserror", "uint", ] @@ -2456,7 +2349,7 @@ dependencies = [ "impl-codec 0.6.0", "impl-rlp", "impl-serde 0.4.0", - "primitive-types 0.12.1", + "primitive-types 0.12.2", "scale-info", "uint", ] @@ -2490,14 +2383,14 @@ dependencies = [ "dunce", "ethers-core", "eyre", - "prettyplease 0.2.15", - "proc-macro2 1.0.67", - "quote 1.0.33", + "prettyplease 0.2.20", + "proc-macro2 1.0.85", + "quote 1.0.36", "regex", "serde", "serde_json", - "syn 2.0.37", - "toml 0.8.13", + "syn 2.0.66", + "toml 0.8.14", "walkdir", ] @@ -2511,10 +2404,10 @@ dependencies = [ "const-hex", "ethers-contract-abigen", "ethers-core", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "serde_json", - "syn 2.0.37", + "syn 2.0.66", ] [[package]] @@ -2532,7 +2425,7 @@ dependencies = [ "ethabi", "generic-array", "k256", - "num_enum", + "num_enum 0.7.2", "once_cell", "open-fastrlp", "rand", @@ -2540,7 +2433,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.2", - "syn 2.0.37", + "syn 2.0.66", "tempfile", "thiserror", "tiny-keccak", @@ -2555,7 +2448,7 @@ checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" dependencies = [ "async-trait", "auto_impl", - "base64 0.21.4", + "base64 0.21.7", "bytes", "const-hex", "enr", @@ -2564,7 +2457,7 @@ dependencies = [ "futures-timer", "futures-util", "hashers", - "http 0.2.9", + "http 0.2.12", "instant", "jsonwebtoken", "once_cell", @@ -2586,16 +2479,22 @@ dependencies = [ [[package]] name = "ethnum" -version = "1.4.0" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + +[[package]] +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8ff382b2fa527fb7fb06eeebfc5bbb3f17e3cc6b9d70b006c41daa8824adac" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "events" version = "0.1.0" dependencies = [ "axelar-wasm-std", - "base64 0.21.4", + "base64 0.21.7", "cosmrs", "error-stack", "serde_json", @@ -2609,10 +2508,10 @@ version = "0.1.0" dependencies = [ "error-stack", "events", - "quote 1.0.33", + "quote 1.0.36", "serde", "serde_json", - "syn 2.0.37", + "syn 2.0.66", ] [[package]] @@ -2627,15 +2526,15 @@ dependencies = [ "k256", "multisig", "router-api", - "sha3 0.10.8", + "sha3", "thiserror", ] [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -2643,8 +2542,8 @@ dependencies = [ [[package]] name = "fastcrypto" -version = "0.1.7" -source = "git+https://github.com/MystenLabs/fastcrypto?rev=69180dc7275f5f0efb69e11e9d03f6db338d1dd6#69180dc7275f5f0efb69e11e9d03f6db338d1dd6" +version = "0.1.8" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6#4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6" dependencies = [ "aes", "aes-gcm", @@ -2654,12 +2553,11 @@ dependencies = [ "ark-serialize", "auto_ops", "base64ct", + "bech32", "bincode", "blake2", - "blake3", "blst", "bs58 0.4.0", - "bulletproofs", "cbc", "ctr", "curve25519-dalek-ng", @@ -2668,13 +2566,13 @@ dependencies = [ "ecdsa", "ed25519-consensus", "elliptic-curve", - "eyre", "fastcrypto-derive", "generic-array", "hex", + "hex-literal", "hkdf", "lazy_static", - "merlin", + "num-bigint 0.4.5", "once_cell", "p256", "rand", @@ -2684,12 +2582,11 @@ dependencies = [ "schemars", "secp256k1", "serde", - "serde_bytes", "serde_json", "serde_with 2.3.3", - "sha2 0.10.7", - "sha3 0.10.8", - "signature 2.1.0", + "sha2 0.10.8", + "sha3", + "signature 2.2.0", "static_assertions", "thiserror", "tokio", @@ -2700,39 +2597,34 @@ dependencies = [ [[package]] name = "fastcrypto-derive" version = "0.1.3" -source = "git+https://github.com/MystenLabs/fastcrypto?rev=69180dc7275f5f0efb69e11e9d03f6db338d1dd6#69180dc7275f5f0efb69e11e9d03f6db338d1dd6" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6#4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6" dependencies = [ - "convert_case 0.6.0", - "proc-macro2 1.0.67", - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "fastcrypto-tbls" version = "0.1.0" -source = "git+https://github.com/MystenLabs/fastcrypto?rev=69180dc7275f5f0efb69e11e9d03f6db338d1dd6#69180dc7275f5f0efb69e11e9d03f6db338d1dd6" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6#4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6" dependencies = [ "bcs", - "bincode", "digest 0.10.7", "fastcrypto", - "fastcrypto-derive", "hex", "itertools 0.10.5", "rand", "serde", - "sha3 0.10.8", + "sha3", "tap", "tracing", "typenum", - "zeroize", ] [[package]] name = "fastcrypto-zkp" -version = "0.1.2" -source = "git+https://github.com/MystenLabs/fastcrypto?rev=69180dc7275f5f0efb69e11e9d03f6db338d1dd6#69180dc7275f5f0efb69e11e9d03f6db338d1dd6" +version = "0.1.3" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6#4988a4744fcaf8bc7f60bf660d9a223ed0f54cc6" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -2742,20 +2634,18 @@ dependencies = [ "ark-relations", "ark-serialize", "ark-snark", - "bcs", "blst", "byte-slice-cast", "derive_more", "fastcrypto", "ff", "im", + "itertools 0.12.1", "lazy_static", "neptune", - "num-bigint 0.4.4", + "num-bigint 0.4.5", "once_cell", - "regex", "reqwest", - "rustls-webpki 0.101.5", "schemars", "serde", "serde_json", @@ -2773,18 +2663,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - -[[package]] -name = "fdlimit" -version = "0.2.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4c9e43643f5a3be4ca5b67d26b98031ff9db6806c3440ae32e02e3ceac3f1b" -dependencies = [ - "libc", -] +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "ff" @@ -2810,16 +2691,16 @@ dependencies = [ "num-bigint 0.3.3", "num-integer", "num-traits", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "fixed-hash" @@ -2859,9 +2740,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flagset" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" +checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1" dependencies = [ "serde", ] @@ -2903,9 +2784,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -2936,9 +2817,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -2951,9 +2832,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -2961,15 +2842,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -2978,38 +2859,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", "send_wrapper 0.4.0", @@ -3017,9 +2898,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -3053,7 +2934,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "gateway-api", "itertools 0.11.0", @@ -3087,9 +2968,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -3100,9 +2981,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -3110,9 +2991,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -3120,6 +3001,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + [[package]] name = "gloo-timers" version = "0.2.6" @@ -3147,20 +3041,20 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.9", - "indexmap 2.0.0", + "http 0.2.12", + "indexmap 2.2.6", "slab", "tokio", - "tokio-util 0.7.9", + "tokio-util", "tracing", ] @@ -3170,7 +3064,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -3179,14 +3073,14 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", ] [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashers" @@ -3199,15 +3093,11 @@ dependencies = [ [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", "byteorder", - "crossbeam-channel", - "flate2", - "nom", "num-traits", ] @@ -3217,10 +3107,10 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "headers-core", - "http 0.2.9", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -3232,29 +3122,26 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http 0.2.9", + "http 0.2.12", ] [[package]] name = "heck" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -3265,11 +3152,17 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -3285,18 +3178,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -3316,12 +3209,12 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.9", + "http 0.2.12", "pin-project-lite", ] @@ -3337,12 +3230,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.0", "pin-project-lite", @@ -3356,9 +3249,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -3384,22 +3277,22 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2", "tokio", "tower-service", "tracing", @@ -3434,14 +3327,14 @@ dependencies = [ "bytes", "futures", "headers", - "http 0.2.9", - "hyper 0.14.27", + "http 0.2.12", + "hyper 0.14.29", "hyper-rustls 0.22.1", - "rustls-native-certs", + "rustls-native-certs 0.5.0", "tokio", "tokio-rustls 0.22.0", "tower-service", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -3452,26 +3345,42 @@ checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" dependencies = [ "ct-logs", "futures-util", - "hyper 0.14.27", + "hyper 0.14.29", "log", "rustls 0.19.1", - "rustls-native-certs", + "rustls-native-certs 0.5.0", "tokio", "tokio-rustls 0.22.0", - "webpki", + "webpki 0.21.4", "webpki-roots 0.21.1", ] [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http 0.2.12", + "hyper 0.14.29", + "log", + "rustls 0.20.9", + "rustls-native-certs 0.6.3", + "tokio", + "tokio-rustls 0.23.4", + "webpki-roots 0.22.6", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.9", - "hyper 0.14.27", - "rustls 0.21.7", + "http 0.2.12", + "hyper 0.14.29", + "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", ] @@ -3482,7 +3391,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.27", + "hyper 0.14.29", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -3490,9 +3399,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes", "futures-util", @@ -3500,22 +3409,21 @@ dependencies = [ "http-body 1.0.0", "hyper 1.3.1", "pin-project-lite", - "socket2 0.5.4", "tokio", ] [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -3527,6 +3435,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -3535,12 +3561,14 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] [[package]] @@ -3572,7 +3600,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.5", + "parity-scale-codec 3.6.12", ] [[package]] @@ -3608,8 +3636,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -3632,12 +3660,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.5", "serde", ] @@ -3647,15 +3675,15 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "block-padding 0.3.3", + "block-padding", "generic-array", ] [[package]] name = "insta" -version = "1.31.0" +version = "1.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a" +checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" dependencies = [ "console", "lazy_static", @@ -3664,14 +3692,13 @@ dependencies = [ "pest_derive", "serde", "similar", - "yaml-rust", ] [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -3698,29 +3725,16 @@ dependencies = [ "serde", "serde_json", "service-registry", - "sha3 0.10.8", + "sha3", "tofn", "voting-verifier", ] -[[package]] -name = "internment" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab388864246d58a276e60e7569a833d9cc4cd75c66e5ca77c177dad38e59996" -dependencies = [ - "ahash 0.7.6", - "dashmap", - "hashbrown 0.12.3", - "once_cell", - "parking_lot", -] - [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "iri-string" @@ -3732,15 +3746,10 @@ dependencies = [ ] [[package]] -name = "is-terminal" -version = "0.4.9" +name = "is_terminal_polyfill" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "itertools" @@ -3761,25 +3770,25 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.9" +name = "itertools" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] [[package]] -name = "jobserver" -version = "0.1.26" +name = "itoa" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -3804,15 +3813,151 @@ dependencies = [ "tabled", ] +[[package]] +name = "jsonrpsee" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-ws-client", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "futures-util", + "http 0.2.12", + "jsonrpsee-core", + "jsonrpsee-types", + "pin-project", + "rustls-native-certs 0.6.3", + "soketto", + "thiserror", + "tokio", + "tokio-rustls 0.23.4", + "tokio-util", + "tracing", + "webpki-roots 0.22.6", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "anyhow", + "arrayvec", + "async-lock", + "async-trait", + "beef", + "futures-channel", + "futures-timer", + "futures-util", + "globset", + "hyper 0.14.29", + "jsonrpsee-types", + "parking_lot", + "rand", + "rustc-hash", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "async-trait", + "hyper 0.14.29", + "hyper-rustls 0.23.2", + "jsonrpsee-core", + "jsonrpsee-types", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 1.0.109", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "futures-channel", + "futures-util", + "http 0.2.12", + "hyper 0.14.29", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "soketto", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.16.2" +source = "git+https://github.com/wlmyng/jsonrpsee.git?rev=b1b300784795f6a64d0fcdf8f03081a9bc38bde8#b1b300784795f6a64d0fcdf8f03081a9bc38bde8" +dependencies = [ + "http 0.2.12", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + [[package]] name = "jsonwebtoken" version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -3828,15 +3973,15 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", ] [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -3847,62 +3992,35 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] -name = "lazycell" -version = "1.3.0" +name = "leb128" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "libloading" -version = "0.7.4" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] -name = "librocksdb-sys" -version = "0.11.0+8.1.1" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "glob", + "bitflags 2.5.0", "libc", - "libz-sys", - "lz4-sys", - "zstd-sys", -] - -[[package]] -name = "libz-sys" -version = "1.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", ] [[package]] @@ -3913,15 +4031,21 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -3937,13 +4061,12 @@ dependencies = [ ] [[package]] -name = "lz4-sys" -version = "1.9.4" +name = "lru" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" dependencies = [ - "cc", - "libc", + "hashbrown 0.13.2", ] [[package]] @@ -3960,27 +4083,15 @@ checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" [[package]] name = "matchit" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "merlin" -version = "3.0.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" -dependencies = [ - "byteorder", - "keccak", - "rand_core 0.6.4", - "zeroize", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mime" @@ -4006,21 +4117,20 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "log", "wasi", "windows-sys 0.48.0", ] @@ -4047,37 +4157,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] -name = "move-abigen" +name = "move-abstract-interpreter" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ - "anyhow", - "bcs", - "heck 0.3.3", - "log", "move-binary-format", - "move-bytecode-verifier", - "move-command-line-common", - "move-core-types", - "move-model", - "serde", + "move-bytecode-verifier-meter", ] [[package]] name = "move-abstract-stack" version = "0.0.1" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" [[package]] name = "move-binary-format" version = "0.0.3" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "enum-compat-util", @@ -4091,12 +4193,12 @@ dependencies = [ [[package]] name = "move-borrow-graph" version = "0.0.1" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" [[package]] name = "move-bytecode-source-map" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", @@ -4111,7 +4213,7 @@ dependencies = [ [[package]] name = "move-bytecode-utils" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "move-binary-format", @@ -4123,42 +4225,56 @@ dependencies = [ [[package]] name = "move-bytecode-verifier" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ + "move-abstract-interpreter", "move-abstract-stack", "move-binary-format", "move-borrow-graph", + "move-bytecode-verifier-meter", "move-core-types", "move-vm-config", "petgraph 0.5.1", ] +[[package]] +name = "move-bytecode-verifier-meter" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" +dependencies = [ + "move-binary-format", + "move-core-types", + "move-vm-config", +] + [[package]] name = "move-command-line-common" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "difference", "dirs-next", "hex", "move-core-types", - "num-bigint 0.4.4", + "num-bigint 0.4.5", "once_cell", "serde", "sha2 0.9.9", + "vfs", "walkdir", ] [[package]] name = "move-compiler" version = "0.0.1" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", "clap", "codespan-reporting", + "dunce", "hex", "move-binary-format", "move-borrow-graph", @@ -4168,24 +4284,30 @@ dependencies = [ "move-core-types", "move-ir-to-bytecode", "move-ir-types", + "move-proc-macros", "move-symbol-pool", "once_cell", "petgraph 0.5.1", "regex", "serde", + "serde_json", + "similar", + "stacker", "tempfile", + "vfs", ] [[package]] name = "move-core-types" version = "0.0.4" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", "enum-compat-util", "ethnum", "hex", + "leb128", "move-proc-macros", "num", "once_cell", @@ -4194,19 +4316,21 @@ dependencies = [ "ref-cast", "serde", "serde_bytes", + "thiserror", "uint", ] [[package]] name = "move-coverage" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", "clap", "codespan", "colored", + "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", "move-command-line-common", @@ -4219,13 +4343,14 @@ dependencies = [ [[package]] name = "move-disassembler" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", "clap", "colored", "hex", + "move-abstract-interpreter", "move-binary-format", "move-bytecode-source-map", "move-command-line-common", @@ -4235,28 +4360,10 @@ dependencies = [ "move-ir-types", ] -[[package]] -name = "move-docgen" -version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" -dependencies = [ - "anyhow", - "codespan", - "codespan-reporting", - "itertools 0.10.5", - "log", - "move-compiler", - "move-model", - "num", - "once_cell", - "regex", - "serde", -] - [[package]] name = "move-ir-to-bytecode" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "codespan-reporting", @@ -4274,7 +4381,7 @@ dependencies = [ [[package]] name = "move-ir-to-bytecode-syntax" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "hex", @@ -4287,7 +4394,7 @@ dependencies = [ [[package]] name = "move-ir-types" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "hex", "move-command-line-common", @@ -4297,77 +4404,20 @@ dependencies = [ "serde", ] -[[package]] -name = "move-model" -version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" -dependencies = [ - "anyhow", - "codespan", - "codespan-reporting", - "internment", - "itertools 0.10.5", - "log", - "move-binary-format", - "move-bytecode-source-map", - "move-command-line-common", - "move-compiler", - "move-core-types", - "move-disassembler", - "move-ir-types", - "move-symbol-pool", - "num", - "once_cell", - "regex", - "serde", -] - -[[package]] -name = "move-package" -version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" -dependencies = [ - "anyhow", - "clap", - "colored", - "move-abigen", - "move-binary-format", - "move-bytecode-source-map", - "move-bytecode-utils", - "move-command-line-common", - "move-compiler", - "move-core-types", - "move-docgen", - "move-model", - "move-symbol-pool", - "named-lock", - "once_cell", - "petgraph 0.5.1", - "regex", - "serde", - "serde_yaml", - "sha2 0.9.9", - "tempfile", - "toml 0.5.11", - "treeline", - "walkdir", - "whoami", -] - [[package]] name = "move-proc-macros" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "enum-compat-util", - "quote 1.0.33", - "syn 2.0.37", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "move-symbol-pool" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "once_cell", "phf", @@ -4377,26 +4427,28 @@ dependencies = [ [[package]] name = "move-vm-config" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "move-binary-format", + "once_cell", ] [[package]] name = "move-vm-profiler" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "move-vm-config", "once_cell", "serde", "serde_json", + "tracing", ] [[package]] name = "move-vm-test-utils" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "move-binary-format", @@ -4410,7 +4462,7 @@ dependencies = [ [[package]] name = "move-vm-types" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "bcs", "move-binary-format", @@ -4420,43 +4472,14 @@ dependencies = [ "smallvec", ] -[[package]] -name = "msim" -version = "0.1.0" -source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" -dependencies = [ - "ahash 0.7.6", - "async-task", - "bincode", - "bytes", - "cc", - "downcast-rs", - "erasable", - "futures", - "lazy_static", - "libc", - "msim-macros", - "naive-timer", - "pin-project-lite", - "rand", - "real_tokio", - "serde", - "socket2 0.4.9", - "tap", - "tokio-util 0.7.7", - "toml 0.5.11", - "tracing", - "tracing-subscriber", -] - [[package]] name = "msim-macros" version = "0.1.0" -source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" +source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=077b735b484cf33e79f9d621db1d0c3a5827b81e#077b735b484cf33e79f9d621db1d0c3a5827b81e" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -4507,12 +4530,12 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -4530,11 +4553,11 @@ dependencies = [ "cosmwasm-crypto", "cosmwasm-schema", "cosmwasm-std", - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw-utils 1.0.1", - "cw2 1.1.0", + "cw-utils 1.0.3", + "cw2 1.1.2", "ed25519-dalek", "enum-display-derive", "error-stack", @@ -4546,7 +4569,7 @@ dependencies = [ "router-api", "serde", "serde_json", - "sha3 0.10.8", + "sha3", "signature-verifier-api", "thiserror", ] @@ -4564,8 +4587,8 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw-utils 1.0.1", - "cw2 1.1.0", + "cw-utils 1.0.3", + "cw2 1.1.2", "elliptic-curve", "error-stack", "ethers-contract", @@ -4583,7 +4606,7 @@ dependencies = [ "router-api", "serde_json", "service-registry", - "sha3 0.10.8", + "sha3", "thiserror", "voting-verifier", ] @@ -4591,7 +4614,7 @@ dependencies = [ [[package]] name = "mysten-metrics" version = "0.7.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "async-trait", "axum 0.6.20", @@ -4605,38 +4628,37 @@ dependencies = [ "tap", "tokio", "tracing", - "uuid 1.4.1", - "workspace-hack", + "uuid 1.8.0", ] [[package]] name = "mysten-network" version = "0.2.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anemo", "bcs", "bytes", "eyre", "futures", - "http 0.2.9", + "http 0.2.12", "multiaddr", + "pin-project-lite", "serde", "snap", "tokio", "tokio-stream", - "tonic 0.10.2", + "tonic 0.11.0", "tonic-health", "tower", "tower-http", "tracing", - "workspace-hack", ] [[package]] name = "mysten-util-mem" version = "0.11.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "cfg-if", "ed25519-consensus", @@ -4644,53 +4666,30 @@ dependencies = [ "fastcrypto-tbls", "hashbrown 0.12.3", "impl-trait-for-tuples", - "indexmap 1.9.3", + "indexmap 2.2.6", "mysten-util-mem-derive", "once_cell", "parking_lot", "roaring", "smallvec", - "workspace-hack", ] [[package]] name = "mysten-util-mem-derive" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ - "proc-macro2 1.0.67", + "proc-macro2 1.0.85", "syn 1.0.109", - "synstructure", - "workspace-hack", -] - -[[package]] -name = "naive-timer" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034a0ad7deebf0c2abcf2435950a6666c3c15ea9d8fad0c0f48efa8a7f843fed" - -[[package]] -name = "named-lock" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a3eb6b7c682b65d1f631ec3176829d72ab450b3aacdd3f719bf220822e59ac" -dependencies = [ - "libc", - "once_cell", - "parking_lot", - "thiserror", - "widestring", - "winapi", + "synstructure 0.12.6", ] [[package]] name = "narwhal-config" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "fastcrypto", - "fastcrypto-tbls", "match_opt", "mysten-network", "mysten-util-mem", @@ -4700,20 +4699,17 @@ dependencies = [ "serde_json", "thiserror", "tracing", - "workspace-hack", ] [[package]] name = "narwhal-crypto" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "bcs", "fastcrypto", - "fastcrypto-tbls", "serde", "shared-crypto", - "workspace-hack", ] [[package]] @@ -4744,7 +4740,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "hex", "mockall", @@ -4766,6 +4762,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995defdca0a589acfdd1bd2e8e3b896b4d4f7675a31fd14c32611440c7f608e6" + [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -4784,11 +4786,11 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.5", "num-complex", "num-integer", "num-iter", @@ -4809,11 +4811,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", "rand", @@ -4838,9 +4839,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -4857,26 +4858,25 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -4885,21 +4885,20 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", - "num-bigint 0.4.4", + "num-bigint 0.4.5", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -4917,30 +4916,51 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.0" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.7.2", ] [[package]] name = "num_enum_derive" -version = "0.7.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "object" -version = "0.32.1" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "memchr", ] @@ -4962,9 +4982,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "open-fastrlp" @@ -4986,8 +5006,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ "bytes", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -5032,9 +5052,9 @@ checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -5052,7 +5072,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -5091,15 +5111,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.5", + "parity-scale-codec-derive 3.6.12", "serde", ] @@ -5109,29 +5129,29 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -5139,15 +5159,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -5157,7 +5177,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ "blake2b_simd", - "ec-gpu", "ff", "group", "hex", @@ -5170,9 +5189,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" @@ -5190,12 +5209,6 @@ dependencies = [ "hmac", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "peg" version = "0.7.0" @@ -5213,8 +5226,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" dependencies = [ "peg-runtime", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", ] [[package]] @@ -5252,15 +5265,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.3" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -5269,9 +5282,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.3" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -5279,26 +5292,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.3" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "pest_meta" -version = "2.7.3" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -5313,12 +5326,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.0.0", + "indexmap 2.2.6", ] [[package]] @@ -5359,9 +5372,9 @@ checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", "phf_shared", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -5375,29 +5388,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -5433,27 +5446,21 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", - "spki 0.7.2", + "der 0.7.9", + "spki 0.7.3", ] -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - [[package]] name = "platforms" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -5509,25 +5516,25 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ - "proc-macro2 1.0.67", + "proc-macro2 1.0.85", "syn 1.0.109", ] [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ - "proc-macro2 1.0.67", - "syn 2.0.37", + "proc-macro2 1.0.85", + "syn 2.0.66", ] [[package]] name = "primeorder" -version = "0.13.2" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ "elliptic-curve", ] @@ -5546,9 +5553,9 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash 0.8.0", "impl-codec 0.6.0", @@ -5568,6 +5575,15 @@ dependencies = [ "toml 0.5.11", ] +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -5575,8 +5591,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", "version_check", ] @@ -5587,8 +5603,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "version_check", ] @@ -5603,18 +5619,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", @@ -5628,12 +5644,11 @@ dependencies = [ [[package]] name = "prometheus-closure-metric" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "prometheus", "protobuf", - "workspace-hack", ] [[package]] @@ -5644,7 +5659,7 @@ checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.0", + "bitflags 2.5.0", "lazy_static", "num-traits", "rand", @@ -5709,7 +5724,7 @@ dependencies = [ "lazy_static", "log", "multimap", - "petgraph 0.6.4", + "petgraph 0.6.5", "prettyplease 0.1.25", "prost 0.11.9", "prost-types", @@ -5727,8 +5742,8 @@ checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -5740,8 +5755,8 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -5752,10 +5767,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "itertools 0.12.1", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -5776,6 +5791,15 @@ dependencies = [ "bytes", ] +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -5794,7 +5818,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.12", "thiserror", "tokio", "tracing", @@ -5802,15 +5826,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13f81c9a9d574310b8351f8666f5a93ac3b0069c45c28ad52c10291389a7cf9" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand", - "ring", + "ring 0.16.20", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.12", "slab", "thiserror", "tinyvec", @@ -5825,7 +5849,7 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", - "socket2 0.5.4", + "socket2", "tracing", "windows-sys 0.48.0", ] @@ -5841,11 +5865,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "proc-macro2 1.0.67", + "proc-macro2 1.0.85", ] [[package]] @@ -5916,9 +5940,9 @@ dependencies = [ [[package]] name = "random-string" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e63111ec5292d8af9c220f06fe3bb87991cc78b6f1f7e291d1ae6b8a60817" +checksum = "f70fd13c3024ae3f17381bb5c4d409c6dc9ea6895c08fa2147aba305bea3c4af" dependencies = [ "fastrand 1.9.0", ] @@ -5930,94 +5954,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", - "ring", + "ring 0.16.20", "time", "yasna", ] [[package]] name = "readonly" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" -dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", -] - -[[package]] -name = "real_tokio" -version = "1.28.1" -source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" -dependencies = [ - "autocfg", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.4.9", - "tokio-macros 2.1.0 (git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45)", - "windows-sys 0.48.0", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "a25d631e41bfb5fdcde1d4e2215f62f7f0afa3ff11e26563765bd6ea1d229aeb" dependencies = [ - "bitflags 1.3.2", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acde58d073e9c79da00f2b5b84eed919c8326832648a5b109b3fce1bb1175280" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -6027,9 +6024,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -6038,9 +6035,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "report" @@ -6055,20 +6052,20 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", - "hyper-rustls 0.24.1", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.29", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", @@ -6076,7 +6073,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.7", + "rustls 0.21.12", "rustls-pemfile", "serde", "serde_json", @@ -6090,16 +6087,10 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", "winreg", ] -[[package]] -name = "retain_mut" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086" - [[package]] name = "rewards" version = "0.3.0" @@ -6110,7 +6101,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "itertools 0.11.0", "report", @@ -6137,12 +6128,27 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -6169,30 +6175,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "roaring" -version = "0.10.2" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6106b5cf8587f5834158895e9715a3c6c9716c8aefab57f1f7680917191c7873" +checksum = "7699249cc2c7d71939f30868f47e9d7add0bdc030d90ee10bfd16887ff8bb1c8" dependencies = [ "bytemuck", "byteorder", - "retain_mut", -] - -[[package]] -name = "rocksdb" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" -dependencies = [ - "libc", - "librocksdb-sys", ] [[package]] @@ -6216,7 +6211,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "flagset", "gateway-api", @@ -6247,7 +6242,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sha3 0.10.8", + "sha3", "thiserror", "valuable", ] @@ -6267,8 +6262,8 @@ dependencies = [ "pkcs1", "pkcs8 0.9.0", "rand_core 0.6.4", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "zeroize", ] @@ -6285,9 +6280,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -6321,15 +6316,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -6340,21 +6335,33 @@ checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ "base64 0.13.1", "log", - "ring", + "ring 0.16.20", "sct 0.6.1", - "webpki", + "webpki 0.21.4", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct 0.7.1", + "webpki 0.22.4", +] + +[[package]] +name = "rustls" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring", - "rustls-webpki 0.101.5", - "sct 0.7.0", + "ring 0.17.8", + "rustls-webpki", + "sct 0.7.1", ] [[package]] @@ -6370,39 +6377,41 @@ dependencies = [ ] [[package]] -name = "rustls-pemfile" -version = "1.0.3" +name = "rustls-native-certs" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "base64 0.21.4", + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", ] [[package]] -name = "rustls-webpki" -version = "0.100.3" +name = "rustls-pemfile" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "ring", - "untrusted", + "base64 0.21.7", ] [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "rusty-fork" @@ -6418,9 +6427,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -6433,42 +6442,42 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.9.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.6.5", + "parity-scale-codec 3.6.12", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.9.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "either", @@ -6479,14 +6488,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.66", ] [[package]] @@ -6501,18 +6510,18 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -6522,7 +6531,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der 0.7.8", + "der 0.7.9", "generic-array", "pkcs8 0.10.2", "subtle", @@ -6551,11 +6560,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -6564,9 +6573,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -6574,9 +6583,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -6595,9 +6604,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -6634,42 +6643,42 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 1.0.109", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -6677,9 +6686,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -6687,13 +6696,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -6735,18 +6744,19 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" dependencies = [ - "base64 0.21.4", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.0", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", - "serde_with_macros 3.3.0", + "serde_with_macros 3.8.1", "time", ] @@ -6756,22 +6766,22 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.3", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "darling 0.20.9", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" dependencies = [ - "darling 0.20.3", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "darling 0.20.9", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] @@ -6797,7 +6807,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "integration-tests", "report", @@ -6807,6 +6817,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha1" version = "0.10.6" @@ -6833,9 +6856,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -6845,25 +6868,13 @@ dependencies = [ [[package]] name = "sha2-asm" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ba7066011e3fb30d808b51affff34f0a66d3a03a58edd787c6e420e40e44e" +checksum = "b845214d6175804686b2bd482bcffe96651bb2d1200742b712003504a2dac1ab" dependencies = [ "cc", ] -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - [[package]] name = "sha3" version = "0.10.8" @@ -6876,9 +6887,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -6886,27 +6897,20 @@ dependencies = [ [[package]] name = "shared-crypto" version = "0.0.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "bcs", "eyre", "fastcrypto", "serde", "serde_repr", - "workspace-hack", ] -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -6919,9 +6923,9 @@ checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -6939,9 +6943,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.2.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" [[package]] name = "simple_asn1" @@ -6949,7 +6953,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.5", "num-traits", "thiserror", "time", @@ -6988,28 +6992,34 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snap" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] -name = "socket2" -version = "0.5.4" +name = "soketto" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ - "libc", - "windows-sys 0.48.0", + "base64 0.13.1", + "bytes", + "futures", + "http 0.2.12", + "httparse", + "log", + "rand", + "sha-1", ] [[package]] @@ -7018,6 +7028,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.6.0" @@ -7030,12 +7046,31 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.9", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", ] [[package]] @@ -7050,6 +7085,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.24.1" @@ -7065,7 +7106,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros 0.25.2", + "strum_macros 0.25.3", ] [[package]] @@ -7074,7 +7115,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" dependencies = [ - "strum_macros 0.26.2", + "strum_macros 0.26.4", ] [[package]] @@ -7084,43 +7125,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "rustversion", "syn 1.0.109", ] [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "rustversion", - "syn 2.0.37", + "syn 2.0.66", ] [[package]] name = "strum_macros" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", + "heck 0.5.0", + "proc-macro2 1.0.85", + "quote 1.0.36", "rustversion", - "syn 2.0.37", + "syn 2.0.66", ] [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "subtle-encoding" @@ -7140,34 +7181,15 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "sui-enum-compat-util" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "serde_yaml", - "workspace-hack", -] - -[[package]] -name = "sui-framework" -version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" -dependencies = [ - "anyhow", - "bcs", - "move-binary-format", - "move-core-types", - "move-package", - "once_cell", - "serde", - "sui-move-build", - "sui-types", - "tracing", - "workspace-hack", ] [[package]] name = "sui-json" version = "0.0.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", @@ -7178,15 +7200,13 @@ dependencies = [ "schemars", "serde", "serde_json", - "sui-framework", "sui-types", - "workspace-hack", ] [[package]] name = "sui-json-rpc-types" version = "0.0.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anyhow", "bcs", @@ -7206,106 +7226,125 @@ dependencies = [ "sui-enum-compat-util", "sui-json", "sui-macros", + "sui-package-resolver", "sui-protocol-config", "sui-types", "tabled", "tracing", - "workspace-hack", ] [[package]] name = "sui-macros" version = "0.7.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "futures", "once_cell", "sui-proc-macros", "tracing", - "workspace-hack", ] [[package]] -name = "sui-move-build" -version = "0.0.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +name = "sui-package-resolver" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ - "anyhow", - "fastcrypto", + "async-trait", + "bcs", + "eyre", + "lru", "move-binary-format", - "move-bytecode-utils", - "move-bytecode-verifier", "move-command-line-common", - "move-compiler", "move-core-types", - "move-ir-types", - "move-package", - "move-symbol-pool", - "serde-reflection", + "serde", + "sui-rest-api", "sui-types", - "sui-verifier-latest", - "tempfile", - "workspace-hack", + "thiserror", + "tokio", ] [[package]] name = "sui-proc-macros" version = "0.7.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "msim-macros", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "sui-enum-compat-util", - "syn 2.0.37", - "workspace-hack", + "syn 2.0.66", ] [[package]] name = "sui-protocol-config" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "clap", "insta", + "move-vm-config", "schemars", "serde", "serde_with 2.3.3", "sui-protocol-config-macros", "tracing", - "workspace-hack", ] [[package]] name = "sui-protocol-config-macros" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", - "workspace-hack", +] + +[[package]] +name = "sui-rest-api" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" +dependencies = [ + "anyhow", + "axum 0.6.20", + "bcs", + "fastcrypto", + "mime", + "rand", + "reqwest", + "serde", + "serde_json", + "serde_with 2.3.3", + "sui-types", + "tap", + "thiserror", ] [[package]] name = "sui-types" version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ "anemo", "anyhow", "bcs", + "better_any", "bincode", "byteorder", + "chrono", + "consensus-config", "derivative", "derive_more", "enum_dispatch", "eyre", "fastcrypto", + "fastcrypto-tbls", "fastcrypto-zkp", "im", - "indexmap 1.9.3", + "indexmap 2.2.6", "itertools 0.10.5", + "jsonrpsee", + "lru", "move-binary-format", "move-bytecode-utils", "move-command-line-common", @@ -7319,7 +7358,12 @@ dependencies = [ "mysten-network", "narwhal-config", "narwhal-crypto", + "nonempty", + "num-bigint 0.4.5", + "num-traits", + "num_enum 0.6.1", "once_cell", + "parking_lot", "prometheus", "proptest", "proptest-derive", @@ -7340,25 +7384,9 @@ dependencies = [ "sui-protocol-config", "tap", "thiserror", - "tonic 0.10.2", - "tracing", - "typed-store", - "workspace-hack", -] - -[[package]] -name = "sui-verifier-latest" -version = "0.1.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" -dependencies = [ - "move-abstract-stack", - "move-binary-format", - "move-bytecode-utils", - "move-bytecode-verifier", - "move-core-types", - "move-vm-config", - "sui-types", - "workspace-hack", + "tonic 0.11.0", + "tracing", + "typed-store-error", ] [[package]] @@ -7378,19 +7406,19 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.37" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "unicode-ident", ] @@ -7412,28 +7440,39 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", "unicode-xid 0.2.4", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", +] + [[package]] name = "system-configuration" -version = "0.6.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 2.4.0", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", @@ -7458,8 +7497,8 @@ checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -7471,15 +7510,14 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.0", - "redox_syscall 0.3.5", + "fastrand 2.1.0", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -7490,7 +7528,7 @@ checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" dependencies = [ "bytes", "digest 0.10.7", - "ed25519 2.2.2", + "ed25519 2.2.3", "ed25519-consensus", "flex-error", "futures", @@ -7504,8 +7542,8 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "subtle-encoding", "tendermint-proto 0.32.2", @@ -7520,7 +7558,7 @@ source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x# dependencies = [ "bytes", "digest 0.10.7", - "ed25519 2.2.2", + "ed25519 2.2.3", "ed25519-consensus", "flex-error", "futures", @@ -7532,8 +7570,8 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "subtle-encoding", "tendermint-proto 0.33.0", @@ -7599,8 +7637,8 @@ dependencies = [ "flex-error", "futures", "getrandom", - "http 0.2.9", - "hyper 0.14.27", + "http 0.2.12", + "hyper 0.14.29", "hyper-proxy", "hyper-rustls 0.22.1", "peg", @@ -7625,13 +7663,23 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "termtree" version = "0.4.1" @@ -7640,29 +7688,29 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -7717,6 +7765,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -7739,36 +7797,35 @@ source = "git+https://github.com/axelarnetwork/tofn.git?branch=update-deps#88285 dependencies = [ "bincode", "crypto-bigint", - "der 0.7.8", + "der 0.7.9", "ecdsa", - "ed25519 2.2.2", + "ed25519 2.2.3", "ed25519-dalek", "hmac", "k256", "rand", "rand_chacha", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "tracing", "zeroize", ] [[package]] name = "tokio" -version = "1.32.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", - "tokio-macros 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2", + "tokio-macros", "windows-sys 0.48.0", ] @@ -7784,34 +7841,35 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] -name = "tokio-macros" -version = "2.1.0" -source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", ] [[package]] name = "tokio-rustls" -version = "0.22.0" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.19.1", + "rustls 0.20.9", "tokio", - "webpki", + "webpki 0.22.4", ] [[package]] @@ -7820,66 +7878,49 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util 0.7.9", + "tokio-util", ] [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.7", + "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots 0.23.1", -] - -[[package]] -name = "tokio-util" -version = "0.7.7" -source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" -dependencies = [ - "bytes", - "futures-core", - "futures-io", - "futures-sink", - "futures-util", - "hashbrown 0.12.3", - "pin-project-lite", - "real_tokio", - "slab", - "tracing", + "webpki-roots 0.25.4", ] [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -7893,14 +7934,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.14", ] [[package]] @@ -7914,15 +7955,26 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.13", ] [[package]] @@ -7933,14 +7985,14 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum 0.6.20", - "base64 0.21.4", + "base64 0.21.7", "bytes", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.29", "hyper-timeout", "percent-encoding", "pin-project", @@ -7955,27 +8007,24 @@ dependencies = [ [[package]] name = "tonic" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" dependencies = [ "async-stream", "async-trait", "axum 0.6.20", - "base64 0.21.4", + "base64 0.21.7", "bytes", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.29", "hyper-timeout", "percent-encoding", "pin-project", "prost 0.12.6", - "rustls 0.21.7", - "rustls-pemfile", "tokio", - "tokio-rustls 0.24.1", "tokio-stream", "tower", "tower-layer", @@ -7990,23 +8039,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" dependencies = [ "prettyplease 0.1.25", - "proc-macro2 1.0.67", + "proc-macro2 1.0.85", "prost-build", - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "tonic-health" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f80db390246dfb46553481f6024f0082ba00178ea495dbb99e70ba9a4fafb5e1" +checksum = "2cef6e24bc96871001a7e48e820ab240b3de2201e59b517cf52835df2f1d2350" dependencies = [ "async-stream", "prost 0.12.6", "tokio", "tokio-stream", - "tonic 0.10.2", + "tonic 0.11.0", ] [[package]] @@ -8024,7 +8073,7 @@ dependencies = [ "rand", "slab", "tokio", - "tokio-util 0.7.9", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -8042,8 +8091,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "httpdate", "iri-string", @@ -8052,12 +8101,12 @@ dependencies = [ "percent-encoding", "pin-project-lite", "tokio", - "tokio-util 0.7.9", + "tokio-util", "tower", "tower-layer", "tower-service", "tracing", - "uuid 1.4.1", + "uuid 1.8.0", ] [[package]] @@ -8074,11 +8123,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -8087,20 +8135,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -8118,12 +8166,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -8141,9 +8189,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", "serde", @@ -8164,37 +8212,31 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b79e2e9c9ab44c6d7c20d5976961b47e8f49ac199154daa514b77cd1ab536625" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] -[[package]] -name = "treeline" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" - [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.9", + "http 0.2.12", "httparse", "log", "rand", - "rustls 0.21.7", + "rustls 0.21.12", "sha1", "thiserror", "url", @@ -8216,37 +8258,18 @@ version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] -name = "typed-store" +name = "typed-store-error" version = "0.4.0" -source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" +source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c745260b60a4ec4906c9f2b22240d872d" dependencies = [ - "async-trait", - "bcs", - "bincode", - "collectable", - "eyre", - "fdlimit", - "hdrhistogram", - "itertools 0.10.5", - "msim", - "once_cell", - "ouroboros", - "prometheus", - "rand", - "rocksdb", "serde", - "sui-macros", - "tap", "thiserror", - "tokio", - "tracing", - "workspace-hack", ] [[package]] @@ -8288,38 +8311,17 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -8355,11 +8357,17 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.4.1" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", "idna", @@ -8372,11 +8380,23 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -8386,9 +8406,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.4.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", "rand", @@ -8409,8 +8429,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d44690c645190cfce32f91a1582281654b2338c6073fa250b0949fd25c55b32" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.85", + "quote 1.0.36", "syn 1.0.109", ] @@ -8430,22 +8450,22 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" dependencies = [ - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vfs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e4fe92cfc1bad19c19925d5eee4b30584dbbdee4ff10183b261acccbef74e2d" + [[package]] name = "voting-verifier" version = "0.4.0" @@ -8457,7 +8477,7 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.0", + "cw2 1.1.2", "error-stack", "integration-tests", "multisig", @@ -8467,7 +8487,7 @@ dependencies = [ "router-api", "serde_json", "service-registry", - "sha3 0.10.8", + "sha3", "thiserror", ] @@ -8482,9 +8502,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -8507,9 +8527,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -8517,24 +8537,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -8544,38 +8564,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ - "quote 1.0.33", + "quote 1.0.36", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -8587,8 +8607,18 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -8597,23 +8627,23 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" dependencies = [ - "webpki", + "webpki 0.21.4", ] [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ - "rustls-webpki 0.100.3", + "webpki 0.22.4", ] [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" @@ -8627,22 +8657,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "whoami" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "widestring" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" - [[package]] name = "winapi" version = "0.3.9" @@ -8661,11 +8675,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -8675,21 +8689,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -8702,18 +8707,12 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -8732,10 +8731,20 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] [[package]] name = "windows_aarch64_gnullvm" @@ -8744,10 +8753,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -8756,10 +8765,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -8768,10 +8777,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -8780,10 +8795,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -8792,10 +8807,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -8804,10 +8819,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -8815,11 +8830,26 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "winnow" -version = "0.6.8" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -8835,10 +8865,16 @@ dependencies = [ ] [[package]] -name = "workspace-hack" -version = "0.1.0" +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beffa227304dbaea3ad6a06ac674f9bc83a3dec3b7f63eeb442de37e7cb6bb01" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "ws_stream_wasm" @@ -8910,11 +8946,76 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", + "synstructure 0.13.1", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", + "synstructure 0.13.1", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -8925,17 +9026,29 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] [[package]] -name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +name = "zerovec" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" dependencies = [ - "cc", - "pkg-config", + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", ] diff --git a/Cargo.toml b/Cargo.toml index 9ddacf8a9..185d9c9c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,8 +37,11 @@ serde_json = "1.0.89" schemars = "0.8.10" sha3 = { version = "0.10.8", default-features = false, features = [] } signature-verifier-api = { version = "^0.1.0", path = "packages/signature-verifier-api" } -ethers-contract = { version = "2.0.13", default-features = false, features = ["abigen"] } -ethers-core = "2.0.13" +ethers-contract = { version = "2.0.14", default-features = false, features = ["abigen"] } +ethers-core = "2.0.14" +tokio = "1.38.0" +tokio-stream = "0.1.11" +tokio-util = "0.7.11" [workspace.lints.clippy] arithmetic_side_effects = "deny" diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index f9b849790..5d2bd101d 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -32,7 +32,7 @@ humantime-serde = "1.1.1" itertools = { workspace = true } k256 = { version = "0.13.1", features = ["ecdsa"] } mockall = "0.11.3" -move-core-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.14.2" } +move-core-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.26.2" } multisig = { workspace = true, features = ["library"] } num-traits = { workspace = true } prost = "0.11.9" @@ -45,8 +45,8 @@ serde_json = { workspace = true } serde_with = "3.2.0" service-registry = { workspace = true } sha3 = { workspace = true } -sui-json-rpc-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.14.2" } -sui-types = { git = "https://github.com/mystenlabs/sui", features = ["test-utils"], tag = "mainnet-v1.14.2" } +sui-json-rpc-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.26.2" } +sui-types = { git = "https://github.com/mystenlabs/sui", features = ["test-utils"], tag = "mainnet-v1.26.2" } # Need to switch to our own fork of tendermint and tendermint-rpc due to event attribute value being nullable. # Can switch back once https://github.com/informalsystems/tendermint-rs/issues/1216 is resolved. # The fix for the issue is at https://github.com/axelarnetwork/tendermint-rs/commit/e97033e20e660a7e707ea86db174ec047bbba50d. @@ -55,9 +55,9 @@ tendermint-rpc = { git = "https://github.com/axelarnetwork/tendermint-rs.git", b "http-client", ] } thiserror = { workspace = true } -tokio = { version = "1.22.0", features = ["signal"] } -tokio-stream = { version = "0.1.11", features = ["sync"] } -tokio-util = "0.7.8" +tokio = { workspace = true, features = ["signal"] } +tokio-stream = { workspace = true, features = ["sync"] } +tokio-util = { workspace = true } toml = "0.5.9" tonic = "0.9.2" tracing = { version = "0.1.37", features = ["valuable", "log"] } @@ -75,6 +75,7 @@ generic-array = "0.14.7" multisig = { workspace = true, features = ["test", "library"] } rand = "0.8.5" random-string = "1.0.0" +tokio = { workspace = true, features = ["test-util"] } [build-dependencies] tonic-build = "0.8.3" From 16a40d817d93cdd7fc8301adfce59d51107d166c Mon Sep 17 00:00:00 2001 From: eguajardo Date: Tue, 18 Jun 2024 09:52:20 -0600 Subject: [PATCH 018/168] chore(minor-multisig-prover)!: update domain separator input format to hex instead of byte array (#459) * update (de)serialization of domain separator during instantiation * update comment --- contracts/multisig-prover/src/msg.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index 197031586..26f7ea992 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -47,7 +47,10 @@ pub struct InstantiateMsg { /// deployed on the destination chain. The multisig contract supports multiple public keys per verifier (each a different type of key), and this /// parameter controls which registered public key to use for signing for each verifier registered to the destination chain. pub key_type: KeyType, - /// an opaque value created to distinguish distinct chains that the external gateway should be initialized with. + /// An opaque value created to distinguish distinct chains that the external gateway should be initialized with. + /// Value must be a String in hex format without `0x`, e.g. "598ba04d225cec385d1ce3cf3c9a076af803aa5c614bc0e0d176f04ac8d28f55". + #[serde(with = "axelar_wasm_std::hex")] // (de)serialization with hex module + #[schemars(with = "String")] // necessary attribute in conjunction with #[serde(with ...)] pub domain_separator: Hash, } From 9538ee51a3499c668c9ea7f084d3badaae2cd6ca Mon Sep 17 00:00:00 2001 From: Sammy Date: Tue, 18 Jun 2024 13:31:35 -0400 Subject: [PATCH 019/168] feat(ampd): change the QueuedBroadcaster so that the BroadcasterClient returns error immediately on fee estimation failures (#454) * feat(ampd): change the QueuedBroadcaster so that the BroadcasterClient returns error immediately on fee estimation failures * remove TODO comment * fix linting * review comments * refactor * review comments --- ampd/src/grpc/server/ampd.rs | 1 - ampd/src/lib.rs | 7 +- ampd/src/queue/queued_broadcaster.rs | 292 +++++++++++++-------------- 3 files changed, 138 insertions(+), 162 deletions(-) diff --git a/ampd/src/grpc/server/ampd.rs b/ampd/src/grpc/server/ampd.rs index 24f2e3048..966103019 100644 --- a/ampd/src/grpc/server/ampd.rs +++ b/ampd/src/grpc/server/ampd.rs @@ -112,7 +112,6 @@ where let req = req.into_inner(); let msg = req.msg.ok_or(Status::invalid_argument("missing msg"))?; - // TODO: validate msg by estimating its gas cost before broadcasting? self.broadcaster .broadcast(msg) .await diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 5bbfa0ba7..50ab79b94 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -23,7 +23,7 @@ use broadcaster::Broadcaster; use event_processor::EventHandler; use event_sub::EventSub; use events::Event; -use queue::queued_broadcaster::{QueuedBroadcaster, QueuedBroadcasterDriver}; +use queue::queued_broadcaster::QueuedBroadcaster; use state::StateUpdater; use tofnd::grpc::{Multisig, MultisigClient}; use types::TMAddress; @@ -172,8 +172,6 @@ where event_subscriber: event_sub::EventSubscriber, event_processor: TaskGroup, broadcaster: QueuedBroadcaster, - #[allow(dead_code)] - broadcaster_driver: QueuedBroadcasterDriver, state_updater: StateUpdater, multisig_client: MultisigClient, block_height_monitor: BlockHeightMonitor, @@ -206,7 +204,7 @@ where }; let event_processor = TaskGroup::new(); - let (broadcaster, broadcaster_driver) = QueuedBroadcaster::new( + let broadcaster = QueuedBroadcaster::new( broadcaster, broadcast_cfg.batch_gas_limit, broadcast_cfg.queue_cap, @@ -218,7 +216,6 @@ where event_subscriber, event_processor, broadcaster, - broadcaster_driver, state_updater, multisig_client, block_height_monitor, diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index a414ac60a..ba2bd260b 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -1,12 +1,14 @@ use std::time::Duration; use async_trait::async_trait; +use axelar_wasm_std::FnExt; use cosmrs::{Any, Gas}; use error_stack::{self, Report, ResultExt}; use mockall::automock; use thiserror::Error; +use tokio::select; +use tokio::sync::{mpsc, oneshot}; use tokio::time; -use tokio::{select, sync::mpsc}; use tracing::info; use tracing::warn; @@ -14,6 +16,7 @@ use super::msg_queue::MsgQueue; use crate::broadcaster::Broadcaster; type Result = error_stack::Result; +type MsgAndResChan = (Any, oneshot::Sender); #[derive(Error, Debug)] pub enum Error { @@ -21,25 +24,12 @@ pub enum Error { EstimateFee, #[error("failed broadcasting messages in queue")] Broadcast, + #[error("failed returning response to client")] + Client, #[error("failed to queue message")] Queue, } -pub struct QueuedBroadcasterDriver { - #[allow(dead_code)] - broadcast_tx: mpsc::Sender<()>, -} - -impl QueuedBroadcasterDriver { - #[allow(dead_code)] - pub async fn force_broadcast(&self) -> Result { - self.broadcast_tx - .send(()) - .await - .map_err(|_| Report::new(Error::Broadcast)) - } -} - #[automock] #[async_trait] pub trait BroadcasterClient { @@ -47,16 +37,19 @@ pub trait BroadcasterClient { } pub struct QueuedBroadcasterClient { - sender: mpsc::Sender, + sender: mpsc::Sender, } #[async_trait] impl BroadcasterClient for QueuedBroadcasterClient { async fn broadcast(&self, msg: Any) -> Result { + let (tx, rx) = oneshot::channel(); self.sender - .send(msg) + .send((msg, tx)) .await - .map_err(|_| Report::new(Error::Broadcast)) + .change_context(Error::Broadcast)?; + + rx.await.change_context(Error::Broadcast)? } } @@ -68,8 +61,7 @@ where queue: MsgQueue, batch_gas_limit: Gas, broadcast_interval: Duration, - channel: (mpsc::Sender, mpsc::Receiver), - broadcast_rx: mpsc::Receiver<()>, + channel: Option<(mpsc::Sender, mpsc::Receiver)>, } impl QueuedBroadcaster @@ -81,94 +73,105 @@ where batch_gas_limit: Gas, capacity: usize, broadcast_interval: Duration, - ) -> (Self, QueuedBroadcasterDriver) { - let (broadcast_tx, broadcast_rx) = mpsc::channel(1); - - ( - Self { - broadcaster, - queue: MsgQueue::default(), - batch_gas_limit, - broadcast_interval, - channel: mpsc::channel(capacity), - broadcast_rx, - }, - QueuedBroadcasterDriver { broadcast_tx }, - ) + ) -> Self { + Self { + broadcaster, + queue: MsgQueue::default(), + batch_gas_limit, + broadcast_interval, + channel: Some(mpsc::channel(capacity)), + } } pub async fn run(mut self) -> Result { - let (tx, mut rx) = self.channel; - drop(tx); - - let mut queue = self.queue; - let mut broadcaster = self.broadcaster; - + let (_, mut rx) = self + .channel + .take() + .expect("broadcast channel is expected to be set during initialization and must be available when running the broadcaster"); let mut interval = time::interval(self.broadcast_interval); loop { select! { - msg = rx.recv() => match msg { - None => break, - Some(msg) => { - let fee = broadcaster.estimate_fee(vec![msg.clone()]).await.change_context(Error::EstimateFee)?; - - if fee.gas_limit.saturating_add(queue.gas_cost()) >= self.batch_gas_limit { - warn!(queue_size = queue.len(), queue_gas_cost = queue.gas_cost(), "exceeded batch gas limit. gas limit can be adjusted in ampd config"); - broadcast_all(&mut queue, &mut broadcaster).await?; - interval.reset(); - } - - let message_type = msg.type_url.clone(); - queue.push(msg, fee.gas_limit).change_context(Error::Queue)?; - info!( - message_type, - queue_size = queue.len(), - queue_gas_cost = queue.gas_cost(), - "pushed a new message into the queue" - ); - } - }, - _ = interval.tick() => { - broadcast_all(&mut queue, &mut broadcaster).await?; - interval.reset(); - }, - _ = self.broadcast_rx.recv() => { - broadcast_all(&mut queue, &mut broadcaster).await?; - interval.reset(); - }, + msg = rx.recv() => match msg { + None => break, + Some(msg_and_res_chan) => interval = self.handle_msg(interval, msg_and_res_chan).await?, + }, + _ = interval.tick() => self.broadcast_all().await?.then(|_| {interval.reset()}), } } - broadcast_all(&mut queue, &mut broadcaster).await?; + self.broadcast_all().await?; Ok(()) } pub fn client(&self) -> QueuedBroadcasterClient { QueuedBroadcasterClient { - sender: self.channel.0.clone(), + sender: self + .channel + .as_ref() + .expect("broadcast channel is expected to be set during initialization and must be available when running the broadcaster") + .0 + .clone(), } } -} -async fn broadcast_all(queue: &mut MsgQueue, broadcaster: &mut T) -> Result -where - T: Broadcaster, -{ - let msgs = queue.pop_all(); + async fn broadcast_all(&mut self) -> Result { + let msgs = self.queue.pop_all(); - match msgs.len() { - 0 => Ok(()), - n => { - info!(message_count = n, "ready to broadcast messages"); + match msgs.len() { + 0 => Ok(()), + n => { + info!(message_count = n, "ready to broadcast messages"); - broadcaster - .broadcast(msgs) - .await - .map(|_| ()) - .change_context(Error::Broadcast) + self.broadcaster + .broadcast(msgs) + .await + .map(|_| ()) + .change_context(Error::Broadcast) + } + } + } + + async fn handle_msg( + &mut self, + mut interval: time::Interval, + msg_and_res_chan: MsgAndResChan, + ) -> Result { + let (msg, tx) = msg_and_res_chan; + + match self.broadcaster.estimate_fee(vec![msg.clone()]).await { + Ok(fee) => { + tx.send(Ok(())).map_err(|_| Report::new(Error::Client))?; + + if fee.gas_limit.saturating_add(self.queue.gas_cost()) >= self.batch_gas_limit { + warn!( + queue_size = self.queue.len(), + queue_gas_cost = self.queue.gas_cost(), + "exceeded batch gas limit. gas limit can be adjusted in ampd config" + ); + self.broadcast_all().await?; + interval.reset(); + } + + let message_type = msg.type_url.clone(); + self.queue + .push(msg, fee.gas_limit) + .change_context(Error::Queue)?; + info!( + message_type, + queue_size = self.queue.len(), + queue_gas_cost = self.queue.gas_cost(), + "pushed a new message into the queue" + ); + } + Err(err) => { + tx.send(Err(err).change_context(Error::EstimateFee)) + .map_err(|_| Report::new(Error::Client))?; + } } + + Ok(interval) } } @@ -178,13 +181,39 @@ mod test { use cosmrs::tx::Fee; use cosmrs::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use error_stack::Report; use tokio::test; use tokio::time::{sleep, Duration}; - use super::QueuedBroadcaster; - use crate::broadcaster::MockBroadcaster; + use super::{Error, QueuedBroadcaster}; + use crate::broadcaster::{self, MockBroadcaster}; use crate::queue::queued_broadcaster::BroadcasterClient; + #[test] + async fn should_ignore_msg_when_fee_estimation_fails() { + let mut broadcaster = MockBroadcaster::new(); + broadcaster + .expect_estimate_fee() + .return_once(|_| Err(Report::new(broadcaster::Error::FeeEstimation))); + + let queued_broadcaster = + QueuedBroadcaster::new(broadcaster, 100, 10, Duration::from_secs(5)); + let client = queued_broadcaster.client(); + let handle = tokio::spawn(queued_broadcaster.run()); + + assert!(matches!( + client + .broadcast(dummy_msg()) + .await + .unwrap_err() + .current_context(), + Error::EstimateFee + )); + drop(client); + + assert!(handle.await.unwrap().is_ok()); + } + #[test] async fn should_not_broadcast_when_gas_limit_has_not_been_reached() { let tx_count = 9; @@ -212,20 +241,21 @@ mod test { Ok(TxResponse::default()) }); - let (client, _driver) = QueuedBroadcaster::new( + let queued_broadcaster = QueuedBroadcaster::new( broadcaster, batch_gas_limit, tx_count, Duration::from_secs(5), ); + let client = queued_broadcaster.client(); + let handle = tokio::spawn(queued_broadcaster.run()); - let tx = client.client(); for _ in 0..tx_count { - tx.broadcast(dummy_msg()).await.unwrap(); + client.broadcast(dummy_msg()).await.unwrap(); } - drop(tx); + drop(client); - assert!(client.run().await.is_ok()); + assert!(handle.await.unwrap().is_ok()); } #[test] @@ -256,20 +286,18 @@ mod test { Ok(TxResponse::default()) }); - let (client, _driver) = + let queued_broadcaster = QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); - let tx = client.client(); - - let handler = tokio::spawn(async move { - assert!(client.run().await.is_ok()); - }); + let client = queued_broadcaster.client(); + let handle = tokio::spawn(queued_broadcaster.run()); for _ in 0..tx_count { - tx.broadcast(dummy_msg()).await.unwrap(); + client.broadcast(dummy_msg()).await.unwrap(); } sleep(broadcast_interval).await; + drop(client); - handler.abort(); + assert!(handle.await.unwrap().is_ok()); } #[test] @@ -307,69 +335,21 @@ mod test { Ok(TxResponse::default()) }); - let (client, _driver) = QueuedBroadcaster::new( + let queued_broadcaster = QueuedBroadcaster::new( broadcaster, batch_gas_limit, tx_count, Duration::from_secs(5), ); + let client = queued_broadcaster.client(); + let handle = tokio::spawn(queued_broadcaster.run()); - let tx = client.client(); for _ in 0..tx_count { - tx.broadcast(dummy_msg()).await.unwrap(); + client.broadcast(dummy_msg()).await.unwrap(); } - drop(tx); - - assert!(client.run().await.is_ok()); - } - - #[test] - async fn should_broadcast_when_forced_to() { - let tx_count = 10; - let batch_gas_limit = 100; - let gas_limit = 2; - - let mut broadcaster = MockBroadcaster::new(); - broadcaster - .expect_estimate_fee() - .times(tx_count) - .returning(move |_| { - Ok(Fee { - gas_limit, - amount: vec![], - granter: None, - payer: None, - }) - }); - broadcaster - .expect_broadcast() - .once() - .returning(move |msgs| { - assert!(msgs.len() == tx_count); - - Ok(TxResponse::default()) - }); - - let (client, driver) = QueuedBroadcaster::new( - broadcaster, - batch_gas_limit, - tx_count, - Duration::from_secs(5), - ); - - let tx = client.client(); - for _ in 0..tx_count { - tx.broadcast(dummy_msg()).await.unwrap(); - } - let handler = tokio::spawn(async move { - assert!(client.run().await.is_ok()); - }); - - sleep(Duration::from_millis(100)).await; - driver.force_broadcast().await.unwrap(); - drop(tx); + drop(client); - assert!(handler.await.is_ok()); + assert!(handle.await.unwrap().is_ok()); } fn dummy_msg() -> Any { From 5dfea6b867135b31777cbc15bf18febbda2d9e7c Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:50:14 -0400 Subject: [PATCH 020/168] feat(minor-multisig)!: better hashing for verifier sets (#457) * feat(minor-multisig)!: better hashing for verifier sets --- contracts/multisig/src/contract.rs | 4 +- contracts/multisig/src/migrations/mod.rs | 2 +- contracts/multisig/src/migrations/v_0_3.rs | 62 -------------- contracts/multisig/src/migrations/v_0_4.rs | 99 ++++++++++++++++++++++ contracts/multisig/src/verifier_set.rs | 15 +++- 5 files changed, 114 insertions(+), 68 deletions(-) delete mode 100644 contracts/multisig/src/migrations/v_0_3.rs create mode 100644 contracts/multisig/src/migrations/v_0_4.rs diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 7bcc5b0be..cfacf785a 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -24,13 +24,13 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( - deps: DepsMut, + mut deps: DepsMut, _env: Env, _msg: Empty, ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_3::migrate_verifier_sets(deps) + migrations::v_0_4::migrate(&mut deps) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/multisig/src/migrations/mod.rs b/contracts/multisig/src/migrations/mod.rs index 194e2b5c7..683e59145 100644 --- a/contracts/multisig/src/migrations/mod.rs +++ b/contracts/multisig/src/migrations/mod.rs @@ -1 +1 @@ -pub mod v_0_3; +pub mod v_0_4; diff --git a/contracts/multisig/src/migrations/v_0_3.rs b/contracts/multisig/src/migrations/v_0_3.rs deleted file mode 100644 index d820eeb51..000000000 --- a/contracts/multisig/src/migrations/v_0_3.rs +++ /dev/null @@ -1,62 +0,0 @@ -use crate::{state::VERIFIER_SETS, verifier_set::VerifierSet}; -use cosmwasm_std::{DepsMut, Order, Response}; -use cw_storage_plus::Map; - -type VerifierSetId = str; -pub const WORKER_SETS: Map<&VerifierSetId, VerifierSet> = Map::new("worker_sets"); - -pub fn migrate_verifier_sets(deps: DepsMut) -> Result { - let all: Vec<_> = WORKER_SETS - .range(deps.storage, None, None, Order::Ascending) - .collect::, _>>()?; - - for v in all { - VERIFIER_SETS.save(deps.storage, &v.0, &v.1)?; - WORKER_SETS.remove(deps.storage, &v.0); - } - - Ok(Response::default()) -} - -#[cfg(test)] -mod test { - use crate::{ - migrations::v_0_3::WORKER_SETS, - state::VERIFIER_SETS, - test::common::{build_verifier_set, ecdsa_test_data::signers}, - }; - - use cosmwasm_std::testing::mock_dependencies; - - use super::migrate_verifier_sets; - - #[test] - fn should_be_able_to_migrate_worker_set_to_verifier_set() { - let mut deps = mock_dependencies(); - let signers = signers(); - let mut worker_sets = vec![]; - let worker_set = build_verifier_set(crate::key::KeyType::Ecdsa, &signers); - WORKER_SETS - .save(&mut deps.storage, &worker_set.id(), &worker_set) - .unwrap(); - worker_sets.push(worker_set); - for s in signers { - let new_signers = vec![s]; - let worker_set = build_verifier_set(crate::key::KeyType::Ecdsa, &new_signers); - WORKER_SETS - .save(&mut deps.storage, &worker_set.id(), &worker_set) - .unwrap(); - worker_sets.push(worker_set); - } - let res = migrate_verifier_sets(deps.as_mut()); - assert!(res.is_ok()); - for worker_set in worker_sets { - let res = VERIFIER_SETS.load(&deps.storage, &worker_set.id()).unwrap(); - assert_eq!(res, worker_set); - assert!(WORKER_SETS - .may_load(&deps.storage, &worker_set.id()) - .unwrap() - .is_none()) - } - } -} diff --git a/contracts/multisig/src/migrations/v_0_4.rs b/contracts/multisig/src/migrations/v_0_4.rs new file mode 100644 index 000000000..1dcd7d038 --- /dev/null +++ b/contracts/multisig/src/migrations/v_0_4.rs @@ -0,0 +1,99 @@ +use crate::{ + signing::SigningSession, + state::{SIGNING_SESSIONS, VERIFIER_SETS}, +}; +use cosmwasm_std::{DepsMut, Order, Response}; + +pub fn migrate_verifier_set_ids( + deps: &mut DepsMut, +) -> Result { + let all: Vec<_> = VERIFIER_SETS + .range(deps.storage, None, None, Order::Ascending) + .collect::, _>>()?; + + for v in all { + VERIFIER_SETS.remove(deps.storage, &v.0); + VERIFIER_SETS.save(deps.storage, &v.1.id(), &v.1)?; + } + + Ok(Response::default()) +} + +pub fn migrate_signing_sessions( + deps: &mut DepsMut, +) -> Result { + let all: Vec<_> = SIGNING_SESSIONS + .range(deps.storage, None, None, Order::Ascending) + .collect::, _>>()?; + + for (session_id, session) in all { + let verifier_set = VERIFIER_SETS.load(deps.storage, &session.verifier_set_id)?; + let new_session = SigningSession { + verifier_set_id: verifier_set.id(), + ..session + }; + SIGNING_SESSIONS.save(deps.storage, session_id, &new_session)?; + } + + Ok(Response::default()) +} + +pub fn migrate(deps: &mut DepsMut) -> Result { + // signing sessions should be migrated first, so that way the old ids still point to the verifier sets + migrate_signing_sessions(deps)?; + migrate_verifier_set_ids(deps) +} + +#[cfg(test)] +mod test { + use crate::{ + signing::SigningSession, + state::{SIGNING_SESSIONS, VERIFIER_SETS}, + test::common::{build_verifier_set, ecdsa_test_data::signers}, + }; + + use cosmwasm_std::{testing::mock_dependencies, HexBinary, Uint64}; + + use super::migrate; + + #[test] + fn should_be_able_to_migrate_verifier_set_ids() { + let mut deps = mock_dependencies(); + let signers = signers(); + let verifier_set = build_verifier_set(crate::key::KeyType::Ecdsa, &signers); + VERIFIER_SETS + .save(&mut deps.storage, "foobar", &verifier_set) + .unwrap(); + let signing_session = SigningSession { + id: Uint64::one(), + verifier_set_id: "foobar".to_string(), + chain_name: "ethereum".parse().unwrap(), + msg: HexBinary::from([2; 32]).try_into().unwrap(), + state: crate::types::MultisigState::Pending, + expires_at: 100, + sig_verifier: None, + }; + SIGNING_SESSIONS + .save( + &mut deps.storage, + signing_session.id.u64(), + &signing_session, + ) + .unwrap(); + migrate(&mut deps.as_mut()).unwrap(); + + let new_verifier_set = VERIFIER_SETS + .load(&deps.storage, &verifier_set.id()) + .unwrap(); + assert_eq!(new_verifier_set, verifier_set); + + let expected_signing_session = SigningSession { + verifier_set_id: verifier_set.id(), + ..signing_session + }; + let new_signing_session = SIGNING_SESSIONS + .load(&deps.storage, expected_signing_session.id.u64()) + .unwrap(); + assert_eq!(new_signing_session, expected_signing_session); + } +} diff --git a/contracts/multisig/src/verifier_set.rs b/contracts/multisig/src/verifier_set.rs index 941354686..07781673c 100644 --- a/contracts/multisig/src/verifier_set.rs +++ b/contracts/multisig/src/verifier_set.rs @@ -44,9 +44,18 @@ impl VerifierSet { } pub fn hash(&self) -> HexBinary { - Keccak256::digest(serde_json::to_vec(&self).expect("couldn't serialize verifier set")) - .as_slice() - .into() + let mut hasher = Keccak256::new(); + + self.signers.values().for_each(|signer| { + hasher.update(signer.address.as_bytes()); + hasher.update(signer.pub_key.as_ref()); + hasher.update(signer.weight.to_be_bytes()); + }); + + hasher.update(self.threshold.to_be_bytes()); + hasher.update(self.created_at.to_be_bytes()); + + hasher.finalize().as_slice().into() } pub fn id(&self) -> String { From c1290ff4388a3301a571edbd8e7c2a3ac5f9f642 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 18 Jun 2024 18:15:05 -0400 Subject: [PATCH 021/168] refactor: improve handling of verifier set hash (#462) --- contracts/multisig-prover/src/events.rs | 2 +- contracts/multisig-prover/src/execute.rs | 2 +- contracts/multisig-prover/src/payload.rs | 18 ++++++------------ contracts/multisig/src/verifier_set.rs | 7 ++++--- contracts/voting-verifier/src/execute.rs | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/contracts/multisig-prover/src/events.rs b/contracts/multisig-prover/src/events.rs index 7f17e4a11..63ce89efd 100644 --- a/contracts/multisig-prover/src/events.rs +++ b/contracts/multisig-prover/src/events.rs @@ -65,7 +65,7 @@ mod tests { let event = Event::ProofUnderConstruction { destination_chain: "avalanche".parse().unwrap(), - payload_id: (&msg_ids).into(), + payload_id: msg_ids.as_slice().into(), multisig_session_id: Uint64::new(2), msg_ids, }; diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index e2061fb27..b7b98f67d 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -38,7 +38,7 @@ pub fn construct_proof( message_ids: Vec, ) -> error_stack::Result { let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; - let payload_id = (&message_ids).into(); + let payload_id = message_ids.as_slice().into(); let messages = get_messages( deps.querier, diff --git a/contracts/multisig-prover/src/payload.rs b/contracts/multisig-prover/src/payload.rs index 905c95ac1..db53b665b 100644 --- a/contracts/multisig-prover/src/payload.rs +++ b/contracts/multisig-prover/src/payload.rs @@ -32,9 +32,9 @@ impl Payload { .map(|msg| msg.cc_id.clone()) .collect::>(); - (&message_ids).into() + message_ids.as_slice().into() } - Payload::VerifierSet(verifier_set) => verifier_set.hash().into(), + Payload::VerifierSet(verifier_set) => verifier_set.hash().as_slice().into(), } } @@ -79,12 +79,6 @@ impl Payload { #[cw_serde] pub struct PayloadId(HexBinary); -impl From for PayloadId { - fn from(id: HexBinary) -> Self { - Self(id) - } -} - impl From<&[u8]> for PayloadId { fn from(id: &[u8]) -> Self { Self(id.into()) @@ -110,8 +104,8 @@ impl KeyDeserialize for PayloadId { } } -impl From<&Vec> for PayloadId { - fn from(ids: &Vec) -> Self { +impl From<&[CrossChainId]> for PayloadId { + fn from(ids: &[CrossChainId]) -> Self { let mut message_ids = ids.iter().map(|id| id.to_string()).collect::>(); message_ids.sort(); @@ -131,10 +125,10 @@ mod test { let mut message_ids: Vec = messages.into_iter().map(|msg| msg.cc_id).collect(); - let res: PayloadId = (&message_ids).into(); + let res: PayloadId = message_ids.as_slice().into(); message_ids.reverse(); - let res2: PayloadId = (&message_ids).into(); + let res2: PayloadId = message_ids.as_slice().into(); assert_eq!(res, res2); } diff --git a/contracts/multisig/src/verifier_set.rs b/contracts/multisig/src/verifier_set.rs index 07781673c..bde7c84af 100644 --- a/contracts/multisig/src/verifier_set.rs +++ b/contracts/multisig/src/verifier_set.rs @@ -1,6 +1,7 @@ use std::collections::{BTreeMap, HashMap}; use crate::{key::PublicKey, msg::Signer}; +use axelar_wasm_std::hash::Hash; use axelar_wasm_std::Participant; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Uint128}; @@ -43,7 +44,7 @@ impl VerifierSet { } } - pub fn hash(&self) -> HexBinary { + pub fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); self.signers.values().for_each(|signer| { @@ -55,11 +56,11 @@ impl VerifierSet { hasher.update(self.threshold.to_be_bytes()); hasher.update(self.created_at.to_be_bytes()); - hasher.finalize().as_slice().into() + hasher.finalize().into() } pub fn id(&self) -> String { - self.hash().to_hex() + HexBinary::from(self.hash()).to_hex() } pub fn get_pub_keys(&self) -> HashMap { diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 6e5e5e90f..a3458cd3f 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -65,7 +65,7 @@ pub fn verify_verifier_set( poll_verifier_sets().save( deps.storage, - &new_verifier_set.hash().as_slice().try_into().unwrap(), + &new_verifier_set.hash(), &PollContent::::new(new_verifier_set.clone(), poll_id), )?; From 1274b047ee7ee76f90361b5a31c08236f6702385 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Tue, 18 Jun 2024 18:48:09 -0400 Subject: [PATCH 022/168] fix(minor-multisig-prover): filter out signers without pubkey (#450) * fix(minor-multisig-prover): rotate signer filter out verifiers without pubkey * rename function * remove verifier info struct --- contracts/multisig-prover/src/error.rs | 3 + contracts/multisig-prover/src/execute.rs | 87 +++++----- contracts/multisig-prover/src/lib.rs | 1 - .../multisig-prover/src/test/test_utils.rs | 60 ++++--- contracts/multisig-prover/src/types.rs | 7 - integration-tests/tests/test_utils/mod.rs | 156 +++++++++--------- integration-tests/tests/update_worker_set.rs | 77 ++++++++- 7 files changed, 248 insertions(+), 143 deletions(-) delete mode 100644 contracts/multisig-prover/src/types.rs diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index 142ecb03f..5d070a80b 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -62,4 +62,7 @@ pub enum ContractError { #[error("invalid verifier set")] InvalidVerifierSet, + + #[error("not enough verifiers")] + NotEnoughVerifiers, } diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index b7b98f67d..25f4c528d 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -6,17 +6,19 @@ use cosmwasm_std::{ }; use itertools::Itertools; -use axelar_wasm_std::{snapshot, FnExt, MajorityThreshold, VerificationStatus}; -use multisig::{key::PublicKey, msg::Signer, verifier_set::VerifierSet}; +use axelar_wasm_std::{ + snapshot::{Participant, Snapshot}, + FnExt, MajorityThreshold, VerificationStatus, +}; +use multisig::{msg::Signer, verifier_set::VerifierSet}; use router_api::{ChainName, CrossChainId, Message}; -use service_registry::state::WeightedVerifier; +use service_registry::state::{Service, WeightedVerifier}; use crate::{ contract::START_MULTISIG_REPLY_ID, error::ContractError, payload::Payload, state::{Config, CONFIG, CURRENT_VERIFIER_SET, NEXT_VERIFIER_SET, PAYLOAD, REPLY_TRACKER}, - types::VerifiersInfo, }; pub fn require_admin(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { @@ -117,7 +119,11 @@ fn get_messages( Ok(messages) } -fn get_verifiers_info(deps: &DepsMut, config: &Config) -> Result { +fn make_verifier_set( + deps: &DepsMut, + env: &Env, + config: &Config, +) -> Result { let active_verifiers_query = service_registry::msg::QueryMsg::GetActiveVerifiers { service_name: config.service_name.clone(), chain_name: config.chain_name.clone(), @@ -129,43 +135,50 @@ fn get_verifiers_info(deps: &DepsMut, config: &Config) -> Result(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: config.service_registry.to_string(), + msg: to_json_binary(&service_registry::msg::QueryMsg::GetService { + service_name: config.service_name.clone(), + })?, + }))? + .min_num_verifiers; + + let participants_with_pubkeys = verifiers .into_iter() - .map(WeightedVerifier::into) - .collect::>(); - - let snapshot = - snapshot::Snapshot::new(config.signing_threshold, participants.clone().try_into()?); - - let mut pub_keys = vec![]; - for participant in &participants { - let pub_key_query = multisig::msg::QueryMsg::GetPublicKey { - verifier_address: participant.address.to_string(), - key_type: config.key_type, - }; - let pub_key: PublicKey = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: config.multisig.to_string(), - msg: to_json_binary(&pub_key_query)?, - }))?; - pub_keys.push(pub_key); + .filter_map(|verifier| { + let pub_key_query = multisig::msg::QueryMsg::GetPublicKey { + verifier_address: verifier.verifier_info.address.to_string(), + key_type: config.key_type, + }; + + match deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: config.multisig.to_string(), + msg: to_json_binary(&pub_key_query).ok()?, + })) { + Ok(pub_key) => Some((Participant::from(verifier), pub_key)), + Err(_) => None, + } + }) + .collect::>(); + + if participants_with_pubkeys.len() < min_num_verifiers as usize { + return Err(ContractError::NotEnoughVerifiers); } - Ok(VerifiersInfo { - snapshot, - pubkeys_by_participant: participants.into_iter().zip(pub_keys).collect(), - }) -} + let snapshot = Snapshot::new( + config.signing_threshold, + participants_with_pubkeys + .iter() + .map(|(participant, _)| participant.clone()) + .collect::>() + .try_into()?, + ); -fn make_verifier_set( - deps: &DepsMut, - env: &Env, - config: &Config, -) -> Result { - let verifiers_info = get_verifiers_info(deps, config)?; Ok(VerifierSet::new( - verifiers_info.pubkeys_by_participant, - verifiers_info.snapshot.quorum.into(), + participants_with_pubkeys, + snapshot.quorum.into(), env.block.height, )) } diff --git a/contracts/multisig-prover/src/lib.rs b/contracts/multisig-prover/src/lib.rs index 4ccc635dd..a46181e07 100644 --- a/contracts/multisig-prover/src/lib.rs +++ b/contracts/multisig-prover/src/lib.rs @@ -9,7 +9,6 @@ pub mod payload; mod query; mod reply; pub mod state; -pub mod types; #[cfg(test)] mod test; diff --git a/contracts/multisig-prover/src/test/test_utils.rs b/contracts/multisig-prover/src/test/test_utils.rs index 2032984ee..9e3dec6ed 100644 --- a/contracts/multisig-prover/src/test/test_utils.rs +++ b/contracts/multisig-prover/src/test/test_utils.rs @@ -1,5 +1,5 @@ use axelar_wasm_std::VerificationStatus; -use cosmwasm_std::{from_json, to_json_binary, QuerierResult, WasmQuery}; +use cosmwasm_std::{from_json, to_json_binary, Addr, QuerierResult, Uint128, WasmQuery}; use multisig::{msg::Signer, multisig::Multisig, types::MultisigState, verifier_set::VerifierSet}; use service_registry::state::{ AuthorizationState, BondingState, Verifier, WeightedVerifier, VERIFIER_WEIGHT, @@ -27,8 +27,8 @@ pub fn mock_querier_handler( WasmQuery::Smart { contract_addr, msg } if contract_addr == MULTISIG_ADDRESS => { multisig_mock_querier_handler(from_json(msg).unwrap(), operators.clone()) } - WasmQuery::Smart { contract_addr, .. } if contract_addr == SERVICE_REGISTRY_ADDRESS => { - service_registry_mock_querier_handler(operators.clone()) + WasmQuery::Smart { contract_addr, msg } if contract_addr == SERVICE_REGISTRY_ADDRESS => { + service_registry_mock_querier_handler(from_json(msg).unwrap(), operators.clone()) } WasmQuery::Smart { contract_addr, .. } if contract_addr == VOTING_VERIFIER_ADDRESS => { voting_verifier_mock_querier_handler(verifier_set_status) @@ -109,24 +109,44 @@ fn mock_get_multisig(operators: Vec) -> Multisig { } } -fn service_registry_mock_querier_handler(operators: Vec) -> QuerierResult { - Ok(to_json_binary( - &operators - .clone() - .into_iter() - .map(|op| WeightedVerifier { - verifier_info: Verifier { - address: op.address, - bonding_state: BondingState::Bonded { amount: op.weight }, - authorization_state: AuthorizationState::Authorized, - service_name: SERVICE_NAME.to_string(), - }, - weight: VERIFIER_WEIGHT, +fn service_registry_mock_querier_handler( + msg: service_registry::msg::QueryMsg, + operators: Vec, +) -> QuerierResult { + let result = match msg { + service_registry::msg::QueryMsg::GetService { service_name } => { + to_json_binary(&service_registry::state::Service { + name: service_name.to_string(), + coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), + min_num_verifiers: 1, + max_num_verifiers: Some(100), + min_verifier_bond: Uint128::new(1), + bond_denom: "uaxl".to_string(), + unbonding_period_days: 1, + description: "verifiers".to_string(), }) - .collect::>(), - ) - .into()) - .into() + } + service_registry::msg::QueryMsg::GetActiveVerifiers { + service_name: _, + chain_name: _, + } => to_json_binary( + &operators + .clone() + .into_iter() + .map(|op| WeightedVerifier { + verifier_info: Verifier { + address: op.address, + bonding_state: BondingState::Bonded { amount: op.weight }, + authorization_state: AuthorizationState::Authorized, + service_name: SERVICE_NAME.to_string(), + }, + weight: VERIFIER_WEIGHT, + }) + .collect::>(), + ), + _ => panic!("unexpected query: {:?}", msg), + }; + Ok(result.into()).into() } fn voting_verifier_mock_querier_handler(status: VerificationStatus) -> QuerierResult { diff --git a/contracts/multisig-prover/src/types.rs b/contracts/multisig-prover/src/types.rs deleted file mode 100644 index 25e1b56c3..000000000 --- a/contracts/multisig-prover/src/types.rs +++ /dev/null @@ -1,7 +0,0 @@ -use axelar_wasm_std::{Participant, Snapshot}; -use multisig::key::PublicKey; - -pub struct VerifiersInfo { - pub snapshot: Snapshot, - pub pubkeys_by_participant: Vec<(Participant, PublicKey)>, -} diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 71d69f31b..b1fc58884 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -435,68 +435,8 @@ pub fn register_verifiers( verifiers: &Vec, min_verifier_bond: Uint128, ) { - let response = protocol.service_registry.execute( - &mut protocol.app, - protocol.governance_address.clone(), - &ExecuteMsg::AuthorizeVerifiers { - verifiers: verifiers - .iter() - .map(|verifier| verifier.addr.to_string()) - .collect(), - service_name: protocol.service_name.to_string(), - }, - ); - assert!(response.is_ok()); - - for verifier in verifiers { - let response = protocol.app.send_tokens( - protocol.genesis_address.clone(), - verifier.addr.clone(), - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), - ); - assert!(response.is_ok()); - - let response = protocol.service_registry.execute_with_funds( - &mut protocol.app, - verifier.addr.clone(), - &ExecuteMsg::BondVerifier { - service_name: protocol.service_name.to_string(), - }, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), - ); - assert!(response.is_ok()); - - let response = protocol.service_registry.execute( - &mut protocol.app, - verifier.addr.clone(), - &ExecuteMsg::RegisterChainSupport { - service_name: protocol.service_name.to_string(), - chains: verifier.supported_chains.clone(), - }, - ); - assert!(response.is_ok()); - - let address_hash = Keccak256::digest(verifier.addr.as_bytes()); - - let sig = tofn::ecdsa::sign( - verifier.key_pair.signing_key(), - &address_hash.as_slice().try_into().unwrap(), - ) - .unwrap(); - let sig = ecdsa::Signature::from_der(&sig).unwrap(); - - let response = protocol.multisig.execute( - &mut protocol.app, - verifier.addr.clone(), - &multisig::msg::ExecuteMsg::RegisterPublicKey { - public_key: PublicKey::Ecdsa(HexBinary::from( - verifier.key_pair.encoded_verifying_key(), - )), - signed_sender_address: HexBinary::from(sig.to_vec()), - }, - ); - assert!(response.is_ok()); - } + register_in_service_registry(protocol, verifiers, min_verifier_bond); + submit_pubkeys(protocol, verifiers); } pub fn deregister_verifiers(protocol: &mut Protocol, verifiers: &Vec) { @@ -715,7 +655,7 @@ pub fn setup_chain( let voting_verifier = VotingVerifierContract::instantiate_contract( protocol, "doesn't matter".to_string().try_into().unwrap(), - Threshold::try_from((9, 10)).unwrap().try_into().unwrap(), + Threshold::try_from((3, 4)).unwrap().try_into().unwrap(), chain_name.clone(), ); @@ -895,18 +835,11 @@ pub fn setup_test_case() -> TestCase { "Ethereum".to_string().try_into().unwrap(), "Polygon".to_string().try_into().unwrap(), ]; - let verifiers = vec![ - Verifier { - addr: Addr::unchecked("verifier1"), - supported_chains: chains.clone(), - key_pair: generate_key(0), - }, - Verifier { - addr: Addr::unchecked("verifier2"), - supported_chains: chains.clone(), - key_pair: generate_key(1), - }, - ]; + let verifiers = create_new_verifiers_vec( + chains.clone(), + vec![("verifier1".to_string(), 0), ("verifier2".to_string(), 1)], + ); + let min_verifier_bond = Uint128::new(100); let unbonding_period_days = 10; register_service(&mut protocol, min_verifier_bond, unbonding_period_days); @@ -930,3 +863,76 @@ pub fn assert_contract_err_strings_equal( ) { assert_eq!(actual.into().to_string(), expected.into().to_string()); } + +pub fn register_in_service_registry( + protocol: &mut Protocol, + verifiers: &Vec, + min_verifier_bond: Uint128, +) { + let response = protocol.service_registry.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &ExecuteMsg::AuthorizeVerifiers { + verifiers: verifiers + .iter() + .map(|verifier| verifier.addr.to_string()) + .collect(), + service_name: protocol.service_name.to_string(), + }, + ); + assert!(response.is_ok()); + + for verifier in verifiers { + let response = protocol.app.send_tokens( + protocol.genesis_address.clone(), + verifier.addr.clone(), + &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + ); + assert!(response.is_ok()); + + let response = protocol.service_registry.execute_with_funds( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::BondVerifier { + service_name: protocol.service_name.to_string(), + }, + &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + ); + assert!(response.is_ok()); + + let response = protocol.service_registry.execute( + &mut protocol.app, + verifier.addr.clone(), + &ExecuteMsg::RegisterChainSupport { + service_name: protocol.service_name.to_string(), + chains: verifier.supported_chains.clone(), + }, + ); + assert!(response.is_ok()); + } +} + +pub fn submit_pubkeys(protocol: &mut Protocol, verifiers: &Vec) { + for verifier in verifiers { + let address_hash = Keccak256::digest(verifier.addr.as_bytes()); + + let sig = tofn::ecdsa::sign( + verifier.key_pair.signing_key(), + &address_hash.as_slice().try_into().unwrap(), + ) + .unwrap(); + let sig = ecdsa::Signature::from_der(&sig).unwrap(); + + let response = protocol.multisig.execute( + &mut protocol.app, + verifier.addr.clone(), + &multisig::msg::ExecuteMsg::RegisterPublicKey { + public_key: PublicKey::Ecdsa(HexBinary::from( + verifier.key_pair.encoded_verifying_key(), + )), + signed_sender_address: HexBinary::from(sig.to_vec()), + }, + ); + assert!(response.is_ok()); + } +} diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index 67ab77d74..33495385f 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -3,9 +3,11 @@ use cw_multi_test::Executor; use integration_tests::contract::Contract; use multisig_prover::msg::ExecuteMsg; -use test_utils::Verifier; - -use crate::test_utils::get_multisig_session_id; +use service_registry::{msg::QueryMsg as ServiceRegistryQueryMsg, state::WeightedVerifier}; +use test_utils::{ + create_new_verifiers_vec, get_multisig_session_id, register_in_service_registry, + register_verifiers, rotate_active_verifier_set, Verifier, +}; pub mod test_utils; @@ -369,3 +371,72 @@ fn governance_should_confirm_new_verifier_set_without_verification() { assert_eq!(new_verifier_set, expected_new_verifier_set); } + +#[test] +fn rotate_signers_should_filter_out_signers_without_pubkey() { + let test_utils::TestCase { + mut protocol, + chain1, + verifiers: initial_verifiers, + min_verifier_bond, + .. + } = test_utils::setup_test_case(); + + let chains: Vec = vec![chain1.chain_name.clone()]; + + // add a third verifier to satisfy min verifier change threshold + register_verifiers( + &mut protocol, + &create_new_verifiers_vec(chains.clone(), vec![("verifier3".to_string(), 2)]), + min_verifier_bond, + ); + + // add a fourth verifier in service registry but does not submit a pubkey to multisig + register_in_service_registry( + &mut protocol, + &create_new_verifiers_vec(chains.clone(), vec![("verifier4".to_string(), 3)]), + min_verifier_bond, + ); + + // the fourth verifier should be filtered out in prover because it does not have a pubkey + let expect_new_verifiers = create_new_verifiers_vec( + chains.clone(), + vec![ + ("verifier1".to_string(), 0), + ("verifier2".to_string(), 1), + ("verifier3".to_string(), 2), + ], + ); + let expected_verifier_set = + test_utils::verifiers_to_verifier_set(&mut protocol, &expect_new_verifiers); + + // should get initial + 2 active verifiers from service registry + let active_verifiers: Vec = protocol + .service_registry + .query( + &protocol.app, + &ServiceRegistryQueryMsg::GetActiveVerifiers { + service_name: protocol.service_name.to_string(), + chain_name: chains[0].clone(), + }, + ) + .unwrap(); + + assert_eq!( + active_verifiers.len(), + initial_verifiers.len().checked_add(2).unwrap() + ); + + // rotate signers + rotate_active_verifier_set( + &mut protocol, + chain1.clone(), + &initial_verifiers, + &expect_new_verifiers, + ); + + let verifier_set = + test_utils::get_verifier_set_from_prover(&mut protocol.app, &chain1.multisig_prover); + + assert_eq!(verifier_set, expected_verifier_set); +} From 8d7f817e6eaddd654e9617939588aa518e28880c Mon Sep 17 00:00:00 2001 From: eguajardo Date: Tue, 18 Jun 2024 17:08:10 -0600 Subject: [PATCH 023/168] feat(multisig-prover)!: add verifier set id to `GetVerifierSet` query (#455) * add verifier set id to query * add response struct --- contracts/multisig-prover/src/contract.rs | 31 ++++++++++++++++------- contracts/multisig-prover/src/msg.rs | 21 +++++++++++++-- contracts/multisig-prover/src/query.rs | 18 ++++++++----- integration-tests/tests/test_utils/mod.rs | 5 ++-- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index d40a098e2..314d4c764 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -154,6 +154,7 @@ mod tests { use crate::{ contract::execute::should_update_verifier_set, + msg::VerifierSetResponse, test::test_utils::{ mock_querier_handler, ADMIN, COORDINATOR_ADDRESS, GATEWAY_ADDRESS, GOVERNANCE, MULTISIG_ADDRESS, SERVICE_NAME, SERVICE_REGISTRY_ADDRESS, VOTING_VERIFIER_ADDRESS, @@ -299,7 +300,7 @@ mod tests { fn query_get_verifier_set( deps: Deps, - ) -> Result, axelar_wasm_std::ContractError> { + ) -> Result, axelar_wasm_std::ContractError> { query(deps, mock_env(), QueryMsg::CurrentVerifierSet {}).map(|res| from_json(res).unwrap()) } @@ -405,7 +406,7 @@ mod tests { let expected_verifier_set = test_operators_to_verifier_set(test_data::operators(), mock_env().block.height); - assert_eq!(verifier_set, expected_verifier_set); + assert_eq!(verifier_set, expected_verifier_set.into()); } #[test] @@ -475,7 +476,7 @@ mod tests { let expected_verifier_set = test_operators_to_verifier_set(test_data::operators(), mock_env().block.height); - assert_eq!(verifier_set, expected_verifier_set); + assert_eq!(verifier_set, expected_verifier_set.into()); } #[test] @@ -509,7 +510,7 @@ mod tests { let expected_verifier_set = test_operators_to_verifier_set(new_verifier_set, mock_env().block.height); - assert_eq!(verifier_set, expected_verifier_set); + assert_eq!(verifier_set, expected_verifier_set.into()); } #[test] @@ -543,7 +544,7 @@ mod tests { let expected_verifier_set = test_operators_to_verifier_set(test_data::operators(), mock_env().block.height); - assert_eq!(verifier_set, expected_verifier_set); + assert_eq!(verifier_set, expected_verifier_set.into()); } #[test] @@ -700,7 +701,10 @@ mod tests { /// Calls update_signing_threshold, increasing the threshold by one. /// Returns (initial threshold, new threshold) fn update_signing_threshold_increase_by_one(deps: DepsMut) -> (Uint128, Uint128) { - let verifier_set = query_get_verifier_set(deps.as_ref()).unwrap().unwrap(); + let verifier_set = query_get_verifier_set(deps.as_ref()) + .unwrap() + .unwrap() + .verifier_set; let initial_threshold = verifier_set.threshold; let total_weight = verifier_set .signers @@ -735,7 +739,10 @@ mod tests { update_signing_threshold_increase_by_one(deps.as_mut()); assert_ne!(initial_threshold, new_threshold); - let verifier_set = query_get_verifier_set(deps.as_ref()).unwrap().unwrap(); + let verifier_set = query_get_verifier_set(deps.as_ref()) + .unwrap() + .unwrap() + .verifier_set; assert_eq!(verifier_set.threshold, initial_threshold); } @@ -753,7 +760,10 @@ mod tests { let governance = Addr::unchecked(GOVERNANCE); confirm_verifier_set(deps.as_mut(), governance).unwrap(); - let verifier_set = query_get_verifier_set(deps.as_ref()).unwrap().unwrap(); + let verifier_set = query_get_verifier_set(deps.as_ref()) + .unwrap() + .unwrap() + .verifier_set; assert_eq!(verifier_set.threshold, new_threshold); } @@ -771,7 +781,10 @@ mod tests { let res = confirm_verifier_set(deps.as_mut(), Addr::unchecked("relayer")); assert!(res.is_ok()); - let verifier_set = query_get_verifier_set(deps.as_ref()).unwrap().unwrap(); + let verifier_set = query_get_verifier_set(deps.as_ref()) + .unwrap() + .unwrap() + .verifier_set; assert_eq!(verifier_set.threshold, new_threshold); } diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index 26f7ea992..4aa108c84 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -80,10 +80,12 @@ pub enum QueryMsg { #[returns(GetProofResponse)] GetProof { multisig_session_id: Uint64 }, - #[returns(Option)] + /// Returns a `VerifierSetResponse` with the current verifier set id and the verifier set itself. + #[returns(Option)] CurrentVerifierSet, - #[returns(Option)] + /// Returns a `VerifierSetResponse` with the next verifier set id and the verifier set itself. + #[returns(Option)] NextVerifierSet, } @@ -100,3 +102,18 @@ pub struct GetProofResponse { pub payload: Payload, pub status: ProofStatus, } + +#[cw_serde] +pub struct VerifierSetResponse { + pub id: String, + pub verifier_set: multisig::verifier_set::VerifierSet, +} + +impl From for VerifierSetResponse { + fn from(set: multisig::verifier_set::VerifierSet) -> Self { + VerifierSetResponse { + id: set.id(), + verifier_set: set, + } + } +} diff --git a/contracts/multisig-prover/src/query.rs b/contracts/multisig-prover/src/query.rs index d7723bf55..d6b2cfc4f 100644 --- a/contracts/multisig-prover/src/query.rs +++ b/contracts/multisig-prover/src/query.rs @@ -1,11 +1,11 @@ use cosmwasm_std::{to_json_binary, Deps, QueryRequest, StdResult, Uint64, WasmQuery}; use error_stack::Result; -use multisig::{multisig::Multisig, types::MultisigState, verifier_set::VerifierSet}; +use multisig::{multisig::Multisig, types::MultisigState}; use crate::{ error::ContractError, - msg::{GetProofResponse, ProofStatus}, + msg::{GetProofResponse, ProofStatus, VerifierSetResponse}, state::{CONFIG, CURRENT_VERIFIER_SET, MULTISIG_SESSION_PAYLOAD, NEXT_VERIFIER_SET, PAYLOAD}, }; @@ -57,12 +57,16 @@ pub fn get_proof( }) } -pub fn current_verifier_set(deps: Deps) -> StdResult> { - CURRENT_VERIFIER_SET.may_load(deps.storage) +pub fn current_verifier_set(deps: Deps) -> StdResult> { + CURRENT_VERIFIER_SET + .may_load(deps.storage) + .map(|op| op.map(|set| set.into())) } -pub fn next_verifier_set(deps: Deps) -> StdResult> { - NEXT_VERIFIER_SET.may_load(deps.storage) +pub fn next_verifier_set(deps: Deps) -> StdResult> { + NEXT_VERIFIER_SET + .may_load(deps.storage) + .map(|op| op.map(|set| set.into())) } #[cfg(test)] @@ -82,7 +86,7 @@ mod test { .unwrap(); assert_eq!( - Some(new_verifier_set()), + Some(new_verifier_set().into()), super::next_verifier_set(deps.as_ref()).unwrap() ); } diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index b1fc58884..6ddc30523 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -8,6 +8,7 @@ use cosmwasm_std::{ coins, Addr, Attribute, BlockInfo, Event, HexBinary, StdError, Uint128, Uint64, }; use cw_multi_test::{App, AppResponse, Executor}; +use multisig_prover::msg::VerifierSetResponse; use router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; use std::collections::HashSet; @@ -315,11 +316,11 @@ pub fn get_verifier_set_from_prover( app: &mut App, multisig_prover_contract: &MultisigProverContract, ) -> VerifierSet { - let query_response: Result = + let query_response: Result, StdError> = multisig_prover_contract.query(app, &multisig_prover::msg::QueryMsg::CurrentVerifierSet); assert!(query_response.is_ok()); - query_response.unwrap() + query_response.unwrap().unwrap().verifier_set } #[allow(clippy::arithmetic_side_effects)] From 24d96ab282f33a03c7ecb1f3170f5d74c8fd64a2 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Wed, 19 Jun 2024 11:57:41 -0400 Subject: [PATCH 024/168] docs: contract messages access levels (#461) * doc: add message_access.md and update SUMMARY.md * refactor: apply PR changes to message_access.md and SUMMARY.md * refactor: remove bullet point from single item headers of SUMMARY.md --- doc/src/SUMMARY.md | 6 +- doc/src/message_access.md | 134 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 doc/src/message_access.md diff --git a/doc/src/SUMMARY.md b/doc/src/SUMMARY.md index 4799b6ae3..1f3cfc509 100644 --- a/doc/src/SUMMARY.md +++ b/doc/src/SUMMARY.md @@ -13,6 +13,10 @@ - [Rewards](contracts/rewards.md) - [Coordinator](contracts/coordinator.md) +## Message Access Requirements + +[Amplifier Access Control](message_access.md) + # Contributing -- [Documentation](contributing/documentation.md) +[Documentation](contributing/documentation.md) \ No newline at end of file diff --git a/doc/src/message_access.md b/doc/src/message_access.md new file mode 100644 index 000000000..71eb26691 --- /dev/null +++ b/doc/src/message_access.md @@ -0,0 +1,134 @@ +# Access Control for Contract Messages +This module provides access control for contract execute messages. An execute message can be called by: +- Anyone +- Only by governance +- Only by the contract admin +- Either governance or the contract admin + +Only contracts that have at least one execute message with restricted access are included in this module. + +## Router + +### Governance-Only +```rust +RegisterChain { + chain: ChainName, + gateway_address: Address, + msg_id_format: MessageIdFormat, +}, + +UpgradeGateway { + chain: ChainName, + contract_address: Address, +}, +``` + +### Admin-Only +```rust +FreezeChain { + chain: ChainName, + direction: GatewayDirection, +}, + +UnfreezeChain { + chain: ChainName, + direction: GatewayDirection, +} +``` + + +## Verifier + +### Governance-Only +```rust +UpdateVotingThreshold { + new_voting_threshold: MajorityThreshold, +} +``` + + +## Prover + +### Governance-Only +```rust +UpdateSigningThreshold { + new_signing_threshold: MajorityThreshold, +}, + +UpdateAdmin { + new_admin_address: String, +} +``` + +### Admin or Governance +```rust +UpdateVerifierSet +``` + + +## Multisig + +### Governance-Only +```rust +AuthorizeCaller { + contract_address: Addr, +}, + +UnauthorizeCaller { + contract_address: Addr, +} +``` + +### Authorized Caller Only +Authorized caller is any contract that is previously authorized from governance by calling `AuthorizeCaller`. +```rust +StartSigningSession { // Can only be called by an authorized contract + verifier_set_id: String, + msg: HexBinary, + chain_name: ChainName, + sig_verifier: Option, +} +``` + + +## Service Registry + +### Governance-Only +```rust +RegisterService { + service_name: String, + coordinator_contract: Addr, + min_num_verifiers: u16, + max_num_verifiers: Option, + min_verifier_bond: Uint128, + bond_denom: String, + unbonding_period_days: u16, + description: String, +}, + +AuthorizeVerifiers { + verifiers: Vec, + service_name: String, +}, + +UnauthorizeVerifiers { + verifiers: Vec, + service_name: String, +}, + +JailVerifiers { + verifiers: Vec, + service_name: String, +} +``` + + +## Coordinator + +### Governance-Only +```rust +RegisterProverContract { + chain_name: ChainName, + new_prover_addr: Addr, +} +``` \ No newline at end of file From f6096f8cd5c1a452783de3de857355a27cbb82db Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 19 Jun 2024 18:11:36 -0400 Subject: [PATCH 025/168] chore: disallow casts with possible truncations (#463) --- Cargo.toml | 1 + ampd/src/block_height_monitor.rs | 1 + ampd/src/event_sub.rs | 2 ++ contracts/gateway/tests/contract.rs | 6 +++--- contracts/rewards/src/contract/execute.rs | 2 +- contracts/router/src/contract.rs | 2 +- contracts/service-registry/src/contract.rs | 1 + contracts/voting-verifier/src/contract.rs | 14 +++++++------- contracts/voting-verifier/src/execute.rs | 7 +++++-- contracts/voting-verifier/src/query.rs | 4 ++-- packages/axelar-wasm-std/src/voting.rs | 2 +- 11 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 185d9c9c6..626437ea2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ tokio-util = "0.7.11" [workspace.lints.clippy] arithmetic_side_effects = "deny" +cast_possible_truncation = "deny" [profile.release] opt-level = 3 diff --git a/ampd/src/block_height_monitor.rs b/ampd/src/block_height_monitor.rs index 5ed7e38f4..bffbb72fa 100644 --- a/ampd/src/block_height_monitor.rs +++ b/ampd/src/block_height_monitor.rs @@ -89,6 +89,7 @@ mod tests { use async_trait::async_trait; #[test] + #[allow(clippy::cast_possible_truncation)] async fn latest_block_height_should_work() { let block: tendermint::Block = serde_json::from_str(include_str!("tests/axelar_block.json")).unwrap(); diff --git a/ampd/src/event_sub.rs b/ampd/src/event_sub.rs index d3551d097..ed830f8b8 100644 --- a/ampd/src/event_sub.rs +++ b/ampd/src/event_sub.rs @@ -244,6 +244,7 @@ mod tests { } #[test] + #[allow(clippy::cast_possible_truncation)] async fn start_from_should_work() { let block_count = 10; let block: tendermint::Block = @@ -424,6 +425,7 @@ mod tests { } #[test] + #[allow(clippy::cast_possible_truncation)] async fn stream_should_work() { let block_count = 10; let block: tendermint::Block = diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index 0043914b4..a0f90fe13 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -334,7 +334,7 @@ fn test_cases_for_duplicate_msgs() -> ( } fn generate_msgs_with_all_statuses( - count_per_status: i32, + count_per_status: u8, ) -> HashMap> { all_statuses() .into_iter() @@ -342,7 +342,7 @@ fn generate_msgs_with_all_statuses( .collect::>>() } -fn generate_msgs(namespace: impl Debug, count: i32) -> Vec { +fn generate_msgs(namespace: impl Debug, count: u8) -> Vec { (0..count) .map(|i| Message { cc_id: CrossChainId { @@ -352,7 +352,7 @@ fn generate_msgs(namespace: impl Debug, count: i32) -> Vec { destination_address: "idc".parse().unwrap(), destination_chain: "mock-chain-2".parse().unwrap(), source_address: "idc".parse().unwrap(), - payload_hash: [i as u8; 32], + payload_hash: [i; 32], }) .collect() } diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index 49a8dff1e..81ec427e3 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -913,7 +913,7 @@ mod test { let rewards_claimed = distribute_rewards( mock_deps.as_mut().storage, pool_id, - block_height_started + epoch_duration * (epoch_count + 2) as u64, + block_height_started + epoch_duration * (epoch_count as u64 + 2), None, ) .unwrap(); diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 2f5674c19..5e042d6c5 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -196,7 +196,7 @@ mod test { .unwrap(); } - #[allow(clippy::arithmetic_side_effects)] + #[allow(clippy::arithmetic_side_effects, clippy::cast_possible_truncation)] fn generate_messages( src_chain: &Chain, dest_chain: &Chain, diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 5283f3d36..39ed44f92 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1763,6 +1763,7 @@ mod test { } #[test] + #[allow(clippy::cast_possible_truncation)] fn get_active_verifiers_should_not_return_less_than_min() { let mut deps = setup(); diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index d982581ab..bf2a97d65 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -207,19 +207,19 @@ mod test { deps } - fn message_id(id: &str, index: u64, msg_id_format: &MessageIdFormat) -> nonempty::String { + fn message_id(id: &str, index: u32, msg_id_format: &MessageIdFormat) -> nonempty::String { let tx_hash = Keccak256::digest(id.as_bytes()).into(); match msg_id_format { MessageIdFormat::HexTxHashAndEventIndex => HexTxHashAndEventIndex { tx_hash, - event_index: index as u32, + event_index: index, } .to_string() .parse() .unwrap(), MessageIdFormat::Base58TxDigestAndEventIndex => Base58TxDigestAndEventIndex { tx_digest: tx_hash, - event_index: index as u32, + event_index: index, } .to_string() .parse() @@ -227,7 +227,7 @@ mod test { } } - fn messages(len: u64, msg_id_format: &MessageIdFormat) -> Vec { + fn messages(len: u32, msg_id_format: &MessageIdFormat) -> Vec { (0..len) .map(|i| Message { cc_id: CrossChainId { @@ -362,7 +362,7 @@ mod test { let mut deps = setup(verifiers.clone(), &msg_id_format); let messages_count = 5; let messages_in_progress = 3; - let messages = messages(messages_count as u64, &msg_id_format); + let messages = messages(messages_count as u32, &msg_id_format); execute( deps.as_mut(), @@ -1157,7 +1157,7 @@ mod test { // simulate a majority of verifiers voting for succeeded on chain verifiers.iter().enumerate().for_each(|(i, verifier)| { - if i >= majority as usize { + if i as u64 >= majority { return; } let msg = ExecuteMsg::Vote { @@ -1266,7 +1266,7 @@ mod test { // which is one less than the updated majority. The messages // should not receive enough votes to be considered verified verifiers.iter().enumerate().for_each(|(i, verifier)| { - if i >= old_majority as usize { + if i as u64 >= old_majority { return; } let msg = ExecuteMsg::Vote { diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index a3458cd3f..991a45837 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -231,14 +231,17 @@ pub fn vote( let results_after_voting = get_poll_results(&poll); - let quorum_events = (results_after_voting.difference(results_before_voting)) + let quorum_events = results_after_voting + .difference(results_before_voting) .expect("failed to substract poll results") .0 .into_iter() .enumerate() .filter_map(|(idx, vote)| vote.map(|vote| (idx, vote))) .map(|(index_in_poll, vote)| { - make_quorum_event(&vote, index_in_poll as u32, &poll_id, &poll, &deps) + let idx = u32::try_from(index_in_poll) + .expect("the amount of votes should never overflow u32"); + make_quorum_event(&vote, idx, &poll_id, &poll, &deps) }) .collect::, _>>()?; diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index 72ff75b96..e387a22d6 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -219,13 +219,13 @@ mod tests { ); } - fn message(id: u64) -> Message { + fn message(id: u32) -> Message { Message { cc_id: CrossChainId { chain: "source-chain".parse().unwrap(), id: HexTxHashAndEventIndex { tx_hash: [0; 32], - event_index: id as u32, + event_index: id, } .to_string() .try_into() diff --git a/packages/axelar-wasm-std/src/voting.rs b/packages/axelar-wasm-std/src/voting.rs index ee591f5e8..4ee555195 100644 --- a/packages/axelar-wasm-std/src/voting.rs +++ b/packages/axelar-wasm-std/src/voting.rs @@ -365,7 +365,7 @@ impl WeightedPoll { return Err(Error::PollExpired); } - if votes.len() != self.poll_size as usize { + if votes.len() as u64 != self.poll_size { return Err(Error::InvalidVoteSize); } From 7f99be2345271a0698c9eb4d8281c74ebf00cb89 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Fri, 21 Jun 2024 12:29:27 -0400 Subject: [PATCH 026/168] chore: update to rust 1.78 (#464) --- .cargo/{config => config.toml} | 0 .github/workflows/basic.yaml | 8 +- .../workflows/build-ampd-and-push-to-r2.yaml | 6 +- .github/workflows/build-ampd-release.yaml | 6 +- .github/workflows/codecov.yaml | 2 +- Cargo.toml | 2 +- ampd/src/evm/json_rpc.rs | 14 --- ampd/src/handlers/sui_verify_verifier_set.rs | 1 + ampd/src/main.rs | 5 +- contracts/coordinator/Cargo.toml | 2 +- contracts/gateway/Cargo.toml | 2 +- contracts/gateway/tests/contract.rs | 4 +- contracts/multisig-prover/Cargo.toml | 8 +- contracts/multisig/Cargo.toml | 2 +- contracts/multisig/src/signing.rs | 12 +-- .../nexus-gateway/src/contract/execute.rs | 2 +- contracts/rewards/Cargo.toml | 2 +- contracts/router/Cargo.toml | 2 +- contracts/service-registry/Cargo.toml | 2 +- contracts/voting-verifier/Cargo.toml | 2 +- integration-tests/Cargo.toml | 2 +- integration-tests/tests/message_routing.rs | 2 +- packages/axelar-wasm-std/Cargo.toml | 2 +- packages/axelar-wasm-std/src/utils.rs | 97 +++++++------------ 24 files changed, 70 insertions(+), 117 deletions(-) rename .cargo/{config => config.toml} (100%) diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index a9e699f1c..ccf2a2086 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -20,7 +20,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.75.0 + toolchain: 1.78.0 override: true - name: Install protoc @@ -52,7 +52,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.75.0 + toolchain: 1.78.0 target: wasm32-unknown-unknown override: true @@ -73,7 +73,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: install - args: --debug --version 1.3.3 --locked cosmwasm-check + args: --version 1.5.5 --locked cosmwasm-check - name: Check wasm contracts run: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm @@ -88,7 +88,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.75.0 + toolchain: 1.78.0 override: true components: rustfmt, clippy diff --git a/.github/workflows/build-ampd-and-push-to-r2.yaml b/.github/workflows/build-ampd-and-push-to-r2.yaml index be4136397..985b64414 100644 --- a/.github/workflows/build-ampd-and-push-to-r2.yaml +++ b/.github/workflows/build-ampd-and-push-to-r2.yaml @@ -44,7 +44,11 @@ jobs: id: compile-contracts run: | cd axelar-amplifier - docker run --rm -v "$(pwd)":/code --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/rust-optimizer:0.15.1 + docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/optimizer:0.16.0 + commit_hash=$(git rev-parse --short HEAD) cd .. mkdir -p ./artifacts/$commit_hash/ diff --git a/.github/workflows/build-ampd-release.yaml b/.github/workflows/build-ampd-release.yaml index 1a7537716..35be5321a 100644 --- a/.github/workflows/build-ampd-release.yaml +++ b/.github/workflows/build-ampd-release.yaml @@ -35,8 +35,8 @@ jobs: needs: extract-semver strategy: matrix: - os: [ubuntu-22.04, macos-12] - arch: [amd64, arm64] + os: [ ubuntu-22.04, macos-12 ] + arch: [ amd64, arm64 ] permissions: contents: write @@ -60,7 +60,7 @@ jobs: - name: Set up Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.75 + toolchain: 1.78 override: true - name: Import GPG key diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 3536f0b8a..95e88d5c6 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -19,7 +19,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.75.0 + toolchain: 1.78.0 override: true - name: Install protoc diff --git a/Cargo.toml b/Cargo.toml index 626437ea2..a0ddecd73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["ampd", "contracts/*", "integration-tests", "packages/*"] resolver = "2" [workspace.package] -rust-version = "1.75.0" # be sure there is an optimizer release supporting this version before updating. See https://github.com/CosmWasm/optimizer +rust-version = "1.78.0" # be sure there is an optimizer release supporting this version before updating. See https://github.com/CosmWasm/optimizer [workspace.dependencies] router = { version = "^0.3.2", path = "contracts/router" } diff --git a/ampd/src/evm/json_rpc.rs b/ampd/src/evm/json_rpc.rs index 5e59600c6..3046d726d 100644 --- a/ampd/src/evm/json_rpc.rs +++ b/ampd/src/evm/json_rpc.rs @@ -19,10 +19,6 @@ pub trait EthereumClient { async fn transaction_receipt(&self, hash: H256) -> Result>; } -#[async_trait] -pub trait MoonbeamClient: EthereumClient { - async fn finalized_block_hash(&self) -> Result; -} #[async_trait] impl

EthereumClient for Client

where @@ -44,13 +40,3 @@ where self.request("eth_getTransactionReceipt", [hash]).await } } - -#[async_trait] -impl

MoonbeamClient for Client

-where - P: JsonRpcClient + Send + Sync + 'static, -{ - async fn finalized_block_hash(&self) -> Result { - self.request("chain_getFinalizedHead", ()).await - } -} diff --git a/ampd/src/handlers/sui_verify_verifier_set.rs b/ampd/src/handlers/sui_verify_verifier_set.rs index b2645e5ca..71c9d70d9 100644 --- a/ampd/src/handlers/sui_verify_verifier_set.rs +++ b/ampd/src/handlers/sui_verify_verifier_set.rs @@ -25,6 +25,7 @@ use crate::sui::json_rpc::SuiClient; use crate::sui::verifier::verify_verifier_set; use crate::types::TMAddress; +#[allow(dead_code)] #[derive(Deserialize, Debug)] pub struct Operators { pub weights_by_addresses: Vec<(HexBinary, Uint128)>, diff --git a/ampd/src/main.rs b/ampd/src/main.rs index 4eea80f94..13224390b 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -16,7 +16,6 @@ use ampd::commands::{ }; use ampd::config::Config; use ampd::Error; -use axelar_wasm_std::utils::InspectorResult; use axelar_wasm_std::FnExt; use report::LoggableError; @@ -111,8 +110,8 @@ fn init_config(config_paths: &[PathBuf]) -> Config { parse_config(files) .change_context(Error::LoadConfig) - .tap_err(|report| error!(err = LoggableError::from(report).as_value(), "{report}")) - .unwrap_or(Config::default()) + .inspect_err(|report| error!(err = LoggableError::from(report).as_value(), "{report}")) + .unwrap_or_default() } fn find_config_files(config: &[PathBuf]) -> Vec> { diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index b96990fed..df6eb2133 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -29,7 +29,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index 3945483da..b6f3d277d 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -31,7 +31,7 @@ generate_golden_files = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index a0f90fe13..3e0992d6b 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -283,7 +283,7 @@ fn route_duplicate_ids_should_fail() { fn test_cases_for_correct_verifier() -> ( Vec>, - impl Fn(voting_verifier::msg::QueryMsg) -> Result, ContractError> + Clone + Sized, + impl Fn(voting_verifier::msg::QueryMsg) -> Result, ContractError> + Clone, ) { let all_messages = generate_msgs_with_all_statuses(10); let status_by_msg = map_status_by_msg(all_messages.clone()); @@ -308,7 +308,7 @@ fn test_cases_for_correct_verifier() -> ( fn test_cases_for_duplicate_msgs() -> ( Vec>, - impl Fn(voting_verifier::msg::QueryMsg) -> Result, ContractError> + Clone + Sized, + impl Fn(voting_verifier::msg::QueryMsg) -> Result, ContractError> + Clone, ) { let all_messages = generate_msgs_with_all_statuses(10); let status_by_msg = map_status_by_msg(all_messages.clone()); diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 5e2ae13cc..16b5d92fa 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -6,9 +6,9 @@ edition = "2021" description = "Multisig prover contract" exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", + # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -29,7 +29,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 47f30c9ef..ba1dcbaeb 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -36,7 +36,7 @@ test = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/multisig/src/signing.rs b/contracts/multisig/src/signing.rs index c810368f9..d596114f9 100644 --- a/contracts/multisig/src/signing.rs +++ b/contracts/multisig/src/signing.rs @@ -133,10 +133,7 @@ fn signers_weight(signatures: &HashMap, verifier_set: &Verifi #[cfg(test)] mod tests { - use cosmwasm_std::{ - testing::{MockQuerier, MockStorage}, - to_json_binary, Addr, HexBinary, QuerierWrapper, - }; + use cosmwasm_std::{testing::MockQuerier, to_json_binary, Addr, HexBinary, QuerierWrapper}; use crate::{ key::KeyType, @@ -147,7 +144,6 @@ mod tests { use super::*; pub struct TestConfig { - pub store: MockStorage, pub verifier_set: VerifierSet, pub session: SigningSession, pub signatures: HashMap, @@ -155,8 +151,6 @@ mod tests { } fn ecdsa_setup() -> TestConfig { - let store = MockStorage::new(); - let signers = ecdsa_test_data::signers(); let verifier_set_id = "subkey".to_string(); @@ -185,7 +179,6 @@ mod tests { .collect(); TestConfig { - store, verifier_set, session, signatures, @@ -194,8 +187,6 @@ mod tests { } fn ed25519_setup() -> TestConfig { - let store = MockStorage::new(); - let signers = ed25519_test_data::signers(); let verifier_set_id = "subkey".to_string(); @@ -224,7 +215,6 @@ mod tests { .collect(); TestConfig { - store, verifier_set, session, signatures, diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index d25cb6762..5b6129098 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -123,7 +123,7 @@ mod test { .returning(move || Ok(config.clone())); let contract = Contract::new(store); - let msg_ids = vec![ + let msg_ids = [ HexTxHashAndEventIndex { tx_hash: vec![0x2f; 32].try_into().unwrap(), event_index: 100, diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index c1911fd77..919a5d162 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -29,7 +29,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 49e369b4a..13c3a863b 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -29,7 +29,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index 0727a2722..184e85b43 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -29,7 +29,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index 99f3e6835..cfb289a47 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -29,7 +29,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 665c8b6e0..4ab645022 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -25,7 +25,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index bdc2764b7..3faf8da08 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -126,7 +126,7 @@ fn routing_to_incorrect_gateway_interface() { .. } = test_utils::setup_test_case(); - let msgs = vec![Message { + let msgs = [Message { cc_id: CrossChainId { chain: chain1.chain_name.clone(), id: "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3" diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index 362659699..cd3e96482 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -25,7 +25,7 @@ library = [] optimize = """docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 + cosmwasm/optimizer:0.16.0 """ [dependencies] diff --git a/packages/axelar-wasm-std/src/utils.rs b/packages/axelar-wasm-std/src/utils.rs index 06d173a2c..e45c0695a 100644 --- a/packages/axelar-wasm-std/src/utils.rs +++ b/packages/axelar-wasm-std/src/utils.rs @@ -1,74 +1,47 @@ -pub fn try_map(vec: Vec, f: F) -> Result, E> -where - F: FnMut(T) -> Result, -{ - vec.into_iter().map(f).collect::, E>>() +pub trait TryMapExt { + type Monad; + fn try_map(self, func: impl FnMut(T) -> Result) -> Result, E>; } -pub trait InspectorResult { - /// This function should be called `inspect`, but would have a name collision with the unstable [core::result::Result::inspect](https://doc.rust-lang.org/core/result/enum.Result.html#method.inspect) function. - fn tap(self, f: F) -> Self - where - F: FnOnce(&T); +impl TryMapExt for Option { + type Monad = Option; - /// This function should be called `inspect_err`, but would have a name collision with the unstable [core::result::Result::inspect_err](https://doc.rust-lang.org/core/result/enum.Result.html#method.inspect_err) function. - fn tap_err(self, f: F) -> Self - where - F: FnOnce(&E); + fn try_map(self, func: impl FnMut(T) -> Result) -> Result, E> { + self.map(func).transpose() + } } -impl InspectorResult for Result { - /// Use this to create a side effect without consuming the result. - /// - /// Example: - /// ``` - /// use axelar_wasm_std::utils::InspectorResult; - /// - /// let result: Result = Ok(1); - /// assert_eq!(result.tap(|x| println!("result is {}", x)).map(|x| x + 1), Ok(2)); - /// - /// let err:Result = Err("wrong value".to_string()); - /// assert!(err.tap(|x| println!("error is {}", x)).is_err()); // println will not be called - /// ``` - fn tap(self, f: F) -> Self - where - F: FnOnce(&T), - { - self.map(|t| { - f(&t); - t - }) - } +impl TryMapExt for Vec { + type Monad = Vec; - /// Use this to create a side effect without consuming the error. - /// - /// Example: - /// ``` - /// use axelar_wasm_std::utils::InspectorResult; - /// - /// let result: Result = Ok(1); - /// assert_eq!(result.tap_err(|x| println!("error is {}", x)).map(|x| x + 1), Ok(2)); // println will not be called - /// - /// let err:Result = Err("wrong value".to_string()); - /// assert!(err.tap_err(|x| println!("result is {}", x)).is_err()); - /// ``` - fn tap_err(self, f: F) -> Self - where - F: FnOnce(&E), - { - self.map_err(|e| { - f(&e); - e - }) + fn try_map(self, func: impl FnMut(T) -> Result) -> Result, E> { + self.into_iter().map(func).collect::, E>>() } } -pub trait TryMapExt { - fn try_map(self, func: impl FnOnce(T) -> Result) -> Result, E>; -} +#[cfg(test)] +mod test { + use super::*; -impl TryMapExt for Option { - fn try_map(self, func: impl FnOnce(T) -> Result) -> Result, E> { - self.map(func).transpose() + #[test] + fn test_try_map_vec() { + let vec = vec![1, 2, 3]; + let result: Result<_, &str> = vec.try_map(|x| Ok(x + 1)); + assert_eq!(result, Ok(vec![2, 3, 4])); + + let vec = vec![1, 2, 3]; + let result: Result, _> = vec.try_map(|_| Err("error")); + assert_eq!(result, Err("error")); + } + + #[test] + fn test_try_map_option() { + let option = Some(1); + let result: Result<_, &str> = option.try_map(|x| Ok(x + 1)); + assert_eq!(result, Ok(Some(2))); + + let option = Some(1); + let result: Result, _> = option.try_map(|_| Err("error")); + assert_eq!(result, Err("error")); } } From 308b1e8189a916d301fadf745858ad5e47bf53f3 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Fri, 21 Jun 2024 12:32:54 -0400 Subject: [PATCH 027/168] refactor(ampd): attach tx response to execution error (#467) --- ampd/src/broadcaster/mod.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index 53380f0f5..f0f848cda 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -57,7 +57,7 @@ pub enum Error { #[error("failed to confirm inclusion in block for tx with hash '{tx_hash}'")] TxConfirmation { tx_hash: String }, #[error("failed to execute tx")] - Execution { response: Box }, + Execution, #[error("failed to query balance for address '{address}' and denomination '{denom}'")] QueryBalance { address: TMAddress, denom: Denom }, #[error("failed to query account for address '{address}'")] @@ -381,7 +381,7 @@ where return Ok(()); } - ConfirmationResult::Critical(err) => return Err(err.into()), + ConfirmationResult::Critical(err) => return Err(err), ConfirmationResult::Retriable(err) => { if let Err(result) = result.as_mut() { result.extend_one(err); @@ -419,9 +419,10 @@ fn evaluate_tx_response( .. }) => match response { TxResponse { code: 0, .. } => ConfirmationResult::Success, - _ => ConfirmationResult::Critical(Error::Execution { - response: Box::new(response), - }), + _ => ConfirmationResult::Critical( + report!(Error::Execution) + .attach_printable(format!("{{ response = {response:?} }}")), + ), }, } } @@ -439,7 +440,7 @@ fn remap_account_not_found_error( enum ConfirmationResult { Success, Retriable(Report), - Critical(Error), + Critical(Report), } #[cfg(test)] @@ -626,9 +627,7 @@ mod tests { let report = broadcaster.broadcast(msgs).await.unwrap_err(); - assert!( - matches!(report.current_context(), Error::Execution { response } if response.code == 32) - ); + assert!(matches!(report.current_context(), Error::Execution)); } #[test] From 9655148fab0d65aab8dfb99f956b9dd58523d4f2 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:31:04 -0400 Subject: [PATCH 028/168] chore(ampd): bump rust version in dockerfile (#469) --- ampd/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ampd/Dockerfile b/ampd/Dockerfile index 9fa27e088..dfada706b 100644 --- a/ampd/Dockerfile +++ b/ampd/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.75-bookworm as builder +FROM rust:1.78-bookworm as builder RUN apt-get update && apt-get install -y clang protobuf-compiler cmake WORKDIR /ampd From 4f9c221f5118ac0b130861e1b2e3dcfa33e8a00c Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Fri, 21 Jun 2024 16:13:32 -0400 Subject: [PATCH 029/168] chore(service-registry): migrate service struct to rename service_contract field (#468) * chore: migrate service registry to rename service_contract field * refactor: add coordinator_contract address as message field * refactor: revert back to empty message and remove migration message * refactor: update service creation inside contracts/service-registry/src/migrations/v_0_4.rs Co-authored-by: Christian Gorenflo * fix: fix formatting of new service creation in migration test --------- Co-authored-by: Christian Gorenflo --- contracts/service-registry/src/contract.rs | 13 +- contracts/service-registry/src/lib.rs | 2 + .../service-registry/src/migrations/mod.rs | 1 + .../service-registry/src/migrations/v_0_4.rs | 111 ++++++++++++++++++ 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 contracts/service-registry/src/migrations/mod.rs create mode 100644 contracts/service-registry/src/migrations/v_0_4.rs diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 39ed44f92..065f6c230 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,11 +1,12 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Order, + to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, Order, QueryRequest, Response, Uint128, WasmQuery, }; use crate::error::ContractError; +use crate::migrations; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{AuthorizationState, BondingState, Config, Service, Verifier, CONFIG, SERVICES}; @@ -156,6 +157,16 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + migrations::v_0_4::migrate_services(deps.storage).map_err(axelar_wasm_std::ContractError::from) +} + #[cfg(test)] mod test { use std::str::FromStr; diff --git a/contracts/service-registry/src/lib.rs b/contracts/service-registry/src/lib.rs index 98208b782..fad5e4ff9 100644 --- a/contracts/service-registry/src/lib.rs +++ b/contracts/service-registry/src/lib.rs @@ -4,4 +4,6 @@ pub mod helpers; pub mod msg; pub mod state; +mod migrations; + pub use crate::error::ContractError; diff --git a/contracts/service-registry/src/migrations/mod.rs b/contracts/service-registry/src/migrations/mod.rs new file mode 100644 index 000000000..683e59145 --- /dev/null +++ b/contracts/service-registry/src/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v_0_4; diff --git a/contracts/service-registry/src/migrations/v_0_4.rs b/contracts/service-registry/src/migrations/v_0_4.rs new file mode 100644 index 000000000..6d86c8966 --- /dev/null +++ b/contracts/service-registry/src/migrations/v_0_4.rs @@ -0,0 +1,111 @@ +//! Migrate the `Service` struct and rename `service_contract` field to `coordinator_contract`. + +use cosmwasm_std::{Order, Response, Storage}; + +use crate::state::{Service, SERVICES}; + +mod v0_3_state { + use cosmwasm_schema::cw_serde; + use cosmwasm_std::{Addr, Uint128}; + use cw_storage_plus::Map; + + #[cw_serde] + pub struct Service { + pub name: String, + pub service_contract: Addr, + pub min_num_verifiers: u16, + pub max_num_verifiers: Option, + pub min_verifier_bond: Uint128, + pub bond_denom: String, + pub unbonding_period_days: u16, + pub description: String, + } + + type ServiceName = str; + pub const SERVICES: Map<&ServiceName, Service> = Map::new("services"); +} + +pub fn migrate_services( + store: &mut dyn Storage, +) -> Result { + v0_3_state::SERVICES + .range(store, None, None, Order::Ascending) + .collect::, _>>()? + .into_iter() + .map(|(service_name, service)| { + let service = Service { + name: service.name, + coordinator_contract: service.service_contract, + min_num_verifiers: service.min_num_verifiers, + max_num_verifiers: service.max_num_verifiers, + min_verifier_bond: service.min_verifier_bond, + bond_denom: service.bond_denom, + unbonding_period_days: service.unbonding_period_days, + description: service.description, + }; + SERVICES.save(store, &service_name, &service) + }) + .collect::, _>>()?; + + Ok(Response::default()) +} + +#[cfg(test)] +mod test { + use super::*; + use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128}; + + #[test] + fn successfully_migrate_services() { + let mut deps = mock_dependencies(); + + let initial_services = vec![ + v0_3_state::Service { + name: "service1".to_string(), + service_contract: Addr::unchecked("service_contract1"), + min_num_verifiers: 5, + max_num_verifiers: Some(10), + min_verifier_bond: Uint128::from(1000u128), + bond_denom: "denom1".to_string(), + unbonding_period_days: 7, + description: "description1".to_string(), + }, + v0_3_state::Service { + name: "service2".to_string(), + service_contract: Addr::unchecked("service_contract2"), + min_num_verifiers: 3, + max_num_verifiers: None, + min_verifier_bond: Uint128::from(2000u128), + bond_denom: "denom2".to_string(), + unbonding_period_days: 14, + description: "description2".to_string(), + }, + ]; + + for service in &initial_services { + v0_3_state::SERVICES + .save(&mut deps.storage, service.name.as_str(), service) + .unwrap(); + } + + migrate_services(&mut deps.storage).unwrap(); + + for service in &initial_services { + let migrated_service: Service = + SERVICES.load(&deps.storage, service.name.as_str()).unwrap(); + + let expected_service = Service { + name: service.name.clone(), + coordinator_contract: service.service_contract.clone(), + min_num_verifiers: service.min_num_verifiers, + max_num_verifiers: service.max_num_verifiers, + min_verifier_bond: service.min_verifier_bond, + bond_denom: service.bond_denom.clone(), + unbonding_period_days: service.unbonding_period_days, + description: service.description.clone(), + }; + + assert_eq!(migrated_service, expected_service); + } + } +} From 92b0f40140aab4b1f7f798239bfa10e74a474f95 Mon Sep 17 00:00:00 2001 From: Sammy Date: Fri, 21 Jun 2024 16:25:14 -0400 Subject: [PATCH 030/168] feat(ampd): remove the state updater (#470) * feat(ampd): remove the state updater * remove dead code * remove more dead code --- ampd/src/commands/bond_verifier.rs | 6 +- ampd/src/commands/daemon.rs | 28 +-- ampd/src/commands/deregister_chain_support.rs | 6 +- ampd/src/commands/mod.rs | 22 +- ampd/src/commands/register_chain_support.rs | 6 +- ampd/src/commands/register_public_key.rs | 5 +- ampd/src/commands/verifier_address.rs | 6 +- ampd/src/event_processor.rs | 25 +- ampd/src/event_sub.rs | 174 +++----------- ampd/src/handlers/chain.rs | 173 -------------- ampd/src/handlers/end_block.rs | 79 ------- ampd/src/handlers/mod.rs | 2 - ampd/src/lib.rs | 87 ++----- ampd/src/main.rs | 19 +- ampd/src/state.rs | 214 ------------------ 15 files changed, 85 insertions(+), 767 deletions(-) delete mode 100644 ampd/src/handlers/chain.rs delete mode 100644 ampd/src/handlers/end_block.rs delete mode 100644 ampd/src/state.rs diff --git a/ampd/src/commands/bond_verifier.rs b/ampd/src/commands/bond_verifier.rs index 3ff02521a..7703df219 100644 --- a/ampd/src/commands/bond_verifier.rs +++ b/ampd/src/commands/bond_verifier.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use axelar_wasm_std::nonempty; use cosmrs::cosmwasm::MsgExecuteContract; use cosmrs::tx::Msg; @@ -20,10 +18,10 @@ pub struct Args { pub denom: String, } -pub async fn run(config: Config, state_path: &Path, args: Args) -> Result, Error> { +pub async fn run(config: Config, args: Args) -> Result, Error> { let coin = Coin::new(args.amount, args.denom.as_str()).change_context(Error::InvalidInput)?; - let pub_key = verifier_pub_key(state_path, config.tofnd_config.clone()).await?; + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; let msg = serde_json::to_vec(&ExecuteMsg::BondVerifier { service_name: args.service_name.into(), diff --git a/ampd/src/commands/daemon.rs b/ampd/src/commands/daemon.rs index 176022a24..0cfc1da85 100644 --- a/ampd/src/commands/daemon.rs +++ b/ampd/src/commands/daemon.rs @@ -1,30 +1,8 @@ -use std::path::Path; - -use error_stack::{Report, ResultExt}; -use tracing::info; +use error_stack::Report; use crate::config::Config; -use crate::state::{flush, load}; use crate::Error; -pub async fn run(config: Config, state_path: &Path) -> Result, Report> { - let state = load(state_path).change_context(Error::LoadConfig)?; - let (state, execution_result) = crate::run(config, state).await; - - info!("persisting state"); - let state_flush_result = flush(&state, state_path).change_context(Error::ReturnState); - - match (execution_result, state_flush_result) { - // both execution and persisting state failed: return the merged error - (Err(mut report), Err(state_err)) => { - report.extend_one(state_err); - Err(report) - } - - // any single path failed: report the error - (Err(report), Ok(())) | (Ok(()), Err(report)) => Err(report), - - // no errors in either execution or persisting state - (Ok(()), Ok(())) => Ok(None), - } +pub async fn run(config: Config) -> Result, Report> { + crate::run(config).await.map(|_| None) } diff --git a/ampd/src/commands/deregister_chain_support.rs b/ampd/src/commands/deregister_chain_support.rs index 7311689d7..c212125f3 100644 --- a/ampd/src/commands/deregister_chain_support.rs +++ b/ampd/src/commands/deregister_chain_support.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use axelar_wasm_std::nonempty; use cosmrs::cosmwasm::MsgExecuteContract; use cosmrs::tx::Msg; @@ -19,8 +17,8 @@ pub struct Args { pub chains: Vec, } -pub async fn run(config: Config, state_path: &Path, args: Args) -> Result, Error> { - let pub_key = verifier_pub_key(state_path, config.tofnd_config.clone()).await?; +pub async fn run(config: Config, args: Args) -> Result, Error> { + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; let msg = serde_json::to_vec(&ExecuteMsg::DeregisterChainSupport { service_name: args.service_name.into(), diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 7ca535c3c..18a187fb2 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use clap::Subcommand; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::proto::cosmos::{ @@ -16,7 +14,6 @@ use valuable::Valuable; use crate::broadcaster::Broadcaster; use crate::config::Config as AmpdConfig; -use crate::state; use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::{PublicKey, TMAddress}; use crate::{broadcaster, Error}; @@ -58,18 +55,13 @@ impl Default for ServiceRegistryConfig { } } -async fn verifier_pub_key(state_path: &Path, config: tofnd::Config) -> Result { - let state = state::load(state_path).change_context(Error::LoadConfig)?; - - match state.pub_key { - Some(pub_key) => Ok(pub_key), - None => MultisigClient::new(config.party_uid, config.url) - .await - .change_context(Error::Connection)? - .keygen(&config.key_uid, tofnd::Algorithm::Ecdsa) - .await - .change_context(Error::Tofnd), - } +async fn verifier_pub_key(config: tofnd::Config) -> Result { + MultisigClient::new(config.party_uid, config.url) + .await + .change_context(Error::Connection)? + .keygen(&config.key_uid, tofnd::Algorithm::Ecdsa) + .await + .change_context(Error::Tofnd) } async fn broadcast_tx( diff --git a/ampd/src/commands/register_chain_support.rs b/ampd/src/commands/register_chain_support.rs index 7e527c845..68c3d8070 100644 --- a/ampd/src/commands/register_chain_support.rs +++ b/ampd/src/commands/register_chain_support.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use axelar_wasm_std::nonempty; use cosmrs::cosmwasm::MsgExecuteContract; use cosmrs::tx::Msg; @@ -19,8 +17,8 @@ pub struct Args { pub chains: Vec, } -pub async fn run(config: Config, state_path: &Path, args: Args) -> Result, Error> { - let pub_key = verifier_pub_key(state_path, config.tofnd_config.clone()).await?; +pub async fn run(config: Config, args: Args) -> Result, Error> { + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; let msg = serde_json::to_vec(&ExecuteMsg::RegisterChainSupport { service_name: args.service_name.into(), diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index eb89fe072..d7010d623 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -1,6 +1,5 @@ use std::convert::TryFrom; use std::convert::TryInto; -use std::path::Path; use cosmrs::{cosmwasm::MsgExecuteContract, tx::Msg}; use error_stack::{Result, ResultExt}; @@ -19,8 +18,8 @@ use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::TMAddress; use crate::{handlers, Error, PREFIX}; -pub async fn run(config: Config, state_path: &Path) -> Result, Error> { - let pub_key = verifier_pub_key(state_path, config.tofnd_config.clone()).await?; +pub async fn run(config: Config) -> Result, Error> { + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; let multisig_address = get_multisig_address(&config)?; diff --git a/ampd/src/commands/verifier_address.rs b/ampd/src/commands/verifier_address.rs index 3378744fa..a4afb66a3 100644 --- a/ampd/src/commands/verifier_address.rs +++ b/ampd/src/commands/verifier_address.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use axelar_wasm_std::FnExt; use error_stack::Result; use report::ResultCompatExt; @@ -9,8 +7,8 @@ use crate::tofnd::Config as TofndConfig; use crate::Error; use crate::PREFIX; -pub async fn run(config: TofndConfig, state_path: &Path) -> Result, Error> { - verifier_pub_key(state_path, config) +pub async fn run(config: TofndConfig) -> Result, Error> { + verifier_pub_key(config) .await .and_then(|pub_key| pub_key.account_id(PREFIX).change_context(Error::Tofnd))? .then(|account_id| Ok(Some(format!("verifier address: {}", account_id)))) diff --git a/ampd/src/event_processor.rs b/ampd/src/event_processor.rs index 14fe2606e..889fc7457 100644 --- a/ampd/src/event_processor.rs +++ b/ampd/src/event_processor.rs @@ -11,12 +11,12 @@ use thiserror::Error; use tokio::time::timeout; use tokio_stream::Stream; use tokio_util::sync::CancellationToken; +use tracing::info; use tracing::warn; use valuable::Valuable; use crate::asyncutil::future::{self, RetryPolicy}; use crate::asyncutil::task::TaskError; -use crate::handlers::chain; use crate::queue::queued_broadcaster::BroadcasterClient; #[async_trait] @@ -24,14 +24,6 @@ pub trait EventHandler { type Err: Context; async fn handle(&self, event: &Event) -> Result, Self::Err>; - - fn chain(self, handler: H) -> chain::Handler - where - Self: Sized, - H: EventHandler, - { - chain::Handler::new(self, handler) - } } #[derive(Error, Debug)] @@ -48,6 +40,7 @@ pub enum Error { /// at the end of each consumed block or when the `event_stream` times out. If the token is cancelled or the /// `event_stream` is closed, the function returns pub async fn consume_events( + handler_label: String, handler: H, broadcaster: B, event_stream: S, @@ -70,6 +63,14 @@ where handle_event(&handler, &broadcaster, event).await?; } + if let StreamStatus::Active(Event::BlockEnd(height)) = &stream_status { + info!( + handler = handler_label, + height = height.value(), + "handler finished processing block" + ); + } + if should_task_stop(stream_status, &token) { return Ok(()); } @@ -184,6 +185,7 @@ mod tests { let result_with_timeout = timeout( Duration::from_secs(1), consume_events( + "handler".to_string(), handler, broadcaster, stream::iter(events), @@ -212,6 +214,7 @@ mod tests { let result_with_timeout = timeout( Duration::from_secs(1), consume_events( + "handler".to_string(), handler, broadcaster, stream::iter(events), @@ -241,6 +244,7 @@ mod tests { let result_with_timeout = timeout( Duration::from_secs(3), consume_events( + "handler".to_string(), handler, broadcaster, stream::iter(events), @@ -274,6 +278,7 @@ mod tests { let result_with_timeout = timeout( Duration::from_secs(3), consume_events( + "handler".to_string(), handler, broadcaster, stream::iter(events), @@ -308,6 +313,7 @@ mod tests { let result_with_timeout = timeout( Duration::from_secs(1), consume_events( + "handler".to_string(), handler, broadcaster, stream::iter(events), @@ -333,6 +339,7 @@ mod tests { let result_with_timeout = timeout( Duration::from_secs(1), consume_events( + "handler".to_string(), handler, broadcaster, stream::pending::>(), // never returns any items so it can time out diff --git a/ampd/src/event_sub.rs b/ampd/src/event_sub.rs index ed830f8b8..c743ef4ab 100644 --- a/ampd/src/event_sub.rs +++ b/ampd/src/event_sub.rs @@ -12,7 +12,7 @@ use tokio::sync::broadcast::{self, Sender}; use tokio::time; use tokio_stream::wrappers::errors::BroadcastStreamRecvError; use tokio_stream::wrappers::BroadcastStream; -use tokio_stream::{Stream, StreamExt}; +use tokio_stream::Stream; use tokio_util::sync::CancellationToken; use tracing::info; @@ -40,7 +40,6 @@ impl EventSub for EventSubscriber { pub struct EventPublisher { tm_client: T, - start_from: Option, poll_interval: Duration, tx: Sender, } @@ -50,7 +49,6 @@ impl EventPublisher { let (tx, _) = broadcast::channel::(capacity); let publisher = EventPublisher { tm_client: client, - start_from: None, poll_interval: Duration::new(5, 0), tx: tx.clone(), }; @@ -59,22 +57,8 @@ impl EventPublisher { (publisher, subscriber) } - pub fn start_from(mut self, height: block::Height) -> Self { - self.start_from = Some(height); - self - } - - #[allow(dead_code)] - pub fn poll_interval(mut self, poll_interval: Duration) -> Self { - self.poll_interval = poll_interval; - self - } - pub async fn run(mut self, token: CancellationToken) -> Result<(), EventSubError> { - let mut curr_block_height = match self.start_from { - Some(start_from) => start_from, - None => self.latest_block_height().await?, - }; + let mut curr_block_height = self.latest_block_height().await?; let mut interval = time::interval(self.poll_interval); loop { @@ -175,13 +159,6 @@ impl EventPublisher { } } -pub fn skip_to_block( - stream: impl Stream>, - height: block::Height, -) -> impl Stream> { - stream.skip_while(move |event| !matches!(event, Ok(Event::BlockBegin(h)) if *h >= height)) -} - #[derive(Error, Debug)] pub enum EventSubError { #[error("querying events for block {block} failed")] @@ -203,110 +180,16 @@ mod tests { use mockall::predicate::eq; use rand::Rng; use random_string::generate; - use tendermint::block; use tendermint::{abci, AppHash}; use tokio::sync::{mpsc, oneshot}; use tokio::test; - use tokio_stream::wrappers::ReceiverStream; use tokio_util::sync::CancellationToken; - use crate::event_sub::{skip_to_block, Event, EventPublisher, EventSub}; + use crate::event_sub::{Event, EventPublisher, EventSub}; use crate::tm_client; #[test] - async fn skip_to_block_should_work() { - let (tx, rx) = mpsc::channel(100); - let skip_to: block::Height = 5u32.into(); - - for i in 1u32..10 { - tx.send(Event::BlockBegin(i.into())).await.unwrap(); - tx.send(Event::BlockEnd(i.into())).await.unwrap(); - } - - let mut stream = skip_to_block::<()>(ReceiverStream::new(rx).map(Ok), skip_to); - - assert_eq!( - stream.next().await.unwrap().unwrap(), - Event::BlockBegin(skip_to) - ); - assert_eq!( - stream.next().await.unwrap().unwrap(), - Event::BlockEnd(skip_to) - ); - assert_eq!( - stream.next().await.unwrap().unwrap(), - Event::BlockBegin(skip_to.increment()) - ); - assert_eq!( - stream.next().await.unwrap().unwrap(), - Event::BlockEnd(skip_to.increment()) - ); - } - - #[test] - #[allow(clippy::cast_possible_truncation)] - async fn start_from_should_work() { - let block_count = 10; - let block: tendermint::Block = - serde_json::from_str(include_str!("tests/axelar_block.json")).unwrap(); - let from_height = (block.header.height.value() - block_count + 1) - .try_into() - .unwrap(); - let to_height = block.header.height; - - let mut mock_client = tm_client::MockTmClient::new(); - mock_client.expect_latest_block().once().returning(move || { - Ok(tm_client::BlockResponse { - block_id: Default::default(), - block: block.clone(), - }) - }); - mock_client - .expect_block_results() - .times(block_count as usize) - .returning(|height| { - Ok(tm_client::BlockResultsResponse { - height, - begin_block_events: None, - end_block_events: None, - consensus_param_updates: None, - txs_results: None, - validator_updates: vec![], - app_hash: AppHash::default(), - finalize_block_events: vec![], - }) - }); - - let token = CancellationToken::new(); - let (event_publisher, event_subcriber) = - EventPublisher::new(mock_client, 2 * block_count as usize); - let event_publisher = event_publisher.start_from(from_height); - let mut stream = event_subcriber.subscribe(); - - let child_token = token.child_token(); - let handle = tokio::spawn(async move { event_publisher.run(child_token).await }); - - for height in from_height.value()..to_height.value() { - let event = stream.next().await; - assert_eq!( - event.unwrap().unwrap(), - Event::BlockBegin(height.try_into().unwrap()) - ); - - let event = stream.next().await; - assert_eq!( - event.unwrap().unwrap(), - Event::BlockEnd(height.try_into().unwrap()) - ); - } - - token.cancel(); - - assert!(handle.await.is_ok()); - } - - #[test] - async fn should_start_from_latest_when_none_is_given() { + async fn should_start_from_the_latest_block() { let block: tendermint::Block = serde_json::from_str(include_str!("tests/axelar_block.json")).unwrap(); let height = block.header.height; @@ -357,9 +240,6 @@ mod tests { let latest_block: tendermint::Block = serde_json::from_str(include_str!("tests/axelar_block.json")).unwrap(); let latest_block_height = latest_block.header.height; - let start_from_block_height = (latest_block.header.height.value() - 100) - .try_into() - .unwrap(); let (sub_tx, mut sub_rx) = oneshot::channel::<()>(); let (pub_tx, mut pub_rx) = mpsc::channel::(100); @@ -398,10 +278,8 @@ mod tests { }); let token = CancellationToken::new(); - let (event_publisher, event_subcriber) = EventPublisher::new(mock_client, 100); - let event_publisher = event_publisher - .start_from(start_from_block_height) - .poll_interval(Duration::from_millis(500)); + let (mut event_publisher, event_subcriber) = EventPublisher::new(mock_client, 100); + event_publisher.poll_interval = Duration::from_millis(500); let handle = tokio::spawn(event_publisher.run(token.child_token())); while let Some(call_count) = pub_rx.recv().await { @@ -425,7 +303,6 @@ mod tests { } #[test] - #[allow(clippy::cast_possible_truncation)] async fn stream_should_work() { let block_count = 10; let block: tendermint::Block = @@ -474,18 +351,27 @@ mod tests { let mut latest_block_call_count = 0; mock_client .expect_latest_block() - .times(block_count) - .returning(move || { - let mut block = block.clone(); - block.header.height = (block_height.value() + latest_block_call_count) - .try_into() - .unwrap(); - - latest_block_call_count += 1; - Ok(tm_client::BlockResponse { - block_id: Default::default(), - block, - }) + .times(block_count + 1) + .returning(move || match latest_block_call_count { + 0 => { + latest_block_call_count += 1; + Ok(tm_client::BlockResponse { + block_id: Default::default(), + block: block.clone(), + }) + } + _ => { + let mut block = block.clone(); + block.header.height = (block_height.value() + latest_block_call_count - 1) + .try_into() + .unwrap(); + + latest_block_call_count += 1; + Ok(tm_client::BlockResponse { + block_id: Default::default(), + block, + }) + } }); mock_client .expect_block_results() @@ -498,11 +384,9 @@ mod tests { }); let token = CancellationToken::new(); - let (event_publisher, event_subcriber) = + let (mut event_publisher, event_subcriber) = EventPublisher::new(mock_client, block_count * event_count_per_block); - let event_publisher = event_publisher - .start_from(block_height) - .poll_interval(Duration::new(0, 1e7 as u32)); + event_publisher.poll_interval = Duration::from_millis(10); let mut stream = event_subcriber.subscribe(); let child_token = token.child_token(); diff --git a/ampd/src/handlers/chain.rs b/ampd/src/handlers/chain.rs deleted file mode 100644 index dd90698ce..000000000 --- a/ampd/src/handlers/chain.rs +++ /dev/null @@ -1,173 +0,0 @@ -use crate::event_processor::EventHandler; -use async_trait::async_trait; -use cosmrs::Any; -use error_stack::{Result, ResultExt}; -use events::Event; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum Error { - #[error("one of the chained handlers failed handling event")] - ChainError, -} - -pub struct Handler -where - H1: EventHandler, - H2: EventHandler, -{ - handler_1: H1, - handler_2: H2, -} - -impl Handler -where - H1: EventHandler, - H2: EventHandler, -{ - pub fn new(handler_1: H1, handler_2: H2) -> Self { - Self { - handler_1, - handler_2, - } - } -} - -#[async_trait] -impl EventHandler for Handler -where - H1: EventHandler + Send + Sync, - H2: EventHandler + Send + Sync, -{ - type Err = Error; - - async fn handle(&self, event: &Event) -> Result, Error> { - let msgs_1 = self - .handler_1 - .handle(event) - .await - .change_context(Error::ChainError)?; - let msgs_2 = self - .handler_2 - .handle(event) - .await - .change_context(Error::ChainError)?; - - Ok(msgs_1.into_iter().chain(msgs_2).collect()) - } -} - -#[cfg(test)] -mod tests { - use async_trait::async_trait; - use cosmrs::tx::Msg; - use cosmrs::{bank::MsgSend, AccountId, Any}; - use error_stack::Result; - use events::Event; - use mockall::{mock, predicate}; - use tendermint::block; - use thiserror::Error; - - use crate::event_processor::{self, EventHandler}; - - #[tokio::test] - async fn should_chain_handlers() { - let height: block::Height = (10_u32).into(); - let msg_1 = dummy_msg(AccountId::new("", &[1, 2, 3]).unwrap()); - let msg_2 = dummy_msg(AccountId::new("", &[2, 3, 4]).unwrap()); - let msg_3 = dummy_msg(AccountId::new("", &[3, 4, 5]).unwrap()); - - let mut handler_1 = MockEventHandler::new(); - let msgs_1 = vec![msg_1.clone()]; - handler_1 - .expect_handle() - .once() - .with(predicate::eq(Event::BlockEnd(height))) - .returning(move |_| Ok(msgs_1.clone())); - let mut handler_2 = MockEventHandler::new(); - let msgs_2 = vec![msg_2.clone(), msg_3.clone()]; - handler_2 - .expect_handle() - .once() - .with(predicate::eq(Event::BlockEnd(height))) - .returning(move |_| Ok(msgs_2.clone())); - - assert_eq!( - handler_1 - .chain(handler_2) - .handle(&Event::BlockEnd(height)) - .await - .unwrap(), - vec![msg_1, msg_2, msg_3] - ); - } - - #[tokio::test] - async fn should_fail_if_the_first_handler_fails() { - let height: block::Height = (10_u32).into(); - - let mut handler_1 = MockEventHandler::new(); - handler_1 - .expect_handle() - .once() - .with(predicate::eq(Event::BlockEnd(height))) - .returning(|_| Err(EventHandlerError::Unknown.into())); - - assert!(handler_1 - .chain(MockEventHandler::new()) - .handle(&Event::BlockEnd(height)) - .await - .is_err()); - } - - #[tokio::test] - async fn should_fail_if_the_second_handler_fails() { - let height: block::Height = (10_u32).into(); - - let mut handler_1 = MockEventHandler::new(); - handler_1 - .expect_handle() - .once() - .with(predicate::eq(Event::BlockEnd(height))) - .returning(|_| Ok(vec![])); - let mut handler_2 = MockEventHandler::new(); - handler_2 - .expect_handle() - .once() - .with(predicate::eq(Event::BlockEnd(height))) - .returning(|_| Err(EventHandlerError::Unknown.into())); - - assert!(handler_1 - .chain(handler_2) - .handle(&Event::BlockEnd(height)) - .await - .is_err()); - } - - #[derive(Error, Debug)] - pub enum EventHandlerError { - #[error("unknown")] - Unknown, - } - - mock! { - EventHandler{} - - #[async_trait] - impl event_processor::EventHandler for EventHandler { - type Err = EventHandlerError; - - async fn handle(&self, event: &Event) -> Result, EventHandlerError>; - } - } - - fn dummy_msg(from_address: AccountId) -> Any { - MsgSend { - from_address, - to_address: AccountId::new("", &[4, 5, 6]).unwrap(), - amount: vec![], - } - .to_any() - .unwrap() - } -} diff --git a/ampd/src/handlers/end_block.rs b/ampd/src/handlers/end_block.rs deleted file mode 100644 index 9b0c88234..000000000 --- a/ampd/src/handlers/end_block.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::event_processor::EventHandler; -use async_trait::async_trait; -use cosmrs::Any; -use error_stack::{Result, ResultExt}; -use events::Event; -use tendermint::block; -use thiserror::Error; -use tokio::sync::mpsc::{self, Receiver}; - -#[derive(Error, Debug)] -pub enum Error { - #[error("failed sending label and block height")] - SendError, -} - -struct Handler { - tx: mpsc::Sender, -} - -impl Handler { - fn new() -> (Self, Receiver) { - let (tx, rx) = mpsc::channel(10000); - (Self { tx }, rx) - } -} - -pub fn with_block_height_notifier( - handler: impl EventHandler + Send + Sync, -) -> (impl EventHandler, Receiver) { - let (end_block_handler, rx) = Handler::new(); - (handler.chain(end_block_handler), rx) -} - -#[async_trait] -impl EventHandler for Handler { - type Err = Error; - - async fn handle(&self, event: &Event) -> Result, Error> { - if let Event::BlockEnd(height) = event { - self.tx - .send(*height) - .await - .change_context(Error::SendError)?; - } - - Ok(vec![]) - } -} - -#[cfg(test)] -mod tests { - use crate::event_processor::EventHandler; - use crate::handlers::end_block::Handler; - use events::Event; - use tendermint::block; - - #[tokio::test] - async fn handle_should_stream_blocks() { - let count = 10; - let (handler, mut rx) = Handler::new(); - let mut height = block::Height::default(); - - for _ in 0..count { - assert_eq!( - handler.handle(&Event::BlockEnd(height)).await.unwrap(), - vec![] - ); - height = height.increment(); - } - - let mut height = block::Height::default(); - for _ in 0..count { - let actual_height = rx.recv().await.unwrap(); - assert_eq!(actual_height, height); - - height = height.increment(); - } - } -} diff --git a/ampd/src/handlers/mod.rs b/ampd/src/handlers/mod.rs index 2711b7f74..026238768 100644 --- a/ampd/src/handlers/mod.rs +++ b/ampd/src/handlers/mod.rs @@ -1,6 +1,4 @@ -pub mod chain; pub mod config; -pub mod end_block; mod errors; pub mod evm_verify_msg; pub mod evm_verify_verifier_set; diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 50ab79b94..c726bc3d8 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -1,4 +1,3 @@ -use std::pin::Pin; use std::time::Duration; use block_height_monitor::BlockHeightMonitor; @@ -7,14 +6,12 @@ use cosmrs::proto::cosmos::{ bank::v1beta1::query_client::QueryClient as BankQueryClient, tx::v1beta1::service_client::ServiceClient, }; -use error_stack::{report, FutureExt, Result, ResultExt}; +use error_stack::{FutureExt, Result, ResultExt}; use evm::finalizer::{pick, Finalization}; use evm::json_rpc::EthereumClient; use router_api::ChainName; use thiserror::Error; use tokio::signal::unix::{signal, SignalKind}; -use tokio::sync::oneshot; -use tokio_stream::Stream; use tokio_util::sync::CancellationToken; use tracing::info; @@ -22,14 +19,11 @@ use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; use broadcaster::Broadcaster; use event_processor::EventHandler; use event_sub::EventSub; -use events::Event; use queue::queued_broadcaster::QueuedBroadcaster; -use state::StateUpdater; use tofnd::grpc::{Multisig, MultisigClient}; use types::TMAddress; use crate::config::Config; -use crate::state::State; mod asyncutil; mod block_height_monitor; @@ -45,7 +39,6 @@ mod handlers; mod health_check; mod json_rpc; mod queue; -pub mod state; mod sui; mod tm_client; mod tofnd; @@ -57,18 +50,11 @@ pub use grpc::{client, proto}; const PREFIX: &str = "axelar"; const DEFAULT_RPC_TIMEOUT: Duration = Duration::from_secs(3); -type HandlerStream = Pin> + Send>>; - -pub async fn run(cfg: Config, state: State) -> (State, Result<(), Error>) { - let app = prepare_app(cfg, state.clone()).await; - - match app { - Ok(app) => app.run().await, - Err(err) => (state, Err(err)), - } +pub async fn run(cfg: Config) -> Result<(), Error> { + prepare_app(cfg).await?.run().await } -async fn prepare_app(cfg: Config, state: State) -> Result, Error> { +async fn prepare_app(cfg: Config) -> Result, Error> { let Config { tm_jsonrpc, tm_grpc, @@ -100,19 +86,10 @@ async fn prepare_app(cfg: Config, state: State) -> Result, .await .change_context(Error::Connection)?; - let mut state_updater = StateUpdater::new(state); - let pub_key = match state_updater.state().pub_key { - Some(pub_key) => pub_key, - None => { - let pub_key = multisig_client - .keygen(&tofnd_config.key_uid, tofnd::Algorithm::Ecdsa) - .await - .change_context(Error::Tofnd)?; - state_updater.as_mut().pub_key = Some(pub_key); - - pub_key - } - }; + let pub_key = multisig_client + .keygen(&tofnd_config.key_uid, tofnd::Algorithm::Ecdsa) + .await + .change_context(Error::Tofnd)?; let broadcaster = broadcaster::UnvalidatedBasicBroadcaster::builder() .auth_query_client(auth_query_client) @@ -137,7 +114,6 @@ async fn prepare_app(cfg: Config, state: State) -> Result, App::new( tm_client, broadcaster, - state_updater, multisig_client, broadcast, event_buffer_cap, @@ -172,7 +148,6 @@ where event_subscriber: event_sub::EventSubscriber, event_processor: TaskGroup, broadcaster: QueuedBroadcaster, - state_updater: StateUpdater, multisig_client: MultisigClient, block_height_monitor: BlockHeightMonitor, health_check_server: health_check::Server, @@ -187,7 +162,6 @@ where fn new( tm_client: tendermint_rpc::HttpClient, broadcaster: T, - state_updater: StateUpdater, multisig_client: MultisigClient, broadcast_cfg: broadcaster::Config, event_buffer_cap: usize, @@ -198,10 +172,6 @@ where let (event_publisher, event_subscriber) = event_sub::EventPublisher::new(tm_client, event_buffer_cap); - let event_publisher = match state_updater.state().min_handler_block_height() { - Some(min_height) => event_publisher.start_from(min_height.increment()), - None => event_publisher, - }; let event_processor = TaskGroup::new(); let broadcaster = QueuedBroadcaster::new( @@ -216,7 +186,6 @@ where event_subscriber, event_processor, broadcaster, - state_updater, multisig_client, block_height_monitor, health_check_server, @@ -360,33 +329,20 @@ where L: AsRef, H: EventHandler + Send + Sync + 'static, { - let (handler, rx) = handlers::end_block::with_block_height_notifier(handler); - self.state_updater.register_event(label.as_ref(), rx); - + let label = label.as_ref().to_string(); let broadcaster = self.broadcaster.client(); - let sub: HandlerStream<_> = match self - .state_updater - .state() - .handler_block_height(label.as_ref()) - { - None => Box::pin(self.event_subscriber.subscribe()), - Some(&completed_height) => Box::pin(event_sub::skip_to_block( - self.event_subscriber.subscribe(), - completed_height.increment(), - )), - }; + let sub = self.event_subscriber.subscribe(); CancellableTask::create(move |token| { - event_processor::consume_events(handler, broadcaster, sub, stream_timeout, token) + event_processor::consume_events(label, handler, broadcaster, sub, stream_timeout, token) }) } - async fn run(self) -> (State, Result<(), Error>) { + async fn run(self) -> Result<(), Error> { let Self { event_publisher, event_processor, broadcaster, - state_updater, block_height_monitor, health_check_server, token, @@ -408,9 +364,7 @@ where exit_token.cancel(); }); - let (state_tx, mut state_rx) = oneshot::channel::(); - - let execution_result = TaskGroup::new() + TaskGroup::new() .add_task(CancellableTask::create(|token| { block_height_monitor .run(token) @@ -434,21 +388,8 @@ where .add_task(CancellableTask::create(|_| { broadcaster.run().change_context(Error::Broadcaster) })) - .add_task(CancellableTask::create(|_| async move { - // assert: the state updater only stops when all handlers that are updating their states have stopped - state_tx - .send(state_updater.run().await) - .map_err(|_| report!(Error::ReturnState)) - })) .run(token) - .await; - - // assert: all tasks have exited, it is safe to receive the state - let state = state_rx - .try_recv() - .expect("the state sender should have been able to send the state"); - - (state, execution_result) + .await } } diff --git a/ampd/src/main.rs b/ampd/src/main.rs index 13224390b..502f216df 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -26,10 +26,6 @@ struct Args { #[arg(short, long, default_values_os_t = vec![std::path::PathBuf::from("~/.ampd/config.toml"), std::path::PathBuf::from("config.toml")])] pub config: Vec, - /// Set the paths for state file lookup - #[arg(short, long, default_value_os_t = std::path::PathBuf::from("~/.ampd/state.json"))] - pub state: PathBuf, - /// Set the output style of the logs #[arg(short, long, value_enum, default_value_t = Output::Text)] pub output: Output, @@ -50,28 +46,25 @@ async fn main() -> ExitCode { set_up_logger(&args.output); let cfg = init_config(&args.config); - let state_path = expand_home_dir(&args.state); let result = match args.cmd { Some(SubCommand::Daemon) | None => { info!(args = args.as_value(), "starting daemon"); - daemon::run(cfg, &state_path).await.then(|result| { + daemon::run(cfg).await.then(|result| { info!("shutting down"); result }) } - Some(SubCommand::BondVerifier(args)) => bond_verifier::run(cfg, &state_path, args).await, + Some(SubCommand::BondVerifier(args)) => bond_verifier::run(cfg, args).await, Some(SubCommand::RegisterChainSupport(args)) => { - register_chain_support::run(cfg, &state_path, args).await + register_chain_support::run(cfg, args).await } Some(SubCommand::DeregisterChainSupport(args)) => { - deregister_chain_support::run(cfg, &state_path, args).await - } - Some(SubCommand::RegisterPublicKey) => register_public_key::run(cfg, &state_path).await, - Some(SubCommand::VerifierAddress) => { - verifier_address::run(cfg.tofnd_config, &state_path).await + deregister_chain_support::run(cfg, args).await } + Some(SubCommand::RegisterPublicKey) => register_public_key::run(cfg).await, + Some(SubCommand::VerifierAddress) => verifier_address::run(cfg.tofnd_config).await, }; match result { diff --git a/ampd/src/state.rs b/ampd/src/state.rs deleted file mode 100644 index 74978e994..000000000 --- a/ampd/src/state.rs +++ /dev/null @@ -1,214 +0,0 @@ -use std::path::Path; -use std::{collections::HashMap, fs}; - -use error_stack::{Result, ResultExt}; -use serde::{Deserialize, Serialize}; -use tendermint::block; -use thiserror::Error; -use tokio::sync::mpsc::Receiver; -use tokio_stream::wrappers::ReceiverStream; -use tokio_stream::{StreamExt, StreamMap}; -use tracing::info; - -use crate::types::PublicKey; - -#[derive(Error, Debug)] -pub enum Error { - #[error("invalid state file")] - InvalidState, - #[error("failed to serialize the state")] - SerializationFailure, - #[error("failed to write the state file to disk")] - WriteFailure, -} - -#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)] -pub struct State { - handlers: HashMap, - pub pub_key: Option, -} - -impl State { - pub fn min_handler_block_height(&self) -> Option<&block::Height> { - self.handlers.values().min() - } - - pub fn handler_block_height(&self, handler_name: &str) -> Option<&block::Height> { - self.handlers.get(handler_name) - } - - pub fn set_handler_block_height( - &mut self, - handler_name: impl Into, - height: impl Into, - ) { - self.handlers.insert(handler_name.into(), height.into()); - } -} - -pub struct StateUpdater { - update_stream: StreamMap>, - state: State, -} - -impl StateUpdater { - pub fn new(state: State) -> Self { - Self { - update_stream: StreamMap::new(), - state, - } - } - - pub fn state(&self) -> &State { - &self.state - } - - pub fn register_event( - &mut self, - label: impl Into, - height_changed: Receiver, - ) { - self.update_stream - .insert(label.into(), ReceiverStream::new(height_changed)); - } - - pub async fn run(mut self) -> State { - while let Some((handler, height)) = self.update_stream.next().await { - info!(handler, height = height.value(), "state updated"); - self.state.set_handler_block_height(handler, height); - } - - self.state - } -} - -impl AsMut for StateUpdater { - fn as_mut(&mut self) -> &mut State { - &mut self.state - } -} - -pub fn load(path: impl AsRef) -> Result { - info!("loading state from disk"); - - match fs::read_to_string(path) { - Ok(state) => serde_json::from_str(&state).change_context(Error::InvalidState), - Err(_) => { - info!("state file does not exist, starting from current blockchain state"); - Ok(State::default()) - } - } -} - -pub fn flush(state: &State, path: impl AsRef) -> Result<(), Error> { - info!("persisting state to disk"); - - let state = serde_json::to_string(state).change_context(Error::SerializationFailure)?; - ensure_parent_dirs_exist(&path)?; - - fs::write(&path, state) - .change_context(Error::WriteFailure) - .attach_printable(format!("{}", path.as_ref().display()))?; - - Ok(()) -} - -fn ensure_parent_dirs_exist(path: impl AsRef) -> Result<(), Error> { - match path.as_ref().parent() { - Some(parent) if !parent.exists() => fs::create_dir_all(parent) - .change_context(Error::WriteFailure) - .attach_printable(format!("{}", parent.display())), - _ => Ok(()), - } -} - -#[cfg(test)] -mod tests { - use std::panic::UnwindSafe; - use std::path::{Path, PathBuf}; - use std::{fs, panic}; - - use ecdsa::signature::rand_core::OsRng; - use tokio::sync::mpsc; - - use crate::state; - - use super::{State, StateUpdater}; - - fn run_test(state_path: impl AsRef, test: T) - where - T: FnOnce() + UnwindSafe, - { - let result = panic::catch_unwind(test); - let _ = fs::remove_file(&state_path); - let _ = state_path.as_ref().parent().map(fs::remove_dir); - assert!(result.is_ok()) - } - - #[allow(clippy::field_reassign_with_default)] // State has private fields, so using the object initializer is not possible - #[test] - fn can_load_and_flush_state() { - let path = PathBuf::from("./state_subfolder/can_load_and_flush_state.json"); - run_test(&path, || { - let mut state = State::default(); - state.pub_key = Some(ecdsa::SigningKey::random(&mut OsRng).verifying_key().into()); - state.set_handler_block_height("handler1", 10u16); - state.set_handler_block_height("handler2", 15u16); - state.set_handler_block_height("handler3", 7u16); - - state::flush(&state, &path).unwrap(); - let loaded_state = state::load(&path).unwrap(); - - assert_eq!(state, loaded_state); - }); - } - - #[tokio::test] - async fn can_update_state() { - let mut state_updater = StateUpdater::new(State::default()); - let state = state_updater.state(); - assert_eq!(state.handlers.len(), 0); - - let (tx1, rx1) = mpsc::channel(10); - let (tx2, rx2) = mpsc::channel(10); - state_updater.register_event("handler1", rx1); - state_updater.register_event("handler2", rx2); - - let pub_key = Some(ecdsa::SigningKey::random(&mut OsRng).verifying_key().into()); - state_updater.as_mut().pub_key = pub_key; - - let handle1 = tokio::spawn(async move { - tx1.send(1u16.into()).await.unwrap(); - tx1.send(2u16.into()).await.unwrap(); - tx1.send(3u16.into()).await.unwrap(); - }); - - let handle2 = tokio::spawn(async move { - tx2.send(1u16.into()).await.unwrap(); - tx2.send(2u16.into()).await.unwrap(); - tx2.send(3u16.into()).await.unwrap(); - tx2.send(4u16.into()).await.unwrap(); - }); - - let state_runner = state_updater.run(); - - assert!(handle1.await.is_ok()); - assert!(handle2.await.is_ok()); - - let modified_state = state_runner.await; - - let mut expected_state = State { - pub_key, - ..State::default() - }; - expected_state.set_handler_block_height("handler1", 3u16); - expected_state.set_handler_block_height("handler2", 4u16); - - assert_eq!(modified_state, expected_state); - - assert_eq!( - modified_state.min_handler_block_height(), - Some(&3u16.into()) - ); - } -} From 0cf4bac69f48d812e7c28d8ec93d22077bdf24fb Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Mon, 24 Jun 2024 14:15:51 -0400 Subject: [PATCH 031/168] chore(contracts): remove previous migrations (#471) --- contracts/multisig-prover/src/contract.rs | 4 +- contracts/multisig-prover/src/lib.rs | 1 - .../multisig-prover/src/migrations/mod.rs | 1 - .../multisig-prover/src/migrations/v_0_5.rs | 187 ------------------ contracts/multisig/src/contract.rs | 5 +- contracts/multisig/src/lib.rs | 1 - contracts/multisig/src/migrations/mod.rs | 1 - contracts/multisig/src/migrations/v_0_4.rs | 99 ---------- 8 files changed, 4 insertions(+), 295 deletions(-) delete mode 100644 contracts/multisig-prover/src/migrations/mod.rs delete mode 100644 contracts/multisig-prover/src/migrations/v_0_5.rs delete mode 100644 contracts/multisig/src/migrations/mod.rs delete mode 100644 contracts/multisig/src/migrations/v_0_4.rs diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 314d4c764..5f1825867 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -7,7 +7,7 @@ use error_stack::ResultExt; use crate::{ error::ContractError, - execute, migrations, + execute, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, query, reply, state::{Config, CONFIG}, @@ -136,7 +136,7 @@ pub fn migrate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_5::migrate_verifier_sets(deps) + Ok(Response::default()) } #[cfg(test)] diff --git a/contracts/multisig-prover/src/lib.rs b/contracts/multisig-prover/src/lib.rs index a46181e07..aa670ca61 100644 --- a/contracts/multisig-prover/src/lib.rs +++ b/contracts/multisig-prover/src/lib.rs @@ -3,7 +3,6 @@ pub mod encoding; pub mod error; pub mod events; mod execute; -mod migrations; pub mod msg; pub mod payload; mod query; diff --git a/contracts/multisig-prover/src/migrations/mod.rs b/contracts/multisig-prover/src/migrations/mod.rs deleted file mode 100644 index 40f174826..000000000 --- a/contracts/multisig-prover/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v_0_5; diff --git a/contracts/multisig-prover/src/migrations/v_0_5.rs b/contracts/multisig-prover/src/migrations/v_0_5.rs deleted file mode 100644 index cb5cf32d3..000000000 --- a/contracts/multisig-prover/src/migrations/v_0_5.rs +++ /dev/null @@ -1,187 +0,0 @@ -use axelar_wasm_std::{hash::Hash, FnExt, MajorityThreshold}; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{from_json, Addr, DepsMut, Response}; -use cw_storage_plus::Item; -use multisig::{key::KeyType, verifier_set::VerifierSet}; -use router_api::ChainName; - -use crate::{ - encoding::Encoder, - state::{Config, CONFIG, CURRENT_VERIFIER_SET, NEXT_VERIFIER_SET}, -}; - -const CURRENT_WORKER_SET: Item = Item::new("current_worker_set"); -const NEXT_WORKER_SET: Item = Item::new("next_worker_set"); - -#[cw_serde] -pub struct OldConfig { - pub admin: Addr, - pub governance: Addr, - pub gateway: Addr, - pub multisig: Addr, - pub coordinator: Addr, - pub service_registry: Addr, - pub voting_verifier: Addr, - pub signing_threshold: MajorityThreshold, - pub service_name: String, - pub chain_name: ChainName, - pub worker_set_diff_threshold: u32, - pub encoder: Encoder, - pub key_type: KeyType, - pub domain_separator: Hash, -} -impl OldConfig { - pub fn migrate(self) -> Config { - Config { - domain_separator: self.domain_separator, - admin: self.admin, - governance: self.governance, - gateway: self.gateway, - multisig: self.multisig, - coordinator: self.coordinator, - service_registry: self.service_registry, - voting_verifier: self.voting_verifier, - signing_threshold: self.signing_threshold, - service_name: self.service_name, - chain_name: self.chain_name, - verifier_set_diff_threshold: self.worker_set_diff_threshold, - encoder: self.encoder, - key_type: self.key_type, - } - } -} - -pub fn migrate_verifier_sets(deps: DepsMut) -> Result { - let old_config: OldConfig = deps - .storage - .get(CONFIG.as_slice()) - .expect("config not found") - .then(from_json)?; - - let new_config = old_config.migrate(); - CONFIG.save(deps.storage, &new_config)?; - let current_worker_set = CURRENT_WORKER_SET.may_load(deps.storage)?; - if let Some(current_worker_set) = current_worker_set { - CURRENT_WORKER_SET.remove(deps.storage); - CURRENT_VERIFIER_SET.save(deps.storage, ¤t_worker_set)?; - } - - let next_worker_set = NEXT_WORKER_SET.may_load(deps.storage)?; - if let Some(next_worker_set) = next_worker_set { - NEXT_WORKER_SET.remove(deps.storage); - NEXT_VERIFIER_SET.save(deps.storage, &next_worker_set)?; - } - - Ok(Response::default()) -} - -#[cfg(test)] -mod test { - use crate::{ - migrations::v_0_5::{OldConfig, NEXT_WORKER_SET}, - state::{CONFIG, CURRENT_VERIFIER_SET, NEXT_VERIFIER_SET}, - test::test_data::new_verifier_set, - }; - - use axelar_wasm_std::Threshold; - use cosmwasm_std::{testing::mock_dependencies, to_json_vec, Addr, Uint128}; - - use super::{migrate_verifier_sets, CURRENT_WORKER_SET}; - - #[test] - fn should_be_able_to_migrate_worker_set_to_verifier_set() { - let mut deps = mock_dependencies(); - - let initial_config = OldConfig { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - gateway: Addr::unchecked("gateway"), - multisig: Addr::unchecked("multisig"), - coordinator: Addr::unchecked("coordinator"), - service_registry: Addr::unchecked("service_registry"), - voting_verifier: Addr::unchecked("voting_verifier"), - signing_threshold: Threshold::try_from((2, 3)).unwrap().try_into().unwrap(), - service_name: "validators".to_string(), - chain_name: "ganache-0".parse().unwrap(), - worker_set_diff_threshold: 0, - encoder: crate::encoding::Encoder::Abi, - key_type: multisig::key::KeyType::Ecdsa, - domain_separator: [1; 32], - }; - deps.as_mut() - .storage - .set(CONFIG.as_slice(), &to_json_vec(&initial_config).unwrap()); - - let worker_set = new_verifier_set(); - - CURRENT_WORKER_SET - .save(&mut deps.storage, &worker_set) - .unwrap(); - - let res = migrate_verifier_sets(deps.as_mut()); - assert!(res.is_ok()); - - let verifier_set = CURRENT_VERIFIER_SET.load(&deps.storage).unwrap(); - assert_eq!(verifier_set, worker_set); - - assert!(NEXT_VERIFIER_SET.may_load(&deps.storage).unwrap().is_none()); - - assert!(CURRENT_WORKER_SET - .may_load(&deps.storage) - .unwrap() - .is_none()); - - assert!(NEXT_WORKER_SET.may_load(&deps.storage).unwrap().is_none()); - } - - #[test] - fn should_be_able_to_migrate_worker_set_to_verifier_set_mid_rotation() { - let mut deps = mock_dependencies(); - let initial_config = OldConfig { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - gateway: Addr::unchecked("gateway"), - multisig: Addr::unchecked("multisig"), - coordinator: Addr::unchecked("coordinator"), - service_registry: Addr::unchecked("service_registry"), - voting_verifier: Addr::unchecked("voting_verifier"), - signing_threshold: Threshold::try_from((2, 3)).unwrap().try_into().unwrap(), - service_name: "validators".to_string(), - chain_name: "ganache-0".parse().unwrap(), - worker_set_diff_threshold: 0, - encoder: crate::encoding::Encoder::Abi, - key_type: multisig::key::KeyType::Ecdsa, - domain_separator: [1; 32], - }; - deps.as_mut() - .storage - .set(CONFIG.as_slice(), &to_json_vec(&initial_config).unwrap()); - - let worker_set = new_verifier_set(); - - CURRENT_WORKER_SET - .save(&mut deps.storage, &worker_set) - .unwrap(); - - let mut next_worker_set = worker_set.clone(); - next_worker_set.threshold = worker_set.threshold.checked_add(Uint128::one()).unwrap(); - NEXT_WORKER_SET - .save(&mut deps.storage, &next_worker_set) - .unwrap(); - - let res = migrate_verifier_sets(deps.as_mut()); - assert!(res.is_ok()); - - let verifier_set = CURRENT_VERIFIER_SET.load(&deps.storage).unwrap(); - assert_eq!(verifier_set, worker_set); - - let next_verifier_set = NEXT_VERIFIER_SET.load(&deps.storage).unwrap(); - assert_eq!(next_verifier_set, next_worker_set); - - assert!(CURRENT_WORKER_SET - .may_load(&deps.storage) - .unwrap() - .is_none()); - assert!(NEXT_WORKER_SET.may_load(&deps.storage).unwrap().is_none()); - } -} diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index cfacf785a..35a07e939 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -7,7 +7,6 @@ use cosmwasm_std::{ use crate::{ events::Event, - migrations, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, state::{ get_verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, @@ -24,13 +23,13 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( - mut deps: DepsMut, + deps: DepsMut, _env: Env, _msg: Empty, ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_4::migrate(&mut deps) + Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/multisig/src/lib.rs b/contracts/multisig/src/lib.rs index 32b01b9ca..189f0ec33 100644 --- a/contracts/multisig/src/lib.rs +++ b/contracts/multisig/src/lib.rs @@ -2,7 +2,6 @@ pub mod contract; pub mod error; pub mod events; pub mod key; -mod migrations; pub mod msg; pub mod multisig; pub mod signing; diff --git a/contracts/multisig/src/migrations/mod.rs b/contracts/multisig/src/migrations/mod.rs deleted file mode 100644 index 683e59145..000000000 --- a/contracts/multisig/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v_0_4; diff --git a/contracts/multisig/src/migrations/v_0_4.rs b/contracts/multisig/src/migrations/v_0_4.rs deleted file mode 100644 index 1dcd7d038..000000000 --- a/contracts/multisig/src/migrations/v_0_4.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::{ - signing::SigningSession, - state::{SIGNING_SESSIONS, VERIFIER_SETS}, -}; -use cosmwasm_std::{DepsMut, Order, Response}; - -pub fn migrate_verifier_set_ids( - deps: &mut DepsMut, -) -> Result { - let all: Vec<_> = VERIFIER_SETS - .range(deps.storage, None, None, Order::Ascending) - .collect::, _>>()?; - - for v in all { - VERIFIER_SETS.remove(deps.storage, &v.0); - VERIFIER_SETS.save(deps.storage, &v.1.id(), &v.1)?; - } - - Ok(Response::default()) -} - -pub fn migrate_signing_sessions( - deps: &mut DepsMut, -) -> Result { - let all: Vec<_> = SIGNING_SESSIONS - .range(deps.storage, None, None, Order::Ascending) - .collect::, _>>()?; - - for (session_id, session) in all { - let verifier_set = VERIFIER_SETS.load(deps.storage, &session.verifier_set_id)?; - let new_session = SigningSession { - verifier_set_id: verifier_set.id(), - ..session - }; - SIGNING_SESSIONS.save(deps.storage, session_id, &new_session)?; - } - - Ok(Response::default()) -} - -pub fn migrate(deps: &mut DepsMut) -> Result { - // signing sessions should be migrated first, so that way the old ids still point to the verifier sets - migrate_signing_sessions(deps)?; - migrate_verifier_set_ids(deps) -} - -#[cfg(test)] -mod test { - use crate::{ - signing::SigningSession, - state::{SIGNING_SESSIONS, VERIFIER_SETS}, - test::common::{build_verifier_set, ecdsa_test_data::signers}, - }; - - use cosmwasm_std::{testing::mock_dependencies, HexBinary, Uint64}; - - use super::migrate; - - #[test] - fn should_be_able_to_migrate_verifier_set_ids() { - let mut deps = mock_dependencies(); - let signers = signers(); - let verifier_set = build_verifier_set(crate::key::KeyType::Ecdsa, &signers); - VERIFIER_SETS - .save(&mut deps.storage, "foobar", &verifier_set) - .unwrap(); - let signing_session = SigningSession { - id: Uint64::one(), - verifier_set_id: "foobar".to_string(), - chain_name: "ethereum".parse().unwrap(), - msg: HexBinary::from([2; 32]).try_into().unwrap(), - state: crate::types::MultisigState::Pending, - expires_at: 100, - sig_verifier: None, - }; - SIGNING_SESSIONS - .save( - &mut deps.storage, - signing_session.id.u64(), - &signing_session, - ) - .unwrap(); - migrate(&mut deps.as_mut()).unwrap(); - - let new_verifier_set = VERIFIER_SETS - .load(&deps.storage, &verifier_set.id()) - .unwrap(); - assert_eq!(new_verifier_set, verifier_set); - - let expected_signing_session = SigningSession { - verifier_set_id: verifier_set.id(), - ..signing_session - }; - let new_signing_session = SIGNING_SESSIONS - .load(&deps.storage, expected_signing_session.id.u64()) - .unwrap(); - assert_eq!(new_signing_session, expected_signing_session); - } -} From a75c99cf0eaa6d8dafd5f1b6986d6a36dfb78190 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:23:16 +0000 Subject: [PATCH 032/168] chore: release router 0.3.3 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/router/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2233c3d74..d694092ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6203,7 +6203,7 @@ dependencies = [ [[package]] name = "router" -version = "0.3.2" +version = "0.3.3" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index a0ddecd73..935bf4b1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ resolver = "2" rust-version = "1.78.0" # be sure there is an optimizer release supporting this version before updating. See https://github.com/CosmWasm/optimizer [workspace.dependencies] -router = { version = "^0.3.2", path = "contracts/router" } +router = { version = "^0.3.3", path = "contracts/router" } cosmwasm-std = "1.5.5" cosmwasm-schema = "1.5.5" cw-storage-plus = "1.2.0" diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 13c3a863b..8465ff312 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "router" -version = "0.3.2" +version = "0.3.3" rust-version = { workspace = true } edition = "2021" description = "Router contract" From 3afbb1d7ea384f63a5a1cc3a176128b74c3cf63a Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:24:27 +0000 Subject: [PATCH 033/168] chore: release gateway 0.2.3 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/gateway/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d694092ef..bd9b91ff8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2925,7 +2925,7 @@ dependencies = [ [[package]] name = "gateway" -version = "0.2.2" +version = "0.2.3" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 935bf4b1f..d23e7394e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ multisig = { version = "^0.3.0", path = "contracts/multisig" } multisig-prover = { version = "^0.5.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^0.3.0", path = "contracts/service-registry" } -gateway = { version = "^0.2.2", path = "contracts/gateway" } +gateway = { version = "^0.2.3", path = "contracts/gateway" } gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } router-api = { version = "^0.1.0", path = "packages/router-api" } report = { version = "^0.1.0", path = "packages/report" } diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index b6f3d277d..f822930ac 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gateway" -version = "0.2.2" +version = "0.2.3" rust-version = { workspace = true } edition = "2021" description = "Gateway contract" From e6ad21fdeea857287cd392e4f61bbc2a41f7b357 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:28:16 +0000 Subject: [PATCH 034/168] chore: release multisig 0.4.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/multisig/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd9b91ff8..5062da11c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4546,7 +4546,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multisig" -version = "0.3.0" +version = "0.4.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index d23e7394e..563001f9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ integration-tests = { version = "^0.1.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.4.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.1.2", path = "contracts/coordinator" } -multisig = { version = "^0.3.0", path = "contracts/multisig" } +multisig = { version = "^0.4.0", path = "contracts/multisig" } multisig-prover = { version = "^0.5.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^0.3.0", path = "contracts/service-registry" } diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index ba1dcbaeb..f5f46158b 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multisig" -version = "0.3.0" +version = "0.4.0" rust-version = { workspace = true } edition = "2021" description = "Multisig contract" From bceb33f1349e0ae154fc7697473cb75c00d4e5a2 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:30:30 +0000 Subject: [PATCH 035/168] chore: release multisig-prover 0.6.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/multisig-prover/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5062da11c..967515bac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4576,7 +4576,7 @@ dependencies = [ [[package]] name = "multisig-prover" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "axelar-wasm-std", diff --git a/Cargo.toml b/Cargo.toml index 563001f9e..f8d612998 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ itertools = "0.11.0" voting-verifier = { version = "^0.4.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.1.2", path = "contracts/coordinator" } multisig = { version = "^0.4.0", path = "contracts/multisig" } -multisig-prover = { version = "^0.5.0", path = "contracts/multisig-prover" } +multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^0.3.0", path = "contracts/service-registry" } gateway = { version = "^0.2.3", path = "contracts/gateway" } diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 16b5d92fa..3f4d92f08 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multisig-prover" -version = "0.5.0" +version = "0.6.0" rust-version = { workspace = true } edition = "2021" description = "Multisig prover contract" From eafb04f065d2492055e29fd9e8c7e452fd88a188 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:33:44 +0000 Subject: [PATCH 036/168] chore: release nexus-gateway 0.3.0 [skip ci] --- Cargo.lock | 2 +- contracts/nexus-gateway/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 967515bac..f3a6fc68b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4733,7 +4733,7 @@ dependencies = [ [[package]] name = "nexus-gateway" -version = "0.2.3" +version = "0.3.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index 818749f73..17f30bbc9 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nexus-gateway" -version = "0.2.3" +version = "0.3.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 8b8d38645dd3fbc0eec24369f90f63a4d9ddf1bc Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:35:18 +0000 Subject: [PATCH 037/168] chore: release rewards 0.4.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/rewards/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3a6fc68b..7a6c4c385 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6093,7 +6093,7 @@ dependencies = [ [[package]] name = "rewards" -version = "0.3.0" +version = "0.4.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index f8d612998..00afed1d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } router-api = { version = "^0.1.0", path = "packages/router-api" } report = { version = "^0.1.0", path = "packages/report" } client = { version = "^0.1.0", path = "packages/client" } -rewards = { version = "^0.3.0", path = "contracts/rewards" } +rewards = { version = "^0.4.0", path = "contracts/rewards" } thiserror = "1.0.47" serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index 919a5d162..8d955565d 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rewards" -version = "0.3.0" +version = "0.4.0" rust-version = { workspace = true } edition = "2021" description = "Validator rewards contract" From d782e87a7b061ddfb020bd201883b8acee8608d6 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:36:32 +0000 Subject: [PATCH 038/168] chore: release service-registry 0.4.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/service-registry/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a6c4c385..b81c562f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6798,7 +6798,7 @@ dependencies = [ [[package]] name = "service-registry" -version = "0.3.0" +version = "0.4.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 00afed1d6..301f57b49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ coordinator = { version = "^0.1.2", path = "contracts/coordinator" } multisig = { version = "^0.4.0", path = "contracts/multisig" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } -service-registry = { version = "^0.3.0", path = "contracts/service-registry" } +service-registry = { version = "^0.4.0", path = "contracts/service-registry" } gateway = { version = "^0.2.3", path = "contracts/gateway" } gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } router-api = { version = "^0.1.0", path = "packages/router-api" } diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index 184e85b43..b362086a0 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "service-registry" -version = "0.3.0" +version = "0.4.0" rust-version = { workspace = true } edition = "2021" description = "Contract handling the service registrations" From c22bea5fda209482d2a25ccf80662cef8f6a7a29 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:38:35 +0000 Subject: [PATCH 039/168] chore: release voting-verifier 0.5.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/voting-verifier/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b81c562f9..2409af617 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8468,7 +8468,7 @@ checksum = "2e4fe92cfc1bad19c19925d5eee4b30584dbbdee4ff10183b261acccbef74e2d" [[package]] name = "voting-verifier" -version = "0.4.0" +version = "0.5.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 301f57b49..20ad73d67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ axelar-wasm-std = { version = "^0.1.0", path = "packages/axelar-wasm-std" } axelar-wasm-std-derive = { version = "^0.1.0", path = "packages/axelar-wasm-std-derive" } integration-tests = { version = "^0.1.0", path = "integration-tests" } itertools = "0.11.0" -voting-verifier = { version = "^0.4.0", path = "contracts/voting-verifier" } +voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.1.2", path = "contracts/coordinator" } multisig = { version = "^0.4.0", path = "contracts/multisig" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index cfb289a47..35f139271 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "voting-verifier" -version = "0.4.0" +version = "0.5.0" rust-version = { workspace = true } edition = "2021" description = "Voting verifier contract" From d7646ebc75fb0522c0f368d42991276b464bb8f8 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:40:29 +0000 Subject: [PATCH 040/168] chore: release coordinator 0.2.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/coordinator/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2409af617..b3819187f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1424,7 +1424,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "coordinator" -version = "0.1.2" +version = "0.2.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 20ad73d67..d5f7f2b7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ axelar-wasm-std-derive = { version = "^0.1.0", path = "packages/axelar-wasm-std- integration-tests = { version = "^0.1.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } -coordinator = { version = "^0.1.2", path = "contracts/coordinator" } +coordinator = { version = "^0.2.0", path = "contracts/coordinator" } multisig = { version = "^0.4.0", path = "contracts/multisig" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index df6eb2133..509558efd 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "coordinator" -version = "0.1.2" +version = "0.2.0" rust-version = { workspace = true } edition = "2021" description = "Amplifier info aggregation for external use, alongside contract management, instantiation and migration" From 6d6b974e1a911b17b2d019cb14c5ceb748cc244a Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Mon, 24 Jun 2024 18:45:13 +0000 Subject: [PATCH 041/168] chore: release ampd 0.5.0 [skip ci] --- Cargo.lock | 2 +- ampd/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3819187f..d851f045d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ dependencies = [ [[package]] name = "ampd" -version = "0.4.0" +version = "0.5.0" dependencies = [ "async-trait", "axelar-wasm-std", diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index 5d2bd101d..5871c06ef 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "ampd" -version = "0.4.0" +version = "0.5.0" rust-version = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 1ebaae763d2f78bae7f0cfc7efb7591a9885e3c9 Mon Sep 17 00:00:00 2001 From: eguajardo Date: Mon, 8 Jul 2024 11:54:26 -0600 Subject: [PATCH 042/168] fix: service registry and multisig migrations (#487) --- Cargo.lock | 4 +- Cargo.toml | 4 +- contracts/multisig/Cargo.toml | 2 +- contracts/multisig/src/contract.rs | 3 +- contracts/multisig/src/lib.rs | 1 + contracts/multisig/src/migrations/mod.rs | 1 + contracts/multisig/src/migrations/v_0_4.rs | 78 +++++++++++++++++++ contracts/service-registry/Cargo.toml | 2 +- contracts/service-registry/src/contract.rs | 9 ++- .../service-registry/src/migrations/v_0_4.rs | 13 ++-- contracts/service-registry/src/msg.rs | 5 ++ 11 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 contracts/multisig/src/migrations/mod.rs create mode 100644 contracts/multisig/src/migrations/v_0_4.rs diff --git a/Cargo.lock b/Cargo.lock index d851f045d..aaebe3aa0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4546,7 +4546,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multisig" -version = "0.4.0" +version = "0.4.1" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", @@ -6798,7 +6798,7 @@ dependencies = [ [[package]] name = "service-registry" -version = "0.4.0" +version = "0.4.1" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index d5f7f2b7b..894ff15ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,10 +21,10 @@ integration-tests = { version = "^0.1.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.2.0", path = "contracts/coordinator" } -multisig = { version = "^0.4.0", path = "contracts/multisig" } +multisig = { version = "^0.4.1", path = "contracts/multisig" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } -service-registry = { version = "^0.4.0", path = "contracts/service-registry" } +service-registry = { version = "^0.4.1", path = "contracts/service-registry" } gateway = { version = "^0.2.3", path = "contracts/gateway" } gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } router-api = { version = "^0.1.0", path = "packages/router-api" } diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index f5f46158b..001e30a3c 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multisig" -version = "0.4.0" +version = "0.4.1" rust-version = { workspace = true } edition = "2021" description = "Multisig contract" diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 35a07e939..be358b93a 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -7,6 +7,7 @@ use cosmwasm_std::{ use crate::{ events::Event, + migrations, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, state::{ get_verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, @@ -29,7 +30,7 @@ pub fn migrate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - Ok(Response::default()) + migrations::v_0_4::migrate(deps) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/multisig/src/lib.rs b/contracts/multisig/src/lib.rs index 189f0ec33..32b01b9ca 100644 --- a/contracts/multisig/src/lib.rs +++ b/contracts/multisig/src/lib.rs @@ -2,6 +2,7 @@ pub mod contract; pub mod error; pub mod events; pub mod key; +mod migrations; pub mod msg; pub mod multisig; pub mod signing; diff --git a/contracts/multisig/src/migrations/mod.rs b/contracts/multisig/src/migrations/mod.rs new file mode 100644 index 000000000..683e59145 --- /dev/null +++ b/contracts/multisig/src/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v_0_4; diff --git a/contracts/multisig/src/migrations/v_0_4.rs b/contracts/multisig/src/migrations/v_0_4.rs new file mode 100644 index 000000000..0913c788f --- /dev/null +++ b/contracts/multisig/src/migrations/v_0_4.rs @@ -0,0 +1,78 @@ +use crate::state::{SIGNING_SESSIONS, VERIFIER_SETS}; +use cosmwasm_std::{DepsMut, Order, Response, Storage}; + +fn migrate_verifier_set_ids( + store: &mut dyn Storage, +) -> Result { + let all: Vec<_> = VERIFIER_SETS + .range(store, None, None, Order::Ascending) + .collect::, _>>()?; + + for v in all { + VERIFIER_SETS.remove(store, &v.0); + VERIFIER_SETS.save(store, &v.1.id(), &v.1)?; + } + + Ok(Response::default()) +} + +fn remove_all_signing_sessions( + store: &mut dyn Storage, +) -> Result { + SIGNING_SESSIONS.clear(store); + + Ok(Response::default()) +} + +pub fn migrate(deps: DepsMut) -> Result { + remove_all_signing_sessions(deps.storage)?; + migrate_verifier_set_ids(deps.storage) +} + +#[cfg(test)] +mod test { + use crate::{ + signing::SigningSession, + state::{SIGNING_SESSIONS, VERIFIER_SETS}, + test::common::{build_verifier_set, ecdsa_test_data::signers}, + }; + + use cosmwasm_std::{testing::mock_dependencies, HexBinary, Uint64}; + + use super::migrate; + + #[test] + fn should_be_able_to_migrate_verifier_set_ids() { + let mut deps = mock_dependencies(); + let signers = signers(); + let verifier_set = build_verifier_set(crate::key::KeyType::Ecdsa, &signers); + VERIFIER_SETS + .save(&mut deps.storage, "foobar", &verifier_set) + .unwrap(); + let signing_session = SigningSession { + id: Uint64::one(), + verifier_set_id: "foobar".to_string(), + chain_name: "ethereum".parse().unwrap(), + msg: HexBinary::from([2; 32]).try_into().unwrap(), + state: crate::types::MultisigState::Pending, + expires_at: 100, + sig_verifier: None, + }; + SIGNING_SESSIONS + .save( + &mut deps.storage, + signing_session.id.u64(), + &signing_session, + ) + .unwrap(); + + migrate(deps.as_mut()).unwrap(); + + let new_verifier_set = VERIFIER_SETS.load(&deps.storage, &verifier_set.id()); + assert!(new_verifier_set.is_ok(), "{:?}", new_verifier_set); + assert_eq!(new_verifier_set.unwrap(), verifier_set); + + let loaded_signing_session = SIGNING_SESSIONS.load(&deps.storage, signing_session.id.u64()); + assert!(loaded_signing_session.is_err()); + } +} diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index b362086a0..91e6ccfdd 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "service-registry" -version = "0.4.0" +version = "0.4.1" rust-version = { workspace = true } edition = "2021" description = "Contract handling the service registrations" diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 065f6c230..33d086c22 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,13 +1,13 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, Order, + to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Order, QueryRequest, Response, Uint128, WasmQuery, }; use crate::error::ContractError; use crate::migrations; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::{AuthorizationState, BondingState, Config, Service, Verifier, CONFIG, SERVICES}; mod execute; @@ -161,10 +161,11 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_4::migrate_services(deps.storage).map_err(axelar_wasm_std::ContractError::from) + migrations::v_0_4::migrate_services_coordinator_contract(deps.storage, msg.coordinator_contract) + .map_err(axelar_wasm_std::ContractError::from) } #[cfg(test)] diff --git a/contracts/service-registry/src/migrations/v_0_4.rs b/contracts/service-registry/src/migrations/v_0_4.rs index 6d86c8966..ebce0cf46 100644 --- a/contracts/service-registry/src/migrations/v_0_4.rs +++ b/contracts/service-registry/src/migrations/v_0_4.rs @@ -1,6 +1,6 @@ //! Migrate the `Service` struct and rename `service_contract` field to `coordinator_contract`. -use cosmwasm_std::{Order, Response, Storage}; +use cosmwasm_std::{Addr, Order, Response, Storage}; use crate::state::{Service, SERVICES}; @@ -25,8 +25,9 @@ mod v0_3_state { pub const SERVICES: Map<&ServiceName, Service> = Map::new("services"); } -pub fn migrate_services( +pub fn migrate_services_coordinator_contract( store: &mut dyn Storage, + coordinator_contract: Addr, ) -> Result { v0_3_state::SERVICES .range(store, None, None, Order::Ascending) @@ -35,7 +36,7 @@ pub fn migrate_services( .map(|(service_name, service)| { let service = Service { name: service.name, - coordinator_contract: service.service_contract, + coordinator_contract: coordinator_contract.clone(), min_num_verifiers: service.min_num_verifiers, max_num_verifiers: service.max_num_verifiers, min_verifier_bond: service.min_verifier_bond, @@ -88,7 +89,9 @@ mod test { .unwrap(); } - migrate_services(&mut deps.storage).unwrap(); + let coordinator_contract = Addr::unchecked("coordinator"); + migrate_services_coordinator_contract(&mut deps.storage, coordinator_contract.clone()) + .unwrap(); for service in &initial_services { let migrated_service: Service = @@ -96,7 +99,7 @@ mod test { let expected_service = Service { name: service.name.clone(), - coordinator_contract: service.service_contract.clone(), + coordinator_contract: coordinator_contract.clone(), min_num_verifiers: service.min_num_verifiers, max_num_verifiers: service.max_num_verifiers, min_verifier_bond: service.min_verifier_bond, diff --git a/contracts/service-registry/src/msg.rs b/contracts/service-registry/src/msg.rs index 777ee0353..34b3718bd 100644 --- a/contracts/service-registry/src/msg.rs +++ b/contracts/service-registry/src/msg.rs @@ -79,3 +79,8 @@ pub enum QueryMsg { verifier: String, }, } + +#[cw_serde] +pub struct MigrateMsg { + pub coordinator_contract: Addr, +} From d4f9cc211d2125a878220ddf065660ce60fd6e67 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 26 Jun 2024 17:30:20 -0400 Subject: [PATCH 043/168] docs: update compatibility matrix (#475) --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a994108d5..6afdc7caf 100644 --- a/README.md +++ b/README.md @@ -43,15 +43,15 @@ contracts and `ampd` that work well together. | Binary | Version | |-------------|---------| -| ampd | 0.4.0 | -| coordinator | 0.1.2 | -| gateway | 0.2.2 | -| multisig-prover | 0.5.0 | -| multisig | 0.3.0 | -| nexus-gateway | 0.2.3 | -| rewards | 0.2.0 | -| router | 0.3.2 | -| service-registry | 0.3.0 | -| voting-verifier | 0.4.0 | +| ampd | 0.5.0 | +| coordinator | 0.2.0 | +| gateway | 0.2.3 | +| multisig-prover | 0.6.0 | +| multisig | 0.4.0 | +| nexus-gateway | 0.3.0 | +| rewards | 0.4.0 | +| router | 0.3.3 | +| service-registry | 0.4.0 | +| voting-verifier | 0.5.0 | | [tofnd](https://github.com/axelarnetwork/tofnd) | TBD | | [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | From a5679f9d7c76afaeefb4ce8260c9b015b5c58160 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Thu, 27 Jun 2024 11:33:16 -0400 Subject: [PATCH 044/168] feat(minor-ampd): support ed25519 keygen and sign (#465) * feat(minor-ampd): register public key takes in key type * tofnd client parse ed25519 * cargo sort --- Cargo.lock | 18 +++---- Cargo.toml | 1 + ampd/Cargo.toml | 3 ++ ampd/src/commands/mod.rs | 2 +- ampd/src/commands/register_public_key.rs | 64 ++++++++++++++++++------ ampd/src/main.rs | 2 +- ampd/src/tofnd/grpc.rs | 42 +++++++++++----- contracts/multisig/Cargo.toml | 2 +- 8 files changed, 92 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaebe3aa0..bde6eaa82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,9 +139,12 @@ dependencies = [ "config", "cosmrs", "cosmwasm-std", + "der 0.7.9", "deref-derive", "dirs", "ecdsa", + "ed25519 2.2.3", + "ed25519-dalek", "elliptic-curve", "enum-display-derive", "error-stack", @@ -1658,16 +1661,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -2164,7 +2166,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519 2.2.3", "rand_core 0.6.4", "serde", @@ -4553,7 +4555,7 @@ dependencies = [ "cosmwasm-crypto", "cosmwasm-schema", "cosmwasm-std", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", @@ -5450,12 +5452,6 @@ dependencies = [ "spki 0.7.3", ] -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "polyval" version = "0.6.2" diff --git a/Cargo.toml b/Cargo.toml index 894ff15ab..37e9d88fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ cosmwasm-std = "1.5.5" cosmwasm-schema = "1.5.5" cw-storage-plus = "1.2.0" cw2 = "1.1.0" +ed25519-dalek = { version = "2.1.1", default-features = false } error-stack = { version = "0.4.0", features = ["eyre"] } events = { version = "^0.1.0", path = "packages/events" } events-derive = { version = "^0.1.0", path = "packages/events-derive" } diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index 5871c06ef..1a0934c01 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -15,9 +15,12 @@ clap = { version = "4.2.7", features = ["derive", "cargo"] } config = "0.13.2" cosmrs = { version = "0.14.0", features = ["cosmwasm", "grpc"] } cosmwasm-std = { workspace = true, features = ["stargate"] } +der = "0.7.9" deref-derive = "0.1.0" dirs = "5.0.1" ecdsa = { version = "0.16.6" } +ed25519 ={ version = "2.2.3", features = ["pem"], default-features = false } +ed25519-dalek = { workspace = true } enum-display-derive = "0.1.1" error-stack = { workspace = true } ethers-contract = { workspace = true } diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 18a187fb2..c00e47911 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -37,7 +37,7 @@ pub enum SubCommand { /// Deregister chain support to the service registry contract DeregisterChainSupport(deregister_chain_support::Args), /// Register public key to the multisig contract - RegisterPublicKey, + RegisterPublicKey(register_public_key::Args), /// Query the verifier address VerifierAddress, } diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index d7010d623..960d6885c 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -1,24 +1,55 @@ -use std::convert::TryFrom; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use cosmrs::{cosmwasm::MsgExecuteContract, tx::Msg}; use error_stack::{Result, ResultExt}; -use multisig::{ - key::{KeyType, PublicKey}, - msg::ExecuteMsg, -}; +use multisig::{key::PublicKey, msg::ExecuteMsg}; use report::ResultCompatExt; use sha3::{Digest, Keccak256}; use tracing::info; +use valuable::Valuable; + +use crate::{ + commands::{broadcast_tx, verifier_pub_key}, + config::Config, + handlers, + tofnd::{ + self, + grpc::{Multisig, MultisigClient}, + }, + types::TMAddress, + Error, PREFIX, +}; -use crate::commands::{broadcast_tx, verifier_pub_key}; -use crate::config::Config; -use crate::tofnd; -use crate::tofnd::grpc::{Multisig, MultisigClient}; -use crate::types::TMAddress; -use crate::{handlers, Error, PREFIX}; +#[derive(clap::ValueEnum, Clone, Debug, Valuable, Copy)] +enum KeyType { + Ecdsa, + Ed25519, +} + +impl From for tofnd::Algorithm { + fn from(val: KeyType) -> Self { + match val { + KeyType::Ecdsa => tofnd::Algorithm::Ecdsa, + KeyType::Ed25519 => tofnd::Algorithm::Ed25519, + } + } +} -pub async fn run(config: Config) -> Result, Error> { +impl From for multisig::key::KeyType { + fn from(val: KeyType) -> Self { + match val { + KeyType::Ecdsa => multisig::key::KeyType::Ecdsa, + KeyType::Ed25519 => multisig::key::KeyType::Ed25519, + } + } +} + +#[derive(clap::Args, Debug, Valuable)] +pub struct Args { + key_type: KeyType, +} + +pub async fn run(config: Config, args: Args) -> Result, Error> { let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; let multisig_address = get_multisig_address(&config)?; @@ -29,9 +60,10 @@ pub async fn run(config: Config) -> Result, Error> { .await .change_context(Error::Connection)?; let multisig_key = multisig_client - .keygen(&multisig_address.to_string(), tofnd::Algorithm::Ecdsa) + .keygen(&multisig_address.to_string(), args.key_type.into()) .await .change_context(Error::Tofnd)?; + info!(key_id = multisig_address.to_string(), "keygen successful"); let sender = pub_key.account_id(PREFIX).change_context(Error::Tofnd)?; @@ -46,14 +78,14 @@ pub async fn run(config: Config) -> Result, Error> { &multisig_address.to_string(), address_hash.into(), &multisig_key, - tofnd::Algorithm::Ecdsa, + args.key_type.into(), ) .await .change_context(Error::Tofnd)? .into(); let msg = serde_json::to_vec(&ExecuteMsg::RegisterPublicKey { - public_key: PublicKey::try_from((KeyType::Ecdsa, multisig_key.to_bytes().into())) + public_key: PublicKey::try_from((args.key_type.into(), multisig_key.to_bytes().into())) .change_context(Error::Tofnd)?, signed_sender_address, }) diff --git a/ampd/src/main.rs b/ampd/src/main.rs index 502f216df..a15b409a1 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -63,7 +63,7 @@ async fn main() -> ExitCode { Some(SubCommand::DeregisterChainSupport(args)) => { deregister_chain_support::run(cfg, args).await } - Some(SubCommand::RegisterPublicKey) => register_public_key::run(cfg).await, + Some(SubCommand::RegisterPublicKey(args)) => register_public_key::run(cfg, args).await, Some(SubCommand::VerifierAddress) => verifier_address::run(cfg.tofnd_config).await, }; diff --git a/ampd/src/tofnd/grpc.rs b/ampd/src/tofnd/grpc.rs index 98260b99a..0c934e423 100644 --- a/ampd/src/tofnd/grpc.rs +++ b/ampd/src/tofnd/grpc.rs @@ -1,8 +1,10 @@ use std::sync::Arc; use async_trait::async_trait; -use ecdsa::VerifyingKey; -use error_stack::ResultExt; +use cosmrs::tendermint::public_key::PublicKey as TMPublicKey; +use der::{asn1::BitStringRef, Sequence}; +use ed25519::pkcs8::spki::{der::Decode, AlgorithmIdentifierRef}; +use error_stack::{Report, ResultExt}; use k256::Secp256k1; use mockall::automock; use tokio::sync::Mutex; @@ -72,12 +74,13 @@ impl Multisig for MultisigClient { }) .change_context(Error::Grpc) .and_then(|response| match response { - KeygenResponse::PubKey(pub_key) => { - VerifyingKey::from_sec1_bytes(pub_key.as_slice()) - .change_context(Error::ParsingFailed) - .attach_printable(format!("{{ invalid_value = {:?} }}", pub_key)) - .map(Into::into) + KeygenResponse::PubKey(pub_key) => match algorithm { + Algorithm::Ecdsa => TMPublicKey::from_raw_secp256k1(&pub_key), + Algorithm::Ed25519 => TMPublicKey::from_raw_ed25519(&pub_key), } + .ok_or_else(|| Report::new(Error::ParsingFailed)) + .attach_printable(format!("{{ invalid_value = {:?} }}", pub_key)) + .map(Into::into), KeygenResponse::Error(error_msg) => { Err(TofndError::ExecutionFailed(error_msg)).change_context(Error::KeygenFailed) } @@ -112,15 +115,30 @@ impl Multisig for MultisigClient { }) .change_context(Error::Grpc) .and_then(|response| match response { - SignResponse::Signature(signature) => { - ecdsa::Signature::::from_der(&signature) - .change_context(Error::ParsingFailed) + SignResponse::Signature(signature) => match algorithm { + Algorithm::Ecdsa => ecdsa::Signature::::from_der(&signature) .map(|sig| sig.to_vec()) - .map(Into::into) - } + .change_context(Error::ParsingFailed), + Algorithm::Ed25519 => parse_der_ed25519_signature(&signature), + }, + SignResponse::Error(error_msg) => { Err(TofndError::ExecutionFailed(error_msg)).change_context(Error::SignFailed) } }) } } + +#[derive(Sequence)] +struct Asn1Signature<'a> { + pub signature_algorithm: AlgorithmIdentifierRef<'a>, + pub signature: BitStringRef<'a>, +} + +fn parse_der_ed25519_signature(der_sig: &[u8]) -> Result { + let der_decoded = Asn1Signature::from_der(der_sig).change_context(Error::ParsingFailed)?; + + ed25519_dalek::Signature::from_slice(der_decoded.signature.raw_bytes()) + .map(|s| s.to_vec()) + .change_context(Error::ParsingFailed) +} diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 001e30a3c..4ca5922e4 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -48,7 +48,7 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = "1.0.1" cw2 = { workspace = true } -ed25519-dalek = { version = "2.1.1", default-features = false } +ed25519-dalek = { workspace = true } enum-display-derive = "0.1.1" error-stack = { workspace = true } getrandom = { version = "0.2", default-features = false, features = ["custom"] } From 34db91ff54a1f22f3ac1d0f3d313c6fafda0cc98 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Thu, 27 Jun 2024 18:13:46 -0400 Subject: [PATCH 045/168] fix(ampd): enable derive for der crate (#477) --- ampd/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index 1a0934c01..faadfd5ba 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -15,7 +15,7 @@ clap = { version = "4.2.7", features = ["derive", "cargo"] } config = "0.13.2" cosmrs = { version = "0.14.0", features = ["cosmwasm", "grpc"] } cosmwasm-std = { workspace = true, features = ["stargate"] } -der = "0.7.9" +der = { version = "0.7.9", features = ["derive"] } deref-derive = "0.1.0" dirs = "5.0.1" ecdsa = { version = "0.16.6" } From 87ef101f48c362c79ca16505903ea722b264507f Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 27 Jun 2024 21:50:30 -0400 Subject: [PATCH 046/168] refactor: generalize msg access control (#473) --- Cargo.lock | 2 + contracts/router/src/contract.rs | 142 +++++--- contracts/router/src/contract/execute.rs | 320 ++++++++---------- contracts/router/src/lib.rs | 1 + contracts/router/src/migrations/mod.rs | 1 + contracts/router/src/migrations/v0_3_3.rs | 65 ++++ packages/axelar-wasm-std/Cargo.toml | 2 + packages/axelar-wasm-std/src/error.rs | 5 + packages/axelar-wasm-std/src/lib.rs | 1 + .../axelar-wasm-std/src/permission_control.rs | 310 +++++++++++++++++ packages/router-api/src/error.rs | 3 - 11 files changed, 623 insertions(+), 229 deletions(-) create mode 100644 contracts/router/src/migrations/mod.rs create mode 100644 contracts/router/src/migrations/v0_3_3.rs create mode 100644 packages/axelar-wasm-std/src/permission_control.rs diff --git a/Cargo.lock b/Cargo.lock index bde6eaa82..960b06367 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -648,9 +648,11 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", + "cw2 1.1.2", "error-stack", "flagset", "hex", + "itertools 0.11.0", "lazy_static", "num-traits", "rand", diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 5e042d6c5..8a389f09f 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -1,3 +1,5 @@ +use axelar_wasm_std::permission_control::Permission; +use axelar_wasm_std::{ensure_any_permission, ensure_permission, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; @@ -5,6 +7,7 @@ use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInf use router_api::msg::{ExecuteMsg, QueryMsg}; use crate::events::RouterInstantiated; +use crate::migrations; use crate::msg::InstantiateMsg; use crate::state::{Config, RouterStore, Store}; @@ -20,10 +23,9 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - // any version checks should be done before here + migrations::v0_3_3::migrate(deps.storage)?; cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - Ok(Response::default()) } @@ -45,6 +47,8 @@ pub fn instantiate( governance: governance.clone(), nexus_gateway: nexus_gateway.clone(), }; + permission_control::set_admin(deps.storage, &admin)?; + permission_control::set_governance(deps.storage, &governance)?; RouterStore::new(deps.storage) .save_config(config) @@ -67,15 +71,14 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - let contract = Contract::new(RouterStore::new(deps.storage)); - match msg { ExecuteMsg::RegisterChain { chain, gateway_address, msg_id_format, } => { - execute::require_governance(&deps, info)?; + ensure_permission!(Permission::Governance, deps.storage, &info.sender); + let gateway_address = deps.api.addr_validate(&gateway_address)?; execute::register_chain(deps, chain, gateway_address, msg_id_format) } @@ -83,43 +86,34 @@ pub fn execute( chain, contract_address, } => { - execute::require_governance(&deps, info)?; + ensure_permission!(Permission::Governance, deps.storage, &info.sender); + let contract_address = deps.api.addr_validate(&contract_address)?; execute::upgrade_gateway(deps, chain, contract_address) } ExecuteMsg::FreezeChain { chain, direction } => { - execute::require_admin(&deps, info)?; + ensure_permission!(Permission::Admin, deps.storage, &info.sender); + execute::freeze_chain(deps, chain, direction) } ExecuteMsg::UnfreezeChain { chain, direction } => { - execute::require_admin(&deps, info)?; + ensure_permission!(Permission::Admin, deps.storage, &info.sender); + execute::unfreeze_chain(deps, chain, direction) } - ExecuteMsg::RouteMessages(msgs) => Ok(contract.route_messages(info.sender, msgs)?), + ExecuteMsg::RouteMessages(msgs) => { + ensure_any_permission!(); + + Ok(execute::route_messages( + RouterStore::new(deps.storage), + info.sender, + msgs, + )?) + } } .map_err(axelar_wasm_std::ContractError::from) } -struct Contract -where - S: Store, -{ - store: S, - #[allow(unused)] - config: Config, -} - -impl Contract -where - S: Store, -{ - pub fn new(store: S) -> Self { - let config = store.load_config().expect("config must be loaded"); - - Self { store, config } - } -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn query( deps: Deps, @@ -166,6 +160,8 @@ mod test { nexus_gateway: Addr::unchecked(NEXUS_GATEWAY_ADDRESS), }; CONFIG.save(deps.as_mut().storage, &config).unwrap(); + permission_control::set_admin(deps.as_mut().storage, &config.admin).unwrap(); + permission_control::set_governance(deps.as_mut().storage, &config.governance).unwrap(); deps } @@ -249,14 +245,28 @@ mod test { } #[test] - fn migrate_sets_contract_version() { + fn migrate_checks_contract_version() { let mut deps = mock_dependencies(); + CONFIG + .save( + deps.as_mut().storage, + &Config { + admin: Addr::unchecked("admin"), + governance: Addr::unchecked("governance"), + nexus_gateway: Addr::unchecked("nexus_gateway"), + }, + ) + .unwrap(); + + assert!(migrate(deps.as_mut(), mock_env(), Empty {}).is_err()); - migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); - let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, "router"); - assert_eq!(contract_version.version, CONTRACT_VERSION); + assert!(migrate(deps.as_mut(), mock_env(), Empty {}).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, CONTRACT_VERSION).unwrap(); + + assert!(migrate(deps.as_mut(), mock_env(), Empty {}).is_ok()); } #[test] @@ -399,7 +409,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::NoPrivilege.into(), + }, + ); let err = execute( deps.as_mut(), @@ -412,7 +428,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::Admin.into(), + }, + ); let res = execute( deps.as_mut(), @@ -436,7 +458,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Admin.into(), + actual: Permission::NoPrivilege.into(), + }, + ); let err = execute( deps.as_mut(), @@ -448,7 +476,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Admin.into(), + actual: Permission::Governance.into(), + }, + ); let res = execute( deps.as_mut(), @@ -471,7 +505,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Admin.into(), + actual: Permission::NoPrivilege.into(), + }, + ); let err = execute( deps.as_mut(), @@ -483,7 +523,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Admin.into(), + actual: Permission::Governance.into(), + }, + ); let res = execute( deps.as_mut(), @@ -509,7 +555,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::NoPrivilege.into(), + }, + ); let err = execute( deps.as_mut(), @@ -524,7 +576,13 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::Unauthorized); + assert_contract_err_strings_equal( + err, + permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::Admin.into(), + }, + ); let res = execute( deps.as_mut(), diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index 0f95d2489..9a4062f19 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -1,7 +1,7 @@ use std::vec; use axelar_wasm_std::msg_id::{self, MessageIdFormat}; -use cosmwasm_std::{to_json_binary, Addr, DepsMut, MessageInfo, Response, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, Addr, DepsMut, Response, StdResult, WasmMsg}; use error_stack::{report, ResultExt}; use itertools::Itertools; @@ -12,9 +12,7 @@ use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection, Message}; use crate::events::{ ChainFrozen, ChainRegistered, ChainUnfrozen, GatewayInfo, GatewayUpgraded, MessageRouted, }; -use crate::state::{chain_endpoints, Store, CONFIG}; - -use super::Contract; +use crate::state::{chain_endpoints, Config, Store}; pub fn register_chain( deps: DepsMut, @@ -119,22 +117,6 @@ pub fn unfreeze_chain( )) } -pub fn require_admin(deps: &DepsMut, info: MessageInfo) -> Result<(), Error> { - let config = CONFIG.load(deps.storage)?; - if config.admin != info.sender { - return Err(Error::Unauthorized); - } - Ok(()) -} - -pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), Error> { - let config = CONFIG.load(deps.storage)?; - if config.governance != info.sender { - return Err(Error::Unauthorized); - } - Ok(()) -} - fn verify_msg_ids( msgs: &[Message], expected_format: &MessageIdFormat, @@ -144,86 +126,81 @@ fn verify_msg_ids( .change_context(Error::InvalidMessageId) } -impl Contract -where - S: Store, -{ - fn validate_msgs( - &self, - sender: &Addr, - msgs: Vec, - ) -> error_stack::Result, Error> { - // If sender is the nexus gateway, we cannot validate the source chain - // because the source chain is registered in the core nexus module. - // All messages received from the nexus gateway must adhere to the - // HexTxHashAndEventIndex message ID format. - if sender == self.config.nexus_gateway { - verify_msg_ids(&msgs, &MessageIdFormat::HexTxHashAndEventIndex)?; - return Ok(msgs); - } +fn validate_msgs( + store: &impl Store, + config: Config, + sender: &Addr, + msgs: Vec, +) -> error_stack::Result, Error> { + // If sender is the nexus gateway, we cannot validate the source chain + // because the source chain is registered in the core nexus module. + // All messages received from the nexus gateway must adhere to the + // HexTxHashAndEventIndex message ID format. + if sender == config.nexus_gateway { + verify_msg_ids(&msgs, &MessageIdFormat::HexTxHashAndEventIndex)?; + return Ok(msgs); + } - let source_chain = self - .store - .load_chain_by_gateway(sender)? - .ok_or(Error::GatewayNotRegistered)?; - if source_chain.incoming_frozen() { - return Err(report!(Error::ChainFrozen { - chain: source_chain.name, - })); - } + let source_chain = store + .load_chain_by_gateway(sender)? + .ok_or(Error::GatewayNotRegistered)?; + if source_chain.incoming_frozen() { + return Err(report!(Error::ChainFrozen { + chain: source_chain.name, + })); + } - if msgs.iter().any(|msg| msg.cc_id.chain != source_chain.name) { - return Err(report!(Error::WrongSourceChain)); - } + if msgs.iter().any(|msg| msg.cc_id.chain != source_chain.name) { + return Err(report!(Error::WrongSourceChain)); + } - verify_msg_ids(&msgs, &source_chain.msg_id_format)?; + verify_msg_ids(&msgs, &source_chain.msg_id_format)?; - Ok(msgs) - } + Ok(msgs) +} - pub fn route_messages( - self, - sender: Addr, - msgs: Vec, - ) -> error_stack::Result { - let msgs = self.validate_msgs(&sender, msgs)?; - - let wasm_msgs = msgs - .iter() - .group_by(|msg| msg.destination_chain.to_owned()) - .into_iter() - .map(|(destination_chain, msgs)| { - let gateway = match self.store.load_chain_by_chain_name(&destination_chain)? { - Some(destination_chain) if destination_chain.outgoing_frozen() => { - return Err(report!(Error::ChainFrozen { - chain: destination_chain.name, - })); - } - Some(destination_chain) => destination_chain.gateway.address, - // messages with unknown destination chains are routed to - // the nexus gateway if the sender is not the nexus gateway - // itself - None if sender != self.config.nexus_gateway => { - self.config.nexus_gateway.clone() - } - _ => return Err(report!(Error::ChainNotFound)), - }; - - Ok(WasmMsg::Execute { - contract_addr: gateway.to_string(), - msg: to_json_binary(&gateway_api::msg::ExecuteMsg::RouteMessages( - msgs.cloned().collect(), - )) - .expect("must serialize message"), - funds: vec![], - }) +pub fn route_messages( + store: impl Store, + sender: Addr, + msgs: Vec, +) -> error_stack::Result { + let config = store.load_config()?; + + let msgs = validate_msgs(&store, config.clone(), &sender, msgs)?; + + let wasm_msgs = msgs + .iter() + .group_by(|msg| msg.destination_chain.to_owned()) + .into_iter() + .map(|(destination_chain, msgs)| { + let gateway = match store.load_chain_by_chain_name(&destination_chain)? { + Some(destination_chain) if destination_chain.outgoing_frozen() => { + return Err(report!(Error::ChainFrozen { + chain: destination_chain.name, + })); + } + Some(destination_chain) => destination_chain.gateway.address, + // messages with unknown destination chains are routed to + // the nexus gateway if the sender is not the nexus gateway + // itself + None if sender != config.nexus_gateway => config.nexus_gateway.clone(), + _ => return Err(report!(Error::ChainNotFound)), + }; + + Ok(WasmMsg::Execute { + contract_addr: gateway.to_string(), + msg: to_json_binary(&gateway_api::msg::ExecuteMsg::RouteMessages( + msgs.cloned().collect(), + )) + .expect("must serialize message"), + funds: vec![], }) - .collect::, _>>()?; + }) + .collect::, _>>()?; - Ok(Response::new() - .add_messages(wasm_msgs) - .add_events(msgs.into_iter().map(|msg| MessageRouted { msg }.into()))) - } + Ok(Response::new() + .add_messages(wasm_msgs) + .add_events(msgs.into_iter().map(|msg| MessageRouted { msg }.into()))) } #[cfg(test)] @@ -241,12 +218,9 @@ mod test { use crate::events::{ChainFrozen, ChainUnfrozen}; use crate::state::chain_endpoints; - use crate::{ - contract::Contract, - state::{Config, MockStore}, - }; + use crate::state::{Config, MockStore}; - use super::{freeze_chain, unfreeze_chain}; + use super::{freeze_chain, route_messages, unfreeze_chain}; fn rand_message(source_chain: ChainName, destination_chain: ChainName) -> Message { let mut bytes = [0; 32]; @@ -302,13 +276,12 @@ mod test { .with(predicate::eq(sender.clone())) .return_once(|_| Ok(None)); - let contract = Contract::new(store); - - assert!(contract - .route_messages(sender, vec![rand_message(source_chain, destination_chain)]) - .is_err_and(move |err| { - matches!(err.current_context(), Error::GatewayNotRegistered) - })); + assert!(route_messages( + store, + sender, + vec![rand_message(source_chain, destination_chain)] + ) + .is_err_and(move |err| { matches!(err.current_context(), Error::GatewayNotRegistered) })); } #[test] @@ -340,13 +313,14 @@ mod test { .with(predicate::eq(sender.clone())) .return_once(|_| Ok(Some(chain_endpoint))); - let contract = Contract::new(store); - - assert!(contract - .route_messages(sender, vec![rand_message(source_chain.clone(), destination_chain)]) - .is_err_and(move |err| { - matches!(err.current_context(), Error::ChainFrozen { chain } if *chain == source_chain) - })); + assert!(route_messages( + store, + sender, + vec![rand_message(source_chain.clone(), destination_chain)] + ) + .is_err_and(move |err| { + matches!(err.current_context(), Error::ChainFrozen { chain } if *chain == source_chain) + })); } #[test] @@ -378,14 +352,12 @@ mod test { .with(predicate::eq(sender.clone())) .return_once(|_| Ok(Some(chain_endpoint))); - let contract = Contract::new(store); - - assert!(contract - .route_messages( - sender, - vec![rand_message("polygon".parse().unwrap(), destination_chain)] - ) - .is_err_and(|err| { matches!(err.current_context(), Error::WrongSourceChain) })); + assert!(route_messages( + store, + sender, + vec![rand_message("polygon".parse().unwrap(), destination_chain)] + ) + .is_err_and(|err| { matches!(err.current_context(), Error::WrongSourceChain) })); } #[test] @@ -430,10 +402,7 @@ mod test { .with(predicate::eq(destination_chain.clone())) .return_once(|_| Ok(Some(destination_chain_endpoint))); - let contract = Contract::new(store); - - assert!(contract - .route_messages(sender, vec![rand_message(source_chain, destination_chain.clone())]) + assert!(route_messages(store, sender, vec![rand_message(source_chain, destination_chain.clone())]) .is_err_and(move |err| { matches!(err.current_context(), Error::ChainFrozen { chain } if *chain == destination_chain) })); @@ -468,12 +437,9 @@ mod test { .with(predicate::eq(sender.clone())) .return_once(|_| Ok(Some(source_chain_endpoint))); - let contract = Contract::new(store); - let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = "foobar".try_into().unwrap(); - assert!(contract - .route_messages(sender, vec![msg]) + assert!(route_messages(store, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } @@ -493,12 +459,9 @@ mod test { .expect_load_config() .returning(move || Ok(config.clone())); - let contract = Contract::new(store); - let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = "foobar".try_into().unwrap(); - assert!(contract - .route_messages(sender, vec![msg]) + assert!(route_messages(store, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } @@ -531,8 +494,6 @@ mod test { .with(predicate::eq(sender.clone())) .return_once(|_| Ok(Some(source_chain_endpoint))); - let contract = Contract::new(store); - let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = HexTxHashAndEventIndex { tx_hash: [0; 32], @@ -541,8 +502,7 @@ mod test { .to_string() .try_into() .unwrap(); - assert!(contract - .route_messages(sender, vec![msg]) + assert!(route_messages(store, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } @@ -602,19 +562,17 @@ mod test { .with(predicate::eq(destination_chain_2.clone())) .return_once(|_| Ok(Some(destination_chain_endpoint_2))); - let contract = Contract::new(store); - - assert!(contract - .route_messages( - sender, - vec![ - rand_message(source_chain.clone(), destination_chain_1.clone()), - rand_message(source_chain.clone(), destination_chain_1.clone()), - rand_message(source_chain.clone(), destination_chain_1.clone()), - rand_message(source_chain.clone(), destination_chain_2.clone()), - ] - ) - .is_ok_and(|res| { res.messages.len() == 2 })); + assert!(route_messages( + store, + sender, + vec![ + rand_message(source_chain.clone(), destination_chain_1.clone()), + rand_message(source_chain.clone(), destination_chain_1.clone()), + rand_message(source_chain.clone(), destination_chain_1.clone()), + rand_message(source_chain.clone(), destination_chain_2.clone()), + ] + ) + .is_ok_and(|res| { res.messages.len() == 2 })); } #[test] @@ -660,19 +618,17 @@ mod test { .with(predicate::eq(destination_chain_2.clone())) .return_once(|_| Ok(Some(destination_chain_endpoint_2))); - let contract = Contract::new(store); - - assert!(contract - .route_messages( - sender, - vec![ - rand_message(source_chain.clone(), destination_chain_1.clone()), - rand_message(source_chain.clone(), destination_chain_1.clone()), - rand_message(source_chain.clone(), destination_chain_1.clone()), - rand_message(source_chain.clone(), destination_chain_2.clone()), - ] - ) - .is_ok_and(|res| { res.messages.len() == 2 })); + assert!(route_messages( + store, + sender, + vec![ + rand_message(source_chain.clone(), destination_chain_1.clone()), + rand_message(source_chain.clone(), destination_chain_1.clone()), + rand_message(source_chain.clone(), destination_chain_1.clone()), + rand_message(source_chain.clone(), destination_chain_2.clone()), + ] + ) + .is_ok_and(|res| { res.messages.len() == 2 })); } #[test] @@ -696,17 +652,15 @@ mod test { .with(predicate::eq(destination_chain.clone())) .return_once(|_| Ok(None)); - let contract = Contract::new(store); - - assert!(contract - .route_messages( - sender, - vec![rand_message( - source_chain.clone(), - destination_chain.clone() - )] - ) - .is_err_and(|err| { matches!(err.current_context(), Error::ChainNotFound) })); + assert!(route_messages( + store, + sender, + vec![rand_message( + source_chain.clone(), + destination_chain.clone() + )] + ) + .is_err_and(|err| { matches!(err.current_context(), Error::ChainNotFound) })); } #[test] @@ -743,17 +697,15 @@ mod test { .with(predicate::eq(destination_chain.clone())) .return_once(|_| Ok(None)); - let contract = Contract::new(store); - - assert!(contract - .route_messages( - sender, - vec![rand_message( - source_chain.clone(), - destination_chain.clone() - )] - ) - .is_ok_and(|res| { res.messages.len() == 1 })); + assert!(route_messages( + store, + sender, + vec![rand_message( + source_chain.clone(), + destination_chain.clone() + )] + ) + .is_ok_and(|res| { res.messages.len() == 1 })); } #[test] diff --git a/contracts/router/src/lib.rs b/contracts/router/src/lib.rs index cdacc8154..4c2b778ae 100644 --- a/contracts/router/src/lib.rs +++ b/contracts/router/src/lib.rs @@ -1,4 +1,5 @@ pub mod contract; pub mod events; +mod migrations; pub mod msg; pub mod state; diff --git a/contracts/router/src/migrations/mod.rs b/contracts/router/src/migrations/mod.rs new file mode 100644 index 000000000..ebcb4aab1 --- /dev/null +++ b/contracts/router/src/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v0_3_3; diff --git a/contracts/router/src/migrations/v0_3_3.rs b/contracts/router/src/migrations/v0_3_3.rs new file mode 100644 index 000000000..261089b21 --- /dev/null +++ b/contracts/router/src/migrations/v0_3_3.rs @@ -0,0 +1,65 @@ +use crate::state::CONFIG; +use axelar_wasm_std::{permission_control, ContractError}; +use cosmwasm_std::{StdResult, Storage}; +use cw2::VersionError; + +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + let current_version = cw2::get_contract_version(storage)?; + if current_version.version != "0.3.3" { + Err(VersionError::WrongVersion { + expected: "0.3.3".into(), + found: current_version.version, + } + .into()) + } else { + set_generalized_permission_control(storage)?; + Ok(()) + } +} + +fn set_generalized_permission_control(storage: &mut dyn Storage) -> StdResult<()> { + let config = CONFIG.load(storage)?; + permission_control::set_admin(storage, &config.admin)?; + permission_control::set_governance(storage, &config.governance)?; + Ok(()) +} + +#[cfg(test)] +mod test { + use crate::state::Config; + use crate::state::CONFIG; + use axelar_wasm_std::ensure_permission; + use axelar_wasm_std::permission_control::{Error, Permission}; + use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::{Addr, Storage}; + use error_stack::Report; + + #[test] + fn set_generalized_permission_control() { + let config = Config { + admin: Addr::unchecked("admin"), + governance: Addr::unchecked("governance"), + nexus_gateway: Addr::unchecked("nexus_gateway"), + }; + + let mut storage = MockStorage::new(); + CONFIG.save(&mut storage, &config).unwrap(); + + let check_admin = |storage: &mut dyn Storage| { + ensure_permission!(Permission::Admin, storage, &config.admin); + Ok::<(), Report>(()) + }; + + let check_governance = |storage: &mut dyn Storage| { + ensure_permission!(Permission::Governance, storage, &config.governance); + Ok::<(), Report>(()) + }; + assert!(check_admin(&mut storage).is_err()); + assert!(check_governance(&mut storage).is_err()); + + super::set_generalized_permission_control(&mut storage).unwrap(); + + assert!(check_admin(&mut storage).is_ok()); + assert!(check_governance(&mut storage).is_ok()); + } +} diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index cd3e96482..0df4ed24a 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -33,8 +33,10 @@ bs58 = "0.5.1" cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } +cw2 = { workspace = true } error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } +itertools = { workspace = true } lazy_static = "1.4.0" num-traits = { workspace = true } regex = { version = "1.10.0", default-features = false, features = ["perf", "std"] } diff --git a/packages/axelar-wasm-std/src/error.rs b/packages/axelar-wasm-std/src/error.rs index 88a9b19db..8e8f7410c 100644 --- a/packages/axelar-wasm-std/src/error.rs +++ b/packages/axelar-wasm-std/src/error.rs @@ -1,3 +1,4 @@ +use crate::permission_control; use cosmwasm_std::StdError; use error_stack::{Context, Report}; use report::LoggableError; @@ -14,6 +15,10 @@ pub enum ContractError { Std(#[from] StdError), #[error(transparent)] Structured(#[from] LoggableError), + #[error(transparent)] + Unauthorized(#[from] permission_control::Error), + #[error(transparent)] + WrongVersion(#[from] cw2::VersionError), } impl From> for ContractError diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index ea0756e45..87ef974a4 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -14,6 +14,7 @@ pub mod hash; pub mod hex; pub mod msg_id; pub mod nonempty; +pub mod permission_control; pub mod snapshot; pub mod threshold; pub mod utils; diff --git a/packages/axelar-wasm-std/src/permission_control.rs b/packages/axelar-wasm-std/src/permission_control.rs new file mode 100644 index 000000000..e9809286c --- /dev/null +++ b/packages/axelar-wasm-std/src/permission_control.rs @@ -0,0 +1,310 @@ +use crate::flagset::FlagSet; +use crate::FnExt; +use cosmwasm_std::{Addr, StdResult}; +use cw_storage_plus::Item; +use flagset::{flags, Flags}; +use itertools::Itertools; +use serde::{Deserialize, Serialize}; +use std::fmt::{Debug, Display, Formatter}; + +flags! { + #[repr(u8)] + #[derive(Serialize, Deserialize)] + pub enum Permission: u8 { + NoPrivilege = 0b001, // this specifies that the user MUST NOT have an elevated role + Admin = 0b010, + Governance = 0b100, + Elevated = (Permission::Admin | Permission::Governance).bits(), + Any = (Permission::NoPrivilege | Permission::Elevated).bits(), + } +} + +impl Display for FlagSet { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + Permission::LIST + .iter() + .find(|permission| self.eq(&(**permission).into())) + .map_or_else( + || { + self.into_iter() + .map(|permission| format!("{:?}", permission)) + .join(" | ") + }, + |permission| format!("{:?}", permission), + ) + .then(|permission| write!(f, "{}", permission)) + } +} + +#[derive(thiserror::Error, Debug, PartialEq)] +pub enum Error { + #[error("sender with role '{actual}' is not allowed to perform this action that requires '{expected}' permissions")] + PermissionDenied { + expected: FlagSet, + actual: FlagSet, + }, +} + +/// Ensure that the sender of a message has the correct permissions to perform following actions. +/// Returns an error if not. +/// # Example +/// ``` +/// # use cosmwasm_std::testing::mock_dependencies; +/// use cosmwasm_std::Addr; +/// use axelar_wasm_std::ensure_permission; +/// use axelar_wasm_std::permission_control::Permission; +///# use axelar_wasm_std::permission_control::Error; +/// +///# fn main() -> Result<(),Box>{ +///# use axelar_wasm_std::permission_control; +///# let mut deps = mock_dependencies(); +///# let deps = deps.as_mut(); +/// let admin = Addr::unchecked("admin"); +/// let governance = Addr::unchecked("governance"); +/// +/// // set these before checking permissions +/// permission_control::set_admin(deps.storage, &admin)?; +/// permission_control::set_governance(deps.storage, &governance)?; +/// +/// ensure_permission!(Permission::Elevated, deps.storage, &admin); +/// ensure_permission!(Permission::Elevated, deps.storage, &governance); +/// +/// do_something(); +/// # Ok(())} +/// +/// # fn do_something() {} +/// ``` +#[macro_export] +macro_rules! ensure_permission { + ($permission_variant:expr, $storage:expr, $sender:expr) => { + let permission = $crate::flagset::FlagSet::from($permission_variant); + + if !permission.contains($crate::permission_control::Permission::Any) { + let role = error_stack::ResultExt::change_context( + $crate::permission_control::sender_role($storage, $sender), + $crate::permission_control::Error::PermissionDenied { + expected: permission.clone(), + actual: Permission::NoPrivilege.into(), + }, + )?; + + if (*permission & *role).is_empty() { + return Err($crate::permission_control::Error::PermissionDenied { + expected: permission, + actual: role, + } + .into()); + } + } + }; +} + +/// This macro should be used as a marker to signify that the call is deliberately without checks +/// +/// # Example +/// ``` +///# fn main() -> Result<(),Box>{ +///# use axelar_wasm_std::{ensure_any_permission}; +/// ensure_any_permission!(); +/// do_something(); +/// # Ok(())} +/// +/// # fn do_something() {} +/// ``` +#[macro_export] +macro_rules! ensure_any_permission { + () => {}; +} + +const ADMIN: Item = Item::new("permission_control_contract_admin_addr"); + +const GOVERNANCE: Item = Item::new("permission_control_governance_addr"); + +pub fn set_admin(storage: &mut dyn cosmwasm_std::Storage, addr: &Addr) -> StdResult<()> { + ADMIN.save(storage, addr) +} + +pub fn set_governance(storage: &mut dyn cosmwasm_std::Storage, addr: &Addr) -> StdResult<()> { + GOVERNANCE.save(storage, addr) +} + +// this is an implementation detail of the macro and shouldn't be called on its own +#[doc(hidden)] +#[allow(clippy::arithmetic_side_effects)] // flagset is safe +pub fn sender_role( + storage: &dyn cosmwasm_std::Storage, + sender: &Addr, +) -> StdResult> { + let admin = ADMIN.may_load(storage)?; + let governance = GOVERNANCE.may_load(storage)?; + + let mut role = FlagSet::from(Permission::NoPrivilege); + + if admin.is_some_and(|admin| admin == sender) { + *role |= Permission::Admin; + } + + if governance.is_some_and(|governance| governance == sender) { + *role |= Permission::Governance; + } + + // a role cannot be both elevated and without privilege at the same time + if !role.is_disjoint(Permission::Elevated) { + *role -= Permission::NoPrivilege; + } + + Ok(role) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::Addr; + use error_stack::Report; + use flagset::Flags; + + #[test] + fn test_ensure_permission() { + let no_privilege = Addr::unchecked("regular user"); + let admin = Addr::unchecked("admin"); + let governance = Addr::unchecked("governance"); + + let check = |permission, user, storage| { + ensure_permission!(permission, storage, user); + Ok::<(), Report>(()) + }; + + // no addresses set: all addresses should be treated as not privileged + let storage = MockStorage::new(); + for permission in Permission::LIST { + match permission { + Permission::NoPrivilege | Permission::Any => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + // none of these can be called if no addresses are set + Permission::Admin | Permission::Governance | Permission::Elevated => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_err()); + assert!(check(*permission, &governance, &storage).is_err()); + } + } + } + + // admin set: only admin should be allowed to call admin and elevated commands + let mut storage = MockStorage::new(); + set_admin(&mut storage, &admin).unwrap(); + + for permission in Permission::LIST { + match permission { + Permission::NoPrivilege => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_err()); // + assert!(check(*permission, &governance, &storage).is_ok()); + } + Permission::Admin | Permission::Elevated => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_err()); + } + // gov address is not set, so these should all fail + Permission::Governance => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_err()); + assert!(check(*permission, &governance, &storage).is_err()); + } + Permission::Any => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + } + } + + // governance set: only governance should be allowed to call governance and elevated commands + let mut storage = MockStorage::new(); + set_governance(&mut storage, &governance).unwrap(); + + for permission in Permission::LIST { + match permission { + Permission::NoPrivilege => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_err()); + } + // admin address is not set, so these should all fail + Permission::Admin => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_err()); + assert!(check(*permission, &governance, &storage).is_err()); + } + Permission::Governance | Permission::Elevated => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_err()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + Permission::Any => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + } + } + + // admin and governance set: both should be allowed to call admin, governance, and elevated commands + let mut storage = MockStorage::new(); + set_admin(&mut storage, &admin).unwrap(); + set_governance(&mut storage, &governance).unwrap(); + + for permission in Permission::LIST { + match permission { + Permission::NoPrivilege => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_err()); + assert!(check(*permission, &governance, &storage).is_err()); + } + Permission::Admin => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_err()); + } + Permission::Governance => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_err()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + Permission::Elevated => { + assert!(check(*permission, &no_privilege, &storage).is_err()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + Permission::Any => { + assert!(check(*permission, &no_privilege, &storage).is_ok()); + assert!(check(*permission, &admin, &storage).is_ok()); + assert!(check(*permission, &governance, &storage).is_ok()); + } + } + } + } + + #[test] + fn test() { + assert_eq!(format!("{}", FlagSet::from(Permission::Admin)), "Admin"); + assert_eq!( + format!( + "{}", + FlagSet::from(Permission::NoPrivilege | Permission::Governance) + ), + "NoPrivilege | Governance" + ); + assert_eq!( + format!( + "{}", + FlagSet::from(Permission::NoPrivilege | Permission::Governance | Permission::Admin) + ), + "Any" + ); + } +} diff --git a/packages/router-api/src/error.rs b/packages/router-api/src/error.rs index 72167a0bf..769cb1902 100644 --- a/packages/router-api/src/error.rs +++ b/packages/router-api/src/error.rs @@ -14,9 +14,6 @@ pub enum Error { #[error(transparent)] Std(#[from] StdError), - #[error("caller is not authorized")] - Unauthorized, - #[error("chain already exists")] ChainAlreadyExists, From f9277043eee336754169818f693fa97593780a05 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Fri, 28 Jun 2024 16:07:51 -0400 Subject: [PATCH 047/168] fix(ampd): directly pass interval to queued broadcaster and ignore first tick (#480) * fix: directly pass interval to queued broadcaster and pass the first unwanted tick * refactor: address PR comments * refactor: simplify steps to take after interval tick in run function --- ampd/src/lib.rs | 3 +- ampd/src/queue/queued_broadcaster.rs | 80 +++++++++++++--------------- 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index c726bc3d8..6183ca619 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -12,6 +12,7 @@ use evm::json_rpc::EthereumClient; use router_api::ChainName; use thiserror::Error; use tokio::signal::unix::{signal, SignalKind}; +use tokio::time::interval; use tokio_util::sync::CancellationToken; use tracing::info; @@ -178,7 +179,7 @@ where broadcaster, broadcast_cfg.batch_gas_limit, broadcast_cfg.queue_cap, - broadcast_cfg.broadcast_interval, + interval(broadcast_cfg.broadcast_interval), ); Self { diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index ba2bd260b..fa65d214d 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -1,14 +1,11 @@ -use std::time::Duration; - use async_trait::async_trait; -use axelar_wasm_std::FnExt; use cosmrs::{Any, Gas}; use error_stack::{self, Report, ResultExt}; use mockall::automock; use thiserror::Error; use tokio::select; use tokio::sync::{mpsc, oneshot}; -use tokio::time; +use tokio::time::Interval; use tracing::info; use tracing::warn; @@ -60,8 +57,8 @@ where broadcaster: T, queue: MsgQueue, batch_gas_limit: Gas, - broadcast_interval: Duration, channel: Option<(mpsc::Sender, mpsc::Receiver)>, + broadcast_interval: Interval, } impl QueuedBroadcaster @@ -72,14 +69,14 @@ where broadcaster: T, batch_gas_limit: Gas, capacity: usize, - broadcast_interval: Duration, + broadcast_interval: Interval, ) -> Self { Self { broadcaster, queue: MsgQueue::default(), batch_gas_limit, - broadcast_interval, channel: Some(mpsc::channel(capacity)), + broadcast_interval, } } @@ -88,15 +85,17 @@ where .channel .take() .expect("broadcast channel is expected to be set during initialization and must be available when running the broadcaster"); - let mut interval = time::interval(self.broadcast_interval); loop { select! { msg = rx.recv() => match msg { None => break, - Some(msg_and_res_chan) => interval = self.handle_msg(interval, msg_and_res_chan).await?, + Some(msg_and_res_chan) => self.handle_msg(msg_and_res_chan).await?, + }, + _ = self.broadcast_interval.tick() => { + self.broadcast_all().await?; + self.broadcast_interval.reset(); }, - _ = interval.tick() => self.broadcast_all().await?.then(|_| {interval.reset()}), } } @@ -133,11 +132,7 @@ where } } - async fn handle_msg( - &mut self, - mut interval: time::Interval, - msg_and_res_chan: MsgAndResChan, - ) -> Result { + async fn handle_msg(&mut self, msg_and_res_chan: MsgAndResChan) -> Result<()> { let (msg, tx) = msg_and_res_chan; match self.broadcaster.estimate_fee(vec![msg.clone()]).await { @@ -151,7 +146,7 @@ where "exceeded batch gas limit. gas limit can be adjusted in ampd config" ); self.broadcast_all().await?; - interval.reset(); + self.broadcast_interval.reset(); } let message_type = msg.type_url.clone(); @@ -171,7 +166,7 @@ where } } - Ok(interval) + Ok(()) } } @@ -183,7 +178,7 @@ mod test { use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use error_stack::Report; use tokio::test; - use tokio::time::{sleep, Duration}; + use tokio::time::{interval, Duration}; use super::{Error, QueuedBroadcaster}; use crate::broadcaster::{self, MockBroadcaster}; @@ -196,8 +191,8 @@ mod test { .expect_estimate_fee() .return_once(|_| Err(Report::new(broadcaster::Error::FeeEstimation))); - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, 100, 10, Duration::from_secs(5)); + let broadcast_interval = interval(Duration::from_secs(5)); + let queued_broadcaster = QueuedBroadcaster::new(broadcaster, 100, 10, broadcast_interval); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); @@ -214,7 +209,7 @@ mod test { assert!(handle.await.unwrap().is_ok()); } - #[test] + #[test(start_paused = true)] async fn should_not_broadcast_when_gas_limit_has_not_been_reached() { let tx_count = 9; let batch_gas_limit = 100; @@ -236,17 +231,17 @@ mod test { .expect_broadcast() .once() .returning(move |msgs| { - assert!(msgs.len() == tx_count); + assert_eq!(msgs.len(), tx_count); Ok(TxResponse::default()) }); - let queued_broadcaster = QueuedBroadcaster::new( - broadcaster, - batch_gas_limit, - tx_count, - Duration::from_secs(5), - ); + let mut broadcast_interval = interval(Duration::from_secs(5)); + // get rid of tick on startup + broadcast_interval.tick().await; + + let queued_broadcaster = + QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); @@ -258,11 +253,10 @@ mod test { assert!(handle.await.unwrap().is_ok()); } - #[test] + #[test(start_paused = true)] async fn should_broadcast_when_broadcast_interval_has_been_reached() { let tx_count = 9; let batch_gas_limit = 100; - let broadcast_interval = Duration::from_millis(100); let gas_limit = 10; let mut broadcaster = MockBroadcaster::new(); @@ -281,10 +275,13 @@ mod test { .expect_broadcast() .once() .returning(move |msgs| { - assert!(msgs.len() == tx_count); + assert_eq!(msgs.len(), tx_count); Ok(TxResponse::default()) }); + let mut broadcast_interval = interval(Duration::from_millis(100)); + // get rid of tick on startup + broadcast_interval.tick().await; let queued_broadcaster = QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); @@ -294,13 +291,12 @@ mod test { for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - sleep(broadcast_interval).await; drop(client); assert!(handle.await.unwrap().is_ok()); } - #[test] + #[test(start_paused = true)] async fn should_broadcast_when_gas_limit_has_been_reached() { let tx_count = 10; let batch_gas_limit = 100; @@ -322,7 +318,7 @@ mod test { .expect_broadcast() .once() .returning(move |msgs| { - assert!(msgs.len() == tx_count - 1); + assert_eq!(msgs.len(), tx_count - 1); Ok(TxResponse::default()) }); @@ -330,23 +326,23 @@ mod test { .expect_broadcast() .once() .returning(move |msgs| { - assert!(msgs.len() == 1); - + assert_eq!(msgs.len(), 1); Ok(TxResponse::default()) }); - let queued_broadcaster = QueuedBroadcaster::new( - broadcaster, - batch_gas_limit, - tx_count, - Duration::from_secs(5), - ); + let mut broadcast_interval = interval(Duration::from_secs(5)); + // get rid of tick on startup + broadcast_interval.tick().await; + + let queued_broadcaster = + QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } + drop(client); assert!(handle.await.unwrap().is_ok()); From 399675a349f275e730d42363369bdd13c70a4520 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 2 Jul 2024 21:14:22 -0400 Subject: [PATCH 048/168] feat(minor-router): add command to freeze all chains (#472) --- Cargo.lock | 48 +- Cargo.toml | 3 +- contracts/router/Cargo.toml | 3 +- contracts/router/src/contract.rs | 497 ++++++++++++++---- contracts/router/src/contract/execute.rs | 292 ++++++---- contracts/router/src/contract/query.rs | 16 +- contracts/router/src/events.rs | 25 +- contracts/router/src/migrations/v0_3_3.rs | 21 +- contracts/router/src/state.rs | 26 +- .../tests/chain_freeze_unfreeze.rs | 2 +- integration-tests/tests/test_utils/mod.rs | 14 +- packages/router-api/src/error.rs | 3 + packages/router-api/src/msg.rs | 31 +- 13 files changed, 719 insertions(+), 262 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 960b06367..9bcbf7d79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,7 +160,7 @@ dependencies = [ "humantime-serde", "itertools 0.11.0", "k256", - "mockall", + "mockall 0.11.4", "move-core-types", "multisig", "num-traits", @@ -4149,8 +4149,23 @@ dependencies = [ "downcast", "fragile", "lazy_static", - "mockall_derive", - "predicates", + "mockall_derive 0.11.4", + "predicates 2.1.5", + "predicates-tree", +] + +[[package]] +name = "mockall" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive 0.12.1", + "predicates 3.1.0", "predicates-tree", ] @@ -4166,6 +4181,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "mockall_derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" +dependencies = [ + "cfg-if", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.66", +] + [[package]] name = "move-abstract-interpreter" version = "0.1.0" @@ -4747,7 +4774,7 @@ dependencies = [ "cw2 1.1.2", "error-stack", "hex", - "mockall", + "mockall 0.11.4", "report", "router-api", "schemars", @@ -5492,6 +5519,16 @@ dependencies = [ "regex", ] +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "predicates-core", +] + [[package]] name = "predicates-core" version = "1.0.6" @@ -6216,11 +6253,12 @@ dependencies = [ "hex", "integration-tests", "itertools 0.11.0", - "mockall", + "mockall 0.12.1", "rand", "report", "router-api", "serde_json", + "thiserror", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 37e9d88fb..4d4ef33fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,8 @@ router-api = { version = "^0.1.0", path = "packages/router-api" } report = { version = "^0.1.0", path = "packages/report" } client = { version = "^0.1.0", path = "packages/client" } rewards = { version = "^0.4.0", path = "contracts/rewards" } -thiserror = "1.0.47" +thiserror = "1.0.61" +mockall = "0.12.1" serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" schemars = "0.8.10" diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 8465ff312..a2a2afc8c 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -43,10 +43,11 @@ error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } gateway-api = { workspace = true } itertools = { workspace = true } -mockall = "0.11.4" +mockall = { workspace = true } report = { workspace = true } router-api = { workspace = true } serde_json = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] cw-multi-test = "0.15.1" diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 8a389f09f..5d9aa1651 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -7,9 +7,9 @@ use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInf use router_api::msg::{ExecuteMsg, QueryMsg}; use crate::events::RouterInstantiated; -use crate::migrations; use crate::msg::InstantiateMsg; -use crate::state::{Config, RouterStore, Store}; +use crate::state::{Config, RouterStore, State, CONFIG, STATE}; +use crate::{migrations, state}; mod execute; mod query; @@ -42,17 +42,17 @@ pub fn instantiate( let governance = deps.api.addr_validate(&msg.governance_address)?; let nexus_gateway = deps.api.addr_validate(&msg.nexus_gateway)?; + permission_control::set_admin(deps.storage, &admin)?; + permission_control::set_governance(deps.storage, &governance)?; + let config = Config { admin: admin.clone(), governance: governance.clone(), nexus_gateway: nexus_gateway.clone(), }; - permission_control::set_admin(deps.storage, &admin)?; - permission_control::set_governance(deps.storage, &governance)?; - RouterStore::new(deps.storage) - .save_config(config) - .expect("must save the config"); + CONFIG.save(deps.storage, &config)?; + STATE.save(deps.storage, &State::Enabled)?; Ok(Response::new().add_event( RouterInstantiated { @@ -91,15 +91,13 @@ pub fn execute( let contract_address = deps.api.addr_validate(&contract_address)?; execute::upgrade_gateway(deps, chain, contract_address) } - ExecuteMsg::FreezeChain { chain, direction } => { + ExecuteMsg::FreezeChains { chains } => { ensure_permission!(Permission::Admin, deps.storage, &info.sender); - - execute::freeze_chain(deps, chain, direction) + execute::freeze_chains(deps, chains) } - ExecuteMsg::UnfreezeChain { chain, direction } => { - ensure_permission!(Permission::Admin, deps.storage, &info.sender); - - execute::unfreeze_chain(deps, chain, direction) + ExecuteMsg::UnfreezeChains { chains } => { + ensure_permission!(Permission::Elevated, deps.storage, &info.sender); + execute::unfreeze_chains(deps, chains) } ExecuteMsg::RouteMessages(msgs) => { ensure_any_permission!(); @@ -110,6 +108,14 @@ pub fn execute( msgs, )?) } + ExecuteMsg::DisableRouting => { + ensure_permission!(Permission::Admin, deps.storage, &info.sender); + execute::disable_routing(deps) + } + ExecuteMsg::EnableRouting => { + ensure_permission!(Permission::Elevated, deps.storage, &info.sender); + execute::enable_routing(deps) + } } .map_err(axelar_wasm_std::ContractError::from) } @@ -125,26 +131,29 @@ pub fn query( QueryMsg::Chains { start_after, limit } => { to_json_binary(&query::chains(deps, start_after, limit)?) } + QueryMsg::IsEnabled => to_json_binary(&state::is_enabled(deps.storage)), } .map_err(axelar_wasm_std::ContractError::from) } #[cfg(test)] mod test { - use std::{collections::HashMap, str::FromStr}; - - use crate::state::CONFIG; - use super::*; - + use crate::events; + use crate::state::CONFIG; use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use axelar_wasm_std::ContractError; + use axelar_wasm_std::FnExt; use cosmwasm_std::{ + from_json, testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, Addr, CosmosMsg, Empty, OwnedDeps, WasmMsg, }; use router_api::{ - error::Error, ChainName, CrossChainId, GatewayDirection, Message, CHAIN_NAME_DELIMITER, + error::Error, ChainEndpoint, ChainName, CrossChainId, GatewayDirection, Message, + CHAIN_NAME_DELIMITER, }; + use std::{collections::HashMap, str::FromStr}; const ADMIN_ADDRESS: &str = "admin"; const GOVERNANCE_ADDRESS: &str = "governance"; @@ -154,14 +163,17 @@ mod test { fn setup() -> OwnedDeps { let mut deps = mock_dependencies(); - let config = Config { - admin: Addr::unchecked(ADMIN_ADDRESS), - governance: Addr::unchecked(GOVERNANCE_ADDRESS), - nexus_gateway: Addr::unchecked(NEXUS_GATEWAY_ADDRESS), - }; - CONFIG.save(deps.as_mut().storage, &config).unwrap(); - permission_control::set_admin(deps.as_mut().storage, &config.admin).unwrap(); - permission_control::set_governance(deps.as_mut().storage, &config.governance).unwrap(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + InstantiateMsg { + admin_address: ADMIN_ADDRESS.to_string(), + governance_address: GOVERNANCE_ADDRESS.to_string(), + nexus_gateway: NEXUS_GATEWAY_ADDRESS.to_string(), + }, + ) + .unwrap(); deps } @@ -452,9 +464,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(UNAUTHORIZED_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + chain.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ) .unwrap_err(); @@ -470,9 +484,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(GOVERNANCE_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + chain.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ) .unwrap_err(); @@ -488,9 +504,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + chain.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -499,9 +517,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(UNAUTHORIZED_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::None, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(chain.chain_name.clone(), GatewayDirection::None)]), }, ) .unwrap_err(); @@ -517,9 +534,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(GOVERNANCE_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::None, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(chain.chain_name.clone(), GatewayDirection::None)]), }, ) .unwrap_err(); @@ -535,9 +551,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::None, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(chain.chain_name.clone(), GatewayDirection::None)]), }, ); assert!(res.is_ok()); @@ -812,9 +827,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ) .unwrap(); @@ -856,9 +870,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ); assert!(res.is_ok()); @@ -886,9 +899,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ); assert!(res.is_ok()); @@ -913,9 +925,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ); assert!(res.is_ok()); @@ -960,9 +971,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -1004,9 +1017,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ) .unwrap(); @@ -1032,6 +1047,114 @@ mod test { assert!(res.is_ok()); } + #[test] + fn freeze_and_unfreeze_all_chains() { + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + let test_case = HashMap::from([ + (eth.chain_name.clone(), GatewayDirection::Bidirectional), + (polygon.chain_name.clone(), GatewayDirection::Bidirectional), + ]); + + let mut deps = setup(); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let chains = query( + deps.as_ref(), + mock_env(), + QueryMsg::Chains { + start_after: None, + limit: None, + }, + ) + .unwrap() + .then(|chains| from_json::>(&chains)) + .unwrap(); + + for chain in chains.iter() { + assert!(!chain.incoming_frozen() && !chain.outgoing_frozen()) + } + + type Check = fn(&Result) -> bool; // clippy complains without the alias about complex types + + // try sender without permission + let permission_control: Vec<(&str, Check)> = vec![ + (UNAUTHORIZED_ADDRESS, Result::is_err), + (GOVERNANCE_ADDRESS, Result::is_err), + (ADMIN_ADDRESS, Result::is_ok), + ]; + + for permission_case in permission_control.iter() { + let (sender, result_check) = permission_case; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(sender, &[]), + ExecuteMsg::FreezeChains { + chains: test_case.clone(), + }, + ); + assert!(result_check(&res)); + } + + let chains = query( + deps.as_ref(), + mock_env(), + QueryMsg::Chains { + start_after: None, + limit: None, + }, + ) + .unwrap() + .then(|chains| from_json::>(&chains)) + .unwrap(); + + for chain in chains.iter() { + assert!(chain.incoming_frozen() && chain.outgoing_frozen()) + } + + // try sender without permission + let permission_control: Vec<(&str, Check)> = vec![ + (UNAUTHORIZED_ADDRESS, Result::is_err), + (GOVERNANCE_ADDRESS, Result::is_ok), + (ADMIN_ADDRESS, Result::is_ok), + ]; + + for permission_case in permission_control.iter() { + let (sender, result_check) = permission_case; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(sender, &[]), + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([ + (eth.chain_name.clone(), GatewayDirection::Bidirectional), + (polygon.chain_name.clone(), GatewayDirection::Bidirectional), + ]), + }, + ); + assert!(result_check(&res)); + } + + let chains = query( + deps.as_ref(), + mock_env(), + QueryMsg::Chains { + start_after: None, + limit: None, + }, + ) + .unwrap() + .then(|chains| from_json::>(&chains)) + .unwrap(); + + for chain in chains.iter() { + assert!(!chain.incoming_frozen() && !chain.outgoing_frozen()) + } + } + #[test] fn unfreeze_incoming() { let mut deps = setup(); @@ -1044,9 +1167,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -1058,9 +1183,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ) .unwrap(); @@ -1104,9 +1228,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -1118,9 +1244,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ) .unwrap(); @@ -1164,9 +1289,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ) .unwrap(); @@ -1175,9 +1299,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ) .unwrap(); @@ -1228,9 +1351,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ) .unwrap(); @@ -1239,9 +1361,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::FreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ) .unwrap(); @@ -1292,9 +1413,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -1304,9 +1427,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ) .unwrap(); @@ -1316,9 +1438,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ) .unwrap(); @@ -1357,9 +1478,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -1369,9 +1492,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Outgoing)]), }, ) .unwrap(); @@ -1381,9 +1503,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::Incoming)]), }, ) .unwrap(); @@ -1422,9 +1543,11 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, + ExecuteMsg::FreezeChains { + chains: HashMap::from([( + polygon.chain_name.clone(), + GatewayDirection::Bidirectional, + )]), }, ); assert!(res.is_ok()); @@ -1434,9 +1557,8 @@ mod test { deps.as_mut(), mock_env(), mock_info(ADMIN_ADDRESS, &[]), - ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::None, + ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(polygon.chain_name.clone(), GatewayDirection::None)]), }, ) .unwrap(); @@ -1473,4 +1595,155 @@ mod test { }, ); } + + #[test] + fn disable_enable_router() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let nonce = &mut 0; + let messages = &generate_messages(ð, &polygon, nonce, 1); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ); + + assert!(res.is_ok()); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::DisableRouting {}, + ) + .unwrap(); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ); + assert!(res.is_err()); + assert_contract_err_strings_equal(res.unwrap_err(), Error::RoutingDisabled); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::EnableRouting {}, + ) + .unwrap(); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ); + + assert!(res.is_ok()); + } + + #[test] + fn ensure_correct_permissions_enable_disable_routing() { + let mut deps = setup(); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(UNAUTHORIZED_ADDRESS, &[]), + ExecuteMsg::EnableRouting {}, + ) + .is_err()); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::EnableRouting {}, + ) + .is_ok()); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::EnableRouting {}, + ) + .is_ok()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(UNAUTHORIZED_ADDRESS, &[]), + ExecuteMsg::DisableRouting {}, + ) + .is_err()); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::DisableRouting {}, + ) + .is_ok()); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::DisableRouting {}, + ) + .is_err()); + } + + #[test] + fn events_are_emitted_enable_disable_routing() { + let mut deps = setup(); + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::DisableRouting {}, + ) + .unwrap(); + + assert!(res.events.len() == 1); + assert!(res.events.contains(&events::RoutingDisabled.into())); + + // don't emit event if already disabled + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::DisableRouting {}, + ) + .unwrap(); + + assert!(res.events.is_empty()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::EnableRouting {}, + ) + .unwrap(); + + assert!(res.events.len() == 1); + assert!(res.events.contains(&events::RoutingEnabled.into())); + + // don't emit event if already enabled + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::EnableRouting {}, + ) + .unwrap(); + + assert!(res.events.is_empty()); + } } diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index 9a4062f19..97421e315 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -1,18 +1,21 @@ +use std::collections::HashMap; use std::vec; -use axelar_wasm_std::msg_id::{self, MessageIdFormat}; -use cosmwasm_std::{to_json_binary, Addr, DepsMut, Response, StdResult, WasmMsg}; -use error_stack::{report, ResultExt}; +use cosmwasm_std::{ + to_json_binary, Addr, DepsMut, Event, Response, StdError, StdResult, Storage, WasmMsg, +}; +use error_stack::{ensure, report, ResultExt}; use itertools::Itertools; -use axelar_wasm_std::flagset::FlagSet; -use router_api::error::Error; -use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection, Message}; - use crate::events::{ ChainFrozen, ChainRegistered, ChainUnfrozen, GatewayInfo, GatewayUpgraded, MessageRouted, }; -use crate::state::{chain_endpoints, Config, Store}; +use crate::state::{chain_endpoints, Config, State, Store, CONFIG, STATE}; +use crate::{events, state}; +use axelar_wasm_std::flagset::FlagSet; +use axelar_wasm_std::msg_id::{self, MessageIdFormat}; +use router_api::error::Error; +use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection, Message}; pub fn register_chain( deps: DepsMut, @@ -74,47 +77,106 @@ pub fn upgrade_gateway( )) } -pub fn freeze_chain( - deps: DepsMut, +fn freeze_specific_chain( + storage: &mut dyn Storage, chain: ChainName, direction: GatewayDirection, -) -> Result { - chain_endpoints().update(deps.storage, chain.clone(), |chain| match chain { +) -> Result { + chain_endpoints().update(storage, chain.clone(), |chain| match chain { None => Err(Error::ChainNotFound), Some(mut chain) => { *chain.frozen_status |= direction; Ok(chain) } })?; - Ok(Response::new().add_event( - ChainFrozen { - name: chain, - direction, - } - .into(), - )) + + Ok(ChainFrozen { + name: chain, + direction, + }) } -#[allow(clippy::arithmetic_side_effects)] // flagset operations don't cause under/overflows -pub fn unfreeze_chain( +pub fn freeze_chains( deps: DepsMut, + chains: HashMap, +) -> Result { + let events: Vec<_> = chains + .into_iter() + .map(|(chain, direction)| freeze_specific_chain(deps.storage, chain, direction)) + .map_ok(Event::from) + .try_collect()?; + + Ok(Response::new().add_events(events)) +} + +#[allow(clippy::arithmetic_side_effects)] // flagset operations don't cause under/overflows +fn unfreeze_specific_chain( + storage: &mut dyn Storage, chain: ChainName, direction: GatewayDirection, -) -> Result { - chain_endpoints().update(deps.storage, chain.clone(), |chain| match chain { +) -> Result { + chain_endpoints().update(storage, chain.clone(), |chain| match chain { None => Err(Error::ChainNotFound), Some(mut chain) => { *chain.frozen_status -= direction; Ok(chain) } })?; - Ok(Response::new().add_event( - ChainUnfrozen { - name: chain, - direction, - } - .into(), - )) + + Ok(ChainUnfrozen { + name: chain, + direction, + }) +} + +pub fn unfreeze_chains( + deps: DepsMut, + chains: HashMap, +) -> Result { + let events: Vec<_> = chains + .into_iter() + .map(|(chain, direction)| unfreeze_specific_chain(deps.storage, chain, direction)) + .map_ok(Event::from) + .try_collect()?; + + Ok(Response::new().add_events(events)) +} + +#[derive(thiserror::Error, Debug)] +enum StateUpdateError { + #[error("router is already in the same state")] + SameState, + #[error(transparent)] + Std(#[from] StdError), +} + +pub fn disable_routing(deps: DepsMut) -> Result { + let state = STATE.update(deps.storage, |state| match state { + State::Enabled => Ok(State::Disabled), + State::Disabled => Err(StateUpdateError::SameState), + }); + + state_toggle_response(state, events::RoutingDisabled) +} + +pub fn enable_routing(deps: DepsMut) -> Result { + let state = STATE.update(deps.storage, |state| match state { + State::Disabled => Ok(State::Enabled), + State::Enabled => Err(StateUpdateError::SameState), + }); + + state_toggle_response(state, events::RoutingEnabled) +} + +fn state_toggle_response( + state: Result, + event: impl Into, +) -> Result { + match state { + Ok(_) => Ok(Response::new().add_event(event.into())), + Err(StateUpdateError::SameState) => Ok(Response::new()), + Err(StateUpdateError::Std(err)) => Err(err.into()), + } } fn verify_msg_ids( @@ -160,11 +222,15 @@ fn validate_msgs( } pub fn route_messages( - store: impl Store, + mut store: impl Store, sender: Addr, msgs: Vec, ) -> error_stack::Result { - let config = store.load_config()?; + ensure!(state::is_enabled(store.storage()), Error::RoutingDisabled); + + let config = CONFIG + .load(store.storage()) + .change_context(Error::StoreFailure)?; let msgs = validate_msgs(&store, config.clone(), &sender, msgs)?; @@ -205,22 +271,25 @@ pub fn route_messages( #[cfg(test)] mod test { - use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use std::collections::HashMap; + + use cosmwasm_std::testing::mock_dependencies; use cosmwasm_std::Addr; + use cosmwasm_std::Storage; use mockall::predicate; - use rand::{Rng, RngCore}; + use rand::{random, RngCore}; use axelar_wasm_std::flagset::FlagSet; - use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::Storage; + use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, CrossChainId, Gateway, GatewayDirection, Message}; + use crate::contract::execute::route_messages; use crate::events::{ChainFrozen, ChainUnfrozen}; - use crate::state::chain_endpoints; + use crate::state::{chain_endpoints, State, Store, CONFIG, STATE}; use crate::state::{Config, MockStore}; - use super::{freeze_chain, route_messages, unfreeze_chain}; + use super::{freeze_chains, unfreeze_chains}; fn rand_message(source_chain: ChainName, destination_chain: ChainName) -> Message { let mut bytes = [0; 32]; @@ -228,7 +297,7 @@ mod test { let id = HexTxHashAndEventIndex { tx_hash: bytes, - event_index: rand::thread_rng().gen::(), + event_index: random::(), } .to_string(); @@ -266,10 +335,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); store .expect_load_chain_by_gateway() .once() @@ -295,10 +366,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -334,10 +407,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -371,10 +446,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -419,10 +496,13 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); + let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -454,10 +534,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = "foobar".try_into().unwrap(); @@ -476,10 +558,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -518,10 +602,12 @@ mod test { let destination_chain_1: ChainName = "bitcoin".parse().unwrap(); let destination_chain_2: ChainName = "polygon".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -587,10 +673,12 @@ mod test { let destination_chain_1: ChainName = "bitcoin".parse().unwrap(); let destination_chain_2: ChainName = "polygon".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let destination_chain_endpoint_1 = ChainEndpoint { name: destination_chain_1.clone(), gateway: Gateway { @@ -642,10 +730,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); store .expect_load_chain_by_chain_name() .once() @@ -674,10 +764,12 @@ mod test { let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); + let storage = cosmwasm_std::MemoryStorage::new(); let mut store = MockStore::new(); - store - .expect_load_config() - .returning(move || Ok(config.clone())); + store.expect_storage().return_var(Box::new(storage)); + + CONFIG.save(store.storage(), &config).unwrap(); + STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -729,8 +821,16 @@ mod test { .unwrap(); // freezing twice produces same result - freeze_chain(deps.as_mut(), chain.clone(), GatewayDirection::Incoming).unwrap(); - freeze_chain(deps.as_mut(), chain.clone(), GatewayDirection::Incoming).unwrap(); + freeze_chains( + deps.as_mut(), + HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), + ) + .unwrap(); + freeze_chains( + deps.as_mut(), + HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), + ) + .unwrap(); assert_chain_endpoint_frozen_status( deps.as_mut().storage, @@ -738,16 +838,14 @@ mod test { FlagSet::from(GatewayDirection::Incoming), ); - freeze_chain( + freeze_chains( deps.as_mut(), - chain.clone(), - GatewayDirection::Bidirectional, + HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); - freeze_chain( + freeze_chains( deps.as_mut(), - chain.clone(), - GatewayDirection::Bidirectional, + HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); @@ -758,8 +856,16 @@ mod test { ); // unfreezing twice produces same result - unfreeze_chain(deps.as_mut(), chain.clone(), GatewayDirection::Outgoing).unwrap(); - unfreeze_chain(deps.as_mut(), chain.clone(), GatewayDirection::Outgoing).unwrap(); + unfreeze_chains( + deps.as_mut(), + HashMap::from([(chain.clone(), GatewayDirection::Outgoing)]), + ) + .unwrap(); + unfreeze_chains( + deps.as_mut(), + HashMap::from([(chain.clone(), GatewayDirection::Outgoing)]), + ) + .unwrap(); assert_chain_endpoint_frozen_status( deps.as_mut().storage, @@ -767,16 +873,14 @@ mod test { FlagSet::from(GatewayDirection::Incoming), ); - unfreeze_chain( + unfreeze_chains( deps.as_mut(), - chain.clone(), - GatewayDirection::Bidirectional, + HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); - unfreeze_chain( + unfreeze_chains( deps.as_mut(), - chain.clone(), - GatewayDirection::Bidirectional, + HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); @@ -807,7 +911,11 @@ mod test { ) .unwrap(); - let res = freeze_chain(deps.as_mut(), chain.clone(), GatewayDirection::Incoming).unwrap(); + let res = freeze_chains( + deps.as_mut(), + HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), + ) + .unwrap(); assert_eq!(res.events.len(), 1); assert!(res.events.contains( @@ -818,7 +926,11 @@ mod test { .into() )); - let res = unfreeze_chain(deps.as_mut(), chain.clone(), GatewayDirection::Incoming).unwrap(); + let res = unfreeze_chains( + deps.as_mut(), + HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), + ) + .unwrap(); assert_eq!(res.events.len(), 1); assert!(res.events.contains( diff --git a/contracts/router/src/contract/query.rs b/contracts/router/src/contract/query.rs index ea3589854..d07546c41 100644 --- a/contracts/router/src/contract/query.rs +++ b/contracts/router/src/contract/query.rs @@ -37,13 +37,13 @@ pub fn chains( #[cfg(test)] mod test { + use crate::state; + use crate::state::{chain_endpoints, State, STATE}; use axelar_wasm_std::flagset::FlagSet; use cosmwasm_std::{testing::mock_dependencies, Addr}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection}; - use crate::state::chain_endpoints; - use super::get_chain_info; #[test] @@ -131,4 +131,16 @@ mod test { super::chains(deps.as_ref(), Some("e-chain".parse().unwrap()), Some(2)).unwrap(); assert_eq!(result.len(), 0); } + + #[test] + fn is_enabled() { + let mut deps = mock_dependencies(); + assert!(!state::is_enabled(deps.as_ref().storage)); + + STATE.save(deps.as_mut().storage, &State::Disabled).unwrap(); + assert!(!state::is_enabled(deps.as_ref().storage)); + + STATE.save(deps.as_mut().storage, &State::Enabled).unwrap(); + assert!(state::is_enabled(deps.as_ref().storage)); + } } diff --git a/contracts/router/src/events.rs b/contracts/router/src/events.rs index 0dad9c8be..29c0c85a0 100644 --- a/contracts/router/src/events.rs +++ b/contracts/router/src/events.rs @@ -21,14 +21,6 @@ pub struct GatewayUpgraded { pub gateway: GatewayInfo, } -pub struct GatewayFrozen { - pub gateway: GatewayInfo, -} - -pub struct GatewayUnfrozen { - pub gateway: GatewayInfo, -} - pub struct ChainFrozen { pub name: ChainName, pub direction: GatewayDirection, @@ -43,6 +35,9 @@ pub struct MessageRouted { pub msg: Message, } +pub struct RoutingDisabled; +pub struct RoutingEnabled; + impl From for Event { fn from(other: RouterInstantiated) -> Self { Event::new("router_instantiated") @@ -75,17 +70,15 @@ impl From for Event { } } -impl From for Event { - fn from(other: GatewayFrozen) -> Self { - let attrs: Vec = other.gateway.into(); - Event::new("gateway_frozen").add_attributes(attrs) +impl From for Event { + fn from(_: RoutingDisabled) -> Self { + Event::new("routing_disabled") } } -impl From for Event { - fn from(other: GatewayUnfrozen) -> Self { - let attrs: Vec = other.gateway.into(); - Event::new("gateway_unfrozen").add_attributes(attrs) +impl From for Event { + fn from(_: RoutingEnabled) -> Self { + Event::new("routing_enabled") } } diff --git a/contracts/router/src/migrations/v0_3_3.rs b/contracts/router/src/migrations/v0_3_3.rs index 261089b21..d6830cc7e 100644 --- a/contracts/router/src/migrations/v0_3_3.rs +++ b/contracts/router/src/migrations/v0_3_3.rs @@ -1,4 +1,4 @@ -use crate::state::CONFIG; +use crate::state::{State, CONFIG, STATE}; use axelar_wasm_std::{permission_control, ContractError}; use cosmwasm_std::{StdResult, Storage}; use cw2::VersionError; @@ -13,10 +13,15 @@ pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { .into()) } else { set_generalized_permission_control(storage)?; + set_router_state(storage)?; Ok(()) } } +fn set_router_state(storage: &mut dyn Storage) -> StdResult<()> { + STATE.save(storage, &State::Enabled) +} + fn set_generalized_permission_control(storage: &mut dyn Storage) -> StdResult<()> { let config = CONFIG.load(storage)?; permission_control::set_admin(storage, &config.admin)?; @@ -27,13 +32,25 @@ fn set_generalized_permission_control(storage: &mut dyn Storage) -> StdResult<() #[cfg(test)] mod test { use crate::state::Config; - use crate::state::CONFIG; + use crate::state::{State, CONFIG, STATE}; use axelar_wasm_std::ensure_permission; use axelar_wasm_std::permission_control::{Error, Permission}; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{Addr, Storage}; use error_stack::Report; + #[test] + fn set_router_state() { + let mut storage = MockStorage::new(); + + assert!(STATE.load(&storage).is_err()); + + super::set_router_state(&mut storage).unwrap(); + + let state = STATE.load(&storage).unwrap(); + assert_eq!(state, State::Enabled); + } + #[test] fn set_generalized_permission_control() { let config = Config { diff --git a/contracts/router/src/state.rs b/contracts/router/src/state.rs index 7b26e9584..2f536c797 100644 --- a/contracts/router/src/state.rs +++ b/contracts/router/src/state.rs @@ -8,8 +8,7 @@ use router_api::{ChainEndpoint, ChainName}; #[automock] pub trait Store { - fn save_config(&mut self, config: Config) -> error_stack::Result<(), Error>; - fn load_config(&self) -> error_stack::Result; + fn storage(&mut self) -> &mut dyn Storage; fn load_chain_by_gateway( &self, gateway: &Addr, @@ -25,16 +24,8 @@ pub struct RouterStore<'a> { } impl Store for RouterStore<'_> { - fn save_config(&mut self, config: Config) -> error_stack::Result<(), Error> { - CONFIG - .save(self.storage, &config) - .change_context(Error::StoreFailure) - } - - fn load_config(&self) -> error_stack::Result { - CONFIG - .load(self.storage) - .change_context(Error::StoreFailure) + fn storage(&mut self) -> &mut dyn Storage { + self.storage } fn load_chain_by_gateway( @@ -73,6 +64,17 @@ pub struct Config { pub const CONFIG: Item = Item::new("config"); +#[cw_serde] +pub enum State { + Enabled, + Disabled, +} +pub const STATE: Item = Item::new("state"); + +pub fn is_enabled(storage: &dyn Storage) -> bool { + STATE.load(storage).unwrap_or(State::Disabled) == State::Enabled +} + pub struct ChainEndpointIndexes<'a> { pub gateway: GatewayIndex<'a>, } diff --git a/integration-tests/tests/chain_freeze_unfreeze.rs b/integration-tests/tests/chain_freeze_unfreeze.rs index 8cc2984a5..084d6eab7 100644 --- a/integration-tests/tests/chain_freeze_unfreeze.rs +++ b/integration-tests/tests/chain_freeze_unfreeze.rs @@ -64,7 +64,7 @@ fn chain_can_be_freezed_unfreezed() { test_utils::freeze_chain( &mut protocol.app, &protocol.router, - &chain1.chain_name, + chain1.chain_name.clone(), router_api::GatewayDirection::Bidirectional, &protocol.router_admin_address, ); diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 6ddc30523..b3aa35554 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -10,7 +10,7 @@ use cosmwasm_std::{ use cw_multi_test::{App, AppResponse, Executor}; use multisig_prover::msg::VerifierSetResponse; use router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use integration_tests::contract::Contract; use integration_tests::coordinator_contract::CoordinatorContract; @@ -88,16 +88,15 @@ pub fn route_messages(app: &mut App, gateway: &GatewayContract, msgs: &[Message] pub fn freeze_chain( app: &mut App, router: &RouterContract, - chain_name: &ChainName, + chain_name: ChainName, direction: GatewayDirection, admin: &Addr, ) { let response = router.execute( app, admin.clone(), - &router_api::msg::ExecuteMsg::FreezeChain { - chain: chain_name.clone(), - direction, + &router_api::msg::ExecuteMsg::FreezeChains { + chains: HashMap::from([(chain_name, direction)]), }, ); assert!(response.is_ok(), "{:?}", response); @@ -113,9 +112,8 @@ pub fn unfreeze_chain( let response = router.execute( app, admin.clone(), - &router_api::msg::ExecuteMsg::UnfreezeChain { - chain: chain_name.clone(), - direction, + &router_api::msg::ExecuteMsg::UnfreezeChains { + chains: HashMap::from([(chain_name.clone(), direction)]), }, ); assert!(response.is_ok(), "{:?}", response); diff --git a/packages/router-api/src/error.rs b/packages/router-api/src/error.rs index 769cb1902..0e04f37f8 100644 --- a/packages/router-api/src/error.rs +++ b/packages/router-api/src/error.rs @@ -14,6 +14,9 @@ pub enum Error { #[error(transparent)] Std(#[from] StdError), + #[error("amplifier routing is disabled")] + RoutingDisabled, + #[error("chain already exists")] ChainAlreadyExists, diff --git a/packages/router-api/src/msg.rs b/packages/router-api/src/msg.rs index a075a1aff..23250e0f2 100644 --- a/packages/router-api/src/msg.rs +++ b/packages/router-api/src/msg.rs @@ -1,5 +1,6 @@ use axelar_wasm_std::msg_id::MessageIdFormat; use cosmwasm_schema::{cw_serde, QueryResponses}; +use std::collections::HashMap; use crate::primitives::*; @@ -9,13 +10,13 @@ pub enum ExecuteMsg { * Governance Methods * All the below messages should only be called by governance */ - // Registers a new chain with the router + /// Registers a new chain with the router RegisterChain { chain: ChainName, gateway_address: Address, msg_id_format: MessageIdFormat, }, - // Changes the gateway address associated with a particular chain + /// Changes the gateway address associated with a particular chain UpgradeGateway { chain: ChainName, contract_address: Address, @@ -25,23 +26,27 @@ pub enum ExecuteMsg { * Router Admin Methods * All the below messages should only be called by the router admin */ - // Freezes a chain, in the specified direction. - FreezeChain { - chain: ChainName, - direction: GatewayDirection, + /// Freezes the specified chains in the specified directions. + FreezeChains { + chains: HashMap, }, - // Unfreezes a chain, in the specified direction. - UnfreezeChain { - chain: ChainName, - direction: GatewayDirection, + + /// Unfreezes the specified chains in the specified directions. + UnfreezeChains { + chains: HashMap, }, + /// Emergency command to stop all amplifier routing. + DisableRouting, + + /// Resumes routing after an emergency shutdown. + EnableRouting, /* * Gateway Messages * The below messages can only be called by registered gateways */ - // Routes a message to all outgoing gateways registered to the destination domain. - // Called by an incoming gateway + /// Routes a message to all outgoing gateways registered to the destination domain. + /// Called by an incoming gateway RouteMessages(Vec), } @@ -60,4 +65,6 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + #[returns(bool)] + IsEnabled, } From 845403386e232b7e011fd6c16314e4bf73aaa64f Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Wed, 3 Jul 2024 11:45:21 -0400 Subject: [PATCH 049/168] feat(multisig): query to check caller authorization status (#478) * feat: check caller authorization status for multisig * refactor: rename query function name to caller_authorized --- contracts/multisig/src/contract.rs | 14 +++++++++++++- contracts/multisig/src/contract/query.rs | 9 ++++++++- contracts/multisig/src/msg.rs | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index be358b93a..7866bb7aa 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -123,6 +123,9 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { deps.api.addr_validate(&verifier_address)?, key_type, )?), + QueryMsg::IsCallerAuthorized { contract_address } => { + to_json_binary(&query::caller_authorized(deps, contract_address)?) + } } } @@ -967,9 +970,10 @@ mod tests { #[test] fn authorize_and_unauthorize_caller() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); + let prover_address = Addr::unchecked(PROVER); // authorize - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + do_authorize_caller(deps.as_mut(), prover_address.clone()).unwrap(); for verifier_set_id in [ecdsa_subkey.clone(), ed25519_subkey.clone()] { let res = do_start_signing_session( @@ -982,6 +986,10 @@ mod tests { assert!(res.is_ok()); } + let caller_authorization_status = + query::caller_authorized(deps.as_ref(), prover_address.clone()).unwrap(); + assert!(caller_authorization_status); + // unauthorize do_unauthorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); for verifier_set_id in [ecdsa_subkey, ed25519_subkey] { @@ -997,6 +1005,10 @@ mod tests { .to_string() .contains(&ContractError::Unauthorized.to_string())); } + + let caller_authorization_status = + query::caller_authorized(deps.as_ref(), prover_address).unwrap(); + assert!(!caller_authorization_status); } #[test] diff --git a/contracts/multisig/src/contract/query.rs b/contracts/multisig/src/contract/query.rs index e79b1100d..b6a900ed6 100644 --- a/contracts/multisig/src/contract/query.rs +++ b/contracts/multisig/src/contract/query.rs @@ -1,7 +1,7 @@ use crate::{ key::{KeyType, PublicKey}, multisig::Multisig, - state::{load_pub_key, load_session_signatures}, + state::{load_pub_key, load_session_signatures, AUTHORIZED_CALLERS}, verifier_set::VerifierSet, }; @@ -28,3 +28,10 @@ pub fn get_public_key(deps: Deps, verifier: Addr, key_type: KeyType) -> StdResul let raw = load_pub_key(deps.storage, verifier, key_type)?; Ok(PublicKey::try_from((key_type, raw)).expect("could not decode pub key")) } + +pub fn caller_authorized(deps: Deps, address: Addr) -> StdResult { + let is_authorized = AUTHORIZED_CALLERS + .may_load(deps.storage, &address)? + .is_some(); + Ok(is_authorized) +} diff --git a/contracts/multisig/src/msg.rs b/contracts/multisig/src/msg.rs index fbae987b5..0d23c423a 100644 --- a/contracts/multisig/src/msg.rs +++ b/contracts/multisig/src/msg.rs @@ -68,6 +68,9 @@ pub enum QueryMsg { verifier_address: String, key_type: KeyType, }, + + #[returns(bool)] + IsCallerAuthorized { contract_address: Addr }, } #[cw_serde] From ab4152d3b73f673b793289d7ccc1337d9fd49f1b Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 3 Jul 2024 12:39:40 -0600 Subject: [PATCH 050/168] fix(ampd): increase number of retries when fetching block events (#484) --- ampd/src/event_sub.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ampd/src/event_sub.rs b/ampd/src/event_sub.rs index c743ef4ab..274e24e5b 100644 --- a/ampd/src/event_sub.rs +++ b/ampd/src/event_sub.rs @@ -138,7 +138,7 @@ impl EventPublisher { }, RetryPolicy::RepeatConstant { sleep: Duration::from_secs(1), - max_attempts: 3, + max_attempts: 15, }, ) .await?; From b3f82a308805c3f9289a4b02d7a1210e3041a8c2 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:08:18 -0600 Subject: [PATCH 051/168] feat(minor-voting-verifier): consistent gas cost for voting (#476) * feat(minor-voting-verifier): consistent gas cost for voting --- Cargo.lock | 1 + contracts/voting-verifier/Cargo.toml | 1 + contracts/voting-verifier/src/contract.rs | 127 ++++++++++++---------- contracts/voting-verifier/src/execute.rs | 65 +++++++---- contracts/voting-verifier/src/state.rs | 5 +- packages/axelar-wasm-std/src/voting.rs | 84 ++++++++++---- 6 files changed, 182 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9bcbf7d79..db4267fb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8516,6 +8516,7 @@ dependencies = [ "cw2 1.1.2", "error-stack", "integration-tests", + "itertools 0.11.0", "multisig", "rand", "report", diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index 35f139271..882c2e1c6 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -41,6 +41,7 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } error-stack = { workspace = true } +itertools = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } rewards = { workspace = true, features = ["library"] } diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index bf2a97d65..52a9795dd 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1324,9 +1324,8 @@ mod test { threshold, Threshold::try_from((2, 3)).unwrap().try_into().unwrap() ); - let votes_to_reach_quorum = 2; - let messages = messages(2, &msg_id_format); + let messages = messages(3, &msg_id_format); // 1. First verification @@ -1342,11 +1341,28 @@ mod test { ); assert!(res.is_ok()); - // 2. Verifiers cast votes, but only reach consensus on the first three messages + // 2. Verifiers cast votes + // The first message reaches quorum after 2 votes, + // The second message reaches quorum after 3 votes, + // The third message never reaches quorum verifiers.iter().enumerate().for_each(|(i, verifier)| { let msg = ExecuteMsg::Vote { poll_id: 1u64.into(), - votes: vec![Vote::SucceededOnChain, Vote::NotFound], + votes: vec![ + Vote::SucceededOnChain, + if i % 2 == 0 { + Vote::NotFound + } else { + Vote::SucceededOnChain + }, + if i % 3 == 0 { + Vote::NotFound + } else if i % 3 == 1 { + Vote::SucceededOnChain + } else { + Vote::FailedOnChain + }, + ], }; let res = execute( @@ -1357,62 +1373,57 @@ mod test { ) .unwrap(); - // should emit event when vote causes quorum to be reached - assert_eq!( - res.events.iter().any(|event| event.ty == "quorum_reached"), - i == votes_to_reach_quorum - 1 - ); - - if i == votes_to_reach_quorum - 1 { - let mut iter = res.events.iter(); - - let first_event = iter.find(|event| event.ty == "quorum_reached").unwrap(); - - let msg: Message = serde_json::from_str( - &first_event - .attributes - .iter() - .find(|attr| attr.key == "content") - .unwrap() - .value, - ) - .unwrap(); - assert_eq!(msg, messages[0]); - - let status: VerificationStatus = serde_json::from_str( - &first_event - .attributes - .iter() - .find(|attr| attr.key == "status") - .unwrap() - .value, - ) - .unwrap(); - assert_eq!(status, VerificationStatus::SucceededOnSourceChain); + let verify_event = + |res: &Response, expected_message: Message, expected_status: VerificationStatus| { + let mut iter = res.events.iter(); + + let event = iter.find(|event| event.ty == "quorum_reached").unwrap(); + + let msg: Message = serde_json::from_str( + &event + .attributes + .iter() + .find(|attr| attr.key == "content") + .unwrap() + .value, + ) + .unwrap(); + assert_eq!(msg, expected_message); + + let status: VerificationStatus = serde_json::from_str( + &event + .attributes + .iter() + .find(|attr| attr.key == "status") + .unwrap() + .value, + ) + .unwrap(); + assert_eq!(status, expected_status); + + let additional_event = iter.find(|event| event.ty == "quorum_reached"); + assert_eq!(additional_event, None); + }; + + if i == 0 { + let event = res.events.iter().find(|event| event.ty == "quorum_reached"); + assert_eq!(event, None); + } - let second_event = iter.find(|event| event.ty == "quorum_reached").unwrap(); + if i == 1 { + verify_event( + &res, + messages[0].clone(), + VerificationStatus::SucceededOnSourceChain, + ); + } - let msg: Message = serde_json::from_str( - &second_event - .attributes - .iter() - .find(|attr| attr.key == "content") - .unwrap() - .value, - ) - .unwrap(); - assert_eq!(msg, messages[1]); - - let status: VerificationStatus = serde_json::from_str( - &second_event - .attributes - .iter() - .find(|attr| attr.key == "status") - .unwrap() - .value, - ) - .unwrap(); - assert_eq!(status, VerificationStatus::NotFoundOnSourceChain); + if i == 2 { + verify_event( + &res, + messages[1].clone(), + VerificationStatus::NotFoundOnSourceChain, + ); } }); } diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 991a45837..c7788fc06 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use cosmwasm_std::{ to_json_binary, Addr, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, @@ -13,7 +15,7 @@ use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; use service_registry::{msg::QueryMsg, state::WeightedVerifier}; -use crate::state::{self, Poll, PollContent}; +use crate::state::{self, Poll, PollContent, VOTES}; use crate::state::{CONFIG, POLLS, POLL_ID}; use crate::{error::ContractError, query::message_status}; use crate::{events::QuorumReached, query::verifier_set_status, state::poll_verifier_sets}; @@ -24,6 +26,8 @@ use crate::{ state::poll_messages, }; +use itertools::Itertools; + // TODO: this type of function exists in many contracts. Would be better to implement this // in one place, and then just include it pub fn require_governance(deps: &DepsMut, sender: Addr) -> Result<(), ContractError> { @@ -167,23 +171,23 @@ pub fn verify_messages( fn get_poll_results(poll: &Poll) -> PollResults { match poll { - Poll::Messages(weighted_poll) => weighted_poll.state().results, - Poll::ConfirmVerifierSet(weighted_poll) => weighted_poll.state().results, + Poll::Messages(weighted_poll) => weighted_poll.results(), + Poll::ConfirmVerifierSet(weighted_poll) => weighted_poll.results(), } } fn make_quorum_event( - vote: &Vote, + vote: Option, index_in_poll: u32, poll_id: &PollId, poll: &Poll, deps: &DepsMut, -) -> Result { - let status = match vote { +) -> Result, ContractError> { + let status = vote.map(|vote| match vote { Vote::SucceededOnChain => VerificationStatus::SucceededOnSourceChain, Vote::FailedOnChain => VerificationStatus::FailedOnSourceChain, Vote::NotFound => VerificationStatus::NotFoundOnSourceChain, - }; + }); match poll { Poll::Messages(_) => { @@ -191,25 +195,32 @@ fn make_quorum_event( .idx .load_message(deps.storage, *poll_id, index_in_poll)? .expect("message not found in poll"); - Ok(QuorumReached { - content: msg, - status, - } - .into()) + + Ok(status.map(|status| { + QuorumReached { + content: msg, + status, + } + .into() + })) } Poll::ConfirmVerifierSet(_) => { let verifier_set = poll_verifier_sets() .idx .load_verifier_set(deps.storage, *poll_id)? .expect("verifier set not found in poll"); - Ok(QuorumReached { - content: verifier_set, - status, - } - .into()) + + Ok(status.map(|status| { + QuorumReached { + content: verifier_set, + status, + } + .into() + })) } } } + pub fn vote( deps: DepsMut, env: Env, @@ -224,7 +235,7 @@ pub fn vote( let results_before_voting = get_poll_results(&poll); let poll = poll.try_map(|poll| { - poll.cast_vote(env.block.height, &info.sender, votes) + poll.cast_vote(env.block.height, &info.sender, votes.clone()) .map_err(ContractError::from) })?; POLLS.save(deps.storage, poll_id, &poll)?; @@ -237,13 +248,14 @@ pub fn vote( .0 .into_iter() .enumerate() - .filter_map(|(idx, vote)| vote.map(|vote| (idx, vote))) .map(|(index_in_poll, vote)| { let idx = u32::try_from(index_in_poll) .expect("the amount of votes should never overflow u32"); - make_quorum_event(&vote, idx, &poll_id, &poll, &deps) + make_quorum_event(vote, idx, &poll_id, &poll, &deps) }) - .collect::, _>>()?; + .collect::>, _>>()?; + + VOTES.save(deps.storage, (poll_id, info.sender.to_string()), &votes)?; Ok(Response::new() .add_event( @@ -253,7 +265,7 @@ pub fn vote( } .into(), ) - .add_events(quorum_events)) + .add_events(quorum_events.into_iter().flatten())) } pub fn end_poll(deps: DepsMut, env: Env, poll_id: PollId) -> Result { @@ -266,8 +278,15 @@ pub fn end_poll(deps: DepsMut, env: Env, poll_id: PollId) -> Result)> = VOTES + .prefix(poll_id) + .range(deps.storage, None, None, cosmwasm_std::Order::Ascending) + .try_collect()?; + let poll_result = match &poll { - Poll::Messages(poll) | Poll::ConfirmVerifierSet(poll) => poll.state(), + Poll::Messages(poll) | Poll::ConfirmVerifierSet(poll) => { + poll.state(HashMap::from_iter(votes)) + } }; // TODO: change rewards contract interface to accept a list of addresses to avoid creating multiple wasm messages diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index d6785ea2f..fefdbaa49 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -7,7 +7,7 @@ use axelar_wasm_std::{ hash::Hash, msg_id::MessageIdFormat, nonempty, - voting::{PollId, WeightedPoll}, + voting::{PollId, Vote, WeightedPoll}, MajorityThreshold, }; use multisig::verifier_set::VerifierSet; @@ -79,6 +79,9 @@ pub const POLL_ID: counter::Counter = counter::Counter::new("poll_id"); pub const POLLS: Map = Map::new("polls"); +type VerifierAddr = String; +pub const VOTES: Map<(PollId, VerifierAddr), Vec> = Map::new("votes"); + pub const CONFIG: Item = Item::new("config"); /// A multi-index that indexes a message by (PollID, index in poll) pair. The primary key of the underlying diff --git a/packages/axelar-wasm-std/src/voting.rs b/packages/axelar-wasm-std/src/voting.rs index 4ee555195..7ce8afcdc 100644 --- a/packages/axelar-wasm-std/src/voting.rs +++ b/packages/axelar-wasm-std/src/voting.rs @@ -15,6 +15,7 @@ */ use std::array::TryFromSliceError; use std::collections::BTreeMap; +use std::collections::HashMap; use std::fmt; use std::ops::Add; use std::ops::Mul; @@ -22,6 +23,7 @@ use std::str::FromStr; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdError, StdResult, Uint128, Uint64}; +use cw_storage_plus::Prefixer; use cw_storage_plus::{IntKey, Key, KeyDeserialize, PrimaryKey}; use num_traits::CheckedAdd; use num_traits::One; @@ -133,6 +135,12 @@ impl<'a> PrimaryKey<'a> for PollId { } } +impl<'a> Prefixer<'a> for PollId { + fn prefix(&self) -> Vec { + vec![Key::Val64(self.0.to_be_bytes())] + } +} + impl KeyDeserialize for PollId { type Output = Self; @@ -223,9 +231,9 @@ impl PollResults { self.0 .into_iter() .zip(rhs.0) - .filter_map(|(lhs, rhs)| { + .map(|(lhs, rhs)| { if lhs.is_some() && rhs.is_none() { - Some(lhs) + lhs } else { None } @@ -252,7 +260,7 @@ pub enum PollStatus { #[cw_serde] pub struct Participation { pub weight: nonempty::Uint128, - pub vote: Option>, + pub voted: bool, } #[cw_serde] @@ -278,7 +286,7 @@ impl WeightedPoll { address, Participation { weight: participant.weight, - vote: None, + voted: false, }, ) }) @@ -309,7 +317,17 @@ impl WeightedPoll { Ok(self) } - pub fn state(&self) -> PollState { + pub fn results(&self) -> PollResults { + let quorum: Uint128 = self.quorum.into(); + PollResults( + self.tallies + .iter() + .map(|tallies| tallies.consensus(quorum)) + .collect(), + ) + } + + pub fn state(&self, voting_history: HashMap>) -> PollState { let quorum: Uint128 = self.quorum.into(); let results: Vec> = self .tallies @@ -320,10 +338,11 @@ impl WeightedPoll { let consensus_participants = self .participation .iter() - .filter_map(|(address, participation)| { - participation.vote.as_ref().and_then(|votes| { + .filter_map(|(address, _)| { + voting_history.get(address).and_then(|votes| { let voted_consensus = votes.iter().zip(results.iter()).all(|(vote, result)| { - result.is_none() || Some(vote) == result.as_ref() // if there was no consensus, we don't care about the vote + result.is_none() || Some(vote) == result.as_ref() + // if there was no consensus, we don't care about the vote }); if voted_consensus { @@ -369,7 +388,7 @@ impl WeightedPoll { return Err(Error::InvalidVoteSize); } - if participation.vote.is_some() { + if participation.voted { return Err(Error::AlreadyVoted); } @@ -380,7 +399,7 @@ impl WeightedPoll { tallies.tally(vote, &participation.weight.into()); }); - participation.vote = Some(votes); + participation.voted = true; Ok(self) } @@ -405,7 +424,7 @@ mod tests { poll.participation.get("addr1").unwrap(), &Participation { weight: nonempty::Uint128::try_from(Uint128::from(100u64)).unwrap(), - vote: None, + voted: false } ); @@ -417,7 +436,7 @@ mod tests { poll.participation.get("addr1").unwrap(), &Participation { weight: nonempty::Uint128::try_from(Uint128::from(100u64)).unwrap(), - vote: Some(votes), + voted: true } ); } @@ -499,17 +518,23 @@ mod tests { fn should_conclude_poll() { let poll = new_poll(2, 2, vec!["addr1", "addr2", "addr3"]); let votes = vec![Vote::SucceededOnChain, Vote::SucceededOnChain]; + let voters = [Addr::unchecked("addr1"), Addr::unchecked("addr2")]; let poll = poll - .cast_vote(1, &Addr::unchecked("addr1"), votes.clone()) + .cast_vote(1, &voters[0], votes.clone()) .unwrap() - .cast_vote(1, &Addr::unchecked("addr2"), votes) + .cast_vote(1, &voters[1], votes.clone()) .unwrap(); let poll = poll.finish(2).unwrap(); assert_eq!(poll.status, PollStatus::Finished); - let result = poll.state(); + let result = poll.state( + voters + .iter() + .map(|voter| (voter.to_string(), votes.clone())) + .collect(), + ); assert_eq!( result, PollState { @@ -528,16 +553,37 @@ mod tests { let poll = new_poll(2, 2, vec!["addr1", "addr2", "addr3"]); let votes = vec![Vote::SucceededOnChain, Vote::SucceededOnChain]; let wrong_votes = vec![Vote::FailedOnChain, Vote::FailedOnChain]; + let voters = [ + Addr::unchecked("addr1"), + Addr::unchecked("addr2"), + Addr::unchecked("addr3"), + ]; + let voting_history: Vec<(&Addr, Vec)> = voters + .iter() + .enumerate() + .map(|(idx, voter)| { + if idx == 1 { + (voter, wrong_votes.clone()) + } else { + (voter, votes.clone()) + } + }) + .collect(); let poll = poll - .cast_vote(1, &Addr::unchecked("addr1"), votes.clone()) + .cast_vote(1, voting_history[0].0, voting_history[0].1.clone()) .unwrap() - .cast_vote(1, &Addr::unchecked("addr2"), wrong_votes) + .cast_vote(1, voting_history[1].0, voting_history[1].1.clone()) .unwrap() - .cast_vote(1, &Addr::unchecked("addr3"), votes) + .cast_vote(1, voting_history[2].0, voting_history[2].1.clone()) .unwrap(); - let result = poll.finish(2).unwrap().state(); + let result = poll.finish(2).unwrap().state( + voting_history + .into_iter() + .map(|(voter, votes)| (voter.to_string(), votes)) + .collect(), + ); assert_eq!( result, From a75b744aa70455f9c658d7aaa4dd2d9adf94a717 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 4 Jul 2024 11:32:34 -0400 Subject: [PATCH 052/168] feat: improve msg permission control with derive macro (#479) --- Cargo.lock | 121 ++-- Cargo.toml | 3 + contracts/router/Cargo.toml | 1 + contracts/router/src/contract.rs | 204 +++---- contracts/router/src/contract/execute.rs | 543 +++++++++--------- contracts/router/src/contract/query.rs | 10 +- contracts/router/src/migrations/v0_3_3.rs | 254 ++++++-- contracts/router/src/state.rs | 86 +-- .../axelar-wasm-std/src/permission_control.rs | 257 ++------- packages/msgs-derive/Cargo.toml | 22 + packages/msgs-derive/release.toml | 1 + packages/msgs-derive/src/lib.rs | 357 ++++++++++++ packages/msgs-derive/tests/macro.rs | 321 +++++++++++ packages/router-api/Cargo.toml | 1 + packages/router-api/src/msg.rs | 27 +- 15 files changed, 1443 insertions(+), 765 deletions(-) create mode 100644 packages/msgs-derive/Cargo.toml create mode 100644 packages/msgs-derive/release.toml create mode 100644 packages/msgs-derive/src/lib.rs create mode 100644 packages/msgs-derive/tests/macro.rs diff --git a/Cargo.lock b/Cargo.lock index db4267fb6..e39571392 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,7 +591,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -602,7 +602,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -624,7 +624,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -675,7 +675,7 @@ dependencies = [ "error-stack", "quote 1.0.36", "report", - "syn 2.0.66", + "syn 2.0.68", "thiserror", ] @@ -1297,7 +1297,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1685,7 +1685,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1845,7 +1845,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "strsim 0.11.1", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1867,7 +1867,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core 0.20.9", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1954,7 +1954,7 @@ checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1999,7 +1999,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "rustc_version", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2085,7 +2085,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2280,7 +2280,7 @@ dependencies = [ "once_cell", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2393,7 +2393,7 @@ dependencies = [ "regex", "serde", "serde_json", - "syn 2.0.66", + "syn 2.0.68", "toml 0.8.14", "walkdir", ] @@ -2411,7 +2411,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "serde_json", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2437,7 +2437,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.2", - "syn 2.0.66", + "syn 2.0.68", "tempfile", "thiserror", "tiny-keccak", @@ -2515,7 +2515,7 @@ dependencies = [ "quote 1.0.36", "serde", "serde_json", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2875,7 +2875,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -3554,7 +3554,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -4190,7 +4190,7 @@ dependencies = [ "cfg-if", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -4442,7 +4442,7 @@ source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.26.2#f531168c7452 dependencies = [ "enum-compat-util", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -4503,6 +4503,19 @@ dependencies = [ "smallvec", ] +[[package]] +name = "msgs-derive" +version = "0.1.0" +dependencies = [ + "axelar-wasm-std", + "cosmwasm-std", + "error-stack", + "itertools 0.11.0", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.68", +] + [[package]] name = "msim-macros" version = "0.1.0" @@ -4972,7 +4985,7 @@ dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -4984,7 +4997,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5085,7 +5098,7 @@ dependencies = [ "proc-macro-error", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5331,7 +5344,7 @@ dependencies = [ "pest_meta", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5405,7 +5418,7 @@ dependencies = [ "phf_shared", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5434,7 +5447,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5562,7 +5575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2 1.0.85", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -5805,7 +5818,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6002,7 +6015,7 @@ checksum = "a25d631e41bfb5fdcde1d4e2215f62f7f0afa3ff11e26563765bd6ea1d229aeb" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6042,7 +6055,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6254,6 +6267,7 @@ dependencies = [ "integration-tests", "itertools 0.11.0", "mockall 0.12.1", + "msgs-derive", "rand", "report", "router-api", @@ -6273,6 +6287,7 @@ dependencies = [ "error-stack", "flagset", "hex", + "msgs-derive", "rand", "report", "schemars", @@ -6531,7 +6546,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "serde_derive_internals", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6694,7 +6709,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6705,7 +6720,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6738,7 +6753,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6805,7 +6820,7 @@ dependencies = [ "darling 0.20.9", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -6817,7 +6832,7 @@ dependencies = [ "darling 0.20.9", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -7177,7 +7192,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "rustversion", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -7190,7 +7205,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "rustversion", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -7308,7 +7323,7 @@ dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", "sui-enum-compat-util", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -7449,9 +7464,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", @@ -7490,7 +7505,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -7739,7 +7754,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -7883,7 +7898,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -8177,7 +8192,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -8296,7 +8311,7 @@ checksum = "1f718dfaf347dcb5b983bfc87608144b0bad87970aebcbea5ce44d2a30c08e63" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -8583,7 +8598,7 @@ dependencies = [ "once_cell", "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-shared", ] @@ -8617,7 +8632,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9003,7 +9018,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", "synstructure 0.13.1", ] @@ -9024,7 +9039,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -9044,7 +9059,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", "synstructure 0.13.1", ] @@ -9065,7 +9080,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -9087,5 +9102,5 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2 1.0.85", "quote 1.0.36", - "syn 2.0.66", + "syn 2.0.68", ] diff --git a/Cargo.toml b/Cargo.toml index 4d4ef33fb..770853dfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ itertools = "0.11.0" voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.2.0", path = "contracts/coordinator" } multisig = { version = "^0.4.1", path = "contracts/multisig" } +msgs-derive = { version = "^0.1.0", path = "packages/msgs-derive" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^0.4.1", path = "contracts/service-registry" } @@ -31,6 +32,7 @@ gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } router-api = { version = "^0.1.0", path = "packages/router-api" } report = { version = "^0.1.0", path = "packages/report" } client = { version = "^0.1.0", path = "packages/client" } +quote = "1.0.36" rewards = { version = "^0.4.0", path = "contracts/rewards" } thiserror = "1.0.61" mockall = "0.12.1" @@ -39,6 +41,7 @@ serde_json = "1.0.89" schemars = "0.8.10" sha3 = { version = "0.10.8", default-features = false, features = [] } signature-verifier-api = { version = "^0.1.0", path = "packages/signature-verifier-api" } +syn = "2.0.68" ethers-contract = { version = "2.0.14", default-features = false, features = ["abigen"] } ethers-core = "2.0.14" tokio = "1.38.0" diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index a2a2afc8c..bb681b9f0 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -44,6 +44,7 @@ flagset = { version = "0.4.3", features = ["serde"] } gateway-api = { workspace = true } itertools = { workspace = true } mockall = { workspace = true } +msgs-derive = { workspace = true } report = { workspace = true } router-api = { workspace = true } serde_json = { workspace = true } diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 5d9aa1651..ba6ee4ccd 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -1,22 +1,21 @@ -use axelar_wasm_std::permission_control::Permission; -use axelar_wasm_std::{ensure_any_permission, ensure_permission, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, +}; +use axelar_wasm_std::{permission_control, FnExt}; +use router_api::error::Error; use router_api::msg::{ExecuteMsg, QueryMsg}; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; -use crate::state::{Config, RouterStore, State, CONFIG, STATE}; +use crate::state::{load_chain_by_gateway, Config, State, CONTRACT_NAME, CONTRACT_VERSION, STATE}; use crate::{migrations, state}; mod execute; mod query; -const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( deps: DepsMut, @@ -46,12 +45,10 @@ pub fn instantiate( permission_control::set_governance(deps.storage, &governance)?; let config = Config { - admin: admin.clone(), - governance: governance.clone(), nexus_gateway: nexus_gateway.clone(), }; - CONFIG.save(deps.storage, &config)?; + state::save_config(deps.storage, &config)?; STATE.save(deps.storage, &State::Enabled)?; Ok(Response::new().add_event( @@ -71,55 +68,48 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { + match msg.ensure_permissions( + deps.storage, + &info.sender, + find_gateway_address(&info.sender), + )? { ExecuteMsg::RegisterChain { chain, gateway_address, msg_id_format, } => { - ensure_permission!(Permission::Governance, deps.storage, &info.sender); - let gateway_address = deps.api.addr_validate(&gateway_address)?; - execute::register_chain(deps, chain, gateway_address, msg_id_format) + execute::register_chain(deps.storage, chain, gateway_address, msg_id_format) } ExecuteMsg::UpgradeGateway { chain, contract_address, } => { - ensure_permission!(Permission::Governance, deps.storage, &info.sender); - let contract_address = deps.api.addr_validate(&contract_address)?; - execute::upgrade_gateway(deps, chain, contract_address) - } - ExecuteMsg::FreezeChains { chains } => { - ensure_permission!(Permission::Admin, deps.storage, &info.sender); - execute::freeze_chains(deps, chains) - } - ExecuteMsg::UnfreezeChains { chains } => { - ensure_permission!(Permission::Elevated, deps.storage, &info.sender); - execute::unfreeze_chains(deps, chains) + execute::upgrade_gateway(deps.storage, chain, contract_address) } + ExecuteMsg::FreezeChains { chains } => execute::freeze_chains(deps.storage, chains), + ExecuteMsg::UnfreezeChains { chains } => execute::unfreeze_chains(deps.storage, chains), ExecuteMsg::RouteMessages(msgs) => { - ensure_any_permission!(); - - Ok(execute::route_messages( - RouterStore::new(deps.storage), - info.sender, - msgs, - )?) - } - ExecuteMsg::DisableRouting => { - ensure_permission!(Permission::Admin, deps.storage, &info.sender); - execute::disable_routing(deps) - } - ExecuteMsg::EnableRouting => { - ensure_permission!(Permission::Elevated, deps.storage, &info.sender); - execute::enable_routing(deps) + Ok(execute::route_messages(deps.storage, info.sender, msgs)?) } + ExecuteMsg::DisableRouting => execute::disable_routing(deps.storage), + ExecuteMsg::EnableRouting => execute::enable_routing(deps.storage), } .map_err(axelar_wasm_std::ContractError::from) } +fn find_gateway_address( + sender: &Addr, +) -> impl FnOnce(&dyn Storage, &ExecuteMsg) -> error_stack::Result + '_ { + |storage, _| { + load_chain_by_gateway(storage, sender)? + .gateway + .address + .then(Ok) + } +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query( deps: Deps, @@ -127,7 +117,9 @@ pub fn query( msg: QueryMsg, ) -> Result { match msg { - QueryMsg::GetChainInfo(chain) => to_json_binary(&query::get_chain_info(deps, chain)?), + QueryMsg::GetChainInfo(chain) => { + to_json_binary(&query::get_chain_info(deps.storage, chain)?) + } QueryMsg::Chains { start_after, limit } => { to_json_binary(&query::chains(deps, start_after, limit)?) } @@ -138,22 +130,22 @@ pub fn query( #[cfg(test)] mod test { + use std::{collections::HashMap, str::FromStr}; + use super::*; use crate::events; - use crate::state::CONFIG; use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; use axelar_wasm_std::ContractError; - use axelar_wasm_std::FnExt; use cosmwasm_std::{ from_json, testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, Addr, CosmosMsg, Empty, OwnedDeps, WasmMsg, }; + use permission_control::Permission; use router_api::{ error::Error, ChainEndpoint, ChainName, CrossChainId, GatewayDirection, Message, CHAIN_NAME_DELIMITER, }; - use std::{collections::HashMap, str::FromStr}; const ADMIN_ADDRESS: &str = "admin"; const GOVERNANCE_ADDRESS: &str = "governance"; @@ -233,11 +225,14 @@ mod test { msgs } - pub fn assert_contract_err_strings_equal( + pub fn assert_contract_err_string_contains( actual: impl Into, expected: impl Into, ) { - assert_eq!(actual.into().to_string(), expected.into().to_string()); + assert!(actual + .into() + .to_string() + .contains(&expected.into().to_string())); } pub fn assert_messages_in_cosmos_msg( @@ -256,31 +251,6 @@ mod test { ); } - #[test] - fn migrate_checks_contract_version() { - let mut deps = mock_dependencies(); - CONFIG - .save( - deps.as_mut().storage, - &Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }, - ) - .unwrap(); - - assert!(migrate(deps.as_mut(), mock_env(), Empty {}).is_err()); - - cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); - - assert!(migrate(deps.as_mut(), mock_env(), Empty {}).is_err()); - - cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, CONTRACT_VERSION).unwrap(); - - assert!(migrate(deps.as_mut(), mock_env(), Empty {}).is_ok()); - } - #[test] fn successful_routing() { let mut deps = setup(); @@ -338,7 +308,7 @@ mod test { ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::WrongSourceChain); + assert_contract_err_string_contains(err, Error::WrongSourceChain); } #[test] @@ -421,7 +391,7 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, permission_control::Error::PermissionDenied { expected: Permission::Governance.into(), @@ -440,7 +410,7 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, permission_control::Error::PermissionDenied { expected: Permission::Governance.into(), @@ -472,15 +442,16 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal( + + assert_contract_err_string_contains( err, permission_control::Error::PermissionDenied { - expected: Permission::Admin.into(), + expected: Permission::Elevated.into(), actual: Permission::NoPrivilege.into(), }, ); - let err = execute( + assert!(execute( deps.as_mut(), mock_env(), mock_info(GOVERNANCE_ADDRESS, &[]), @@ -491,14 +462,7 @@ mod test { )]), }, ) - .unwrap_err(); - assert_contract_err_strings_equal( - err, - permission_control::Error::PermissionDenied { - expected: Permission::Admin.into(), - actual: Permission::Governance.into(), - }, - ); + .is_ok()); let res = execute( deps.as_mut(), @@ -522,15 +486,15 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, permission_control::Error::PermissionDenied { - expected: Permission::Admin.into(), + expected: Permission::Elevated.into(), actual: Permission::NoPrivilege.into(), }, ); - let err = execute( + assert!(execute( deps.as_mut(), mock_env(), mock_info(GOVERNANCE_ADDRESS, &[]), @@ -538,14 +502,7 @@ mod test { chains: HashMap::from([(chain.chain_name.clone(), GatewayDirection::None)]), }, ) - .unwrap_err(); - assert_contract_err_strings_equal( - err, - permission_control::Error::PermissionDenied { - expected: Permission::Admin.into(), - actual: Permission::Governance.into(), - }, - ); + .is_ok()); let res = execute( deps.as_mut(), @@ -570,7 +527,7 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, permission_control::Error::PermissionDenied { expected: Permission::Governance.into(), @@ -591,7 +548,7 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, permission_control::Error::PermissionDenied { expected: Permission::Governance.into(), @@ -681,7 +638,7 @@ mod test { ExecuteMsg::RouteMessages(messages.clone()), ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::GatewayNotRegistered); + assert_contract_err_string_contains(err, Error::GatewayNotRegistered); let res = execute( deps.as_mut(), @@ -713,7 +670,12 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::GatewayNotRegistered); + assert_contract_err_string_contains( + err, + permission_control::Error::WhitelistNotFound { + sender: eth.gateway.clone(), + }, + ); register_chain(deps.as_mut(), ð); register_chain(deps.as_mut(), &polygon); @@ -747,7 +709,7 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::ChainAlreadyExists); + assert_contract_err_string_contains(err, Error::ChainAlreadyExists); // case insensitive let err = execute( @@ -764,17 +726,17 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::ChainAlreadyExists); + assert_contract_err_string_contains(err, Error::ChainAlreadyExists); } #[test] fn invalid_chain_name() { - assert_contract_err_strings_equal( + assert_contract_err_string_contains( ChainName::from_str(format!("bad{}", CHAIN_NAME_DELIMITER).as_str()).unwrap_err(), Error::InvalidChainName, ); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( ChainName::from_str("").unwrap_err(), Error::InvalidChainName, ); @@ -798,7 +760,7 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::GatewayAlreadyRegistered); + assert_contract_err_string_contains(err, Error::GatewayAlreadyRegistered); register_chain(deps.as_mut(), &polygon); let err = execute( @@ -812,7 +774,7 @@ mod test { ) .unwrap_err(); - assert_contract_err_strings_equal(err, Error::GatewayAlreadyRegistered); + assert_contract_err_string_contains(err, Error::GatewayAlreadyRegistered); } #[test] @@ -842,7 +804,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -914,7 +876,7 @@ mod test { ExecuteMsg::RouteMessages(messages.clone()), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -989,7 +951,7 @@ mod test { ) .unwrap_err(); // can't route to frozen chain - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1005,7 +967,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1082,7 +1044,7 @@ mod test { // try sender without permission let permission_control: Vec<(&str, Check)> = vec![ (UNAUTHORIZED_ADDRESS, Result::is_err), - (GOVERNANCE_ADDRESS, Result::is_err), + (GOVERNANCE_ADDRESS, Result::is_ok), (ADMIN_ADDRESS, Result::is_ok), ]; @@ -1208,7 +1170,7 @@ mod test { ) .unwrap_err(); // can't route to the chain - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1259,7 +1221,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1315,7 +1277,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1331,7 +1293,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1377,7 +1339,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1393,7 +1355,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1572,7 +1534,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1588,7 +1550,7 @@ mod test { ExecuteMsg::RouteMessages(vec![message.clone()]), ) .unwrap_err(); - assert_contract_err_strings_equal( + assert_contract_err_string_contains( err, Error::ChainFrozen { chain: polygon.chain_name.clone(), @@ -1631,7 +1593,7 @@ mod test { ExecuteMsg::RouteMessages(messages.clone()), ); assert!(res.is_err()); - assert_contract_err_strings_equal(res.unwrap_err(), Error::RoutingDisabled); + assert_contract_err_string_contains(res.unwrap_err(), Error::RoutingDisabled); let _ = execute( deps.as_mut(), @@ -1696,7 +1658,7 @@ mod test { mock_info(GOVERNANCE_ADDRESS, &[]), ExecuteMsg::DisableRouting {}, ) - .is_err()); + .is_ok()); } #[test] diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index 97421e315..5d1b7feab 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -1,32 +1,31 @@ use std::collections::HashMap; use std::vec; -use cosmwasm_std::{ - to_json_binary, Addr, DepsMut, Event, Response, StdError, StdResult, Storage, WasmMsg, -}; +use cosmwasm_std::{to_json_binary, Addr, Event, Response, StdError, StdResult, Storage, WasmMsg}; use error_stack::{ensure, report, ResultExt}; use itertools::Itertools; -use crate::events::{ - ChainFrozen, ChainRegistered, ChainUnfrozen, GatewayInfo, GatewayUpgraded, MessageRouted, -}; -use crate::state::{chain_endpoints, Config, State, Store, CONFIG, STATE}; -use crate::{events, state}; use axelar_wasm_std::flagset::FlagSet; use axelar_wasm_std::msg_id::{self, MessageIdFormat}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection, Message}; +use crate::events::{ + ChainFrozen, ChainRegistered, ChainUnfrozen, GatewayInfo, GatewayUpgraded, MessageRouted, +}; +use crate::state::{chain_endpoints, Config, State, STATE}; +use crate::{events, state}; + pub fn register_chain( - deps: DepsMut, + storage: &mut dyn Storage, name: ChainName, gateway: Addr, msg_id_format: MessageIdFormat, ) -> Result { - if find_chain_for_gateway(&deps, &gateway)?.is_some() { + if find_chain_for_gateway(storage, &gateway)?.is_some() { return Err(Error::GatewayAlreadyRegistered); } - chain_endpoints().update(deps.storage, name.clone(), |chain| match chain { + chain_endpoints().update(storage, name.clone(), |chain| match chain { Some(_) => Err(Error::ChainAlreadyExists), None => Ok(ChainEndpoint { name: name.clone(), @@ -41,25 +40,24 @@ pub fn register_chain( } pub fn find_chain_for_gateway( - deps: &DepsMut, + storage: &dyn Storage, contract_address: &Addr, ) -> StdResult> { - #[allow(deprecated)] chain_endpoints() .idx .gateway - .find_chain(deps, contract_address) + .load_chain_by_gateway(storage, contract_address) } pub fn upgrade_gateway( - deps: DepsMut, + storage: &mut dyn Storage, chain: ChainName, contract_address: Addr, ) -> Result { - if find_chain_for_gateway(&deps, &contract_address)?.is_some() { + if find_chain_for_gateway(storage, &contract_address)?.is_some() { return Err(Error::GatewayAlreadyRegistered); } - chain_endpoints().update(deps.storage, chain.clone(), |chain| match chain { + chain_endpoints().update(storage, chain.clone(), |chain| match chain { None => Err(Error::ChainNotFound), Some(mut chain) => { chain.gateway.address = contract_address.clone(); @@ -97,12 +95,12 @@ fn freeze_specific_chain( } pub fn freeze_chains( - deps: DepsMut, + storage: &mut dyn Storage, chains: HashMap, ) -> Result { let events: Vec<_> = chains .into_iter() - .map(|(chain, direction)| freeze_specific_chain(deps.storage, chain, direction)) + .map(|(chain, direction)| freeze_specific_chain(storage, chain, direction)) .map_ok(Event::from) .try_collect()?; @@ -130,12 +128,12 @@ fn unfreeze_specific_chain( } pub fn unfreeze_chains( - deps: DepsMut, + storage: &mut dyn Storage, chains: HashMap, ) -> Result { let events: Vec<_> = chains .into_iter() - .map(|(chain, direction)| unfreeze_specific_chain(deps.storage, chain, direction)) + .map(|(chain, direction)| unfreeze_specific_chain(storage, chain, direction)) .map_ok(Event::from) .try_collect()?; @@ -150,8 +148,8 @@ enum StateUpdateError { Std(#[from] StdError), } -pub fn disable_routing(deps: DepsMut) -> Result { - let state = STATE.update(deps.storage, |state| match state { +pub fn disable_routing(storage: &mut dyn Storage) -> Result { + let state = STATE.update(storage, |state| match state { State::Enabled => Ok(State::Disabled), State::Disabled => Err(StateUpdateError::SameState), }); @@ -159,8 +157,8 @@ pub fn disable_routing(deps: DepsMut) -> Result { state_toggle_response(state, events::RoutingDisabled) } -pub fn enable_routing(deps: DepsMut) -> Result { - let state = STATE.update(deps.storage, |state| match state { +pub fn enable_routing(storage: &mut dyn Storage) -> Result { + let state = STATE.update(storage, |state| match state { State::Disabled => Ok(State::Enabled), State::Enabled => Err(StateUpdateError::SameState), }); @@ -189,7 +187,7 @@ fn verify_msg_ids( } fn validate_msgs( - store: &impl Store, + storage: &dyn Storage, config: Config, sender: &Addr, msgs: Vec, @@ -203,9 +201,7 @@ fn validate_msgs( return Ok(msgs); } - let source_chain = store - .load_chain_by_gateway(sender)? - .ok_or(Error::GatewayNotRegistered)?; + let source_chain = state::load_chain_by_gateway(storage, sender)?; if source_chain.incoming_frozen() { return Err(report!(Error::ChainFrozen { chain: source_chain.name, @@ -222,24 +218,22 @@ fn validate_msgs( } pub fn route_messages( - mut store: impl Store, + storage: &dyn Storage, sender: Addr, msgs: Vec, ) -> error_stack::Result { - ensure!(state::is_enabled(store.storage()), Error::RoutingDisabled); + ensure!(state::is_enabled(storage), Error::RoutingDisabled); - let config = CONFIG - .load(store.storage()) - .change_context(Error::StoreFailure)?; + let config = state::load_config(storage)?; - let msgs = validate_msgs(&store, config.clone(), &sender, msgs)?; + let msgs = validate_msgs(storage, config.clone(), &sender, msgs)?; let wasm_msgs = msgs .iter() .group_by(|msg| msg.destination_chain.to_owned()) .into_iter() .map(|(destination_chain, msgs)| { - let gateway = match store.load_chain_by_chain_name(&destination_chain)? { + let gateway = match state::load_chain_by_chain_name(storage, &destination_chain)? { Some(destination_chain) if destination_chain.outgoing_frozen() => { return Err(report!(Error::ChainFrozen { chain: destination_chain.name, @@ -271,25 +265,20 @@ pub fn route_messages( #[cfg(test)] mod test { - use std::collections::HashMap; - - use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::Addr; - use cosmwasm_std::Storage; - use mockall::predicate; - use rand::{random, RngCore}; - + use super::{freeze_chains, unfreeze_chains}; + use crate::contract::execute::route_messages; + use crate::contract::instantiate; + use crate::events::{ChainFrozen, ChainUnfrozen}; + use crate::msg::InstantiateMsg; + use crate::state::chain_endpoints; use axelar_wasm_std::flagset::FlagSet; use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, Storage}; + use rand::{random, RngCore}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, CrossChainId, Gateway, GatewayDirection, Message}; - - use crate::contract::execute::route_messages; - use crate::events::{ChainFrozen, ChainUnfrozen}; - use crate::state::{chain_endpoints, State, Store, CONFIG, STATE}; - use crate::state::{Config, MockStore}; - - use super::{freeze_chains, unfreeze_chains}; + use std::collections::HashMap; fn rand_message(source_chain: ChainName, destination_chain: ChainName) -> Message { let mut bytes = [0; 32]; @@ -326,29 +315,25 @@ mod test { #[test] fn route_messages_with_not_registered_source_chain() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); - - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(None)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![rand_message(source_chain, destination_chain)] ) @@ -357,21 +342,23 @@ mod test { #[test] fn route_messages_with_frozen_source_chain() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); let chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -380,14 +367,12 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::Incoming), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(chain_endpoint))); + chain_endpoints() + .save(deps.as_mut().storage, source_chain.clone(), &chain_endpoint) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![rand_message(source_chain.clone(), destination_chain)] ) @@ -398,21 +383,23 @@ mod test { #[test] fn route_messages_with_wrong_source_chain() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); let chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -421,14 +408,12 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(chain_endpoint))); + chain_endpoints() + .save(deps.as_mut().storage, source_chain.clone(), &chain_endpoint) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![rand_message("polygon".parse().unwrap(), destination_chain)] ) @@ -437,21 +422,22 @@ mod test { #[test] fn route_messages_with_frozen_destination_chain() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); - - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -460,26 +446,30 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(source_chain_endpoint))); + chain_endpoints() + .save( + deps.as_mut().storage, + source_chain.clone(), + &source_chain_endpoint, + ) + .unwrap(); let destination_chain_endpoint = ChainEndpoint { name: destination_chain.clone(), gateway: Gateway { - address: sender.clone(), + address: Addr::unchecked("destination"), }, frozen_status: FlagSet::from(GatewayDirection::Bidirectional), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain.clone())) - .return_once(|_| Ok(Some(destination_chain_endpoint))); + chain_endpoints() + .save( + deps.as_mut().storage, + destination_chain.clone(), + &destination_chain_endpoint, + ) + .unwrap(); - assert!(route_messages(store, sender, vec![rand_message(source_chain, destination_chain.clone())]) + assert!(route_messages(deps.as_mut().storage, sender, vec![rand_message(source_chain, destination_chain.clone())]) .is_err_and(move |err| { matches!(err.current_context(), Error::ChainFrozen { chain } if *chain == destination_chain) })); @@ -487,21 +477,22 @@ mod test { #[test] fn route_messages_from_non_nexus_with_invalid_message_id() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); - - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), @@ -511,59 +502,64 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(source_chain_endpoint))); + chain_endpoints() + .save( + deps.as_mut().storage, + source_chain.clone(), + &source_chain_endpoint, + ) + .unwrap(); let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = "foobar".try_into().unwrap(); - assert!(route_messages(store, sender, vec![msg]) + assert!(route_messages(deps.as_mut().storage, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } #[test] fn route_messages_from_nexus_with_invalid_message_id() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; - let sender = config.nexus_gateway.clone(); + let sender = Addr::unchecked("nexus_gateway"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); - - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = "foobar".try_into().unwrap(); - assert!(route_messages(store, sender, vec![msg]) + assert!(route_messages(deps.as_mut().storage, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } #[test] fn route_messages_from_non_nexus_with_incorrect_message_id_format() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -572,11 +568,13 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::Base58TxDigestAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(source_chain_endpoint))); + chain_endpoints() + .save( + deps.as_mut().storage, + source_chain.clone(), + &source_chain_endpoint, + ) + .unwrap(); let mut msg = rand_message(source_chain, destination_chain.clone()); msg.cc_id.id = HexTxHashAndEventIndex { @@ -586,28 +584,30 @@ mod test { .to_string() .try_into() .unwrap(); - assert!(route_messages(store, sender, vec![msg]) + assert!(route_messages(deps.as_mut().storage, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } #[test] fn route_messages_from_non_nexus_to_non_nexus() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain_1: ChainName = "bitcoin".parse().unwrap(); let destination_chain_2: ChainName = "polygon".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -616,40 +616,46 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(source_chain_endpoint))); + chain_endpoints() + .save( + deps.as_mut().storage, + source_chain.clone(), + &source_chain_endpoint, + ) + .unwrap(); let destination_chain_endpoint_1 = ChainEndpoint { name: destination_chain_1.clone(), gateway: Gateway { - address: sender.clone(), + address: Addr::unchecked("destination_1"), }, frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain_1.clone())) - .return_once(|_| Ok(Some(destination_chain_endpoint_1))); + chain_endpoints() + .save( + deps.as_mut().storage, + destination_chain_1.clone(), + &destination_chain_endpoint_1, + ) + .unwrap(); let destination_chain_endpoint_2 = ChainEndpoint { name: destination_chain_2.clone(), gateway: Gateway { - address: sender.clone(), + address: Addr::unchecked("destination_2"), }, frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain_2.clone())) - .return_once(|_| Ok(Some(destination_chain_endpoint_2))); + chain_endpoints() + .save( + deps.as_mut().storage, + destination_chain_2.clone(), + &destination_chain_endpoint_2, + ) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![ rand_message(source_chain.clone(), destination_chain_1.clone()), @@ -663,22 +669,24 @@ mod test { #[test] fn route_messages_from_nexus_to_registered_chains() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; - let sender = config.nexus_gateway.clone(); + let sender = Addr::unchecked("nexus_gateway"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain_1: ChainName = "bitcoin".parse().unwrap(); let destination_chain_2: ChainName = "polygon".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); let destination_chain_endpoint_1 = ChainEndpoint { name: destination_chain_1.clone(), gateway: Gateway { @@ -687,11 +695,13 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain_1.clone())) - .return_once(|_| Ok(Some(destination_chain_endpoint_1))); + chain_endpoints() + .save( + deps.as_mut().storage, + destination_chain_1.clone(), + &destination_chain_endpoint_1, + ) + .unwrap(); let destination_chain_endpoint_2 = ChainEndpoint { name: destination_chain_2.clone(), gateway: Gateway { @@ -700,14 +710,16 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain_2.clone())) - .return_once(|_| Ok(Some(destination_chain_endpoint_2))); + chain_endpoints() + .save( + deps.as_mut().storage, + destination_chain_2.clone(), + &destination_chain_endpoint_2, + ) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![ rand_message(source_chain.clone(), destination_chain_1.clone()), @@ -721,29 +733,25 @@ mod test { #[test] fn route_messages_from_nexus_to_non_registered_chains() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; - let sender = config.nexus_gateway.clone(); + let sender = Addr::unchecked("nexus_gateway"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); - - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain.clone())) - .return_once(|_| Ok(None)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![rand_message( source_chain.clone(), @@ -755,21 +763,23 @@ mod test { #[test] fn route_messages_from_registered_chain_to_nexus() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), - }; let sender = Addr::unchecked("sender"); let source_chain: ChainName = "ethereum".parse().unwrap(); let destination_chain: ChainName = "bitcoin".parse().unwrap(); - let storage = cosmwasm_std::MemoryStorage::new(); - let mut store = MockStore::new(); - store.expect_storage().return_var(Box::new(storage)); + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + nexus_gateway: "nexus_gateway".to_string(), + }, + ) + .unwrap(); - CONFIG.save(store.storage(), &config).unwrap(); - STATE.save(store.storage(), &State::Enabled).unwrap(); let source_chain_endpoint = ChainEndpoint { name: source_chain.clone(), gateway: Gateway { @@ -778,19 +788,16 @@ mod test { frozen_status: FlagSet::from(GatewayDirection::None), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; - store - .expect_load_chain_by_gateway() - .once() - .with(predicate::eq(sender.clone())) - .return_once(|_| Ok(Some(source_chain_endpoint))); - store - .expect_load_chain_by_chain_name() - .once() - .with(predicate::eq(destination_chain.clone())) - .return_once(|_| Ok(None)); + chain_endpoints() + .save( + deps.as_mut().storage, + source_chain.clone(), + &source_chain_endpoint, + ) + .unwrap(); assert!(route_messages( - store, + deps.as_mut().storage, sender, vec![rand_message( source_chain.clone(), @@ -822,12 +829,12 @@ mod test { // freezing twice produces same result freeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), ) .unwrap(); freeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), ) .unwrap(); @@ -839,12 +846,12 @@ mod test { ); freeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); freeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); @@ -857,12 +864,12 @@ mod test { // unfreezing twice produces same result unfreeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Outgoing)]), ) .unwrap(); unfreeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Outgoing)]), ) .unwrap(); @@ -874,12 +881,12 @@ mod test { ); unfreeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); unfreeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Bidirectional)]), ) .unwrap(); @@ -912,7 +919,7 @@ mod test { .unwrap(); let res = freeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), ) .unwrap(); @@ -927,7 +934,7 @@ mod test { )); let res = unfreeze_chains( - deps.as_mut(), + deps.as_mut().storage, HashMap::from([(chain.clone(), GatewayDirection::Incoming)]), ) .unwrap(); diff --git a/contracts/router/src/contract/query.rs b/contracts/router/src/contract/query.rs index d07546c41..7e963bc69 100644 --- a/contracts/router/src/contract/query.rs +++ b/contracts/router/src/contract/query.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{Deps, Order}; +use cosmwasm_std::{Deps, Order, Storage}; use cw_storage_plus::Bound; use error_stack::{Result, ResultExt}; @@ -10,9 +10,9 @@ use crate::state::chain_endpoints; // Pagination limits const DEFAULT_LIMIT: u32 = u32::MAX; -pub fn get_chain_info(deps: Deps, chain: ChainName) -> Result { +pub fn get_chain_info(storage: &dyn Storage, chain: ChainName) -> Result { chain_endpoints() - .may_load(deps.storage, chain) + .may_load(storage, chain) .change_context(Error::StoreFailure)? .ok_or(Error::ChainNotFound.into()) } @@ -62,7 +62,7 @@ mod test { assert!(chain_endpoints() .save(deps.as_mut().storage, chain_name.clone(), &chain_info) .is_ok()); - let result = get_chain_info(deps.as_ref(), chain_name); + let result = get_chain_info(deps.as_ref().storage, chain_name); assert!(result.is_ok()); assert_eq!(result.unwrap(), chain_info); } @@ -71,7 +71,7 @@ mod test { fn get_non_existent_chain_info() { let deps = mock_dependencies(); let chain_name: ChainName = "Ethereum".to_string().try_into().unwrap(); - let result = get_chain_info(deps.as_ref(), chain_name); + let result = get_chain_info(deps.as_ref().storage, chain_name); assert!(result.is_err()); assert_eq!(result.unwrap_err().current_context(), &Error::ChainNotFound); } diff --git a/contracts/router/src/migrations/v0_3_3.rs b/contracts/router/src/migrations/v0_3_3.rs index d6830cc7e..e2c3292f0 100644 --- a/contracts/router/src/migrations/v0_3_3.rs +++ b/contracts/router/src/migrations/v0_3_3.rs @@ -1,16 +1,22 @@ -use crate::state::{State, CONFIG, STATE}; -use axelar_wasm_std::{permission_control, ContractError}; -use cosmwasm_std::{StdResult, Storage}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, StdResult, Storage}; use cw2::VersionError; +use cw_storage_plus::Item; + +use axelar_wasm_std::{permission_control, ContractError}; +use router_api::error::Error; + +use crate::state::{Config, State, CONFIG, STATE}; + +const BASE_VERSION: &str = "0.3.3"; pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { let current_version = cw2::get_contract_version(storage)?; - if current_version.version != "0.3.3" { + if current_version.version != BASE_VERSION { Err(VersionError::WrongVersion { - expected: "0.3.3".into(), + expected: BASE_VERSION.into(), found: current_version.version, - } - .into()) + })? } else { set_generalized_permission_control(storage)?; set_router_state(storage)?; @@ -18,65 +24,225 @@ pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { } } -fn set_router_state(storage: &mut dyn Storage) -> StdResult<()> { - STATE.save(storage, &State::Enabled) +#[deprecated(since = "0.3.3", note = "only used during migration")] +#[cw_serde] +struct ConfigOld { + pub admin: Addr, + pub governance: Addr, + pub nexus_gateway: Addr, } -fn set_generalized_permission_control(storage: &mut dyn Storage) -> StdResult<()> { - let config = CONFIG.load(storage)?; - permission_control::set_admin(storage, &config.admin)?; - permission_control::set_governance(storage, &config.governance)?; +#[allow(deprecated)] +fn set_generalized_permission_control(storage: &mut dyn Storage) -> Result<(), Error> { + let old_config = CONFIG_OLD.load(storage)?; + permission_control::set_admin(storage, &old_config.admin) + .and_then(|_| permission_control::set_governance(storage, &old_config.governance)) + .map_err(Error::from)?; + + let new_config = &Config { + nexus_gateway: old_config.nexus_gateway, + }; + CONFIG.save(storage, new_config)?; Ok(()) } +fn set_router_state(storage: &mut dyn Storage) -> StdResult<()> { + STATE.save(storage, &State::Enabled) +} + +#[deprecated(since = "0.3.3", note = "only used during migration")] +#[allow(deprecated)] +const CONFIG_OLD: Item = Item::new("config"); + #[cfg(test)] +#[allow(deprecated)] mod test { - use crate::state::Config; - use crate::state::{State, CONFIG, STATE}; - use axelar_wasm_std::ensure_permission; - use axelar_wasm_std::permission_control::{Error, Permission}; - use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::{Addr, Storage}; - use error_stack::Report; + use std::collections::HashMap; + use std::env; + + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; + + use axelar_wasm_std::msg_id::MessageIdFormat; + use axelar_wasm_std::ContractError; + use router_api::msg::ExecuteMsg; + + use crate::contract::execute; + use crate::events::RouterInstantiated; + use crate::msg::InstantiateMsg; + use crate::state::{State, CONFIG, CONTRACT_NAME, CONTRACT_VERSION, STATE}; + + use super::{migrate, ConfigOld, BASE_VERSION, CONFIG_OLD}; #[test] - fn set_router_state() { - let mut storage = MockStorage::new(); + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + let _ = instantiate_old_contract(deps.as_mut()).unwrap(); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, BASE_VERSION).unwrap(); + + assert!(migrate(deps.as_mut().storage).is_ok()); + } + + #[test] + fn config_gets_migrated() { + let mut deps = mock_dependencies(); + let instantiate_msg = instantiate_old_contract(deps.as_mut()).unwrap(); - assert!(STATE.load(&storage).is_err()); + assert!(CONFIG_OLD.load(deps.as_mut().storage).is_ok()); + assert!(CONFIG.load(deps.as_mut().storage).is_err()); - super::set_router_state(&mut storage).unwrap(); + assert!(migrate(deps.as_mut().storage).is_ok()); - let state = STATE.load(&storage).unwrap(); - assert_eq!(state, State::Enabled); + assert!(CONFIG_OLD.load(deps.as_mut().storage).is_err()); + let config = CONFIG.load(deps.as_mut().storage); + assert!(config.is_ok()); + assert!(config.unwrap().nexus_gateway == instantiate_msg.nexus_gateway); } #[test] - fn set_generalized_permission_control() { - let config = Config { - admin: Addr::unchecked("admin"), - governance: Addr::unchecked("governance"), - nexus_gateway: Addr::unchecked("nexus_gateway"), + fn set_router_state() { + let mut deps = mock_dependencies(); + let _ = instantiate_old_contract(deps.as_mut()).unwrap(); + + assert!(migrate(deps.as_mut().storage).is_ok()); + + let state = STATE.load(deps.as_ref().storage); + assert!(state.is_ok()); + assert_eq!(state.unwrap(), State::Enabled); + } + + #[test] + #[allow(deprecated)] + fn migration() { + let mut deps = mock_dependencies(); + let instantiate_msg = instantiate_old_contract(deps.as_mut()).unwrap(); + + let msg = ExecuteMsg::RegisterChain { + chain: "chain".parse().unwrap(), + gateway_address: "gateway".parse().unwrap(), + msg_id_format: MessageIdFormat::HexTxHashAndEventIndex, }; - let mut storage = MockStorage::new(); - CONFIG.save(&mut storage, &config).unwrap(); + // before migration no address should be able to execute this message + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(&instantiate_msg.admin_address, &[]), + msg.clone(), + ) + .is_err()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(&instantiate_msg.governance_address, &[]), + msg.clone(), + ) + .is_err()); + + //set to future version + env::set_var("CARGO_PKG_VERSION", "0.4.0"); + assert!(migrate(&mut deps.storage).is_ok()); + + // after migration only governance should be able to register a chain + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(&instantiate_msg.admin_address, &[]), + msg.clone(), + ) + .is_err()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(&instantiate_msg.governance_address, &[]), + msg.clone(), + ) + .is_ok()); - let check_admin = |storage: &mut dyn Storage| { - ensure_permission!(Permission::Admin, storage, &config.admin); - Ok::<(), Report>(()) + // check that both admin and governance permissions are set correctly + + let msg = ExecuteMsg::UnfreezeChains { + chains: HashMap::new(), }; - let check_governance = |storage: &mut dyn Storage| { - ensure_permission!(Permission::Governance, storage, &config.governance); - Ok::<(), Report>(()) + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("no_privilege", &[]), + msg.clone(), + ) + .is_err()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(instantiate_msg.admin_address.as_str(), &[]), + msg.clone(), + ) + .is_ok()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(instantiate_msg.governance_address.as_str(), &[]), + msg.clone(), + ) + .is_ok()); + } + + #[allow(deprecated)] + fn instantiate_old_contract(deps: DepsMut) -> Result { + let admin = "admin"; + let governance = "governance"; + let nexus_gateway = "nexus_gateway"; + + let msg = InstantiateMsg { + nexus_gateway: nexus_gateway.to_string(), + admin_address: admin.to_string(), + governance_address: governance.to_string(), + }; + instantiate_old(deps, mock_env(), mock_info(admin, &[]), msg.clone())?; + Ok(msg) + } + + #[deprecated(since = "0.3.3", note = "only used to test the migration")] + #[allow(deprecated)] + pub fn instantiate_old( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + let admin = deps.api.addr_validate(&msg.admin_address)?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + let nexus_gateway = deps.api.addr_validate(&msg.nexus_gateway)?; + + let config = ConfigOld { + admin: admin.clone(), + governance: governance.clone(), + nexus_gateway: nexus_gateway.clone(), }; - assert!(check_admin(&mut storage).is_err()); - assert!(check_governance(&mut storage).is_err()); - super::set_generalized_permission_control(&mut storage).unwrap(); + CONFIG_OLD + .save(deps.storage, &config) + .expect("must save the config"); - assert!(check_admin(&mut storage).is_ok()); - assert!(check_governance(&mut storage).is_ok()); + Ok(Response::new().add_event( + RouterInstantiated { + admin, + governance, + nexus_gateway, + } + .into(), + )) } } diff --git a/contracts/router/src/state.rs b/contracts/router/src/state.rs index 2f536c797..c6bfdf0d1 100644 --- a/contracts/router/src/state.rs +++ b/contracts/router/src/state.rs @@ -1,64 +1,45 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, DepsMut, Order, StdResult, Storage}; +use cosmwasm_std::{Addr, Order, StdResult, Storage}; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, MultiIndex}; -use error_stack::ResultExt; -use mockall::automock; +use error_stack::{report, ResultExt}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName}; -#[automock] -pub trait Store { - fn storage(&mut self) -> &mut dyn Storage; - fn load_chain_by_gateway( - &self, - gateway: &Addr, - ) -> error_stack::Result, Error>; - fn load_chain_by_chain_name( - &self, - chain_name: &ChainName, - ) -> error_stack::Result, Error>; -} +pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -pub struct RouterStore<'a> { - storage: &'a mut dyn Storage, +pub fn save_config(storage: &mut dyn Storage, config: &Config) -> error_stack::Result<(), Error> { + CONFIG + .save(storage, config) + .change_context(Error::StoreFailure) } -impl Store for RouterStore<'_> { - fn storage(&mut self) -> &mut dyn Storage { - self.storage - } - - fn load_chain_by_gateway( - &self, - gateway: &Addr, - ) -> error_stack::Result, Error> { - chain_endpoints() - .idx - .gateway - .load_chain_by_gateway(self.storage, gateway) - .change_context(Error::StoreFailure) - } - - fn load_chain_by_chain_name( - &self, - chain_name: &ChainName, - ) -> error_stack::Result, Error> { - chain_endpoints() - .may_load(self.storage, chain_name.clone()) - .change_context(Error::StoreFailure) - } +pub fn load_config(storage: &dyn Storage) -> error_stack::Result { + CONFIG.load(storage).change_context(Error::StoreFailure) } -impl<'a> RouterStore<'a> { - pub fn new(storage: &'a mut dyn Storage) -> Self { - Self { storage } - } +pub fn load_chain_by_chain_name( + storage: &dyn Storage, + chain_name: &ChainName, +) -> error_stack::Result, Error> { + chain_endpoints() + .may_load(storage, chain_name.clone()) + .change_context(Error::StoreFailure) +} +pub fn load_chain_by_gateway( + storage: &dyn Storage, + gateway: &Addr, +) -> error_stack::Result { + chain_endpoints() + .idx + .gateway + .load_chain_by_gateway(storage, gateway) + .change_context(Error::StoreFailure)? + .ok_or(report!(Error::GatewayNotRegistered)) } #[cw_serde] pub struct Config { - pub admin: Addr, - pub governance: Addr, pub nexus_gateway: Addr, } @@ -90,16 +71,7 @@ impl<'a> GatewayIndex<'a> { GatewayIndex(MultiIndex::new(idx_fn, pk_namespace, idx_namespace)) } - #[deprecated(note = "use load_chain_by_gateway instead")] - pub fn find_chain( - &self, - deps: &DepsMut, - contract_address: &Addr, - ) -> StdResult> { - self.load_chain_by_gateway(deps.storage, contract_address) - } - - fn load_chain_by_gateway( + pub fn load_chain_by_gateway( &self, storage: &dyn Storage, contract_address: &Addr, diff --git a/packages/axelar-wasm-std/src/permission_control.rs b/packages/axelar-wasm-std/src/permission_control.rs index e9809286c..7bb64e097 100644 --- a/packages/axelar-wasm-std/src/permission_control.rs +++ b/packages/axelar-wasm-std/src/permission_control.rs @@ -43,77 +43,10 @@ pub enum Error { expected: FlagSet, actual: FlagSet, }, -} - -/// Ensure that the sender of a message has the correct permissions to perform following actions. -/// Returns an error if not. -/// # Example -/// ``` -/// # use cosmwasm_std::testing::mock_dependencies; -/// use cosmwasm_std::Addr; -/// use axelar_wasm_std::ensure_permission; -/// use axelar_wasm_std::permission_control::Permission; -///# use axelar_wasm_std::permission_control::Error; -/// -///# fn main() -> Result<(),Box>{ -///# use axelar_wasm_std::permission_control; -///# let mut deps = mock_dependencies(); -///# let deps = deps.as_mut(); -/// let admin = Addr::unchecked("admin"); -/// let governance = Addr::unchecked("governance"); -/// -/// // set these before checking permissions -/// permission_control::set_admin(deps.storage, &admin)?; -/// permission_control::set_governance(deps.storage, &governance)?; -/// -/// ensure_permission!(Permission::Elevated, deps.storage, &admin); -/// ensure_permission!(Permission::Elevated, deps.storage, &governance); -/// -/// do_something(); -/// # Ok(())} -/// -/// # fn do_something() {} -/// ``` -#[macro_export] -macro_rules! ensure_permission { - ($permission_variant:expr, $storage:expr, $sender:expr) => { - let permission = $crate::flagset::FlagSet::from($permission_variant); - - if !permission.contains($crate::permission_control::Permission::Any) { - let role = error_stack::ResultExt::change_context( - $crate::permission_control::sender_role($storage, $sender), - $crate::permission_control::Error::PermissionDenied { - expected: permission.clone(), - actual: Permission::NoPrivilege.into(), - }, - )?; - - if (*permission & *role).is_empty() { - return Err($crate::permission_control::Error::PermissionDenied { - expected: permission, - actual: role, - } - .into()); - } - } - }; -} - -/// This macro should be used as a marker to signify that the call is deliberately without checks -/// -/// # Example -/// ``` -///# fn main() -> Result<(),Box>{ -///# use axelar_wasm_std::{ensure_any_permission}; -/// ensure_any_permission!(); -/// do_something(); -/// # Ok(())} -/// -/// # fn do_something() {} -/// ``` -#[macro_export] -macro_rules! ensure_any_permission { - () => {}; + #[error("sender '{actual}' must be one of the addresses {expected:?}")] + AddressNotWhitelisted { expected: Vec, actual: Addr }, + #[error("no whitelisting condition found for sender address '{sender}'")] + WhitelistNotFound { sender: Addr }, } const ADMIN: Item = Item::new("permission_control_contract_admin_addr"); @@ -128,7 +61,7 @@ pub fn set_governance(storage: &mut dyn cosmwasm_std::Storage, addr: &Addr) -> S GOVERNANCE.save(storage, addr) } -// this is an implementation detail of the macro and shouldn't be called on its own +// this is an implementation detail of the `EnsurePermission` derived ensure_permission macro and shouldn't be called on its own #[doc(hidden)] #[allow(clippy::arithmetic_side_effects)] // flagset is safe pub fn sender_role( @@ -160,137 +93,9 @@ pub fn sender_role( mod tests { use super::*; use cosmwasm_std::testing::MockStorage; - use cosmwasm_std::Addr; - use error_stack::Report; - use flagset::Flags; - - #[test] - fn test_ensure_permission() { - let no_privilege = Addr::unchecked("regular user"); - let admin = Addr::unchecked("admin"); - let governance = Addr::unchecked("governance"); - - let check = |permission, user, storage| { - ensure_permission!(permission, storage, user); - Ok::<(), Report>(()) - }; - - // no addresses set: all addresses should be treated as not privileged - let storage = MockStorage::new(); - for permission in Permission::LIST { - match permission { - Permission::NoPrivilege | Permission::Any => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - // none of these can be called if no addresses are set - Permission::Admin | Permission::Governance | Permission::Elevated => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_err()); - assert!(check(*permission, &governance, &storage).is_err()); - } - } - } - - // admin set: only admin should be allowed to call admin and elevated commands - let mut storage = MockStorage::new(); - set_admin(&mut storage, &admin).unwrap(); - - for permission in Permission::LIST { - match permission { - Permission::NoPrivilege => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_err()); // - assert!(check(*permission, &governance, &storage).is_ok()); - } - Permission::Admin | Permission::Elevated => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_err()); - } - // gov address is not set, so these should all fail - Permission::Governance => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_err()); - assert!(check(*permission, &governance, &storage).is_err()); - } - Permission::Any => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - } - } - - // governance set: only governance should be allowed to call governance and elevated commands - let mut storage = MockStorage::new(); - set_governance(&mut storage, &governance).unwrap(); - - for permission in Permission::LIST { - match permission { - Permission::NoPrivilege => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_err()); - } - // admin address is not set, so these should all fail - Permission::Admin => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_err()); - assert!(check(*permission, &governance, &storage).is_err()); - } - Permission::Governance | Permission::Elevated => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_err()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - Permission::Any => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - } - } - - // admin and governance set: both should be allowed to call admin, governance, and elevated commands - let mut storage = MockStorage::new(); - set_admin(&mut storage, &admin).unwrap(); - set_governance(&mut storage, &governance).unwrap(); - - for permission in Permission::LIST { - match permission { - Permission::NoPrivilege => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_err()); - assert!(check(*permission, &governance, &storage).is_err()); - } - Permission::Admin => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_err()); - } - Permission::Governance => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_err()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - Permission::Elevated => { - assert!(check(*permission, &no_privilege, &storage).is_err()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - Permission::Any => { - assert!(check(*permission, &no_privilege, &storage).is_ok()); - assert!(check(*permission, &admin, &storage).is_ok()); - assert!(check(*permission, &governance, &storage).is_ok()); - } - } - } - } #[test] - fn test() { + fn display_permissions() { assert_eq!(format!("{}", FlagSet::from(Permission::Admin)), "Admin"); assert_eq!( format!( @@ -307,4 +112,54 @@ mod tests { "Any" ); } + + #[test] + fn sender_role_from_storage() { + let admin = Addr::unchecked("admin"); + let governance = Addr::unchecked("governance"); + let regular_user = Addr::unchecked("regular user"); + + let mut storage = MockStorage::new(); + set_admin(&mut storage, &admin).unwrap(); + set_governance(&mut storage, &governance).unwrap(); + + assert_eq!( + sender_role(&storage, &admin).unwrap(), + FlagSet::from(Permission::Admin) + ); + assert_eq!( + sender_role(&storage, &governance).unwrap(), + FlagSet::from(Permission::Governance) + ); + assert_eq!( + sender_role(&storage, ®ular_user).unwrap(), + FlagSet::from(Permission::NoPrivilege) + ); + + set_governance(&mut storage, &admin).unwrap(); + assert_eq!( + sender_role(&storage, &admin).unwrap(), + FlagSet::from(Permission::Elevated) + ); + } + + #[test] + fn permission_level_correctly_defined() { + assert!(!FlagSet::from(Permission::NoPrivilege).contains(Permission::Admin)); + assert!(!FlagSet::from(Permission::NoPrivilege).contains(Permission::Governance)); + + assert!(!FlagSet::from(Permission::Admin).contains(Permission::NoPrivilege)); + assert!(!FlagSet::from(Permission::Admin).contains(Permission::Governance)); + + assert!(!FlagSet::from(Permission::Governance).contains(Permission::NoPrivilege)); + assert!(!FlagSet::from(Permission::Governance).contains(Permission::Admin)); + + assert!(!FlagSet::from(Permission::Elevated).contains(Permission::NoPrivilege)); + assert!(FlagSet::from(Permission::Elevated).contains(Permission::Admin)); + assert!(FlagSet::from(Permission::Elevated).contains(Permission::Governance)); + + assert!(FlagSet::from(Permission::Any).contains(Permission::NoPrivilege)); + assert!(FlagSet::from(Permission::Any).contains(Permission::Admin)); + assert!(FlagSet::from(Permission::Any).contains(Permission::Governance)); + } } diff --git a/packages/msgs-derive/Cargo.toml b/packages/msgs-derive/Cargo.toml new file mode 100644 index 000000000..cca7aef88 --- /dev/null +++ b/packages/msgs-derive/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "msgs-derive" +version = "0.1.0" +edition = "2021" +rust-version = { workspace = true } + +[lib] +proc-macro = true + +[dependencies] +axelar-wasm-std = { workspace = true } +cosmwasm-std = { workspace = true } +error-stack = { workspace = true } +itertools = { workspace = true } +proc-macro2 = "1.0.85" +quote = { workspace = true } +syn = { workspace = true } + +[dev-dependencies] + +[lints] +workspace = true diff --git a/packages/msgs-derive/release.toml b/packages/msgs-derive/release.toml new file mode 100644 index 000000000..954564097 --- /dev/null +++ b/packages/msgs-derive/release.toml @@ -0,0 +1 @@ +release = false diff --git a/packages/msgs-derive/src/lib.rs b/packages/msgs-derive/src/lib.rs new file mode 100644 index 000000000..dd7a0ee95 --- /dev/null +++ b/packages/msgs-derive/src/lib.rs @@ -0,0 +1,357 @@ +use axelar_wasm_std::permission_control::Permission; +use itertools::Itertools; +use proc_macro::TokenStream; +use quote::{format_ident, quote}; +use syn::punctuated::Punctuated; +use syn::token::Comma; +use syn::{Data, DataEnum, DeriveInput, Expr, ExprCall, Ident, Path, Token, Variant}; + +/// This macro derives the `ensure_permissions` method for an enum. The method checks if the sender +/// has the required permissions to execute the variant. The permissions are defined using the +/// `#[permission]` attribute. The attribute can be used in two ways: +/// - `#[permission(Permission1, Permission2, ...)]` requires the sender to have at least one of +/// the specified permissions. These permissions are defined in the [axelar_wasm_std::permission_control::Permission] enum. +/// - `#[permission(Specific(Addr1, Addr2, ...))]` requires the sender to be one of the specified +/// addresses. The macro will generate a function signature that takes closures as arguments to determine +/// the whitelisted addresses. +/// +/// Both attributes can be used together, in which case the sender must have at least one of the +/// specified permissions or be one of the specified addresses. +/// The `ensure_permissions` method will return an error if the sender does not have the required +/// permissions. +/// +/// # Example +/// ``` +/// use cosmwasm_std::{Addr, Deps, Env, MessageInfo}; +/// use axelar_wasm_std::permission_control::Permission; +/// use msgs_derive::EnsurePermissions; +/// +/// #[derive(EnsurePermissions)] +/// pub enum ExecuteMsg { +/// #[permission(NoPrivilege, Admin)] +/// AnyoneButGovernanceCanCallThis, +/// #[permission(Governance)] +/// OnlyGovernanceCanCallThis, +/// #[permission(Admin, Specific(gateway))] +/// AdminOrGatewayCanCallThis, +/// #[permission(Specific(gateway))] +/// OnlyGatewayCanCallThis +/// } +/// +/// fn execute(deps: Deps, env: Env, info: MessageInfo, msg: ExecuteMsg) -> error_stack::Result<(), axelar_wasm_std::permission_control::Error> { +/// // check permissions before handling the message +/// match msg.ensure_permissions(deps.storage, &info.sender, |storage, message | GATEWAY.load(storage))? { +/// ExecuteMsg::AnyoneButGovernanceCanCallThis => Ok(()), +/// ExecuteMsg::OnlyGovernanceCanCallThis => Ok(()), +/// ExecuteMsg::AdminOrGatewayCanCallThis => Ok(()), +/// ExecuteMsg::OnlyGatewayCanCallThis => Ok(()), +/// } +/// } +/// +/// # // mock to make the example compile +/// # struct Store; +/// # impl Store { +/// # fn load(&self, storage: &dyn cosmwasm_std::Storage) -> error_stack::Result { +/// # Ok(Addr::unchecked("gateway")) +/// # } +/// # } +/// # const GATEWAY:Store = Store; +/// # use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +/// # fn main() { +/// # let mocks = mock_dependencies(); +/// # let deps = mocks.as_ref(); +/// # let env = mock_env(); +/// // example how to call the execute function +/// let info = MessageInfo{ +/// sender: Addr::unchecked("sender"), +/// funds: vec![], +/// }; +/// +/// # let info_root = info; +/// # let info = info_root.clone(); +/// assert!(execute(deps, env, info, ExecuteMsg::AnyoneButGovernanceCanCallThis).is_ok()); +/// # let env = mock_env(); +/// # let info = info_root.clone(); +/// assert!(execute(deps, env, info, ExecuteMsg::OnlyGatewayCanCallThis).is_err()); +/// # } +/// ``` + +#[proc_macro_derive(EnsurePermissions, attributes(permission))] +pub fn derive_ensure_permissions(input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input as DeriveInput); + let ident = input.ident.clone(); + + match input.data.clone() { + Data::Enum(data) => build_implementation(ident, data), + _ => panic!("Only enums are supported"), + } +} +fn build_implementation(enum_type: Ident, data: DataEnum) -> TokenStream { + let (variants, permissions): (Vec<_>, Vec<_>) = data + .variants + .into_iter() + .filter_map(find_permissions) + .unzip(); + + let specific_check = build_specific_permissions_check(&enum_type, &variants, &permissions); + let general_check = build_general_permissions_check(&enum_type, &variants, &permissions); + let check_function = build_full_check_function(&permissions, specific_check, general_check); + + TokenStream::from(quote! { + impl #enum_type{ + #check_function + } + }) +} + +#[derive(Debug)] +struct MsgPermissions { + specific: Vec, + general: Vec, +} + +fn find_permissions(variant: Variant) -> Option<(Ident, MsgPermissions)> { + let (specific, general): (Vec<_>, Vec<_>) = variant + .attrs + .iter() + .filter(|attr| attr.path().is_ident("permission")) + .flat_map(|attr| + { + match attr. + parse_args_with(Punctuated::::parse_terminated){ + Ok(expr) => expr, + _=> panic!("wrong format of 'permission' attribute for variant {}", variant.ident) + } + }) + .map(|expr| match expr { + Expr::Path(path) => (None, Some(path.path)), + Expr::Call(ExprCall { args, func, .. }) => { + let paths = parse_specific_permissions(&variant, args); + if !is_specific_attribute(&func) { + panic!( + "unrecognized permission attribute for variant {}, suggestion: 'Specific(...)'?", + variant.ident + ); + } + (Some(paths), None) + } + expr => + panic!( + "unrecognized permission attribute '{}' for variant {}", + quote! {#expr}, variant.ident + ) + }) + .unzip(); + + let specific: Vec = specific.into_iter().flatten().flatten().collect(); + let general: Vec = general.into_iter().flatten().collect(); + + if !general.iter().all_unique() { + panic!("permissions for variant {} must be unique", variant.ident); + } + + if !specific.iter().all_unique() { + panic!( + "whitelisted addresses for variant {} must be unique", + variant.ident + ); + } + + if general.is_empty() && specific.is_empty() { + panic!( + "permissions for variant {} must not be empty", + variant.ident + ); + } + + if general.iter().any(is_permission_any) && !specific.is_empty() { + panic!( + "whitelisting addresses for variant {} is useless because permission '{:?}' is set", + variant.ident, + Permission::Any + ); + } + + Some((variant.ident, MsgPermissions { specific, general })) +} + +fn is_specific_attribute(func: &Expr) -> bool { + match func { + Expr::Path(path) => path.path.is_ident("Specific"), + _ => false, + } +} + +fn parse_specific_permissions( + variant: &Variant, + args: Punctuated, +) -> impl IntoIterator + '_ { + args.into_iter().map(|arg| match arg { + Expr::Path(path) => path.path, + _ => panic!("wrong format of 'Specific' permission attribute for variant {}, only comma separated identifiers are allowed", variant.ident), + }) +} + +fn is_permission_any(path: &Path) -> bool { + path.get_ident() + .filter(|ident| ident.to_string() == format!("{:?}", Permission::Any)) + .is_some() +} + +fn build_specific_permissions_check( + enum_type: &Ident, + variants: &[Ident], + permissions: &[MsgPermissions], +) -> proc_macro2::TokenStream { + let specific_permissions = permissions.iter().map(|permission| { + let specific_permissions: &[_] = permission.specific.as_ref(); + + if permission.specific.is_empty() { + // don't do anything if there are no specific permissions + quote! {();} + } else { + // load all whitelisted addresses from storage and check if the sender is whitelisted + quote! { + #( + let stored_addr = error_stack::ResultExt::change_context( + #specific_permissions(storage, &self).map_err(|err| error_stack::Report::from(err)), + axelar_wasm_std::permission_control::Error::WhitelistNotFound{sender: sender.clone()})?; + if sender == stored_addr { + return Ok(self); + } + whitelisted.push(stored_addr); + )* + } + } + }); + + // map enum variants to specific permission checks + quote! { + let mut whitelisted = Vec::new(); + match self { + #(#enum_type::#variants {..}=> {#specific_permissions})* + }; + } +} + +fn build_general_permissions_check( + enum_type: &Ident, + variants: &[Ident], + permissions: &[MsgPermissions], +) -> proc_macro2::TokenStream { + let general_permissions_quote = permissions.iter().map(|permission| { + let general_permissions: &[_] = permission.general.as_ref(); + + if general_permissions.is_empty() && !permission.specific.is_empty() { + // getting to this point means the specific check has failed, so we return an error + quote! { + return Err(axelar_wasm_std::permission_control::Error::AddressNotWhitelisted { + expected: whitelisted.clone(), + actual: sender.clone(), + }.into()) + } + } else { + // specific permissions have either failed or there were none, so check general permissions + quote! {(#(axelar_wasm_std::permission_control::Permission::#general_permissions )|*).into()} + } + }); + + // map enum variants to general permission checks. Exclude checks for the 'Any' case, + // because it allows any address, compare permissions to the sender's role otherwise. + quote! { + let permission : axelar_wasm_std::flagset::FlagSet<_> = match self { + #(#enum_type::#variants {..}=> {#general_permissions_quote})* + }; + + if permission.contains(axelar_wasm_std::permission_control::Permission::Any) { + return Ok(self); + } + + let role = error_stack::ResultExt::change_context( + axelar_wasm_std::permission_control::sender_role(storage, sender), + axelar_wasm_std::permission_control::Error::PermissionDenied { + expected: permission.clone(), + actual: axelar_wasm_std::permission_control::Permission::NoPrivilege.into(), + }, + )?; + + if (*permission & *role).is_empty() { + return Err(axelar_wasm_std::permission_control::Error::PermissionDenied { + expected: permission, + actual: role, + } + .into()); + } + + Ok(self) + } +} + +fn build_full_check_function( + permissions: &[MsgPermissions], + specific_permission_body: proc_macro2::TokenStream, + general_permission_body: proc_macro2::TokenStream, +) -> proc_macro2::TokenStream { + let unique_specific_permissions = permissions + .iter() + .flat_map(|permission| permission.specific.iter()) + .unique() + .collect::>(); + + let comments = quote! { + /// Ensure the annotated permissions are met by the sender. + /// If the sender does not have the required permissions, an error is returned. + }; + + // the function signature is different depending on how many specific permissions are defined + if unique_specific_permissions.is_empty() { + quote! { + #comments + /// # Arguments + /// * `storage` - The storage to load the sender's role from. + /// * `sender` - The sender's address to check for whitelisting. + pub fn ensure_permissions(self, storage: &dyn cosmwasm_std::Storage, sender: &cosmwasm_std::Addr) + -> error_stack::Result { + + #general_permission_body + } + } + } else { + // due to how rust handles closures, the easiest way to define functions as parameters is with independent generic types, + // one function with one return value for each specific permission + let fs: Vec<_> = (0..unique_specific_permissions.len()) + .map(|i| format_ident!("F{}", i)) + .collect(); + + let cs: Vec<_> = (0..unique_specific_permissions.len()) + .map(|i| format_ident!("C{}", i)) + .collect(); + + let args = quote!(#(#unique_specific_permissions),*); + let format = format!( + "* `{}` - The function(s) to load whitelisted addresses from storage.", + args + ); + quote! { + #comments + /// # Arguments + /// * `storage` - The storage to load the whitelisted addresses and the sender's role from. + /// * `sender` - The sender's address to check for whitelisting. + #[doc = #format] + pub fn ensure_permissions<#(#fs),*, #(#cs),*>( + self, + storage: &dyn cosmwasm_std::Storage, + sender: &cosmwasm_std::Addr, + #(#unique_specific_permissions: #fs),*) + -> error_stack::Result + where + #(#fs:FnOnce(&dyn cosmwasm_std::Storage, &Self) -> error_stack::Result),*, + #(#cs: error_stack::Context),* + { + #specific_permission_body + + #general_permission_body + } + } + } +} diff --git a/packages/msgs-derive/tests/macro.rs b/packages/msgs-derive/tests/macro.rs new file mode 100644 index 000000000..c3db0ac58 --- /dev/null +++ b/packages/msgs-derive/tests/macro.rs @@ -0,0 +1,321 @@ +use axelar_wasm_std::permission_control; +use cosmwasm_std::testing::MockStorage; +use cosmwasm_std::{Addr, Storage}; +use error_stack::{report, Report}; +use std::fmt::Display; + +#[derive(msgs_derive::EnsurePermissions, Clone, Debug)] +#[allow(dead_code)] // the msg fields are only defined to make sure the derive attribute can handle fields correctly +enum TestMsg { + #[permission(NoPrivilege)] + NoPrivilege, + #[permission(Admin)] + Admin, + #[permission(Governance)] + Governance, + #[permission(Any)] + Any { test: u8 }, + #[permission(Elevated)] + Elevated(bool), + #[permission(Admin, NoPrivilege)] + Multi, +} + +#[derive(msgs_derive::EnsurePermissions, Clone, Debug)] +enum TestMsg2 { + #[permission(Any)] + Any, + #[permission(Specific(gateway1))] + Specific1, + #[permission(Elevated, Specific(gateway1))] + Specific2, + #[permission(Admin, Specific(gateway1), Specific(gateway2), NoPrivilege)] + Specific3, + #[permission(Specific(gateway1, gateway2, gateway3))] + Specific4, +} + +#[test] +fn test_general_ensure_permission() { + let no_privilege = Addr::unchecked("regular user"); + let admin = Addr::unchecked("admin"); + let governance = Addr::unchecked("governance"); + + let mut storage = MockStorage::new(); + permission_control::set_admin(&mut storage, &admin).unwrap(); + permission_control::set_governance(&mut storage, &governance).unwrap(); + + assert!(TestMsg::NoPrivilege + .ensure_permissions(&storage, &no_privilege) + .is_ok()); + assert!(matches!( + TestMsg::NoPrivilege + .ensure_permissions(&storage, &admin) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(matches!( + TestMsg::NoPrivilege + .ensure_permissions(&storage, &governance) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + + assert!(matches!( + TestMsg::Admin + .ensure_permissions(&storage, &no_privilege) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(TestMsg::Admin.ensure_permissions(&storage, &admin).is_ok()); + assert!(matches!( + TestMsg::Admin + .ensure_permissions(&storage, &governance) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + + assert!(matches!( + TestMsg::Governance + .ensure_permissions(&storage, &no_privilege) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(matches!( + TestMsg::Governance + .ensure_permissions(&storage, &admin) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(TestMsg::Governance + .ensure_permissions(&storage, &governance) + .is_ok()); + + assert!(TestMsg::Any { test: 0 } + .ensure_permissions(&storage, &no_privilege) + .is_ok()); + assert!(TestMsg::Any { test: 0 } + .ensure_permissions(&storage, &admin) + .is_ok()); + assert!(TestMsg::Any { test: 0 } + .ensure_permissions(&storage, &governance) + .is_ok()); + + assert!(matches!( + TestMsg::Elevated(true) + .ensure_permissions(&storage, &no_privilege) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(TestMsg::Elevated(true) + .ensure_permissions(&storage, &admin) + .is_ok()); + assert!(TestMsg::Elevated(true) + .ensure_permissions(&storage, &governance) + .is_ok()); + + assert!(TestMsg::Multi + .ensure_permissions(&storage, &no_privilege) + .is_ok()); + assert!(TestMsg::Multi.ensure_permissions(&storage, &admin).is_ok()); + assert!(matches!( + TestMsg::Multi + .ensure_permissions(&storage, &governance) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); +} + +#[test] +fn ensure_specific_permissions() { + let no_privilege = Addr::unchecked("regular user"); + let admin = Addr::unchecked("admin"); + let governance = Addr::unchecked("governance"); + + let gateway1_addr = Addr::unchecked("gateway1"); + let gateway2_addr = Addr::unchecked("gateway2"); + let gateway3_addr = Addr::unchecked("gateway3"); + + let gateway1 = + |_: &dyn Storage, _: &TestMsg2| Ok::>(Addr::unchecked("gateway1")); + let gateway2 = + |_: &dyn Storage, _: &TestMsg2| Ok::>(Addr::unchecked("gateway2")); + let gateway3 = + |_: &dyn Storage, _: &TestMsg2| Ok::>(Addr::unchecked("gateway3")); + + let mut storage = MockStorage::new(); + permission_control::set_admin(&mut storage, &admin).unwrap(); + permission_control::set_governance(&mut storage, &governance).unwrap(); + + assert!(TestMsg2::Any + .ensure_permissions(&storage, &no_privilege, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Any + .ensure_permissions(&storage, &admin, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Any + .ensure_permissions(&storage, &governance, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Any + .ensure_permissions(&storage, &gateway1_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Any + .ensure_permissions(&storage, &gateway2_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Any + .ensure_permissions(&storage, &gateway3_addr, gateway1, gateway2, gateway3) + .is_ok()); + + assert!(matches!( + TestMsg2::Specific1 + .ensure_permissions(&storage, &no_privilege, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(matches!( + TestMsg2::Specific1 + .ensure_permissions(&storage, &admin, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(matches!( + TestMsg2::Specific1 + .ensure_permissions(&storage, &governance, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(TestMsg2::Specific1 + .ensure_permissions(&storage, &gateway1_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(matches!( + TestMsg2::Specific1 + .ensure_permissions(&storage, &gateway2_addr, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(matches!( + TestMsg2::Specific1 + .ensure_permissions(&storage, &gateway3_addr, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + + assert!(matches!( + TestMsg2::Specific2 + .ensure_permissions(&storage, &no_privilege, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(TestMsg2::Specific2 + .ensure_permissions(&storage, &admin, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific2 + .ensure_permissions(&storage, &governance, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific2 + .ensure_permissions(&storage, &gateway1_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(matches!( + TestMsg2::Specific2 + .ensure_permissions(&storage, &gateway2_addr, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(matches!( + TestMsg2::Specific2 + .ensure_permissions(&storage, &gateway3_addr, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + + assert!(TestMsg2::Specific3 + .ensure_permissions(&storage, &no_privilege, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific3 + .ensure_permissions(&storage, &admin, gateway1, gateway2, gateway3) + .is_ok()); + assert!(matches!( + TestMsg2::Specific3 + .ensure_permissions(&storage, &governance, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::PermissionDenied { .. } + )); + assert!(TestMsg2::Specific3 + .ensure_permissions(&storage, &gateway1_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific3 + .ensure_permissions(&storage, &gateway2_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific3 + .ensure_permissions(&storage, &gateway3_addr, gateway1, gateway2, gateway3) + .is_ok()); // because of NoPrivilege + + assert!(matches!( + TestMsg2::Specific4 + .ensure_permissions(&storage, &no_privilege, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(matches!( + TestMsg2::Specific4 + .ensure_permissions(&storage, &admin, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(matches!( + TestMsg2::Specific4 + .ensure_permissions(&storage, &governance, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::AddressNotWhitelisted { .. } + )); + assert!(TestMsg2::Specific4 + .ensure_permissions(&storage, &gateway1_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific4 + .ensure_permissions(&storage, &gateway2_addr, gateway1, gateway2, gateway3) + .is_ok()); + assert!(TestMsg2::Specific4 + .ensure_permissions(&storage, &gateway3_addr, gateway1, gateway2, gateway3) + .is_ok()); + + let gateway3 = |_: &dyn Storage, _: &TestMsg2| Err(report!(Error)); + + assert!(matches!( + TestMsg2::Specific4 + .ensure_permissions(&storage, &gateway3_addr, gateway1, gateway2, gateway3) + .unwrap_err() + .current_context(), + permission_control::Error::WhitelistNotFound { .. } + )); +} + +#[derive(Debug)] +struct Error; + +impl std::error::Error for Error {} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "error") + } +} diff --git a/packages/router-api/Cargo.toml b/packages/router-api/Cargo.toml index 08286ad7d..22edbaa45 100644 --- a/packages/router-api/Cargo.toml +++ b/packages/router-api/Cargo.toml @@ -13,6 +13,7 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } +msgs-derive = { workspace = true } report = { workspace = true } schemars = { workspace = true } serde = { workspace = true } diff --git a/packages/router-api/src/msg.rs b/packages/router-api/src/msg.rs index 23250e0f2..a7b2de172 100644 --- a/packages/router-api/src/msg.rs +++ b/packages/router-api/src/msg.rs @@ -1,52 +1,47 @@ +use crate::primitives::*; use axelar_wasm_std::msg_id::MessageIdFormat; use cosmwasm_schema::{cw_serde, QueryResponses}; +use msgs_derive::EnsurePermissions; use std::collections::HashMap; -use crate::primitives::*; - #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { - /* - * Governance Methods - * All the below messages should only be called by governance - */ /// Registers a new chain with the router + #[permission(Governance)] RegisterChain { chain: ChainName, gateway_address: Address, msg_id_format: MessageIdFormat, }, /// Changes the gateway address associated with a particular chain + #[permission(Governance)] UpgradeGateway { chain: ChainName, contract_address: Address, }, - - /* - * Router Admin Methods - * All the below messages should only be called by the router admin - */ /// Freezes the specified chains in the specified directions. + #[permission(Elevated)] FreezeChains { chains: HashMap, }, - /// Unfreezes the specified chains in the specified directions. + #[permission(Elevated)] UnfreezeChains { chains: HashMap, }, /// Emergency command to stop all amplifier routing. + #[permission(Elevated)] DisableRouting, /// Resumes routing after an emergency shutdown. + #[permission(Elevated)] EnableRouting, - /* - * Gateway Messages - * The below messages can only be called by registered gateways - */ + /// Routes a message to all outgoing gateways registered to the destination domain. /// Called by an incoming gateway + #[permission(Specific(gateway))] RouteMessages(Vec), } From e13d98204641b6be780e9329106cef39c46588cf Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Fri, 5 Jul 2024 09:33:06 -0400 Subject: [PATCH 053/168] refactor(coordinator): use generalized permission control (#485) --- Cargo.lock | 1 + contracts/coordinator/Cargo.toml | 1 + contracts/coordinator/src/contract.rs | 94 +++++++------ .../coordinator/src/{ => contract}/execute.rs | 10 +- .../src/contract/migrations/mod.rs | 53 ++++++++ .../src/contract/migrations/v0_2_0.rs | 127 ++++++++++++++++++ contracts/coordinator/src/contract/query.rs | 15 +++ contracts/coordinator/src/error.rs | 4 + contracts/coordinator/src/lib.rs | 4 +- contracts/coordinator/src/msg.rs | 9 +- contracts/coordinator/src/query.rs | 26 ---- contracts/coordinator/src/state.rs | 23 +--- contracts/router/src/contract.rs | 16 +-- .../router/src/contract/migrations/mod.rs | 15 +++ .../src/{ => contract}/migrations/v0_3_3.rs | 70 +++++----- contracts/router/src/lib.rs | 1 - contracts/router/src/migrations/mod.rs | 1 - 17 files changed, 324 insertions(+), 146 deletions(-) rename contracts/coordinator/src/{ => contract}/execute.rs (66%) create mode 100644 contracts/coordinator/src/contract/migrations/mod.rs create mode 100644 contracts/coordinator/src/contract/migrations/v0_2_0.rs create mode 100644 contracts/coordinator/src/contract/query.rs delete mode 100644 contracts/coordinator/src/query.rs create mode 100644 contracts/router/src/contract/migrations/mod.rs rename contracts/router/src/{ => contract}/migrations/v0_3_3.rs (75%) delete mode 100644 contracts/router/src/migrations/mod.rs diff --git a/Cargo.lock b/Cargo.lock index e39571392..32a2f3771 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1440,6 +1440,7 @@ dependencies = [ "cw2 1.1.2", "error-stack", "integration-tests", + "msgs-derive", "multisig", "report", "router-api", diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index 509558efd..00f4874ee 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -40,6 +40,7 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } error-stack = { workspace = true } +msgs-derive = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } router-api = { workspace = true } diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 6da163524..9d01212d6 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -1,27 +1,26 @@ +mod execute; +mod query; + +mod migrations; +use crate::contract::migrations::{set_version_after_migration, v0_2_0}; +use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{Config, CONFIG}; +use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; +use axelar_wasm_std::{permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; -use crate::error::ContractError; -use crate::execute; -use crate::query; - -const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, ) -> Result { - // any version checks should be done before here - - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - Ok(Response::default()) + set_version_after_migration(deps.storage, |storage| { + v0_2_0::migrate(storage).map(|_| Response::default()) + })? + .then(Ok) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -33,12 +32,9 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - CONFIG.save( - deps.storage, - &Config { - governance: deps.api.addr_validate(&msg.governance_address)?, - }, - )?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + permission_control::set_governance(deps.storage, &governance)?; + Ok(Response::default()) } @@ -49,14 +45,11 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { + match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::RegisterProverContract { chain_name, new_prover_addr, - } => { - execute::check_governance(&deps, info)?; - execute::register_prover(deps, chain_name, new_prover_addr) - } + } => execute::register_prover(deps, chain_name, new_prover_addr), ExecuteMsg::SetActiveVerifiers { verifiers } => { execute::set_active_verifier_set(deps, info, verifiers) } @@ -78,15 +71,16 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result, env: Env, @@ -121,21 +115,29 @@ mod tests { #[allow(clippy::arithmetic_side_effects)] fn test_instantiation() { let governance = "governance_for_coordinator"; - let test_setup = setup(governance); - - let config = CONFIG.load(test_setup.deps.as_ref().storage).unwrap(); - assert_eq!(config.governance, governance); - } - - #[test] - fn migrate_sets_contract_version() { - let mut deps = mock_dependencies(); + let mut test_setup = setup(governance); - migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); + assert!(execute( + test_setup.deps.as_mut(), + test_setup.env.clone(), + mock_info("not_governance", &[]), + ExecuteMsg::RegisterProverContract { + chain_name: test_setup.chain_name.clone(), + new_prover_addr: test_setup.prover.clone(), + } + ) + .is_err()); - let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, "coordinator"); - assert_eq!(contract_version.version, CONTRACT_VERSION); + assert!(execute( + test_setup.deps.as_mut(), + test_setup.env, + mock_info(governance, &[]), + ExecuteMsg::RegisterProverContract { + chain_name: test_setup.chain_name.clone(), + new_prover_addr: test_setup.prover.clone(), + } + ) + .is_ok()); } #[test] @@ -155,7 +157,7 @@ mod tests { .unwrap(); let chain_provers = - query::prover(test_setup.deps.as_ref(), test_setup.chain_name.clone()).unwrap(); + prover(test_setup.deps.as_ref(), test_setup.chain_name.clone()).unwrap(); assert_eq!(chain_provers, test_setup.prover); } @@ -175,7 +177,17 @@ mod tests { ); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::Unauthorized).to_string() + axelar_wasm_std::ContractError::from(permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::NoPrivilege.into() + }) + .to_string() ); } + + fn prover(deps: Deps, chain_name: ChainName) -> Result { + PROVER_PER_CHAIN + .may_load(deps.storage, chain_name.clone())? + .ok_or(ContractError::NoProversRegisteredForChain(chain_name)) + } } diff --git a/contracts/coordinator/src/execute.rs b/contracts/coordinator/src/contract/execute.rs similarity index 66% rename from contracts/coordinator/src/execute.rs rename to contracts/coordinator/src/contract/execute.rs index d96277058..dc12643af 100644 --- a/contracts/coordinator/src/execute.rs +++ b/contracts/coordinator/src/contract/execute.rs @@ -4,15 +4,7 @@ use std::collections::HashSet; use router_api::ChainName; use crate::error::ContractError; -use crate::state::{update_verifier_set_for_prover, CONFIG, PROVER_PER_CHAIN}; - -pub fn check_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { - let config = CONFIG.load(deps.storage)?; - if config.governance != info.sender { - return Err(ContractError::Unauthorized); - } - Ok(()) -} +use crate::state::{update_verifier_set_for_prover, PROVER_PER_CHAIN}; pub fn register_prover( deps: DepsMut, diff --git a/contracts/coordinator/src/contract/migrations/mod.rs b/contracts/coordinator/src/contract/migrations/mod.rs new file mode 100644 index 000000000..ddae2f14d --- /dev/null +++ b/contracts/coordinator/src/contract/migrations/mod.rs @@ -0,0 +1,53 @@ +//! Migrations for the Coordinator contract. +//! +//! To make it easier to manage the migrations, we put the actual implementation into submodules. +//! This way, multiple migrations can be combined and switched out more easily, when we release a new version. + +use crate::error::ContractError; +use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; +use cosmwasm_std::{Response, Storage}; + +pub mod v0_2_0; + +pub fn set_version_after_migration( + storage: &mut dyn Storage, + migration: fn(&mut dyn Storage) -> Result, +) -> Result { + migration(storage)?; + + cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} + +#[cfg(test)] +mod tests { + use crate::contract::migrations::set_version_after_migration; + use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{Response, StdError}; + + #[test] + #[allow(deprecated)] + fn set_contract_version_only_on_migration_success() { + let mut deps = mock_dependencies(); + + cw2::set_contract_version(deps.as_mut().storage, "contract", "old").unwrap(); + + assert!(set_version_after_migration(deps.as_mut().storage, |_| Err( + StdError::generic_err("some_error").into() + )) + .is_err()); + + let version = cw2::get_contract_version(deps.as_ref().storage).unwrap(); + assert!(version.contract == "contract"); + assert!(version.version == "old"); + + assert!( + set_version_after_migration(deps.as_mut().storage, |_| Ok(Response::default())).is_ok() + ); + + let version = cw2::get_contract_version(deps.as_ref().storage).unwrap(); + assert!(version.contract == CONTRACT_NAME); + assert!(version.version == CONTRACT_VERSION); + } +} diff --git a/contracts/coordinator/src/contract/migrations/v0_2_0.rs b/contracts/coordinator/src/contract/migrations/v0_2_0.rs new file mode 100644 index 000000000..f2a63e769 --- /dev/null +++ b/contracts/coordinator/src/contract/migrations/v0_2_0.rs @@ -0,0 +1,127 @@ +use crate::error::ContractError; +use axelar_wasm_std::permission_control; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Storage}; +use cw2::VersionError; +use cw_storage_plus::Item; + +const BASE_VERSION: &str = "0.2.0"; + +pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + let current_version = cw2::get_contract_version(storage)?; + if current_version.version != BASE_VERSION { + Err(VersionError::WrongVersion { + expected: BASE_VERSION.into(), + found: current_version.version, + } + .into()) + } else { + migrate_config_to_permission_control(storage)?; + Ok(()) + } +} + +fn migrate_config_to_permission_control(storage: &mut dyn Storage) -> Result<(), ContractError> { + let config = CONFIG.load(storage).map_err(ContractError::from)?; + permission_control::set_governance(storage, &config.governance).map_err(ContractError::from)?; + CONFIG.remove(storage); + Ok(()) +} + +#[cw_serde] +pub struct Config { + pub governance: Addr, +} + +pub const CONFIG: Item = Item::new("config"); + +#[cfg(test)] +#[allow(deprecated)] +mod tests { + use crate::contract::execute; + use crate::contract::migrations::v0_2_0; + use crate::contract::migrations::v0_2_0::BASE_VERSION; + use crate::error::ContractError; + use crate::msg::{ExecuteMsg, InstantiateMsg}; + use crate::state::CONTRACT_NAME; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + let _ = instantiate_0_2_0_contract(deps.as_mut()).unwrap(); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_2_0::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, BASE_VERSION).unwrap(); + + assert!(v0_2_0::migrate(deps.as_mut().storage).is_ok()); + } + + #[test] + fn ensure_governance_is_migrated_to_permission_control() { + let mut deps = mock_dependencies(); + + let msg = instantiate_0_2_0_contract(deps.as_mut()).unwrap(); + + assert!(v0_2_0::CONFIG.may_load(&deps.storage).unwrap().is_some()); + + assert!(v0_2_0::migrate(deps.as_mut().storage).is_ok()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("anyone", &[]), + ExecuteMsg::RegisterProverContract { + chain_name: "chain".parse().unwrap(), + new_prover_addr: Addr::unchecked("any_addr"), + }, + ) + .is_err()); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(&msg.governance_address, &[]), + ExecuteMsg::RegisterProverContract { + chain_name: "chain".parse().unwrap(), + new_prover_addr: Addr::unchecked("any_addr"), + }, + ) + .is_ok()); + + assert!(v0_2_0::CONFIG.may_load(&deps.storage).unwrap().is_none()) + } + + fn instantiate_0_2_0_contract( + deps: DepsMut, + ) -> Result { + let governance = "governance"; + + let msg = InstantiateMsg { + governance_address: governance.to_string(), + }; + instantiate_0_2_0(deps, mock_env(), mock_info("sender", &[]), msg.clone())?; + Ok(msg) + } + + #[deprecated(since = "0.2.0", note = "only used to test the migration")] + fn instantiate_0_2_0( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, BASE_VERSION)?; + + v0_2_0::CONFIG.save( + deps.storage, + &v0_2_0::Config { + governance: deps.api.addr_validate(&msg.governance_address)?, + }, + )?; + Ok(Response::default()) + } +} diff --git a/contracts/coordinator/src/contract/query.rs b/contracts/coordinator/src/contract/query.rs new file mode 100644 index 000000000..fc277dcf4 --- /dev/null +++ b/contracts/coordinator/src/contract/query.rs @@ -0,0 +1,15 @@ +use crate::state::VERIFIER_PROVER_INDEXED_MAP; +use cosmwasm_std::{Addr, Deps, Order, StdResult}; + +fn is_verifier_in_any_verifier_set(deps: Deps, verifier_address: &Addr) -> bool { + VERIFIER_PROVER_INDEXED_MAP + .idx + .by_verifier + .prefix(verifier_address.clone()) + .range(deps.storage, None, None, Order::Ascending) + .any(|_| true) +} + +pub fn check_verifier_ready_to_unbond(deps: Deps, verifier_address: Addr) -> StdResult { + Ok(!is_verifier_in_any_verifier_set(deps, &verifier_address)) +} diff --git a/contracts/coordinator/src/error.rs b/contracts/coordinator/src/error.rs index 8a69ce8ba..79d2dc974 100644 --- a/contracts/coordinator/src/error.rs +++ b/contracts/coordinator/src/error.rs @@ -1,5 +1,6 @@ use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::StdError; +use cw2::VersionError; use router_api::ChainName; use thiserror::Error; @@ -8,6 +9,9 @@ pub enum ContractError { #[error(transparent)] Std(#[from] StdError), + #[error(transparent)] + Version(#[from] VersionError), + #[error("caller not unauthorized to perform this action")] Unauthorized, diff --git a/contracts/coordinator/src/lib.rs b/contracts/coordinator/src/lib.rs index b1acd54e1..f6466fdf3 100644 --- a/contracts/coordinator/src/lib.rs +++ b/contracts/coordinator/src/lib.rs @@ -1,6 +1,4 @@ pub mod contract; pub mod error; -pub mod execute; pub mod msg; -pub mod query; -pub mod state; +mod state; diff --git a/contracts/coordinator/src/msg.rs b/contracts/coordinator/src/msg.rs index af75e4d0e..559ea0905 100644 --- a/contracts/coordinator/src/msg.rs +++ b/contracts/coordinator/src/msg.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Addr; +use msgs_derive::EnsurePermissions; use router_api::ChainName; use std::collections::HashSet; @@ -9,15 +10,15 @@ pub struct InstantiateMsg { } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { - // Can only be called by governance + #[permission(Governance)] RegisterProverContract { chain_name: ChainName, new_prover_addr: Addr, }, - SetActiveVerifiers { - verifiers: HashSet, - }, + #[permission(Any)] + SetActiveVerifiers { verifiers: HashSet }, } #[cw_serde] diff --git a/contracts/coordinator/src/query.rs b/contracts/coordinator/src/query.rs deleted file mode 100644 index c7241d3d0..000000000 --- a/contracts/coordinator/src/query.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::error::ContractError; -use crate::state::{VerifierAddress, PROVER_PER_CHAIN, VERIFIER_PROVER_INDEXED_MAP}; -use cosmwasm_std::{Addr, Deps, Order, StdResult}; -use router_api::ChainName; - -pub fn prover(deps: Deps, chain_name: ChainName) -> Result { - PROVER_PER_CHAIN - .may_load(deps.storage, chain_name.clone())? - .ok_or(ContractError::NoProversRegisteredForChain(chain_name)) -} - -fn is_verifier_in_any_verifier_set(deps: Deps, verifier_address: &VerifierAddress) -> bool { - VERIFIER_PROVER_INDEXED_MAP - .idx - .by_verifier - .prefix(verifier_address.clone()) - .range(deps.storage, None, None, Order::Ascending) - .any(|_| true) -} - -pub fn check_verifier_ready_to_unbond( - deps: Deps, - verifier_address: VerifierAddress, -) -> StdResult { - Ok(!is_verifier_in_any_verifier_set(deps, &verifier_address)) -} diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index 631387162..2df43614f 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -1,25 +1,16 @@ use crate::error::ContractError; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Order, Storage}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; +use cw_storage_plus::{Index, IndexList, IndexedMap, Map, MultiIndex}; use router_api::ChainName; use std::collections::HashSet; -#[cw_serde] -pub struct Config { - pub governance: Addr, -} - -pub const CONFIG: Item = Item::new("config"); - -pub type ProverAddress = Addr; +pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +type ProverAddress = Addr; pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); -pub type ChainNames = HashSet; -pub type VerifierAddress = Addr; -pub const CHAINS_OF_VERIFIER: Map = Map::new("chains_of_verifier"); - pub struct VerifierSetIndex<'a> { pub by_verifier: MultiIndex<'a, Addr, VerifierProverRecord, (Addr, Addr)>, } @@ -34,7 +25,7 @@ impl<'a> IndexList for VerifierSetIndex<'a> { #[cw_serde] pub struct VerifierProverRecord { pub prover: ProverAddress, - pub verifier: VerifierAddress, + pub verifier: Addr, } pub const VERIFIER_PROVER_INDEXED_MAP: IndexedMap< @@ -55,13 +46,13 @@ pub const VERIFIER_PROVER_INDEXED_MAP: IndexedMap< pub fn update_verifier_set_for_prover( storage: &mut dyn Storage, prover_address: ProverAddress, - new_verifiers: HashSet, + new_verifiers: HashSet, ) -> Result<(), ContractError> { let existing_verifiers = VERIFIER_PROVER_INDEXED_MAP .prefix(prover_address.clone()) .keys(storage, None, None, Order::Ascending) .filter_map(Result::ok) - .collect::>(); + .collect::>(); for verifier in existing_verifiers.difference(&new_verifiers) { VERIFIER_PROVER_INDEXED_MAP diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index ba6ee4ccd..396c7d156 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -4,16 +4,17 @@ use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, }; -use axelar_wasm_std::{permission_control, FnExt}; -use router_api::error::Error; -use router_api::msg::{ExecuteMsg, QueryMsg}; - +use crate::contract::migrations::{set_version_after_migration, v0_3_3}; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; +use crate::state; use crate::state::{load_chain_by_gateway, Config, State, CONTRACT_NAME, CONTRACT_VERSION, STATE}; -use crate::{migrations, state}; +use axelar_wasm_std::{permission_control, FnExt}; +use router_api::error::Error; +use router_api::msg::{ExecuteMsg, QueryMsg}; mod execute; +mod migrations; mod query; #[cfg_attr(not(feature = "library"), entry_point)] @@ -22,10 +23,7 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - migrations::v0_3_3::migrate(deps.storage)?; - - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - Ok(Response::default()) + set_version_after_migration(deps.storage, |storage| v0_3_3::migrate(storage)) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/router/src/contract/migrations/mod.rs b/contracts/router/src/contract/migrations/mod.rs new file mode 100644 index 000000000..561b14d51 --- /dev/null +++ b/contracts/router/src/contract/migrations/mod.rs @@ -0,0 +1,15 @@ +use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; +use axelar_wasm_std::ContractError; +use cosmwasm_std::{Response, Storage}; + +pub mod v0_3_3; + +pub fn set_version_after_migration( + storage: &mut dyn Storage, + migration: fn(&mut dyn Storage) -> Result, +) -> Result { + migration(storage)?; + + cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; + Ok(Response::default()) +} diff --git a/contracts/router/src/migrations/v0_3_3.rs b/contracts/router/src/contract/migrations/v0_3_3.rs similarity index 75% rename from contracts/router/src/migrations/v0_3_3.rs rename to contracts/router/src/contract/migrations/v0_3_3.rs index e2c3292f0..f57ef4340 100644 --- a/contracts/router/src/migrations/v0_3_3.rs +++ b/contracts/router/src/contract/migrations/v0_3_3.rs @@ -1,16 +1,16 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, StdResult, Storage}; +use cosmwasm_std::{Addr, Response, StdResult, Storage}; use cw2::VersionError; use cw_storage_plus::Item; +use crate::state; +use crate::state::{State, STATE}; use axelar_wasm_std::{permission_control, ContractError}; use router_api::error::Error; -use crate::state::{Config, State, CONFIG, STATE}; - const BASE_VERSION: &str = "0.3.3"; -pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { +pub fn migrate(storage: &mut dyn Storage) -> Result { let current_version = cw2::get_contract_version(storage)?; if current_version.version != BASE_VERSION { Err(VersionError::WrongVersion { @@ -20,13 +20,13 @@ pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { } else { set_generalized_permission_control(storage)?; set_router_state(storage)?; - Ok(()) + Ok(Response::default()) } } #[deprecated(since = "0.3.3", note = "only used during migration")] #[cw_serde] -struct ConfigOld { +struct Config { pub admin: Addr, pub governance: Addr, pub nexus_gateway: Addr, @@ -34,15 +34,15 @@ struct ConfigOld { #[allow(deprecated)] fn set_generalized_permission_control(storage: &mut dyn Storage) -> Result<(), Error> { - let old_config = CONFIG_OLD.load(storage)?; + let old_config = CONFIG.load(storage)?; permission_control::set_admin(storage, &old_config.admin) .and_then(|_| permission_control::set_governance(storage, &old_config.governance)) .map_err(Error::from)?; - let new_config = &Config { + let new_config = &state::Config { nexus_gateway: old_config.nexus_gateway, }; - CONFIG.save(storage, new_config)?; + state::CONFIG.save(storage, new_config)?; Ok(()) } @@ -52,13 +52,12 @@ fn set_router_state(storage: &mut dyn Storage) -> StdResult<()> { #[deprecated(since = "0.3.3", note = "only used during migration")] #[allow(deprecated)] -const CONFIG_OLD: Item = Item::new("config"); +const CONFIG: Item = Item::new("config"); #[cfg(test)] #[allow(deprecated)] mod test { use std::collections::HashMap; - use std::env; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; @@ -68,47 +67,48 @@ mod test { use router_api::msg::ExecuteMsg; use crate::contract::execute; + use crate::contract::migrations::v0_3_3; + use crate::contract::migrations::v0_3_3::BASE_VERSION; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; - use crate::state::{State, CONFIG, CONTRACT_NAME, CONTRACT_VERSION, STATE}; - - use super::{migrate, ConfigOld, BASE_VERSION, CONFIG_OLD}; + use crate::state; + use crate::state::{State, CONTRACT_NAME, STATE}; #[test] fn migrate_checks_contract_version() { let mut deps = mock_dependencies(); - let _ = instantiate_old_contract(deps.as_mut()).unwrap(); + let _ = instantiate_0_3_3_contract(deps.as_mut()).unwrap(); cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); - assert!(migrate(deps.as_mut().storage).is_err()); + assert!(v0_3_3::migrate(deps.as_mut().storage).is_err()); cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, BASE_VERSION).unwrap(); - assert!(migrate(deps.as_mut().storage).is_ok()); + assert!(v0_3_3::migrate(deps.as_mut().storage).is_ok()); } #[test] fn config_gets_migrated() { let mut deps = mock_dependencies(); - let instantiate_msg = instantiate_old_contract(deps.as_mut()).unwrap(); + let instantiate_msg = instantiate_0_3_3_contract(deps.as_mut()).unwrap(); - assert!(CONFIG_OLD.load(deps.as_mut().storage).is_ok()); - assert!(CONFIG.load(deps.as_mut().storage).is_err()); + assert!(v0_3_3::CONFIG.load(deps.as_mut().storage).is_ok()); + assert!(state::CONFIG.load(deps.as_mut().storage).is_err()); - assert!(migrate(deps.as_mut().storage).is_ok()); + assert!(v0_3_3::migrate(deps.as_mut().storage).is_ok()); - assert!(CONFIG_OLD.load(deps.as_mut().storage).is_err()); - let config = CONFIG.load(deps.as_mut().storage); + assert!(v0_3_3::CONFIG.load(deps.as_mut().storage).is_err()); + let config = state::CONFIG.load(deps.as_mut().storage); assert!(config.is_ok()); assert!(config.unwrap().nexus_gateway == instantiate_msg.nexus_gateway); } #[test] - fn set_router_state() { + fn router_is_enabled() { let mut deps = mock_dependencies(); - let _ = instantiate_old_contract(deps.as_mut()).unwrap(); + let _ = instantiate_0_3_3_contract(deps.as_mut()).unwrap(); - assert!(migrate(deps.as_mut().storage).is_ok()); + assert!(v0_3_3::migrate(deps.as_mut().storage).is_ok()); let state = STATE.load(deps.as_ref().storage); assert!(state.is_ok()); @@ -119,7 +119,7 @@ mod test { #[allow(deprecated)] fn migration() { let mut deps = mock_dependencies(); - let instantiate_msg = instantiate_old_contract(deps.as_mut()).unwrap(); + let instantiate_msg = instantiate_0_3_3_contract(deps.as_mut()).unwrap(); let msg = ExecuteMsg::RegisterChain { chain: "chain".parse().unwrap(), @@ -145,9 +145,7 @@ mod test { ) .is_err()); - //set to future version - env::set_var("CARGO_PKG_VERSION", "0.4.0"); - assert!(migrate(&mut deps.storage).is_ok()); + assert!(v0_3_3::migrate(&mut deps.storage).is_ok()); // after migration only governance should be able to register a chain assert!(execute( @@ -198,7 +196,7 @@ mod test { } #[allow(deprecated)] - fn instantiate_old_contract(deps: DepsMut) -> Result { + fn instantiate_0_3_3_contract(deps: DepsMut) -> Result { let admin = "admin"; let governance = "governance"; let nexus_gateway = "nexus_gateway"; @@ -208,31 +206,31 @@ mod test { admin_address: admin.to_string(), governance_address: governance.to_string(), }; - instantiate_old(deps, mock_env(), mock_info(admin, &[]), msg.clone())?; + instantiate(deps, mock_env(), mock_info(admin, &[]), msg.clone())?; Ok(msg) } #[deprecated(since = "0.3.3", note = "only used to test the migration")] #[allow(deprecated)] - pub fn instantiate_old( + fn instantiate( deps: DepsMut, _env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> Result { - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + cw2::set_contract_version(deps.storage, CONTRACT_NAME, BASE_VERSION)?; let admin = deps.api.addr_validate(&msg.admin_address)?; let governance = deps.api.addr_validate(&msg.governance_address)?; let nexus_gateway = deps.api.addr_validate(&msg.nexus_gateway)?; - let config = ConfigOld { + let config = v0_3_3::Config { admin: admin.clone(), governance: governance.clone(), nexus_gateway: nexus_gateway.clone(), }; - CONFIG_OLD + v0_3_3::CONFIG .save(deps.storage, &config) .expect("must save the config"); diff --git a/contracts/router/src/lib.rs b/contracts/router/src/lib.rs index 4c2b778ae..cdacc8154 100644 --- a/contracts/router/src/lib.rs +++ b/contracts/router/src/lib.rs @@ -1,5 +1,4 @@ pub mod contract; pub mod events; -mod migrations; pub mod msg; pub mod state; diff --git a/contracts/router/src/migrations/mod.rs b/contracts/router/src/migrations/mod.rs deleted file mode 100644 index ebcb4aab1..000000000 --- a/contracts/router/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v0_3_3; From 18b9112b4deacec864e9f0ea7510ac12593d071e Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Fri, 5 Jul 2024 15:12:37 -0400 Subject: [PATCH 054/168] fix(minor-router): use singular form for address in event attribute (#488) * fix(minor-router): use sigular form for address in event attribute * update golden files --- .../gateway/tests/test_route_incoming.json | 504 +++++++++--------- .../gateway/tests/test_route_outgoing.json | 504 +++++++++--------- contracts/gateway/tests/test_verify.json | 504 +++++++++--------- packages/router-api/src/primitives.rs | 4 +- 4 files changed, 758 insertions(+), 758 deletions(-) diff --git a/contracts/gateway/tests/test_route_incoming.json b/contracts/gateway/tests/test_route_incoming.json index f69f36d33..b8bb48025 100644 --- a/contracts/gateway/tests/test_route_incoming.json +++ b/contracts/gateway/tests/test_route_incoming.json @@ -36,7 +36,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -44,7 +44,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -72,7 +72,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -80,7 +80,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -108,7 +108,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -116,7 +116,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -144,7 +144,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -152,7 +152,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -180,7 +180,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -188,7 +188,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -216,7 +216,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -224,7 +224,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -267,7 +267,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -275,7 +275,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -296,7 +296,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -304,7 +304,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -325,7 +325,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -333,7 +333,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -354,7 +354,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -362,7 +362,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -383,7 +383,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -391,7 +391,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -412,7 +412,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -420,7 +420,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -441,7 +441,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -449,7 +449,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -470,7 +470,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -478,7 +478,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -499,7 +499,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -507,7 +507,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -528,7 +528,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -536,7 +536,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -564,7 +564,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -572,7 +572,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -593,7 +593,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -601,7 +601,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -622,7 +622,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -630,7 +630,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -651,7 +651,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -659,7 +659,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -680,7 +680,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -688,7 +688,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -709,7 +709,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -717,7 +717,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -738,7 +738,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -746,7 +746,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -767,7 +767,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -775,7 +775,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -796,7 +796,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -804,7 +804,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -825,7 +825,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -833,7 +833,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -861,7 +861,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -869,7 +869,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -890,7 +890,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -898,7 +898,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -919,7 +919,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -927,7 +927,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -948,7 +948,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -956,7 +956,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -977,7 +977,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -985,7 +985,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1006,7 +1006,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1014,7 +1014,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1035,7 +1035,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1043,7 +1043,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1064,7 +1064,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1072,7 +1072,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1093,7 +1093,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1101,7 +1101,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1122,7 +1122,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1130,7 +1130,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1158,7 +1158,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1166,7 +1166,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1187,7 +1187,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1195,7 +1195,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1216,7 +1216,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1224,7 +1224,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1245,7 +1245,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1253,7 +1253,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1274,7 +1274,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1282,7 +1282,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1303,7 +1303,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1311,7 +1311,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1332,7 +1332,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1340,7 +1340,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1361,7 +1361,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1369,7 +1369,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1390,7 +1390,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1398,7 +1398,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1419,7 +1419,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1427,7 +1427,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1455,7 +1455,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1463,7 +1463,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1484,7 +1484,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1492,7 +1492,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1513,7 +1513,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1521,7 +1521,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1542,7 +1542,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1550,7 +1550,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1571,7 +1571,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1579,7 +1579,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1600,7 +1600,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1608,7 +1608,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1629,7 +1629,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1637,7 +1637,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1658,7 +1658,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1666,7 +1666,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1687,7 +1687,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1695,7 +1695,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1716,7 +1716,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1724,7 +1724,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1752,7 +1752,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1760,7 +1760,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1781,7 +1781,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1789,7 +1789,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1810,7 +1810,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1818,7 +1818,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1839,7 +1839,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1847,7 +1847,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1868,7 +1868,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1876,7 +1876,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1897,7 +1897,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1905,7 +1905,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1926,7 +1926,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1934,7 +1934,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1955,7 +1955,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1963,7 +1963,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1984,7 +1984,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1992,7 +1992,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2013,7 +2013,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2021,7 +2021,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2064,7 +2064,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2072,7 +2072,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2093,7 +2093,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2101,7 +2101,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2122,7 +2122,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2130,7 +2130,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2151,7 +2151,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2159,7 +2159,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2180,7 +2180,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2188,7 +2188,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2209,7 +2209,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2217,7 +2217,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2238,7 +2238,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2246,7 +2246,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2267,7 +2267,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2275,7 +2275,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2296,7 +2296,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2304,7 +2304,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2325,7 +2325,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2333,7 +2333,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2354,7 +2354,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2362,7 +2362,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2383,7 +2383,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2391,7 +2391,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2412,7 +2412,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2420,7 +2420,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2441,7 +2441,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2449,7 +2449,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2470,7 +2470,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2478,7 +2478,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2499,7 +2499,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2507,7 +2507,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2528,7 +2528,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2536,7 +2536,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2557,7 +2557,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2565,7 +2565,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2586,7 +2586,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2594,7 +2594,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2615,7 +2615,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2623,7 +2623,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2644,7 +2644,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2652,7 +2652,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2673,7 +2673,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2681,7 +2681,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2702,7 +2702,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2710,7 +2710,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2731,7 +2731,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2739,7 +2739,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2760,7 +2760,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2768,7 +2768,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2789,7 +2789,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2797,7 +2797,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2818,7 +2818,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2826,7 +2826,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2847,7 +2847,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2855,7 +2855,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2876,7 +2876,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2884,7 +2884,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2905,7 +2905,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2913,7 +2913,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2934,7 +2934,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2942,7 +2942,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2963,7 +2963,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2971,7 +2971,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2992,7 +2992,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3000,7 +3000,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3021,7 +3021,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3029,7 +3029,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3050,7 +3050,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3058,7 +3058,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3079,7 +3079,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3087,7 +3087,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3108,7 +3108,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3116,7 +3116,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3137,7 +3137,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3145,7 +3145,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3166,7 +3166,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3174,7 +3174,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3195,7 +3195,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3203,7 +3203,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3224,7 +3224,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3232,7 +3232,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3253,7 +3253,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3261,7 +3261,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3282,7 +3282,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3290,7 +3290,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3311,7 +3311,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3319,7 +3319,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3340,7 +3340,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3348,7 +3348,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3369,7 +3369,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3377,7 +3377,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3398,7 +3398,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3406,7 +3406,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3427,7 +3427,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3435,7 +3435,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3456,7 +3456,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3464,7 +3464,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3485,7 +3485,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3493,7 +3493,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3514,7 +3514,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3522,7 +3522,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3543,7 +3543,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3551,7 +3551,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3572,7 +3572,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3580,7 +3580,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3601,7 +3601,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3609,7 +3609,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3630,7 +3630,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3638,7 +3638,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3659,7 +3659,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3667,7 +3667,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3688,7 +3688,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3696,7 +3696,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3717,7 +3717,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3725,7 +3725,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3746,7 +3746,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3754,7 +3754,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3775,7 +3775,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3783,7 +3783,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { diff --git a/contracts/gateway/tests/test_route_outgoing.json b/contracts/gateway/tests/test_route_outgoing.json index 030d0a533..ef0605400 100644 --- a/contracts/gateway/tests/test_route_outgoing.json +++ b/contracts/gateway/tests/test_route_outgoing.json @@ -21,7 +21,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -29,7 +29,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -57,7 +57,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -65,7 +65,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -93,7 +93,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -101,7 +101,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -129,7 +129,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -137,7 +137,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -165,7 +165,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -173,7 +173,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -201,7 +201,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -209,7 +209,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -237,7 +237,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -245,7 +245,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -266,7 +266,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -274,7 +274,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -295,7 +295,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -303,7 +303,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -324,7 +324,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -332,7 +332,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -353,7 +353,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -361,7 +361,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -382,7 +382,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -390,7 +390,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -411,7 +411,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -419,7 +419,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -440,7 +440,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -448,7 +448,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -469,7 +469,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -477,7 +477,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -498,7 +498,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -506,7 +506,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -534,7 +534,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -542,7 +542,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -563,7 +563,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -571,7 +571,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -592,7 +592,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -600,7 +600,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -621,7 +621,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -629,7 +629,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -650,7 +650,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -658,7 +658,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -679,7 +679,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -687,7 +687,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -708,7 +708,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -716,7 +716,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -737,7 +737,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -745,7 +745,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -766,7 +766,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -774,7 +774,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -795,7 +795,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -803,7 +803,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -831,7 +831,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -839,7 +839,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -860,7 +860,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -868,7 +868,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -889,7 +889,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -897,7 +897,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -918,7 +918,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -926,7 +926,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -947,7 +947,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -955,7 +955,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -976,7 +976,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -984,7 +984,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1005,7 +1005,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1013,7 +1013,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1034,7 +1034,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1042,7 +1042,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1063,7 +1063,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1071,7 +1071,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1092,7 +1092,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1100,7 +1100,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1128,7 +1128,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1136,7 +1136,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1157,7 +1157,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1165,7 +1165,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1186,7 +1186,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1194,7 +1194,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1215,7 +1215,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1223,7 +1223,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1244,7 +1244,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1252,7 +1252,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1273,7 +1273,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1281,7 +1281,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1302,7 +1302,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1310,7 +1310,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1331,7 +1331,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1339,7 +1339,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1360,7 +1360,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1368,7 +1368,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1389,7 +1389,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1397,7 +1397,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1425,7 +1425,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1433,7 +1433,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1454,7 +1454,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1462,7 +1462,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1483,7 +1483,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1491,7 +1491,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1512,7 +1512,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1520,7 +1520,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1541,7 +1541,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1549,7 +1549,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1570,7 +1570,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1578,7 +1578,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1599,7 +1599,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1607,7 +1607,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1628,7 +1628,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1636,7 +1636,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1657,7 +1657,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1665,7 +1665,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1686,7 +1686,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1694,7 +1694,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1722,7 +1722,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1730,7 +1730,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1751,7 +1751,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1759,7 +1759,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1780,7 +1780,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1788,7 +1788,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1809,7 +1809,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1817,7 +1817,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1838,7 +1838,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1846,7 +1846,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1867,7 +1867,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1875,7 +1875,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1896,7 +1896,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1904,7 +1904,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1925,7 +1925,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1933,7 +1933,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1954,7 +1954,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1962,7 +1962,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1983,7 +1983,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1991,7 +1991,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2019,7 +2019,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2027,7 +2027,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2048,7 +2048,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2056,7 +2056,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2077,7 +2077,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2085,7 +2085,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2106,7 +2106,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2114,7 +2114,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2135,7 +2135,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2143,7 +2143,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2164,7 +2164,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2172,7 +2172,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2193,7 +2193,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2201,7 +2201,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2222,7 +2222,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2230,7 +2230,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2251,7 +2251,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2259,7 +2259,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2280,7 +2280,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2288,7 +2288,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2309,7 +2309,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2317,7 +2317,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2338,7 +2338,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2346,7 +2346,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2367,7 +2367,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2375,7 +2375,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2396,7 +2396,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2404,7 +2404,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2425,7 +2425,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2433,7 +2433,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2454,7 +2454,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2462,7 +2462,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2483,7 +2483,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2491,7 +2491,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2512,7 +2512,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2520,7 +2520,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2541,7 +2541,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2549,7 +2549,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2570,7 +2570,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2578,7 +2578,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2599,7 +2599,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2607,7 +2607,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2628,7 +2628,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2636,7 +2636,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2657,7 +2657,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2665,7 +2665,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2686,7 +2686,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2694,7 +2694,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2715,7 +2715,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2723,7 +2723,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2744,7 +2744,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2752,7 +2752,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2773,7 +2773,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2781,7 +2781,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2802,7 +2802,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2810,7 +2810,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2831,7 +2831,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2839,7 +2839,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2860,7 +2860,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2868,7 +2868,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2889,7 +2889,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2897,7 +2897,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2918,7 +2918,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2926,7 +2926,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2947,7 +2947,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2955,7 +2955,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2976,7 +2976,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2984,7 +2984,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3005,7 +3005,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3013,7 +3013,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3034,7 +3034,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3042,7 +3042,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3063,7 +3063,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3071,7 +3071,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3092,7 +3092,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3100,7 +3100,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3121,7 +3121,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3129,7 +3129,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3150,7 +3150,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3158,7 +3158,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3179,7 +3179,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3187,7 +3187,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3208,7 +3208,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3216,7 +3216,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3237,7 +3237,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3245,7 +3245,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3266,7 +3266,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3274,7 +3274,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3295,7 +3295,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3303,7 +3303,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3324,7 +3324,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3332,7 +3332,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3353,7 +3353,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3361,7 +3361,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3382,7 +3382,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3390,7 +3390,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3411,7 +3411,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3419,7 +3419,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3440,7 +3440,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3448,7 +3448,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3469,7 +3469,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3477,7 +3477,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3498,7 +3498,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3506,7 +3506,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3527,7 +3527,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3535,7 +3535,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3556,7 +3556,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3564,7 +3564,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3585,7 +3585,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3593,7 +3593,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3614,7 +3614,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3622,7 +3622,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3643,7 +3643,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3651,7 +3651,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3672,7 +3672,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3680,7 +3680,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3701,7 +3701,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3709,7 +3709,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3730,7 +3730,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3738,7 +3738,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { diff --git a/contracts/gateway/tests/test_verify.json b/contracts/gateway/tests/test_verify.json index 0b37c440e..d335c7a1f 100644 --- a/contracts/gateway/tests/test_verify.json +++ b/contracts/gateway/tests/test_verify.json @@ -21,7 +21,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -29,7 +29,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -57,7 +57,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -65,7 +65,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -108,7 +108,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -116,7 +116,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -159,7 +159,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -167,7 +167,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -195,7 +195,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -203,7 +203,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -246,7 +246,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -254,7 +254,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -282,7 +282,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -290,7 +290,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -311,7 +311,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -319,7 +319,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -340,7 +340,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -348,7 +348,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -369,7 +369,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -377,7 +377,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -398,7 +398,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -406,7 +406,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -427,7 +427,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -435,7 +435,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -456,7 +456,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -464,7 +464,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -485,7 +485,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -493,7 +493,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -514,7 +514,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -522,7 +522,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -543,7 +543,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -551,7 +551,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -579,7 +579,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -587,7 +587,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -608,7 +608,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -616,7 +616,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -637,7 +637,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -645,7 +645,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -666,7 +666,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -674,7 +674,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -695,7 +695,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -703,7 +703,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -724,7 +724,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -732,7 +732,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -753,7 +753,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -761,7 +761,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -782,7 +782,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -790,7 +790,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -811,7 +811,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -819,7 +819,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -840,7 +840,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -848,7 +848,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -891,7 +891,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -899,7 +899,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -920,7 +920,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -928,7 +928,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -949,7 +949,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -957,7 +957,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -978,7 +978,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -986,7 +986,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1007,7 +1007,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1015,7 +1015,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1036,7 +1036,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1044,7 +1044,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1065,7 +1065,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1073,7 +1073,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1094,7 +1094,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1102,7 +1102,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1123,7 +1123,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1131,7 +1131,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1152,7 +1152,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1160,7 +1160,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1203,7 +1203,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1211,7 +1211,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1232,7 +1232,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1240,7 +1240,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1261,7 +1261,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1269,7 +1269,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1290,7 +1290,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1298,7 +1298,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1319,7 +1319,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1327,7 +1327,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1348,7 +1348,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1356,7 +1356,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1377,7 +1377,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1385,7 +1385,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1406,7 +1406,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1414,7 +1414,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1435,7 +1435,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1443,7 +1443,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1464,7 +1464,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1472,7 +1472,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1500,7 +1500,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1508,7 +1508,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1529,7 +1529,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1537,7 +1537,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1558,7 +1558,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1566,7 +1566,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1587,7 +1587,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1595,7 +1595,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1616,7 +1616,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1624,7 +1624,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1645,7 +1645,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1653,7 +1653,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1674,7 +1674,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1682,7 +1682,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1703,7 +1703,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1711,7 +1711,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1732,7 +1732,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1740,7 +1740,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1761,7 +1761,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1769,7 +1769,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1812,7 +1812,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1820,7 +1820,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1841,7 +1841,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1849,7 +1849,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1870,7 +1870,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1878,7 +1878,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1899,7 +1899,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1907,7 +1907,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1928,7 +1928,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1936,7 +1936,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1957,7 +1957,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1965,7 +1965,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -1986,7 +1986,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -1994,7 +1994,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2015,7 +2015,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2023,7 +2023,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2044,7 +2044,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2052,7 +2052,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2073,7 +2073,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2081,7 +2081,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2124,7 +2124,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2132,7 +2132,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2153,7 +2153,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2161,7 +2161,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2182,7 +2182,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2190,7 +2190,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2211,7 +2211,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2219,7 +2219,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2240,7 +2240,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2248,7 +2248,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2269,7 +2269,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2277,7 +2277,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2298,7 +2298,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2306,7 +2306,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2327,7 +2327,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2335,7 +2335,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2356,7 +2356,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2364,7 +2364,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2385,7 +2385,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2393,7 +2393,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2414,7 +2414,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2422,7 +2422,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2443,7 +2443,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2451,7 +2451,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2472,7 +2472,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2480,7 +2480,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2501,7 +2501,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2509,7 +2509,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2530,7 +2530,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2538,7 +2538,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2559,7 +2559,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2567,7 +2567,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2588,7 +2588,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2596,7 +2596,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2617,7 +2617,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2625,7 +2625,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2646,7 +2646,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2654,7 +2654,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2675,7 +2675,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2683,7 +2683,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2704,7 +2704,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2712,7 +2712,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2733,7 +2733,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2741,7 +2741,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2762,7 +2762,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2770,7 +2770,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2791,7 +2791,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2799,7 +2799,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2820,7 +2820,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2828,7 +2828,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2849,7 +2849,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2857,7 +2857,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2878,7 +2878,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2886,7 +2886,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2907,7 +2907,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2915,7 +2915,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2936,7 +2936,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2944,7 +2944,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2965,7 +2965,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -2973,7 +2973,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -2994,7 +2994,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3002,7 +3002,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3023,7 +3023,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3031,7 +3031,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3052,7 +3052,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3060,7 +3060,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3081,7 +3081,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3089,7 +3089,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3110,7 +3110,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3118,7 +3118,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3139,7 +3139,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3147,7 +3147,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3168,7 +3168,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3176,7 +3176,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3197,7 +3197,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3205,7 +3205,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3226,7 +3226,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3234,7 +3234,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3255,7 +3255,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3263,7 +3263,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3284,7 +3284,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3292,7 +3292,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3313,7 +3313,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3321,7 +3321,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3342,7 +3342,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3350,7 +3350,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3371,7 +3371,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3379,7 +3379,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3400,7 +3400,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3408,7 +3408,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3429,7 +3429,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3437,7 +3437,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3458,7 +3458,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3466,7 +3466,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3487,7 +3487,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3495,7 +3495,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3516,7 +3516,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3524,7 +3524,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3545,7 +3545,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3553,7 +3553,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3574,7 +3574,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3582,7 +3582,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3603,7 +3603,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3611,7 +3611,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3632,7 +3632,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3640,7 +3640,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3661,7 +3661,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3669,7 +3669,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3690,7 +3690,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3698,7 +3698,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3719,7 +3719,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3727,7 +3727,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3748,7 +3748,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3756,7 +3756,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3777,7 +3777,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3785,7 +3785,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3806,7 +3806,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3814,7 +3814,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { @@ -3835,7 +3835,7 @@ "value": "mock-chain" }, { - "key": "source_addresses", + "key": "source_address", "value": "idc" }, { @@ -3843,7 +3843,7 @@ "value": "mock-chain-2" }, { - "key": "destination_addresses", + "key": "destination_address", "value": "idc" }, { diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index 724d11404..c0d515411 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -52,9 +52,9 @@ impl From for Vec { vec![ ("id", other.cc_id.id).into(), ("source_chain", other.cc_id.chain).into(), - ("source_addresses", other.source_address.deref()).into(), + ("source_address", other.source_address.deref()).into(), ("destination_chain", other.destination_chain).into(), - ("destination_addresses", other.destination_address.deref()).into(), + ("destination_address", other.destination_address.deref()).into(), ( "payload_hash", HexBinary::from(other.payload_hash).to_string(), From 06df09c174385ff290cba423d2b6bd3aa271003b Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Mon, 8 Jul 2024 16:06:03 -0600 Subject: [PATCH 055/168] feat(minor-multisig)!: add command to enable and disable signing (#483) --- Cargo.lock | 1 + contracts/multisig/Cargo.toml | 1 + contracts/multisig/src/contract.rs | 142 ++++++++++- contracts/multisig/src/contract/execute.rs | 25 +- contracts/multisig/src/error.rs | 3 + contracts/multisig/src/events.rs | 4 + contracts/multisig/src/msg.rs | 30 ++- contracts/multisig/src/state.rs | 1 - contracts/router/src/contract.rs | 23 +- contracts/router/src/contract/execute.rs | 43 +--- .../router/src/contract/migrations/v0_3_3.rs | 13 +- contracts/router/src/contract/query.rs | 15 +- contracts/router/src/state.rs | 11 - integration-tests/src/multisig_contract.rs | 2 + integration-tests/tests/test_utils/mod.rs | 7 +- packages/axelar-wasm-std/src/killswitch.rs | 220 ++++++++++++++++++ packages/axelar-wasm-std/src/lib.rs | 1 + 17 files changed, 441 insertions(+), 101 deletions(-) create mode 100644 packages/axelar-wasm-std/src/killswitch.rs diff --git a/Cargo.lock b/Cargo.lock index 32a2f3771..72914dc94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4609,6 +4609,7 @@ dependencies = [ "getrandom", "itertools 0.11.0", "k256", + "msgs-derive", "report", "rewards", "router-api", diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 4ca5922e4..d25b44bf8 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -54,6 +54,7 @@ error-stack = { workspace = true } getrandom = { version = "0.2", default-features = false, features = ["custom"] } itertools = "0.11.0" k256 = { version = "0.13.1", features = ["ecdsa"] } +msgs-derive = { workspace = true } report = { workspace = true } rewards = { workspace = true, features = ["library"] } router-api = { workspace = true } diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 7866bb7aa..8082a421c 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::{killswitch, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -42,8 +43,15 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + let admin = deps.api.addr_validate(&msg.admin_address)?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + + permission_control::set_admin(deps.storage, &admin)?; + permission_control::set_governance(deps.storage, &governance)?; + + killswitch::init(deps.storage, killswitch::State::Disengaged)?; + let config = Config { - governance: deps.api.addr_validate(&msg.governance_address)?, rewards_contract: deps.api.addr_validate(&msg.rewards_address)?, block_expiry: msg.block_expiry, }; @@ -61,13 +69,14 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { + match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::StartSigningSession { verifier_set_id, msg, chain_name, sig_verifier, } => { + // TODO: use new permission model execute::require_authorized_caller(&deps, info.sender)?; let sig_verifier = sig_verifier @@ -95,13 +104,13 @@ pub fn execute( signed_sender_address, } => execute::register_pub_key(deps, info, public_key, signed_sender_address), ExecuteMsg::AuthorizeCaller { contract_address } => { - execute::require_governance(&deps, info.sender)?; execute::authorize_caller(deps, contract_address) } ExecuteMsg::UnauthorizeCaller { contract_address } => { - execute::require_governance(&deps, info.sender)?; execute::unauthorize_caller(deps, contract_address) } + ExecuteMsg::DisableSigning => execute::disable_signing(deps), + ExecuteMsg::EnableSigning => execute::enable_signing(deps), } .map_err(axelar_wasm_std::ContractError::from) } @@ -139,6 +148,7 @@ mod tests { testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, Addr, Empty, OwnedDeps, WasmMsg, }; + use permission_control::Permission; use serde_json::from_str; use router_api::ChainName; @@ -158,6 +168,8 @@ mod tests { const INSTANTIATOR: &str = "inst"; const PROVER: &str = "prover"; const REWARDS_CONTRACT: &str = "rewards"; + const GOVERNANCE: &str = "governance"; + const ADMIN: &str = "admin"; const SIGNATURE_BLOCK_EXPIRY: u64 = 100; @@ -166,7 +178,8 @@ mod tests { let env = mock_env(); let msg = InstantiateMsg { - governance_address: "governance".parse().unwrap(), + governance_address: GOVERNANCE.parse().unwrap(), + admin_address: ADMIN.parse().unwrap(), rewards_address: REWARDS_CONTRACT.to_string(), block_expiry: SIGNATURE_BLOCK_EXPIRY, }; @@ -254,8 +267,7 @@ mod tests { deps: DepsMut, contract_address: Addr, ) -> Result { - let config = CONFIG.load(deps.storage)?; - let info = mock_info(config.governance.as_str(), &[]); + let info = mock_info(GOVERNANCE, &[]); let env = mock_env(); let msg = ExecuteMsg::AuthorizeCaller { contract_address }; @@ -266,14 +278,35 @@ mod tests { deps: DepsMut, contract_address: Addr, ) -> Result { - let config = CONFIG.load(deps.storage)?; - let info = mock_info(config.governance.as_str(), &[]); + let info = mock_info(GOVERNANCE, &[]); let env = mock_env(); let msg = ExecuteMsg::UnauthorizeCaller { contract_address }; execute(deps, env, info, msg) } + fn do_disable_signing( + deps: DepsMut, + sender: &str, + ) -> Result { + let info = mock_info(sender, &[]); + let env = mock_env(); + + let msg = ExecuteMsg::DisableSigning; + execute(deps, env, info, msg) + } + + fn do_enable_signing( + deps: DepsMut, + sender: &str, + ) -> Result { + let info = mock_info(sender, &[]); + let env = mock_env(); + + let msg = ExecuteMsg::EnableSigning; + execute(deps, env, info, msg) + } + fn query_registered_public_key( deps: Deps, verifier: Addr, @@ -1025,7 +1058,11 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::Unauthorized).to_string() + axelar_wasm_std::permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::NoPrivilege.into() + } + .to_string() ); } @@ -1043,7 +1080,90 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::Unauthorized).to_string() + axelar_wasm_std::permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::NoPrivilege.into() + } + .to_string() ); } + + #[test] + fn disable_enable_signing() { + let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); + let prover_address = Addr::unchecked(PROVER); + + // authorize + do_authorize_caller(deps.as_mut(), prover_address.clone()).unwrap(); + + do_disable_signing(deps.as_mut(), ADMIN).unwrap(); + + for verifier_set_id in [ecdsa_subkey.clone(), ed25519_subkey.clone()] { + let res = do_start_signing_session( + deps.as_mut(), + PROVER, + &verifier_set_id, + "mock-chain".parse().unwrap(), + ); + + assert_eq!( + res.unwrap_err().to_string(), + ContractError::SigningDisabled.to_string() + ); + } + + do_enable_signing(deps.as_mut(), ADMIN).unwrap(); + + for verifier_set_id in [ecdsa_subkey.clone(), ed25519_subkey.clone()] { + let res = do_start_signing_session( + deps.as_mut(), + PROVER, + &verifier_set_id, + "mock-chain".parse().unwrap(), + ); + + assert!(res.is_ok()); + } + } + + #[test] + fn disable_signing_after_session_creation() { + let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); + do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + + let chain_name: ChainName = "mock-chain".parse().unwrap(); + + for (_, verifier_set_id, signers, session_id) in + signature_test_data(&ecdsa_subkey, &ed25519_subkey) + { + do_start_signing_session(deps.as_mut(), PROVER, verifier_set_id, chain_name.clone()) + .unwrap(); + + do_disable_signing(deps.as_mut(), ADMIN).unwrap(); + + let signer = signers.first().unwrap().to_owned(); + + let res = do_sign(deps.as_mut(), mock_env(), session_id, &signer); + + assert_eq!( + res.unwrap_err().to_string(), + ContractError::SigningDisabled.to_string() + ); + + do_enable_signing(deps.as_mut(), ADMIN).unwrap(); + assert!(do_sign(deps.as_mut(), mock_env(), session_id, &signer).is_ok()); + } + } + + #[test] + fn disable_enable_signing_has_correct_permissions() { + let mut deps = setup().0; + + assert!(do_disable_signing(deps.as_mut(), "user1").is_err()); + assert!(do_disable_signing(deps.as_mut(), ADMIN).is_ok()); + assert!(do_enable_signing(deps.as_mut(), "user").is_err()); + assert!(do_enable_signing(deps.as_mut(), ADMIN).is_ok()); + assert!(do_disable_signing(deps.as_mut(), GOVERNANCE).is_ok()); + assert!(do_enable_signing(deps.as_mut(), GOVERNANCE).is_ok()); + } } diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index 3fc0a3cbf..fa067e88d 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{OverflowError, OverflowOperation, WasmMsg}; +use cosmwasm_std::{ensure, OverflowError, OverflowOperation, WasmMsg}; use router_api::ChainName; use sha3::{Digest, Keccak256}; use signature_verifier_api::client::SignatureVerifier; @@ -23,7 +23,13 @@ pub fn start_signing_session( chain_name: ChainName, sig_verifier: Option, ) -> Result { + ensure!( + killswitch::is_contract_active(deps.storage), + ContractError::SigningDisabled + ); + let config = CONFIG.load(deps.storage)?; + let verifier_set = get_verifier_set(deps.storage, &verifier_set_id)?; let session_id = SIGNING_SESSION_COUNTER.update( @@ -80,6 +86,11 @@ pub fn submit_signature( session_id: Uint64, signature: HexBinary, ) -> Result { + ensure!( + killswitch::is_contract_active(deps.storage), + ContractError::SigningDisabled + ); + let config = CONFIG.load(deps.storage)?; let mut session = SIGNING_SESSIONS .load(deps.storage, session_id.into()) @@ -194,12 +205,12 @@ pub fn unauthorize_caller( Ok(Response::new().add_event(Event::CallerUnauthorized { contract_address }.into())) } -pub fn require_governance(deps: &DepsMut, sender: Addr) -> Result<(), ContractError> { - let config = CONFIG.load(deps.storage)?; - if config.governance != sender { - return Err(ContractError::Unauthorized); - } - Ok(()) +pub fn enable_signing(deps: DepsMut) -> Result { + killswitch::disengage(deps.storage, Event::SigningEnabled).map_err(|err| err.into()) +} + +pub fn disable_signing(deps: DepsMut) -> Result { + killswitch::engage(deps.storage, Event::SigningDisabled).map_err(|err| err.into()) } fn signing_response( diff --git a/contracts/multisig/src/error.rs b/contracts/multisig/src/error.rs index 66f6cf7ee..d4080966a 100644 --- a/contracts/multisig/src/error.rs +++ b/contracts/multisig/src/error.rs @@ -57,4 +57,7 @@ pub enum ContractError { #[error("caller is not authorized")] Unauthorized, + + #[error("signing is disabled")] + SigningDisabled, } diff --git a/contracts/multisig/src/events.rs b/contracts/multisig/src/events.rs index 972a6f423..935743824 100644 --- a/contracts/multisig/src/events.rs +++ b/contracts/multisig/src/events.rs @@ -40,6 +40,8 @@ pub enum Event { CallerUnauthorized { contract_address: Addr, }, + SigningEnabled, + SigningDisabled, } impl From for cosmwasm_std::Event { @@ -97,6 +99,8 @@ impl From for cosmwasm_std::Event { cosmwasm_std::Event::new("caller_unauthorized") .add_attribute("contract_address", contract_address) } + Event::SigningEnabled => cosmwasm_std::Event::new("signing_enabled"), + Event::SigningDisabled => cosmwasm_std::Event::new("signing_disabled"), } } } diff --git a/contracts/multisig/src/msg.rs b/contracts/multisig/src/msg.rs index 0d23c423a..2483f0f28 100644 --- a/contracts/multisig/src/msg.rs +++ b/contracts/multisig/src/msg.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, HexBinary, Uint128, Uint64}; +use msgs_derive::EnsurePermissions; use router_api::ChainName; use crate::{ @@ -12,13 +13,17 @@ use crate::{ pub struct InstantiateMsg { // the governance address is allowed to modify the authorized caller list for this contract pub governance_address: String, + // The admin address (or governance) is allowed to disable signing. Only governance can re-enable + pub admin_address: String, pub rewards_address: String, pub block_expiry: u64, } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { // Can only be called by an authorized contract. + #[permission(Any)] StartSigningSession { verifier_set_id: String, msg: HexBinary, @@ -31,13 +36,14 @@ pub enum ExecuteMsg { /// [signature_verifier_api::msg] sig_verifier: Option, }, + #[permission(Any)] SubmitSignature { session_id: Uint64, signature: HexBinary, }, - RegisterVerifierSet { - verifier_set: VerifierSet, - }, + #[permission(Any)] + RegisterVerifierSet { verifier_set: VerifierSet }, + #[permission(Any)] RegisterPublicKey { public_key: PublicKey, /* To prevent anyone from registering a public key that belongs to someone else, we require the sender @@ -45,13 +51,19 @@ pub enum ExecuteMsg { signed_sender_address: HexBinary, }, // Authorizes a contract to call StartSigningSession. Callable only by governance - AuthorizeCaller { - contract_address: Addr, - }, + #[permission(Governance)] + AuthorizeCaller { contract_address: Addr }, // Unauthorizes a contract, so it can no longer call StartSigningSession. Callable only by governance - UnauthorizeCaller { - contract_address: Addr, - }, + #[permission(Governance)] + UnauthorizeCaller { contract_address: Addr }, + + /// Emergency command to stop all amplifier signing + #[permission(Elevated)] + DisableSigning, + + /// Resumes routing after an emergency shutdown + #[permission(Elevated)] + EnableSigning, } #[cw_serde] diff --git a/contracts/multisig/src/state.rs b/contracts/multisig/src/state.rs index 66e5cf529..9a9ade409 100644 --- a/contracts/multisig/src/state.rs +++ b/contracts/multisig/src/state.rs @@ -13,7 +13,6 @@ use crate::{ #[cw_serde] pub struct Config { - pub governance: Addr, pub rewards_contract: Addr, pub block_expiry: u64, // number of blocks after which a signing session expires } diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 396c7d156..26ce48d8d 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::killswitch; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -8,7 +9,7 @@ use crate::contract::migrations::{set_version_after_migration, v0_3_3}; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; use crate::state; -use crate::state::{load_chain_by_gateway, Config, State, CONTRACT_NAME, CONTRACT_VERSION, STATE}; +use crate::state::{load_chain_by_gateway, Config, CONTRACT_NAME, CONTRACT_VERSION}; use axelar_wasm_std::{permission_control, FnExt}; use router_api::error::Error; use router_api::msg::{ExecuteMsg, QueryMsg}; @@ -47,7 +48,7 @@ pub fn instantiate( }; state::save_config(deps.storage, &config)?; - STATE.save(deps.storage, &State::Enabled)?; + killswitch::init(deps.storage, killswitch::State::Disengaged)?; Ok(Response::new().add_event( RouterInstantiated { @@ -121,7 +122,7 @@ pub fn query( QueryMsg::Chains { start_after, limit } => { to_json_binary(&query::chains(deps, start_after, limit)?) } - QueryMsg::IsEnabled => to_json_binary(&state::is_enabled(deps.storage)), + QueryMsg::IsEnabled => to_json_binary(&killswitch::is_contract_active(deps.storage)), } .map_err(axelar_wasm_std::ContractError::from) } @@ -1706,4 +1707,20 @@ mod test { assert!(res.events.is_empty()); } + + #[test] + fn is_enabled() { + let mut deps = mock_dependencies(); + let is_enabled = |deps: Deps| { + from_json::(query(deps, mock_env(), QueryMsg::IsEnabled).unwrap()).unwrap() + }; + assert!(!is_enabled(deps.as_ref())); + + killswitch::init(deps.as_mut().storage, killswitch::State::Engaged).unwrap(); + assert!(!is_enabled(deps.as_ref())); + killswitch::engage(deps.as_mut().storage, events::RoutingDisabled).unwrap(); + assert!(!is_enabled(deps.as_ref())); + killswitch::disengage(deps.as_mut().storage, events::RoutingEnabled).unwrap(); + assert!(is_enabled(deps.as_ref())); + } } diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index 5d1b7feab..d879376ff 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; use std::vec; -use cosmwasm_std::{to_json_binary, Addr, Event, Response, StdError, StdResult, Storage, WasmMsg}; +use axelar_wasm_std::killswitch; +use cosmwasm_std::{to_json_binary, Addr, Event, Response, StdResult, Storage, WasmMsg}; use error_stack::{ensure, report, ResultExt}; use itertools::Itertools; @@ -13,7 +14,7 @@ use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection, Message}; use crate::events::{ ChainFrozen, ChainRegistered, ChainUnfrozen, GatewayInfo, GatewayUpgraded, MessageRouted, }; -use crate::state::{chain_endpoints, Config, State, STATE}; +use crate::state::{chain_endpoints, Config}; use crate::{events, state}; pub fn register_chain( @@ -140,41 +141,12 @@ pub fn unfreeze_chains( Ok(Response::new().add_events(events)) } -#[derive(thiserror::Error, Debug)] -enum StateUpdateError { - #[error("router is already in the same state")] - SameState, - #[error(transparent)] - Std(#[from] StdError), -} - pub fn disable_routing(storage: &mut dyn Storage) -> Result { - let state = STATE.update(storage, |state| match state { - State::Enabled => Ok(State::Disabled), - State::Disabled => Err(StateUpdateError::SameState), - }); - - state_toggle_response(state, events::RoutingDisabled) + killswitch::engage(storage, events::RoutingDisabled).map_err(|err| err.into()) } pub fn enable_routing(storage: &mut dyn Storage) -> Result { - let state = STATE.update(storage, |state| match state { - State::Disabled => Ok(State::Enabled), - State::Enabled => Err(StateUpdateError::SameState), - }); - - state_toggle_response(state, events::RoutingEnabled) -} - -fn state_toggle_response( - state: Result, - event: impl Into, -) -> Result { - match state { - Ok(_) => Ok(Response::new().add_event(event.into())), - Err(StateUpdateError::SameState) => Ok(Response::new()), - Err(StateUpdateError::Std(err)) => Err(err.into()), - } + killswitch::disengage(storage, events::RoutingEnabled).map_err(|err| err.into()) } fn verify_msg_ids( @@ -222,7 +194,10 @@ pub fn route_messages( sender: Addr, msgs: Vec, ) -> error_stack::Result { - ensure!(state::is_enabled(storage), Error::RoutingDisabled); + ensure!( + killswitch::is_contract_active(storage), + Error::RoutingDisabled + ); let config = state::load_config(storage)?; diff --git a/contracts/router/src/contract/migrations/v0_3_3.rs b/contracts/router/src/contract/migrations/v0_3_3.rs index f57ef4340..c65b8d683 100644 --- a/contracts/router/src/contract/migrations/v0_3_3.rs +++ b/contracts/router/src/contract/migrations/v0_3_3.rs @@ -4,8 +4,7 @@ use cw2::VersionError; use cw_storage_plus::Item; use crate::state; -use crate::state::{State, STATE}; -use axelar_wasm_std::{permission_control, ContractError}; +use axelar_wasm_std::{killswitch, permission_control, ContractError}; use router_api::error::Error; const BASE_VERSION: &str = "0.3.3"; @@ -47,7 +46,7 @@ fn set_generalized_permission_control(storage: &mut dyn Storage) -> Result<(), E } fn set_router_state(storage: &mut dyn Storage) -> StdResult<()> { - STATE.save(storage, &State::Enabled) + killswitch::init(storage, killswitch::State::Disengaged) } #[deprecated(since = "0.3.3", note = "only used during migration")] @@ -63,7 +62,7 @@ mod test { use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; use axelar_wasm_std::msg_id::MessageIdFormat; - use axelar_wasm_std::ContractError; + use axelar_wasm_std::{killswitch, ContractError}; use router_api::msg::ExecuteMsg; use crate::contract::execute; @@ -72,7 +71,7 @@ mod test { use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; use crate::state; - use crate::state::{State, CONTRACT_NAME, STATE}; + use crate::state::CONTRACT_NAME; #[test] fn migrate_checks_contract_version() { @@ -110,9 +109,7 @@ mod test { assert!(v0_3_3::migrate(deps.as_mut().storage).is_ok()); - let state = STATE.load(deps.as_ref().storage); - assert!(state.is_ok()); - assert_eq!(state.unwrap(), State::Enabled); + assert!(killswitch::is_contract_active(deps.as_mut().storage)); } #[test] diff --git a/contracts/router/src/contract/query.rs b/contracts/router/src/contract/query.rs index 7e963bc69..054003a09 100644 --- a/contracts/router/src/contract/query.rs +++ b/contracts/router/src/contract/query.rs @@ -37,8 +37,7 @@ pub fn chains( #[cfg(test)] mod test { - use crate::state; - use crate::state::{chain_endpoints, State, STATE}; + use crate::state::chain_endpoints; use axelar_wasm_std::flagset::FlagSet; use cosmwasm_std::{testing::mock_dependencies, Addr}; use router_api::error::Error; @@ -131,16 +130,4 @@ mod test { super::chains(deps.as_ref(), Some("e-chain".parse().unwrap()), Some(2)).unwrap(); assert_eq!(result.len(), 0); } - - #[test] - fn is_enabled() { - let mut deps = mock_dependencies(); - assert!(!state::is_enabled(deps.as_ref().storage)); - - STATE.save(deps.as_mut().storage, &State::Disabled).unwrap(); - assert!(!state::is_enabled(deps.as_ref().storage)); - - STATE.save(deps.as_mut().storage, &State::Enabled).unwrap(); - assert!(state::is_enabled(deps.as_ref().storage)); - } } diff --git a/contracts/router/src/state.rs b/contracts/router/src/state.rs index c6bfdf0d1..bce63a715 100644 --- a/contracts/router/src/state.rs +++ b/contracts/router/src/state.rs @@ -45,17 +45,6 @@ pub struct Config { pub const CONFIG: Item = Item::new("config"); -#[cw_serde] -pub enum State { - Enabled, - Disabled, -} -pub const STATE: Item = Item::new("state"); - -pub fn is_enabled(storage: &dyn Storage) -> bool { - STATE.load(storage).unwrap_or(State::Disabled) == State::Enabled -} - pub struct ChainEndpointIndexes<'a> { pub gateway: GatewayIndex<'a>, } diff --git a/integration-tests/src/multisig_contract.rs b/integration-tests/src/multisig_contract.rs index 63d35b0d0..859348cd2 100644 --- a/integration-tests/src/multisig_contract.rs +++ b/integration-tests/src/multisig_contract.rs @@ -11,6 +11,7 @@ impl MultisigContract { pub fn instantiate_contract( app: &mut App, governance: Addr, + admin: Addr, rewards_address: Addr, block_expiry: u64, ) -> Self { @@ -28,6 +29,7 @@ impl MultisigContract { &multisig::msg::InstantiateMsg { rewards_address: rewards_address.to_string(), governance_address: governance.to_string(), + admin_address: admin.to_string(), block_expiry, }, &[], diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index b3aa35554..8d5f8f5af 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -363,13 +363,13 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { .init_balance(storage, &genesis, coins(u128::MAX, AXL_DENOMINATION)) .unwrap() }); - let router_admin_address = Addr::unchecked("admin"); + let admin_address = Addr::unchecked("admin"); let governance_address = Addr::unchecked("governance"); let nexus_gateway = Addr::unchecked("nexus_gateway"); let router = RouterContract::instantiate_contract( &mut app, - router_admin_address.clone(), + admin_address.clone(), governance_address.clone(), nexus_gateway.clone(), ); @@ -389,6 +389,7 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { let multisig = MultisigContract::instantiate_contract( &mut app, governance_address.clone(), + admin_address.clone(), rewards.contract_addr.clone(), SIGNATURE_BLOCK_EXPIRY, ); @@ -403,7 +404,7 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { genesis_address: genesis, governance_address, router, - router_admin_address, + router_admin_address: admin_address, multisig, coordinator, service_registry, diff --git a/packages/axelar-wasm-std/src/killswitch.rs b/packages/axelar-wasm-std/src/killswitch.rs new file mode 100644 index 000000000..597a79bb1 --- /dev/null +++ b/packages/axelar-wasm-std/src/killswitch.rs @@ -0,0 +1,220 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Event, Response, StdError, StdResult, Storage}; +use cw_storage_plus::Item; + +/// This is a generic module to be used as a "killswitch" for any contract. +/// The killswitch can be set to "engaged" or "disengaged". The contract +/// can then call `is_contract_active`, which will return true if the killswitch +/// is disengaged. `init` should be called at contract instantiation to set +/// the initial state of the killswitch. + +#[cw_serde] +pub enum State { + Engaged, + Disengaged, +} + +/// Sets the initial state of the killswitch. Should be called during contract instantiation +pub fn init(storage: &mut dyn cosmwasm_std::Storage, initial_state: State) -> StdResult<()> { + STATE.save(storage, &initial_state) +} + +/// Sets the killswitch state to `Engaged`. If the state was previously `Disengaged`, +/// adds the on_state_changed event to the response. Returns an error if the killswitch +/// was not initialized via `init` +pub fn engage( + storage: &mut dyn cosmwasm_std::Storage, + on_state_change: impl Into, +) -> StdResult { + let state = STATE.update(storage, |state| match state { + State::Disengaged => Ok(State::Engaged), + State::Engaged => Err(KillSwitchUpdateError::SameState), + }); + + killswitch_update_response(state, on_state_change) +} + +/// Sets the killswitch state to `Disengaged`. If the state was previously `Engaged`, +/// adds the on_state_changed event to the response. Returns an error if the killswitch +/// was not initialized via `init` +pub fn disengage( + storage: &mut dyn cosmwasm_std::Storage, + on_state_change: impl Into, +) -> StdResult { + let state = STATE.update(storage, |state| match state { + State::Engaged => Ok(State::Disengaged), + State::Disengaged => Err(KillSwitchUpdateError::SameState), + }); + + killswitch_update_response(state, on_state_change) +} + +/// Returns true if the killswitch state is `Disengaged`. Otherwise returns false. +/// Returns false if the killswitch was not initialized +pub fn is_contract_active(storage: &dyn Storage) -> bool { + STATE.load(storage).unwrap_or(State::Engaged) == State::Disengaged +} + +#[derive(thiserror::Error, Debug)] +enum KillSwitchUpdateError { + #[error("killswitch is already in the same state")] + SameState, + #[error(transparent)] + Std(#[from] StdError), +} + +fn killswitch_update_response( + state: Result, + on_state_change: impl Into, +) -> StdResult { + match state { + Ok(_) => Ok(Response::new().add_event(on_state_change.into())), + Err(KillSwitchUpdateError::SameState) => Ok(Response::new()), + Err(KillSwitchUpdateError::Std(err)) => Err(err), + } +} + +const STATE: Item = Item::new("state"); + +#[cfg(test)] +mod tests { + use cosmwasm_std::{testing::mock_dependencies, Event}; + + use crate::killswitch::{disengage, engage, init, is_contract_active, State, STATE}; + + enum Events { + Engaged, + Disengaged, + } + + impl From for Event { + fn from(val: Events) -> Event { + match val { + Events::Engaged => Event::new("engaged"), + Events::Disengaged => Event::new("disengaged"), + } + } + } + + #[test] + fn init_should_be_able_to_set_state_to_engaged() { + let mut deps = mock_dependencies(); + assert!(STATE.may_load(&deps.storage).unwrap().is_none()); + + init(deps.as_mut().storage, State::Engaged).unwrap(); + + assert_eq!(STATE.load(&deps.storage).unwrap(), State::Engaged); + assert!(!is_contract_active(&deps.storage)); + } + + #[test] + fn init_should_be_able_to_set_state_to_disengaged() { + let mut deps = mock_dependencies(); + assert!(STATE.may_load(&deps.storage).unwrap().is_none()); + + init(deps.as_mut().storage, State::Disengaged).unwrap(); + + assert_eq!(STATE.load(&deps.storage).unwrap(), State::Disengaged); + assert!(is_contract_active(&deps.storage)); + } + + #[test] + fn is_contract_active_should_return_true_when_disengaged() { + let mut deps = mock_dependencies(); + + assert!(!is_contract_active(&deps.storage)); + + STATE.save(deps.as_mut().storage, &State::Engaged).unwrap(); + + assert!(!is_contract_active(&deps.storage)); + + STATE + .save(deps.as_mut().storage, &State::Disengaged) + .unwrap(); + + assert!(is_contract_active(&deps.storage)); + } + + #[test] + fn engage_should_error_when_unset() { + let mut deps = mock_dependencies(); + + assert!(engage(deps.as_mut().storage, Events::Engaged).is_err()); + } + + #[test] + fn engage_should_correctly_set_state_when_disengaged() { + let mut deps = mock_dependencies(); + + STATE + .save(deps.as_mut().storage, &State::Disengaged) + .unwrap(); + engage(deps.as_mut().storage, Events::Engaged).unwrap(); + assert_eq!(STATE.load(&deps.storage).unwrap(), State::Engaged); + assert!(!is_contract_active(&deps.storage)); + } + + #[test] + fn engage_should_correctly_set_state_when_engaged() { + let mut deps = mock_dependencies(); + + STATE.save(deps.as_mut().storage, &State::Engaged).unwrap(); + engage(deps.as_mut().storage, Events::Engaged).unwrap(); + assert_eq!(STATE.load(&deps.storage).unwrap(), State::Engaged); + assert!(!is_contract_active(&deps.storage)); + } + + #[test] + fn disengage_should_error_when_unset() { + let mut deps = mock_dependencies(); + + assert!(disengage(deps.as_mut().storage, Events::Disengaged).is_err()); + } + + #[test] + fn disengage_should_correctly_set_state_when_disengaged() { + let mut deps = mock_dependencies(); + + STATE + .save(deps.as_mut().storage, &State::Disengaged) + .unwrap(); + disengage(deps.as_mut().storage, Events::Disengaged).unwrap(); + assert_eq!(STATE.load(&deps.storage).unwrap(), State::Disengaged); + assert!(is_contract_active(&deps.storage)); + } + + #[test] + fn disengage_should_correctly_set_state_when_engaged() { + let mut deps = mock_dependencies(); + + STATE.save(deps.as_mut().storage, &State::Engaged).unwrap(); + disengage(deps.as_mut().storage, Events::Engaged).unwrap(); + assert_eq!(STATE.load(&deps.storage).unwrap(), State::Disengaged); + assert!(is_contract_active(&deps.storage)); + } + + #[test] + fn engage_and_disengage_should_emit_event_when_state_changes() { + let mut deps = mock_dependencies(); + + init(deps.as_mut().storage, State::Disengaged).unwrap(); + + let engaged_event: Event = Events::Engaged.into(); + let disengaged_event: Event = Events::Disengaged.into(); + + let res = engage(deps.as_mut().storage, Events::Engaged).unwrap(); + assert!(res.events.into_iter().any(|event| event == engaged_event)); + + let res = engage(deps.as_mut().storage, Events::Engaged).unwrap(); + assert_eq!(res.events.len(), 0); + + let res = disengage(deps.as_mut().storage, Events::Disengaged).unwrap(); + assert!(res + .events + .into_iter() + .any(|event| event == disengaged_event)); + + let res = disengage(deps.as_mut().storage, Events::Disengaged).unwrap(); + assert_eq!(res.events.len(), 0); + } +} diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 87ef974a4..5b986b59c 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -12,6 +12,7 @@ pub mod flagset; mod fn_ext; pub mod hash; pub mod hex; +pub mod killswitch; pub mod msg_id; pub mod nonempty; pub mod permission_control; From 299e4bea233b32ee2a5cf38bce7e938e551c738b Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 8 Jul 2024 21:35:19 -0400 Subject: [PATCH 056/168] docs: update compatibility matrix (#490) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6afdc7caf..c5ea0e940 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,11 @@ contracts and `ampd` that work well together. | coordinator | 0.2.0 | | gateway | 0.2.3 | | multisig-prover | 0.6.0 | -| multisig | 0.4.0 | +| multisig | 0.4.1 | | nexus-gateway | 0.3.0 | | rewards | 0.4.0 | | router | 0.3.3 | -| service-registry | 0.4.0 | +| service-registry | 0.4.1 | | voting-verifier | 0.5.0 | | [tofnd](https://github.com/axelarnetwork/tofnd) | TBD | | [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | From 25a65aa51d9a6005fed0fd75f6fc647871183562 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 8 Jul 2024 23:57:42 -0400 Subject: [PATCH 057/168] docs: fix broken link to contribution documentation (#492) --- doc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/README.md b/doc/README.md index 88a313bee..4e03fe37c 100644 --- a/doc/README.md +++ b/doc/README.md @@ -33,4 +33,4 @@ mdbook serve doc --open ## Contributing Information about how to contribute to the documentation can be found in the documentation -chapter [here](http://localhost:3000/contributing/documentation.html) +chapter [here](src/contributing/documentation.md) From 62a8c6fa5fb1a2183a5bcb51b958525147ef1ed2 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 9 Jul 2024 11:18:20 -0400 Subject: [PATCH 058/168] fix(minor-multisig): prevent instantiation with 0 length signing session expiry (#491) --- contracts/coordinator/src/contract.rs | 19 +- .../src/contract/migrations/mod.rs | 52 ---- .../src/contract/migrations/v0_2_0.rs | 20 +- contracts/coordinator/src/state.rs | 2 - contracts/multisig/src/contract.rs | 46 ++-- contracts/multisig/src/contract/execute.rs | 2 +- .../multisig/src/contract/migrations/mod.rs | 1 + .../src/contract/migrations/v0_4_1.rs | 232 ++++++++++++++++++ contracts/multisig/src/error.rs | 7 + contracts/multisig/src/lib.rs | 1 - contracts/multisig/src/migrations/mod.rs | 1 - contracts/multisig/src/migrations/v_0_4.rs | 78 ------ contracts/multisig/src/msg.rs | 8 +- contracts/multisig/src/state.rs | 10 +- contracts/router/src/contract.rs | 14 +- .../router/src/contract/migrations/mod.rs | 14 -- .../router/src/contract/migrations/v0_3_3.rs | 25 +- contracts/router/src/state.rs | 3 - integration-tests/src/multisig_contract.rs | 3 +- integration-tests/tests/test_utils/mod.rs | 2 +- .../axelar-wasm-std/src/permission_control.rs | 3 +- 21 files changed, 327 insertions(+), 216 deletions(-) create mode 100644 contracts/multisig/src/contract/migrations/mod.rs create mode 100644 contracts/multisig/src/contract/migrations/v0_4_1.rs delete mode 100644 contracts/multisig/src/migrations/mod.rs delete mode 100644 contracts/multisig/src/migrations/v_0_4.rs diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 9d01212d6..7055bad14 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -2,25 +2,30 @@ mod execute; mod query; mod migrations; -use crate::contract::migrations::{set_version_after_migration, v0_2_0}; +use crate::contract::migrations::v0_2_0; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; -use axelar_wasm_std::{permission_control, FnExt}; +use axelar_wasm_std::permission_control; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; +pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, ) -> Result { - set_version_after_migration(deps.storage, |storage| { - v0_2_0::migrate(storage).map(|_| Response::default()) - })? - .then(Ok) + v0_2_0::migrate(deps.storage)?; + + // this needs to be the last thing to do during migration, + // because previous migration steps should check the old version + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/coordinator/src/contract/migrations/mod.rs b/contracts/coordinator/src/contract/migrations/mod.rs index ddae2f14d..f12a530a4 100644 --- a/contracts/coordinator/src/contract/migrations/mod.rs +++ b/contracts/coordinator/src/contract/migrations/mod.rs @@ -1,53 +1 @@ -//! Migrations for the Coordinator contract. -//! -//! To make it easier to manage the migrations, we put the actual implementation into submodules. -//! This way, multiple migrations can be combined and switched out more easily, when we release a new version. - -use crate::error::ContractError; -use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; -use cosmwasm_std::{Response, Storage}; - pub mod v0_2_0; - -pub fn set_version_after_migration( - storage: &mut dyn Storage, - migration: fn(&mut dyn Storage) -> Result, -) -> Result { - migration(storage)?; - - cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; - Ok(Response::default()) -} - -#[cfg(test)] -mod tests { - use crate::contract::migrations::set_version_after_migration; - use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; - use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::{Response, StdError}; - - #[test] - #[allow(deprecated)] - fn set_contract_version_only_on_migration_success() { - let mut deps = mock_dependencies(); - - cw2::set_contract_version(deps.as_mut().storage, "contract", "old").unwrap(); - - assert!(set_version_after_migration(deps.as_mut().storage, |_| Err( - StdError::generic_err("some_error").into() - )) - .is_err()); - - let version = cw2::get_contract_version(deps.as_ref().storage).unwrap(); - assert!(version.contract == "contract"); - assert!(version.version == "old"); - - assert!( - set_version_after_migration(deps.as_mut().storage, |_| Ok(Response::default())).is_ok() - ); - - let version = cw2::get_contract_version(deps.as_ref().storage).unwrap(); - assert!(version.contract == CONTRACT_NAME); - assert!(version.version == CONTRACT_VERSION); - } -} diff --git a/contracts/coordinator/src/contract/migrations/v0_2_0.rs b/contracts/coordinator/src/contract/migrations/v0_2_0.rs index f2a63e769..c073ca915 100644 --- a/contracts/coordinator/src/contract/migrations/v0_2_0.rs +++ b/contracts/coordinator/src/contract/migrations/v0_2_0.rs @@ -1,24 +1,17 @@ +use crate::contract::CONTRACT_NAME; use crate::error::ContractError; use axelar_wasm_std::permission_control; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; -use cw2::VersionError; use cw_storage_plus::Item; const BASE_VERSION: &str = "0.2.0"; pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { - let current_version = cw2::get_contract_version(storage)?; - if current_version.version != BASE_VERSION { - Err(VersionError::WrongVersion { - expected: BASE_VERSION.into(), - found: current_version.version, - } - .into()) - } else { - migrate_config_to_permission_control(storage)?; - Ok(()) - } + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + migrate_config_to_permission_control(storage)?; + Ok(()) } fn migrate_config_to_permission_control(storage: &mut dyn Storage) -> Result<(), ContractError> { @@ -38,12 +31,11 @@ pub const CONFIG: Item = Item::new("config"); #[cfg(test)] #[allow(deprecated)] mod tests { - use crate::contract::execute; use crate::contract::migrations::v0_2_0; use crate::contract::migrations::v0_2_0::BASE_VERSION; + use crate::contract::{execute, CONTRACT_NAME}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg}; - use crate::state::CONTRACT_NAME; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index 2df43614f..0ddb792ec 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -5,8 +5,6 @@ use cw_storage_plus::{Index, IndexList, IndexedMap, Map, MultiIndex}; use router_api::ChainName; use std::collections::HashSet; -pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); -pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); type ProverAddress = Addr; pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 8082a421c..9acef253a 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1,14 +1,6 @@ -use axelar_wasm_std::{killswitch, permission_control}; -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, HexBinary, MessageInfo, Response, - StdResult, Uint64, -}; - +use crate::msg::MigrationMsg; use crate::{ events::Event, - migrations, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, state::{ get_verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, @@ -16,8 +8,17 @@ use crate::{ types::{MsgToSign, MultisigState}, ContractError, }; +use axelar_wasm_std::{killswitch, permission_control}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, + Uint64, +}; +use error_stack::ResultExt; mod execute; +mod migrations; mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); @@ -27,11 +28,17 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); pub fn migrate( deps: DepsMut, _env: Env, - _msg: Empty, + msg: MigrationMsg, ) -> Result { + let admin = deps.api.addr_validate(&msg.admin_address)?; + + migrations::v0_4_1::migrate(deps.storage, admin).change_context(ContractError::Migration)?; + + // this needs to be the last thing to do during migration, + // because previous migration steps should check the old version cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_4::migrate(deps) + Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -149,9 +156,8 @@ mod tests { Addr, Empty, OwnedDeps, WasmMsg, }; use permission_control::Permission; - use serde_json::from_str; - use router_api::ChainName; + use serde_json::from_str; use crate::{ key::{KeyType, PublicKey, Signature}, @@ -181,7 +187,7 @@ mod tests { governance_address: GOVERNANCE.parse().unwrap(), admin_address: ADMIN.parse().unwrap(), rewards_address: REWARDS_CONTRACT.to_string(), - block_expiry: SIGNATURE_BLOCK_EXPIRY, + block_expiry: SIGNATURE_BLOCK_EXPIRY.try_into().unwrap(), }; instantiate(deps, env, info, msg) @@ -385,6 +391,18 @@ mod tests { let session_counter = SIGNING_SESSION_COUNTER.load(deps.as_ref().storage).unwrap(); + assert_eq!( + permission_control::sender_role(deps.as_ref().storage, &Addr::unchecked(ADMIN)) + .unwrap(), + Permission::Admin.into() + ); + + assert_eq!( + permission_control::sender_role(deps.as_ref().storage, &Addr::unchecked(GOVERNANCE)) + .unwrap(), + Permission::Governance.into() + ); + assert_eq!(session_counter, Uint64::zero()); } diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index fa067e88d..96c42b107 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -45,7 +45,7 @@ pub fn start_signing_session( let expires_at = env .block .height - .checked_add(config.block_expiry) + .checked_add(config.block_expiry.into()) .ok_or_else(|| { OverflowError::new( OverflowOperation::Add, diff --git a/contracts/multisig/src/contract/migrations/mod.rs b/contracts/multisig/src/contract/migrations/mod.rs new file mode 100644 index 000000000..080e953e7 --- /dev/null +++ b/contracts/multisig/src/contract/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v0_4_1; diff --git a/contracts/multisig/src/contract/migrations/v0_4_1.rs b/contracts/multisig/src/contract/migrations/v0_4_1.rs new file mode 100644 index 000000000..f71f1a8f9 --- /dev/null +++ b/contracts/multisig/src/contract/migrations/v0_4_1.rs @@ -0,0 +1,232 @@ +#![allow(deprecated)] + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, StdError, Storage}; +use cw2::VersionError; +use cw_storage_plus::Item; + +use crate::contract::CONTRACT_NAME; +use axelar_wasm_std::killswitch::State; +use axelar_wasm_std::{killswitch, nonempty, permission_control}; + +const BASE_VERSION: &str = "0.4.1"; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Std(#[from] StdError), + #[error(transparent)] + Version(#[from] VersionError), + #[error(transparent)] + NonEmpty(#[from] nonempty::Error), +} + +pub fn migrate(storage: &mut dyn Storage, admin: Addr) -> Result<(), Error> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + killswitch::init(storage, State::Disengaged)?; + + let config = ensure_expiry_height_is_not_zero(storage)?; + permission_control::set_governance(storage, &config.governance)?; + permission_control::set_admin(storage, &admin)?; + migrate_config(storage, config)?; + Ok(()) +} + +fn ensure_expiry_height_is_not_zero(storage: &mut dyn Storage) -> Result { + CONFIG.update(storage, |mut config| { + if config.block_expiry == 0 { + config.block_expiry = 10; + } + Ok(config) + }) +} + +fn migrate_config(storage: &mut dyn Storage, config: Config) -> Result<(), Error> { + let new_config = crate::state::Config { + rewards_contract: config.rewards_contract, + block_expiry: nonempty::Uint64::try_from(config.block_expiry)?, + }; + + CONFIG.remove(storage); + crate::state::CONFIG.save(storage, &new_config)?; + Ok(()) +} + +#[cw_serde] +#[deprecated(since = "0.4.1", note = "only used during migration")] +struct Config { + pub governance: Addr, + pub rewards_contract: Addr, + pub block_expiry: u64, // number of blocks after which a signing session expires +} + +#[deprecated(since = "0.4.1", note = "only used during migration")] +const CONFIG: Item = Item::new("config"); + +#[cfg(test)] +mod tests { + use cosmwasm_schema::cw_serde; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, DepsMut, Env, HexBinary, MessageInfo, Response, Uint64}; + + use axelar_wasm_std::nonempty; + + use crate::contract::migrations::v0_4_1; + use crate::contract::migrations::v0_4_1::BASE_VERSION; + use crate::contract::{execute, CONTRACT_NAME}; + use crate::msg::ExecuteMsg::{DisableSigning, SubmitSignature}; + use crate::state::SIGNING_SESSION_COUNTER; + use crate::ContractError; + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: "governance".to_string(), + rewards_address: "rewards".to_string(), + block_expiry: 100, + }, + ) + .unwrap(); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, BASE_VERSION).unwrap(); + + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_ok()); + } + + #[test] + fn migrate_config() { + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: "governance".to_string(), + rewards_address: "rewards".to_string(), + block_expiry: 0, + }, + ) + .unwrap(); + + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_ok()); + + assert!(v0_4_1::CONFIG.load(deps.as_mut().storage).is_err()); + + let new_config = crate::state::CONFIG.load(deps.as_mut().storage); + assert!(new_config.is_ok()); + let new_config = new_config.unwrap(); + assert_eq!( + new_config.block_expiry, + nonempty::Uint64::try_from(10).unwrap() + ); + } + + #[test] + fn permissions_are_set_after_migration_and_contract_can_be_disabled() { + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: "governance".to_string(), + rewards_address: "rewards".to_string(), + block_expiry: 100, + }, + ) + .unwrap(); + + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_ok()); + + // contract is enabled + assert!(!execute( + deps.as_mut(), + mock_env(), + mock_info("any_addr", &[]), + SubmitSignature { + session_id: 0u64.into(), + signature: HexBinary::from_hex("04").unwrap(), + } + ) + .unwrap_err() + .to_string() + .contains(&ContractError::SigningDisabled.to_string())); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("any_addr", &[]), + DisableSigning + ) + .is_err()); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + DisableSigning + ) + .is_ok()); + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("governance", &[]), + DisableSigning + ) + .is_ok()); + + // contract is disabled + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("any_addr", &[]), + SubmitSignature { + session_id: 0u64.into(), + signature: HexBinary::from_hex("04").unwrap(), + } + ) + .unwrap_err() + .to_string() + .contains(&ContractError::SigningDisabled.to_string())); + } + + #[deprecated(since = "0.4.1", note = "only used to test migration")] + fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, BASE_VERSION)?; + + let config = v0_4_1::Config { + governance: deps.api.addr_validate(&msg.governance_address)?, + rewards_contract: deps.api.addr_validate(&msg.rewards_address)?, + block_expiry: msg.block_expiry, + }; + + v0_4_1::CONFIG.save(deps.storage, &config)?; + + SIGNING_SESSION_COUNTER.save(deps.storage, &Uint64::zero())?; + + Ok(Response::default()) + } + + #[cw_serde] + #[deprecated(since = "0.4.1", note = "only used to test migration")] + struct InstantiateMsg { + // the governance address is allowed to modify the authorized caller list for this contract + pub governance_address: String, + pub rewards_address: String, + pub block_expiry: u64, + } +} diff --git a/contracts/multisig/src/error.rs b/contracts/multisig/src/error.rs index d4080966a..013fffa48 100644 --- a/contracts/multisig/src/error.rs +++ b/contracts/multisig/src/error.rs @@ -1,5 +1,6 @@ use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::{OverflowError, StdError, Uint64}; +use cw2::VersionError; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] @@ -7,6 +8,12 @@ pub enum ContractError { #[error(transparent)] Std(#[from] StdError), + #[error(transparent)] + Version(#[from] VersionError), + + #[error("failed to migrate contract state")] + Migration, + #[error(transparent)] Overflow(#[from] OverflowError), diff --git a/contracts/multisig/src/lib.rs b/contracts/multisig/src/lib.rs index 32b01b9ca..189f0ec33 100644 --- a/contracts/multisig/src/lib.rs +++ b/contracts/multisig/src/lib.rs @@ -2,7 +2,6 @@ pub mod contract; pub mod error; pub mod events; pub mod key; -mod migrations; pub mod msg; pub mod multisig; pub mod signing; diff --git a/contracts/multisig/src/migrations/mod.rs b/contracts/multisig/src/migrations/mod.rs deleted file mode 100644 index 683e59145..000000000 --- a/contracts/multisig/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v_0_4; diff --git a/contracts/multisig/src/migrations/v_0_4.rs b/contracts/multisig/src/migrations/v_0_4.rs deleted file mode 100644 index 0913c788f..000000000 --- a/contracts/multisig/src/migrations/v_0_4.rs +++ /dev/null @@ -1,78 +0,0 @@ -use crate::state::{SIGNING_SESSIONS, VERIFIER_SETS}; -use cosmwasm_std::{DepsMut, Order, Response, Storage}; - -fn migrate_verifier_set_ids( - store: &mut dyn Storage, -) -> Result { - let all: Vec<_> = VERIFIER_SETS - .range(store, None, None, Order::Ascending) - .collect::, _>>()?; - - for v in all { - VERIFIER_SETS.remove(store, &v.0); - VERIFIER_SETS.save(store, &v.1.id(), &v.1)?; - } - - Ok(Response::default()) -} - -fn remove_all_signing_sessions( - store: &mut dyn Storage, -) -> Result { - SIGNING_SESSIONS.clear(store); - - Ok(Response::default()) -} - -pub fn migrate(deps: DepsMut) -> Result { - remove_all_signing_sessions(deps.storage)?; - migrate_verifier_set_ids(deps.storage) -} - -#[cfg(test)] -mod test { - use crate::{ - signing::SigningSession, - state::{SIGNING_SESSIONS, VERIFIER_SETS}, - test::common::{build_verifier_set, ecdsa_test_data::signers}, - }; - - use cosmwasm_std::{testing::mock_dependencies, HexBinary, Uint64}; - - use super::migrate; - - #[test] - fn should_be_able_to_migrate_verifier_set_ids() { - let mut deps = mock_dependencies(); - let signers = signers(); - let verifier_set = build_verifier_set(crate::key::KeyType::Ecdsa, &signers); - VERIFIER_SETS - .save(&mut deps.storage, "foobar", &verifier_set) - .unwrap(); - let signing_session = SigningSession { - id: Uint64::one(), - verifier_set_id: "foobar".to_string(), - chain_name: "ethereum".parse().unwrap(), - msg: HexBinary::from([2; 32]).try_into().unwrap(), - state: crate::types::MultisigState::Pending, - expires_at: 100, - sig_verifier: None, - }; - SIGNING_SESSIONS - .save( - &mut deps.storage, - signing_session.id.u64(), - &signing_session, - ) - .unwrap(); - - migrate(deps.as_mut()).unwrap(); - - let new_verifier_set = VERIFIER_SETS.load(&deps.storage, &verifier_set.id()); - assert!(new_verifier_set.is_ok(), "{:?}", new_verifier_set); - assert_eq!(new_verifier_set.unwrap(), verifier_set); - - let loaded_signing_session = SIGNING_SESSIONS.load(&deps.storage, signing_session.id.u64()); - assert!(loaded_signing_session.is_err()); - } -} diff --git a/contracts/multisig/src/msg.rs b/contracts/multisig/src/msg.rs index 2483f0f28..fe862673a 100644 --- a/contracts/multisig/src/msg.rs +++ b/contracts/multisig/src/msg.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::nonempty; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, HexBinary, Uint128, Uint64}; use msgs_derive::EnsurePermissions; @@ -9,6 +10,11 @@ use crate::{ verifier_set::VerifierSet, }; +#[cw_serde] +pub struct MigrationMsg { + pub admin_address: String, +} + #[cw_serde] pub struct InstantiateMsg { // the governance address is allowed to modify the authorized caller list for this contract @@ -16,7 +22,7 @@ pub struct InstantiateMsg { // The admin address (or governance) is allowed to disable signing. Only governance can re-enable pub admin_address: String, pub rewards_address: String, - pub block_expiry: u64, + pub block_expiry: nonempty::Uint64, // number of blocks after which a signing session expires } #[cw_serde] diff --git a/contracts/multisig/src/state.rs b/contracts/multisig/src/state.rs index 9a9ade409..8cd4ba7f9 100644 --- a/contracts/multisig/src/state.rs +++ b/contracts/multisig/src/state.rs @@ -1,20 +1,20 @@ use std::collections::HashMap; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, HexBinary, Order, StdResult, Storage, Uint64}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; - use crate::{ key::{KeyType, KeyTyped, PublicKey, Signature}, signing::SigningSession, verifier_set::VerifierSet, ContractError, }; +use axelar_wasm_std::nonempty; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, HexBinary, Order, StdResult, Storage, Uint64}; +use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; #[cw_serde] pub struct Config { pub rewards_contract: Addr, - pub block_expiry: u64, // number of blocks after which a signing session expires + pub block_expiry: nonempty::Uint64, // number of blocks after which a signing session expires } pub const CONFIG: Item = Item::new("config"); diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 26ce48d8d..91588d384 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -5,11 +5,11 @@ use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, }; -use crate::contract::migrations::{set_version_after_migration, v0_3_3}; +use crate::contract::migrations::v0_3_3; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; use crate::state; -use crate::state::{load_chain_by_gateway, Config, CONTRACT_NAME, CONTRACT_VERSION}; +use crate::state::{load_chain_by_gateway, Config}; use axelar_wasm_std::{permission_control, FnExt}; use router_api::error::Error; use router_api::msg::{ExecuteMsg, QueryMsg}; @@ -18,13 +18,21 @@ mod execute; mod migrations; mod query; +pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, ) -> Result { - set_version_after_migration(deps.storage, |storage| v0_3_3::migrate(storage)) + v0_3_3::migrate(deps.storage)?; + + // this needs to be the last thing to do during migration, + // because previous migration steps should check the old version + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/router/src/contract/migrations/mod.rs b/contracts/router/src/contract/migrations/mod.rs index 561b14d51..ebcb4aab1 100644 --- a/contracts/router/src/contract/migrations/mod.rs +++ b/contracts/router/src/contract/migrations/mod.rs @@ -1,15 +1 @@ -use crate::state::{CONTRACT_NAME, CONTRACT_VERSION}; -use axelar_wasm_std::ContractError; -use cosmwasm_std::{Response, Storage}; - pub mod v0_3_3; - -pub fn set_version_after_migration( - storage: &mut dyn Storage, - migration: fn(&mut dyn Storage) -> Result, -) -> Result { - migration(storage)?; - - cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; - Ok(Response::default()) -} diff --git a/contracts/router/src/contract/migrations/v0_3_3.rs b/contracts/router/src/contract/migrations/v0_3_3.rs index c65b8d683..2783cca7e 100644 --- a/contracts/router/src/contract/migrations/v0_3_3.rs +++ b/contracts/router/src/contract/migrations/v0_3_3.rs @@ -1,26 +1,20 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Response, StdResult, Storage}; -use cw2::VersionError; +use cosmwasm_std::{Addr, StdResult, Storage}; use cw_storage_plus::Item; +use crate::contract::CONTRACT_NAME; use crate::state; use axelar_wasm_std::{killswitch, permission_control, ContractError}; use router_api::error::Error; const BASE_VERSION: &str = "0.3.3"; -pub fn migrate(storage: &mut dyn Storage) -> Result { - let current_version = cw2::get_contract_version(storage)?; - if current_version.version != BASE_VERSION { - Err(VersionError::WrongVersion { - expected: BASE_VERSION.into(), - found: current_version.version, - })? - } else { - set_generalized_permission_control(storage)?; - set_router_state(storage)?; - Ok(Response::default()) - } +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + set_generalized_permission_control(storage)?; + set_router_state(storage)?; + Ok(()) } #[deprecated(since = "0.3.3", note = "only used during migration")] @@ -65,13 +59,12 @@ mod test { use axelar_wasm_std::{killswitch, ContractError}; use router_api::msg::ExecuteMsg; - use crate::contract::execute; use crate::contract::migrations::v0_3_3; use crate::contract::migrations::v0_3_3::BASE_VERSION; + use crate::contract::{execute, CONTRACT_NAME}; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; use crate::state; - use crate::state::CONTRACT_NAME; #[test] fn migrate_checks_contract_version() { diff --git a/contracts/router/src/state.rs b/contracts/router/src/state.rs index bce63a715..ca014106c 100644 --- a/contracts/router/src/state.rs +++ b/contracts/router/src/state.rs @@ -5,9 +5,6 @@ use error_stack::{report, ResultExt}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName}; -pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); -pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - pub fn save_config(storage: &mut dyn Storage, config: &Config) -> error_stack::Result<(), Error> { CONFIG .save(storage, config) diff --git a/integration-tests/src/multisig_contract.rs b/integration-tests/src/multisig_contract.rs index 859348cd2..52a35ebdc 100644 --- a/integration-tests/src/multisig_contract.rs +++ b/integration-tests/src/multisig_contract.rs @@ -1,4 +1,5 @@ use crate::contract::Contract; +use axelar_wasm_std::nonempty; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; @@ -13,7 +14,7 @@ impl MultisigContract { governance: Addr, admin: Addr, rewards_address: Addr, - block_expiry: u64, + block_expiry: nonempty::Uint64, ) -> Self { let code = ContractWrapper::new( multisig::contract::execute, diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 8d5f8f5af..888841196 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -391,7 +391,7 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { governance_address.clone(), admin_address.clone(), rewards.contract_addr.clone(), - SIGNATURE_BLOCK_EXPIRY, + SIGNATURE_BLOCK_EXPIRY.try_into().unwrap(), ); let coordinator = diff --git a/packages/axelar-wasm-std/src/permission_control.rs b/packages/axelar-wasm-std/src/permission_control.rs index 7bb64e097..7693cbc65 100644 --- a/packages/axelar-wasm-std/src/permission_control.rs +++ b/packages/axelar-wasm-std/src/permission_control.rs @@ -61,8 +61,7 @@ pub fn set_governance(storage: &mut dyn cosmwasm_std::Storage, addr: &Addr) -> S GOVERNANCE.save(storage, addr) } -// this is an implementation detail of the `EnsurePermission` derived ensure_permission macro and shouldn't be called on its own -#[doc(hidden)] +/// Generally it shouldn't be necessary to call this function directly, use derived permission controlled functions instead #[allow(clippy::arithmetic_side_effects)] // flagset is safe pub fn sender_role( storage: &dyn cosmwasm_std::Storage, From df3240f3e716b471dac62e613181e9c077aa0c12 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 9 Jul 2024 11:50:28 -0400 Subject: [PATCH 059/168] refactor: hide internal structure of msg_id module (#495) --- ampd/src/handlers/evm_verify_msg.rs | 2 +- ampd/src/handlers/evm_verify_verifier_set.rs | 2 +- ampd/src/handlers/sui_verify_verifier_set.rs | 2 +- contracts/nexus-gateway/src/contract/execute.rs | 2 +- contracts/nexus-gateway/src/nexus.rs | 7 ++----- contracts/router/src/contract.rs | 2 +- contracts/router/src/contract/execute.rs | 2 +- contracts/voting-verifier/src/client.rs | 4 +--- contracts/voting-verifier/src/contract.rs | 5 +---- contracts/voting-verifier/src/events.rs | 9 +++------ contracts/voting-verifier/src/query.rs | 2 +- integration-tests/tests/test_utils/mod.rs | 2 +- packages/axelar-wasm-std/src/msg_id/mod.rs | 6 +++--- 13 files changed, 18 insertions(+), 29 deletions(-) diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 5a8fc859a..6999583c4 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -12,7 +12,7 @@ use tokio::sync::watch::Receiver; use tracing::{info, info_span}; use valuable::Valuable; -use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::voting::{PollId, Vote}; use events::Error::EventTypeMismatch; use events_derive::try_from; diff --git a/ampd/src/handlers/evm_verify_verifier_set.rs b/ampd/src/handlers/evm_verify_verifier_set.rs index 72c2cd563..6b85578ca 100644 --- a/ampd/src/handlers/evm_verify_verifier_set.rs +++ b/ampd/src/handlers/evm_verify_verifier_set.rs @@ -12,7 +12,7 @@ use tracing::{info, info_span}; use valuable::Valuable; use axelar_wasm_std::{ - msg_id::tx_hash_event_index::HexTxHashAndEventIndex, + msg_id::HexTxHashAndEventIndex, voting::{PollId, Vote}, }; use events::Error::EventTypeMismatch; diff --git a/ampd/src/handlers/sui_verify_verifier_set.rs b/ampd/src/handlers/sui_verify_verifier_set.rs index 71c9d70d9..bc8cb6272 100644 --- a/ampd/src/handlers/sui_verify_verifier_set.rs +++ b/ampd/src/handlers/sui_verify_verifier_set.rs @@ -13,7 +13,7 @@ use tokio::sync::watch::Receiver; use tracing::{info, info_span}; use valuable::Valuable; -use axelar_wasm_std::msg_id::base_58_event_index::Base58TxDigestAndEventIndex; +use axelar_wasm_std::msg_id::Base58TxDigestAndEventIndex; use axelar_wasm_std::voting::{PollId, Vote}; use events::{Error::EventTypeMismatch, Event}; use events_derive::try_from; diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index 5b6129098..dad9b9c69 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -67,7 +67,7 @@ where #[cfg(test)] mod test { - use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use cosmwasm_std::{from_json, CosmosMsg}; use hex::decode; diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 26baad411..55ad071d1 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use axelar_wasm_std::{msg_id::tx_hash_event_index::HexTxHashAndEventIndex, nonempty}; +use axelar_wasm_std::{msg_id::HexTxHashAndEventIndex, nonempty}; use cosmwasm_std::{CosmosMsg, CustomMsg}; use error_stack::{Report, Result, ResultExt}; use router_api::{Address, ChainName, CrossChainId}; @@ -83,10 +83,7 @@ impl From for CosmosMsg { mod test { use std::vec; - use axelar_wasm_std::msg_id::{ - base_58_event_index::Base58TxDigestAndEventIndex, - tx_hash_event_index::HexTxHashAndEventIndex, - }; + use axelar_wasm_std::msg_id::{Base58TxDigestAndEventIndex, HexTxHashAndEventIndex}; use router_api::CrossChainId; use super::Message; diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 91588d384..f72938e8a 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -141,7 +141,7 @@ mod test { use super::*; use crate::events; - use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::ContractError; use cosmwasm_std::{ from_json, diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index d879376ff..69f649d36 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -247,7 +247,7 @@ mod test { use crate::msg::InstantiateMsg; use crate::state::chain_endpoints; use axelar_wasm_std::flagset::FlagSet; - use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; + use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{Addr, Storage}; use rand::{random, RngCore}; diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index d0ac78f41..4445044a0 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -104,9 +104,7 @@ fn ignore_empty(msgs: Vec) -> Option> { mod test { use std::collections::BTreeMap; - use axelar_wasm_std::{ - msg_id::tx_hash_event_index::HexTxHashAndEventIndex, Threshold, VerificationStatus, - }; + use axelar_wasm_std::{msg_id::HexTxHashAndEventIndex, Threshold, VerificationStatus}; use cosmwasm_std::{ from_json, testing::{mock_dependencies, mock_env, mock_info, MockQuerier}, diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 52a9795dd..150945fec 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -104,10 +104,7 @@ mod test { use sha3::{Digest, Keccak256}; use axelar_wasm_std::{ - msg_id::{ - base_58_event_index::Base58TxDigestAndEventIndex, - tx_hash_event_index::HexTxHashAndEventIndex, MessageIdFormat, - }, + msg_id::{Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat}, nonempty, voting::Vote, MajorityThreshold, Threshold, VerificationStatus, diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index c2d0a9436..4d337ff7a 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -1,8 +1,8 @@ use std::str::FromStr; use std::vec::Vec; -use axelar_wasm_std::msg_id::base_58_event_index::Base58TxDigestAndEventIndex; -use axelar_wasm_std::msg_id::tx_hash_event_index::HexTxHashAndEventIndex; +use axelar_wasm_std::msg_id::Base58TxDigestAndEventIndex; +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::msg_id::MessageIdFormat; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Attribute, Event}; @@ -248,10 +248,7 @@ mod test { use std::collections::BTreeMap; use axelar_wasm_std::{ - msg_id::{ - base_58_event_index::Base58TxDigestAndEventIndex, - tx_hash_event_index::HexTxHashAndEventIndex, MessageIdFormat, - }, + msg_id::{Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat}, nonempty, }; use cosmwasm_std::Uint128; diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index e387a22d6..35265250d 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -95,7 +95,7 @@ fn is_finished(poll: &state::Poll) -> bool { #[cfg(test)] mod tests { use axelar_wasm_std::{ - msg_id::tx_hash_event_index::HexTxHashAndEventIndex, + msg_id::HexTxHashAndEventIndex, nonempty, voting::{PollId, Tallies, Vote, WeightedPoll}, Participant, Snapshot, Threshold, diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 888841196..c785bd9fa 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -1,5 +1,5 @@ use axelar_wasm_std::{ - msg_id::tx_hash_event_index::HexTxHashAndEventIndex, + msg_id::HexTxHashAndEventIndex, nonempty, voting::{PollId, Vote}, Participant, Threshold, diff --git a/packages/axelar-wasm-std/src/msg_id/mod.rs b/packages/axelar-wasm-std/src/msg_id/mod.rs index 475c9b3b8..71a6dc91e 100644 --- a/packages/axelar-wasm-std/src/msg_id/mod.rs +++ b/packages/axelar-wasm-std/src/msg_id/mod.rs @@ -3,12 +3,12 @@ use std::{fmt::Display, str::FromStr}; use cosmwasm_schema::cw_serde; use error_stack::Report; -use self::{ +pub use self::{ base_58_event_index::Base58TxDigestAndEventIndex, tx_hash_event_index::HexTxHashAndEventIndex, }; -pub mod base_58_event_index; -pub mod tx_hash_event_index; +mod base_58_event_index; +mod tx_hash_event_index; #[derive(thiserror::Error)] #[cw_serde] From c050daa0f6340675270eedc0face535621364c0e Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 9 Jul 2024 14:05:01 -0400 Subject: [PATCH 060/168] chore: replace deprecated cargo config file format (#496) --- .../{gateway/.cargo/config => coordinator/.cargo/config.toml} | 0 .../.cargo/config => gateway/.cargo/config.toml} | 0 .../.cargo/config => multisig-prover/.cargo/config.toml} | 0 .../{rewards/.cargo/config => multisig/.cargo/config.toml} | 0 .../.cargo/config => nexus-gateway/.cargo/config.toml} | 0 .../.cargo/config => rewards/.cargo/config.toml} | 0 contracts/router/.cargo/config.toml | 4 ++++ contracts/service-registry/.cargo/config.toml | 4 ++++ contracts/voting-verifier/.cargo/{config => config.toml} | 0 9 files changed, 8 insertions(+) rename contracts/{gateway/.cargo/config => coordinator/.cargo/config.toml} (100%) rename contracts/{multisig-prover/.cargo/config => gateway/.cargo/config.toml} (100%) rename contracts/{multisig/.cargo/config => multisig-prover/.cargo/config.toml} (100%) rename contracts/{rewards/.cargo/config => multisig/.cargo/config.toml} (100%) rename contracts/{router/.cargo/config => nexus-gateway/.cargo/config.toml} (100%) rename contracts/{service-registry/.cargo/config => rewards/.cargo/config.toml} (100%) create mode 100644 contracts/router/.cargo/config.toml create mode 100644 contracts/service-registry/.cargo/config.toml rename contracts/voting-verifier/.cargo/{config => config.toml} (100%) diff --git a/contracts/gateway/.cargo/config b/contracts/coordinator/.cargo/config.toml similarity index 100% rename from contracts/gateway/.cargo/config rename to contracts/coordinator/.cargo/config.toml diff --git a/contracts/multisig-prover/.cargo/config b/contracts/gateway/.cargo/config.toml similarity index 100% rename from contracts/multisig-prover/.cargo/config rename to contracts/gateway/.cargo/config.toml diff --git a/contracts/multisig/.cargo/config b/contracts/multisig-prover/.cargo/config.toml similarity index 100% rename from contracts/multisig/.cargo/config rename to contracts/multisig-prover/.cargo/config.toml diff --git a/contracts/rewards/.cargo/config b/contracts/multisig/.cargo/config.toml similarity index 100% rename from contracts/rewards/.cargo/config rename to contracts/multisig/.cargo/config.toml diff --git a/contracts/router/.cargo/config b/contracts/nexus-gateway/.cargo/config.toml similarity index 100% rename from contracts/router/.cargo/config rename to contracts/nexus-gateway/.cargo/config.toml diff --git a/contracts/service-registry/.cargo/config b/contracts/rewards/.cargo/config.toml similarity index 100% rename from contracts/service-registry/.cargo/config rename to contracts/rewards/.cargo/config.toml diff --git a/contracts/router/.cargo/config.toml b/contracts/router/.cargo/config.toml new file mode 100644 index 000000000..af5698e58 --- /dev/null +++ b/contracts/router/.cargo/config.toml @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" diff --git a/contracts/service-registry/.cargo/config.toml b/contracts/service-registry/.cargo/config.toml new file mode 100644 index 000000000..af5698e58 --- /dev/null +++ b/contracts/service-registry/.cargo/config.toml @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" diff --git a/contracts/voting-verifier/.cargo/config b/contracts/voting-verifier/.cargo/config.toml similarity index 100% rename from contracts/voting-verifier/.cargo/config rename to contracts/voting-verifier/.cargo/config.toml From 061117a211a923c2a5232542b12cfce6a7f3f183 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 10 Jul 2024 10:33:03 -0600 Subject: [PATCH 061/168] feat(minor-voting-verifier): allow restarting expired polls (#481) * feat(minor-voting-verifier): allow restarting expired polls --- contracts/voting-verifier/src/contract.rs | 53 +++++++------------- contracts/voting-verifier/src/execute.rs | 7 ++- contracts/voting-verifier/src/query.rs | 60 ++++++++++++++++------- packages/axelar-wasm-std/src/voting.rs | 34 ++++++++++--- 4 files changed, 93 insertions(+), 61 deletions(-) diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 150945fec..375305da8 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -65,18 +65,18 @@ pub fn execute( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::GetPoll { poll_id: _ } => { todo!() } QueryMsg::GetMessagesStatus { messages } => { - to_json_binary(&query::messages_status(deps, &messages)?) - } - QueryMsg::GetVerifierSetStatus { new_verifier_set } => { - to_json_binary(&query::verifier_set_status(deps, &new_verifier_set)?) + to_json_binary(&query::messages_status(deps, &messages, env.block.height)?) } + QueryMsg::GetVerifierSetStatus { new_verifier_set } => to_json_binary( + &query::verifier_set_status(deps, &new_verifier_set, env.block.height)?, + ), QueryMsg::GetCurrentThreshold => to_json_binary(&query::voting_threshold(deps)?), } } @@ -434,21 +434,11 @@ mod test { ) .unwrap(); - execute( - deps.as_mut(), - mock_env_expired(), - mock_info(SENDER, &[]), - ExecuteMsg::EndPoll { - poll_id: Uint64::one().into(), - }, - ) - .unwrap(); - // confirm it was not verified let status: Vec = from_json( query( deps.as_ref(), - mock_env(), + mock_env_expired(), QueryMsg::GetMessagesStatus { messages: messages.clone(), }, @@ -462,7 +452,13 @@ mod test { ); // retries same message - let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap(); + let res = execute( + deps.as_mut(), + mock_env_expired(), + mock_info(SENDER, &[]), + msg, + ) + .unwrap(); let actual: Vec = serde_json::from_str( &res.events @@ -563,7 +559,7 @@ mod test { let res: Vec = from_json( query( deps.as_ref(), - mock_env(), + mock_env_expired(), QueryMsg::GetMessagesStatus { messages: messages.clone(), }, @@ -592,7 +588,7 @@ mod test { let res = execute( deps.as_mut(), - mock_env(), + mock_env_expired(), mock_info(SENDER, &[]), msg_verify, ); @@ -601,7 +597,7 @@ mod test { let res: Vec = from_json( query( deps.as_ref(), - mock_env(), + mock_env_expired(), QueryMsg::GetMessagesStatus { messages: messages.clone(), }, @@ -685,7 +681,7 @@ mod test { } #[test] - fn should_query_status_failed_to_verify_when_no_consensus_and_poll_ended() { + fn should_query_status_failed_to_verify_when_no_consensus_and_poll_expired() { let msg_id_format = MessageIdFormat::HexTxHashAndEventIndex; let verifiers = verifiers(2); let mut deps = setup(verifiers.clone(), &msg_id_format); @@ -703,21 +699,10 @@ mod test { ) .unwrap(); - // end poll - execute( - deps.as_mut(), - mock_env_expired(), - mock_info(SENDER, &[]), - ExecuteMsg::EndPoll { - poll_id: Uint64::one().into(), - }, - ) - .unwrap(); - let statuses: Vec = from_json( query( deps.as_ref(), - mock_env(), + mock_env_expired(), QueryMsg::GetMessagesStatus { messages: messages.clone(), }, @@ -1293,7 +1278,7 @@ mod test { let res: Vec = from_json( query( deps.as_ref(), - mock_env(), + mock_env_expired(), QueryMsg::GetMessagesStatus { messages: messages.clone(), }, diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index c7788fc06..8bbf3edc2 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -55,7 +55,7 @@ pub fn verify_verifier_set( message_id: nonempty::String, new_verifier_set: VerifierSet, ) -> Result { - let status = verifier_set_status(deps.as_ref(), &new_verifier_set)?; + let status = verifier_set_status(deps.as_ref(), &new_verifier_set, env.block.height)?; if status.is_confirmed() { return Ok(Response::new()); } @@ -115,7 +115,10 @@ pub fn verify_messages( let messages = messages .into_iter() - .map(|message| message_status(deps.as_ref(), &message).map(|status| (status, message))) + .map(|message| { + message_status(deps.as_ref(), &message, env.block.height) + .map(|status| (status, message)) + }) .collect::, _>>()?; let msgs_to_verify: Vec = messages diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index 35265250d..3a8ff8405 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -22,38 +22,55 @@ pub fn voting_threshold(deps: Deps) -> Result pub fn messages_status( deps: Deps, messages: &[Message], + cur_block_height: u64, ) -> Result, ContractError> { messages .iter() .map(|message| { - message_status(deps, message) + message_status(deps, message, cur_block_height) .map(|status| MessageStatus::new(message.to_owned(), status)) }) .collect() } -pub fn message_status(deps: Deps, message: &Message) -> Result { +pub fn message_status( + deps: Deps, + message: &Message, + cur_block_height: u64, +) -> Result { let loaded_poll_content = poll_messages().may_load(deps.storage, &message.hash())?; - Ok(verification_status(deps, loaded_poll_content, message)) + Ok(verification_status( + deps, + loaded_poll_content, + message, + cur_block_height, + )) } pub fn verifier_set_status( deps: Deps, verifier_set: &VerifierSet, + cur_block_height: u64, ) -> Result { let loaded_poll_content = poll_verifier_sets().may_load( deps.storage, &verifier_set.hash().as_slice().try_into().unwrap(), )?; - Ok(verification_status(deps, loaded_poll_content, verifier_set)) + Ok(verification_status( + deps, + loaded_poll_content, + verifier_set, + cur_block_height, + )) } fn verification_status( deps: Deps, stored_poll_content: Option>, content: &T, + cur_block_height: u64, ) -> VerificationStatus { match stored_poll_content { Some(stored) => { @@ -76,7 +93,9 @@ fn verification_status( Some(Vote::SucceededOnChain) => VerificationStatus::SucceededOnSourceChain, Some(Vote::FailedOnChain) => VerificationStatus::FailedOnSourceChain, Some(Vote::NotFound) => VerificationStatus::NotFoundOnSourceChain, - None if is_finished(&poll) => VerificationStatus::FailedToVerify, + None if voting_completed(&poll, cur_block_height) => { + VerificationStatus::FailedToVerify + } None => VerificationStatus::InProgress, } } @@ -84,10 +103,13 @@ fn verification_status( } } -fn is_finished(poll: &state::Poll) -> bool { +fn voting_completed(poll: &state::Poll, cur_block_height: u64) -> bool { match poll { state::Poll::Messages(poll) | state::Poll::ConfirmVerifierSet(poll) => { - poll.status == PollStatus::Finished + matches!( + poll.status(cur_block_height), + PollStatus::Expired | PollStatus::Finished + ) } } } @@ -111,8 +133,9 @@ mod tests { fn verification_status_in_progress() { let mut deps = mock_dependencies(); let idx = 0; + let cur_block_height = 100; - let poll = poll(); + let poll = poll(cur_block_height + 10); POLLS .save( deps.as_mut().storage, @@ -135,7 +158,7 @@ mod tests { msg.clone(), VerificationStatus::InProgress )], - messages_status(deps.as_ref(), &[msg]).unwrap() + messages_status(deps.as_ref(), &[msg], cur_block_height).unwrap() ); } @@ -143,8 +166,9 @@ mod tests { fn verification_status_verified() { let mut deps = mock_dependencies(); let idx = 0; + let cur_block_height = 100; - let mut poll = poll(); + let mut poll = poll(cur_block_height + 10); poll.tallies[idx] = Tallies::default(); poll.tallies[idx].tally(&Vote::SucceededOnChain, &Uint128::from(5u64)); @@ -170,7 +194,7 @@ mod tests { msg.clone(), VerificationStatus::SucceededOnSourceChain )], - messages_status(deps.as_ref(), &[msg]).unwrap() + messages_status(deps.as_ref(), &[msg], cur_block_height).unwrap() ); } @@ -178,9 +202,11 @@ mod tests { fn verification_status_failed_to_verify() { let mut deps = mock_dependencies(); let idx = 0; + let cur_block_height = 100; + let poll_duration = 10; + let expires_at = cur_block_height + poll_duration; - let mut poll = poll(); - poll.status = PollStatus::Finished; + let poll = poll(expires_at); POLLS .save( @@ -204,7 +230,7 @@ mod tests { msg.clone(), VerificationStatus::FailedToVerify )], - messages_status(deps.as_ref(), &[msg]).unwrap() + messages_status(deps.as_ref(), &[msg], expires_at).unwrap() ); } @@ -215,7 +241,7 @@ mod tests { assert_eq!( vec![MessageStatus::new(msg.clone(), VerificationStatus::Unknown)], - messages_status(deps.as_ref(), &[msg]).unwrap() + messages_status(deps.as_ref(), &[msg], 0).unwrap() ); } @@ -238,7 +264,7 @@ mod tests { } } - pub fn poll() -> WeightedPoll { + pub fn poll(expires_at: u64) -> WeightedPoll { let participants: nonempty::Vec = vec!["addr1", "addr2", "addr3"] .into_iter() .map(|participant| Participant { @@ -255,6 +281,6 @@ mod tests { let snapshot = Snapshot::new(threshold.try_into().unwrap(), participants); - WeightedPoll::new(PollId::from(Uint64::one()), snapshot, 0, 5) + WeightedPoll::new(PollId::from(Uint64::one()), snapshot, expires_at, 5) } } diff --git a/packages/axelar-wasm-std/src/voting.rs b/packages/axelar-wasm-std/src/voting.rs index 7ce8afcdc..b815fb0d6 100644 --- a/packages/axelar-wasm-std/src/voting.rs +++ b/packages/axelar-wasm-std/src/voting.rs @@ -254,6 +254,7 @@ pub struct PollState { #[cw_serde] pub enum PollStatus { InProgress, + Expired, Finished, } @@ -267,10 +268,10 @@ pub struct Participation { pub struct WeightedPoll { pub poll_id: PollId, pub quorum: nonempty::Uint128, - pub expires_at: u64, + expires_at: u64, pub poll_size: u64, pub tallies: Vec, // running tally of weighted votes - pub status: PollStatus, + finished: bool, pub participation: BTreeMap, } @@ -298,13 +299,13 @@ impl WeightedPoll { expires_at: expiry, poll_size: poll_size as u64, tallies: vec![Tallies::default(); poll_size], - status: PollStatus::InProgress, + finished: false, participation, } } pub fn finish(mut self, block_height: u64) -> Result { - if matches!(self.status, PollStatus::Finished { .. }) { + if self.finished { return Err(Error::PollNotInProgress); } @@ -312,7 +313,7 @@ impl WeightedPoll { return Err(Error::PollNotEnded); } - self.status = PollStatus::Finished; + self.finished = true; Ok(self) } @@ -403,6 +404,14 @@ impl WeightedPoll { Ok(self) } + + pub fn status(&self, current_height: u64) -> PollStatus { + match self.finished { + true => PollStatus::Finished, + false if current_height >= self.expires_at => PollStatus::Expired, + _ => PollStatus::InProgress, + } + } } #[cfg(test)] @@ -510,8 +519,8 @@ mod tests { #[test] fn finish_after_poll_conclude() { let mut poll = new_poll(2, 2, vec!["addr1", "addr2"]); - poll.status = PollStatus::Finished; - assert_eq!(poll.finish(2), Err(Error::PollNotInProgress)); + poll = poll.finish(2).unwrap(); + assert_eq!(poll.finish(3), Err(Error::PollNotInProgress)); } #[test] @@ -527,7 +536,7 @@ mod tests { .unwrap(); let poll = poll.finish(2).unwrap(); - assert_eq!(poll.status, PollStatus::Finished); + assert_eq!(poll.status(2), PollStatus::Finished); let result = poll.state( voters @@ -598,6 +607,15 @@ mod tests { ); } + #[test] + fn status_should_return_current_status() { + let mut poll = new_poll(2, 2, vec!["addr1", "addr2"]); + assert_eq!(poll.status(1), PollStatus::InProgress); + assert_eq!(poll.status(2), PollStatus::Expired); + poll = poll.finish(3).unwrap(); + assert_eq!(poll.status(3), PollStatus::Finished); + } + fn new_poll(expires_at: u64, poll_size: usize, participants: Vec<&str>) -> WeightedPoll { let participants: nonempty::Vec = participants .into_iter() From 0934d812bb2aefaf68c0072990ca7f152b8cafe7 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 10 Jul 2024 11:47:01 -0600 Subject: [PATCH 062/168] feat(minor-voting-verifier): add poll id to quorum reached event (#500) --- contracts/voting-verifier/src/events.rs | 5 +++++ contracts/voting-verifier/src/execute.rs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 4d337ff7a..f9870fddb 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -224,6 +224,7 @@ impl From for Event { pub struct QuorumReached { pub content: T, pub status: VerificationStatus, + pub poll_id: PollId, } impl From> for Event @@ -240,6 +241,10 @@ where "status", serde_json::to_string(&value.status).expect("failed to serialize status"), ) + .add_attribute( + "poll_id", + serde_json::to_string(&value.poll_id).expect("failed to serialize poll_id"), + ) } } diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 8bbf3edc2..618fb1b57 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -203,6 +203,7 @@ fn make_quorum_event( QuorumReached { content: msg, status, + poll_id: *poll_id, } .into() })) @@ -217,6 +218,7 @@ fn make_quorum_event( QuorumReached { content: verifier_set, status, + poll_id: *poll_id, } .into() })) From e1ea66d201c3a905b7543ae39e3d230d2bf9f342 Mon Sep 17 00:00:00 2001 From: eloylp Date: Wed, 10 Jul 2024 13:09:00 -0500 Subject: [PATCH 063/168] feat: add support for Solana base58 msg id (#494) --- contracts/voting-verifier/src/contract.rs | 21 +- contracts/voting-verifier/src/events.rs | 7 + .../src/msg_id/base_58_solana_event_index.rs | 361 ++++++++++++++++++ packages/axelar-wasm-std/src/msg_id/mod.rs | 9 +- 4 files changed, 392 insertions(+), 6 deletions(-) create mode 100644 packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 375305da8..61e35c6c5 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -101,10 +101,13 @@ mod test { testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, Addr, Empty, Fraction, OwnedDeps, Uint128, Uint64, WasmQuery, }; - use sha3::{Digest, Keccak256}; + use sha3::{Digest, Keccak256, Keccak512}; use axelar_wasm_std::{ - msg_id::{Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat}, + msg_id::{ + Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, + HexTxHashAndEventIndex, MessageIdFormat, + }, nonempty, voting::Vote, MajorityThreshold, Threshold, VerificationStatus, @@ -205,22 +208,30 @@ mod test { } fn message_id(id: &str, index: u32, msg_id_format: &MessageIdFormat) -> nonempty::String { - let tx_hash = Keccak256::digest(id.as_bytes()).into(); match msg_id_format { MessageIdFormat::HexTxHashAndEventIndex => HexTxHashAndEventIndex { - tx_hash, + tx_hash: Keccak256::digest(id.as_bytes()).into(), event_index: index, } .to_string() .parse() .unwrap(), MessageIdFormat::Base58TxDigestAndEventIndex => Base58TxDigestAndEventIndex { - tx_digest: tx_hash, + tx_digest: Keccak256::digest(id.as_bytes()).into(), event_index: index, } .to_string() .parse() .unwrap(), + MessageIdFormat::Base58SolanaTxSignatureAndEventIndex => { + Base58SolanaTxSignatureAndEventIndex { + raw_signature: Keccak512::digest(id.as_bytes()).into(), + event_index: index, + } + .to_string() + .parse() + .unwrap() + } } } diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index f9870fddb..15da8d871 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use std::vec::Vec; +use axelar_wasm_std::msg_id::Base58SolanaTxSignatureAndEventIndex; use axelar_wasm_std::msg_id::Base58TxDigestAndEventIndex; use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::msg_id::MessageIdFormat; @@ -137,6 +138,12 @@ fn parse_message_id( Ok((id.tx_hash_as_hex(), id.event_index)) } + MessageIdFormat::Base58SolanaTxSignatureAndEventIndex => { + let id = Base58SolanaTxSignatureAndEventIndex::from_str(&message_id) + .map_err(|_| ContractError::InvalidMessageID(message_id.into()))?; + + Ok((id.signature_as_base58(), id.event_index)) + } } } diff --git a/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs b/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs new file mode 100644 index 000000000..4c7fd150b --- /dev/null +++ b/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs @@ -0,0 +1,361 @@ +use core::fmt; +use std::{fmt::Display, str::FromStr}; + +use error_stack::{Report, ResultExt}; +use lazy_static::lazy_static; +use regex::Regex; + +use super::Error; +use crate::nonempty; + +type RawSignature = [u8; 64]; + +pub struct Base58SolanaTxSignatureAndEventIndex { + // Base58 decoded bytes of the Solana signature. + pub raw_signature: RawSignature, + pub event_index: u32, +} + +impl Base58SolanaTxSignatureAndEventIndex { + pub fn signature_as_base58(&self) -> nonempty::String { + bs58::encode(self.raw_signature) + .into_string() + .try_into() + .expect("failed to convert tx hash to non-empty string") + } + + pub fn new(tx_id: impl Into, event_index: impl Into) -> Self { + Self { + raw_signature: tx_id.into(), + event_index: event_index.into(), + } + } +} + +fn decode_b58_signature(signature: &str) -> Result> { + Ok(bs58::decode(signature) + .into_vec() + .change_context(Error::InvalidTxDigest(signature.to_string()))? + .as_slice() + .try_into() + .map_err(|_| Error::InvalidTxDigest(signature.to_owned()))?) +} + +const PATTERN: &str = "^([1-9A-HJ-NP-Za-km-z]{64,88})-(0|[1-9][0-9]*)$"; +lazy_static! { + static ref REGEX: Regex = Regex::new(PATTERN).expect("invalid regex"); +} + +impl FromStr for Base58SolanaTxSignatureAndEventIndex { + type Err = Report; + + fn from_str(message_id: &str) -> Result + where + Self: Sized, + { + // the PATTERN has exactly two capture groups, so the groups can be extracted safely + let (_, [signature, event_index]) = REGEX + .captures(message_id) + .ok_or(Error::InvalidMessageID { + id: message_id.to_string(), + expected_format: PATTERN.to_string(), + })? + .extract(); + + Ok(Base58SolanaTxSignatureAndEventIndex { + raw_signature: decode_b58_signature(signature)?, + event_index: event_index + .parse() + .map_err(|_| Error::EventIndexOverflow(message_id.to_string()))?, + }) + } +} + +impl Display for Base58SolanaTxSignatureAndEventIndex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}-{}", + bs58::encode(self.raw_signature).into_string(), + self.event_index + ) + } +} + +#[cfg(test)] +mod tests { + + use hex::ToHex; + + use super::*; + + fn random_bytes() -> RawSignature { + let mut bytes = [0; 64]; + for b in &mut bytes { + *b = rand::random(); + } + bytes + } + + fn random_tx_digest() -> String { + bs58::encode(random_bytes()).into_string() + } + + fn random_event_index() -> u32 { + rand::random() + } + + #[test] + fn should_parse_msg_id() { + let res = Base58SolanaTxSignatureAndEventIndex::from_str( + "4hHzKKdpXH2QMB5Jm11YR48cLqUJb9Cwq2YL3tveVTPeFkZaLP8cdcH5UphVPJ7kYwCUCRLnywd3xkUhb4ZYWtf5-0", + ); + assert!(res.is_ok()); + + for _ in 0..1000 { + let tx_digest = random_tx_digest(); + let event_index = random_event_index(); + let msg_id = format!("{}-{}", tx_digest, event_index); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&msg_id); + let parsed = res.unwrap(); + assert_eq!(parsed.event_index, event_index); + assert_eq!(parsed.signature_as_base58(), tx_digest.try_into().unwrap()); + assert_eq!(parsed.to_string(), msg_id); + } + } + + #[test] + fn should_not_parse_msg_id_with_wrong_length_base58_tx_digest() { + let tx_digest = random_tx_digest(); + let event_index = random_event_index(); + + // too long + let msg_id = format!("{}{}-{}", tx_digest, tx_digest, event_index); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&msg_id); + assert!(res.is_err()); + + // too short + let msg_id = format!("{}-{}", &tx_digest[0..63], event_index); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&msg_id); + assert!(res.is_err()); + } + + #[test] + fn leading_ones_should_not_be_ignored() { + let tx_digest = random_tx_digest(); + let event_index = random_event_index(); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "1{}-{}", + tx_digest, event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "11{}-{}", + tx_digest, event_index + )); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_correct_length_base58_but_wrong_length_hex() { + // this is 88 chars and valid base58, but will decode to 66 bytes + // the leading 1s are encoded as 00 in hex and thus result in too many bytes + let tx_digest = "1111KKdpXH2QMB5Jm11YR48cLqUJb9Cwq2YL3tveVTPeFkZaLP8cdcH5UphVPJ7kYwCUCRLnywd3xkUhb4ZYWtf5"; + let event_index = random_event_index(); + let msg_id = format!("{}-{}", tx_digest, event_index); + + assert!(REGEX.captures(&msg_id).is_some()); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&msg_id); + assert!(res.is_err()); + + // this is 88 chars and valid base 58, but will encode to 65 bytes + // (z is the largest base58 digit, and so this will overflow 2^512) + let tx_digest = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; + assert_eq!(tx_digest.len(), 88); + let msg_id = format!("{}-{}", tx_digest, event_index); + + assert!(REGEX.captures(&msg_id).is_some()); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_parse_msg_id_less_than_88_chars_tx_digest() { + // the tx digest can be less than 88 chars in the presence of leading 1s (00 in hex) + let tx_digest = + "1111KKdpXH2QMB5Jm11YR48cLqUJb9Cwq2YL3tveVTPeFkZaLP8cdcH5UphVPJ7kYwCUCRLnywd3xkUhb4ZYW"; + assert!(tx_digest.len() < 88); + let event_index = random_event_index(); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}-{}", + tx_digest, event_index + )); + assert!(res.is_ok()); + } + + #[test] + fn should_not_parse_msg_id_with_invalid_base58() { + let tx_digest = random_tx_digest(); + let event_index = random_event_index(); + + // 0, O and I are invalid base58 chars + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "0{}-{}", + &tx_digest[1..], + event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "I{}-{}", + &tx_digest[1..], + event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "O{}-{}", + &tx_digest[1..], + event_index + )); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_hex_tx_digest() { + let tx_digest = random_tx_digest(); + let event_index = random_event_index(); + let tx_digest_hex = bs58::decode(tx_digest) + .into_vec() + .unwrap() + .encode_hex::(); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}-{}", + tx_digest_hex, event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "0x{}-{}", + tx_digest_hex, event_index + )); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_missing_event_index() { + let msg_id = random_tx_digest(); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_wrong_separator() { + let tx_digest = random_tx_digest(); + let event_index = random_event_index(); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}:{}", + tx_digest, event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}_{}", + tx_digest, event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}+{}", + tx_digest, event_index + )); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}{}", + tx_digest, event_index + )); + assert!(res.is_err()); + + for _ in 0..10 { + let random_sep: char = rand::random(); + if random_sep == '-' { + continue; + } + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}{}{}", + tx_digest, random_sep, event_index + )); + assert!(res.is_err()); + } + } + + #[test] + fn should_not_parse_msg_id_with_event_index_with_leading_zeroes() { + let tx_digest = random_tx_digest(); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!("{}-01", tx_digest)); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_non_integer_event_index() { + let tx_digest = random_tx_digest(); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!("{}-1.0", tx_digest)); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!("{}-0x00", tx_digest)); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!("{}-foobar", tx_digest)); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!("{}-true", tx_digest)); + assert!(res.is_err()); + + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!("{}-", tx_digest)); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_overflowing_event_index() { + let event_index: u64 = u64::MAX; + let tx_digest = random_tx_digest(); + let res = Base58SolanaTxSignatureAndEventIndex::from_str(&format!( + "{}-{}", + tx_digest, event_index + )); + assert!(res.is_err()); + } + + #[test] + fn trimming_leading_ones_should_change_bytes() { + for _ in 0..100 { + let mut bytes = random_bytes(); + + // set a random (non-zero) number of leading bytes to 0 + let leading_zeroes = rand::random::() % bytes.len() + 1; + for b in bytes.iter_mut().take(leading_zeroes) { + *b = 0; + } + + let b58 = bs58::encode(&bytes).into_string(); + + // verify the base58 has the expected number of leading 1's + for c in b58.chars().take(leading_zeroes) { + assert_eq!(c, '1'); + } + + // trim a random (non-zero) number of leading 1's + let trim = rand::random::() % leading_zeroes + 1; + + // converting back to bytes should yield a different result + let decoded = bs58::decode(&b58[trim..]).into_vec().unwrap(); + assert_ne!(bytes.to_vec(), decoded); + } + } +} diff --git a/packages/axelar-wasm-std/src/msg_id/mod.rs b/packages/axelar-wasm-std/src/msg_id/mod.rs index 71a6dc91e..b900d1c92 100644 --- a/packages/axelar-wasm-std/src/msg_id/mod.rs +++ b/packages/axelar-wasm-std/src/msg_id/mod.rs @@ -4,10 +4,13 @@ use cosmwasm_schema::cw_serde; use error_stack::Report; pub use self::{ - base_58_event_index::Base58TxDigestAndEventIndex, tx_hash_event_index::HexTxHashAndEventIndex, + base_58_event_index::Base58TxDigestAndEventIndex, + base_58_solana_event_index::Base58SolanaTxSignatureAndEventIndex, + tx_hash_event_index::HexTxHashAndEventIndex, }; mod base_58_event_index; +mod base_58_solana_event_index; mod tx_hash_event_index; #[derive(thiserror::Error)] @@ -39,6 +42,7 @@ pub trait MessageId: FromStr + Display {} pub enum MessageIdFormat { HexTxHashAndEventIndex, Base58TxDigestAndEventIndex, + Base58SolanaTxSignatureAndEventIndex, } // function the router calls to verify msg ids @@ -50,6 +54,9 @@ pub fn verify_msg_id(message_id: &str, format: &MessageIdFormat) -> Result<(), R MessageIdFormat::Base58TxDigestAndEventIndex => { Base58TxDigestAndEventIndex::from_str(message_id).map(|_| ()) } + MessageIdFormat::Base58SolanaTxSignatureAndEventIndex => { + Base58SolanaTxSignatureAndEventIndex::from_str(message_id).map(|_| ()) + } } } From c188e31106ff81dfe11fbf86a98b33adc2c14093 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Wed, 10 Jul 2024 17:38:55 -0400 Subject: [PATCH 064/168] fix(ampd): reconfiguration of queued_broadcaster tests (#486) * docs: update compatibility matrix (#475) * feat(minor-ampd): support ed25519 keygen and sign (#465) * feat(minor-ampd): register public key takes in key type * tofnd client parse ed25519 * cargo sort * fix(ampd): enable derive for der crate (#477) * refactor: generalize msg access control (#473) * fix(ampd): directly pass interval to queued broadcaster and ignore first tick (#480) * fix: directly pass interval to queued broadcaster and pass the first unwanted tick * refactor: address PR comments * refactor: simplify steps to take after interval tick in run function * feat(minor-router): add command to freeze all chains (#472) * feat(multisig): query to check caller authorization status (#478) * feat: check caller authorization status for multisig * refactor: rename query function name to caller_authorized * fix(ampd): increase number of retries when fetching block events (#484) * feat(minor-voting-verifier): consistent gas cost for voting (#476) * feat(minor-voting-verifier): consistent gas cost for voting * feat: improve msg permission control with derive macro (#479) * refactor(coordinator): use generalized permission control (#485) * feat: add two new test cases for low and high load in queue * fix: address cargo clippy errors with unused handle * refactor: remove old tests, address PR comments * refactor: use mpsc instead of oneshot --------- --- ampd/src/queue/queued_broadcaster.rs | 88 +++++++++++++++++++--------- 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index fa65d214d..ef1b549fc 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -177,8 +177,9 @@ mod test { use cosmrs::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use error_stack::Report; + use tokio::sync::mpsc; use tokio::test; - use tokio::time::{interval, Duration}; + use tokio::time::{interval, timeout, Duration, Instant}; use super::{Error, QueuedBroadcaster}; use crate::broadcaster::{self, MockBroadcaster}; @@ -210,10 +211,13 @@ mod test { } #[test(start_paused = true)] - async fn should_not_broadcast_when_gas_limit_has_not_been_reached() { - let tx_count = 9; + async fn should_broadcast_after_interval_in_low_load() { + let tx_count = 5; // Less than what would exceed batch_gas_limit let batch_gas_limit = 100; let gas_limit = 10; + let interval_duration = Duration::from_secs(5); + + let (tx, mut rx) = mpsc::channel(5); let mut broadcaster = MockBroadcaster::new(); broadcaster @@ -227,73 +231,99 @@ mod test { payer: None, }) }); + broadcaster .expect_broadcast() - .once() + .times(1) .returning(move |msgs| { assert_eq!(msgs.len(), tx_count); - + tx.try_send(()) + .expect("Failed to send broadcast completion signal"); Ok(TxResponse::default()) }); - let mut broadcast_interval = interval(Duration::from_secs(5)); - // get rid of tick on startup + let mut broadcast_interval = interval(interval_duration); broadcast_interval.tick().await; let queued_broadcaster = QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); let client = queued_broadcaster.client(); - let handle = tokio::spawn(queued_broadcaster.run()); + let _handle = tokio::spawn(queued_broadcaster.run()); + + let start_time = Instant::now(); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - drop(client); - assert!(handle.await.unwrap().is_ok()); + // Advance time to just after one interval + tokio::time::advance(interval_duration + Duration::from_millis(10)).await; + + match timeout(interval_duration, rx.recv()).await { + Ok(_) => { + let elapsed = start_time.elapsed(); + assert!(elapsed > interval_duration); + assert!(elapsed < interval_duration * 2); + } + Err(_) => panic!("Broadcast did not occur within the expected timeframe"), + } } #[test(start_paused = true)] - async fn should_broadcast_when_broadcast_interval_has_been_reached() { - let tx_count = 9; + async fn should_broadcast_full_batches_in_high_load() { + let tx_count = 20; + let batch_size = 10; let batch_gas_limit = 100; - let gas_limit = 10; + let gas_limit = 11; // This will cause a batch to be full after 9 messages + let interval_duration = Duration::from_secs(5); let mut broadcaster = MockBroadcaster::new(); + broadcaster.expect_estimate_fee().returning(move |_| { + Ok(Fee { + gas_limit, + amount: vec![], + granter: None, + payer: None, + }) + }); broadcaster - .expect_estimate_fee() - .times(tx_count) - .returning(move |_| { - Ok(Fee { - gas_limit, - amount: vec![], - granter: None, - payer: None, - }) + .expect_broadcast() + .once() + .returning(move |msgs| { + assert_eq!(msgs.len(), 9); + + Ok(TxResponse::default()) }); broadcaster .expect_broadcast() .once() .returning(move |msgs| { - assert_eq!(msgs.len(), tx_count); + assert_eq!(msgs.len(), 9); Ok(TxResponse::default()) }); - let mut broadcast_interval = interval(Duration::from_millis(100)); - // get rid of tick on startup + + let mut broadcast_interval = interval(interval_duration); broadcast_interval.tick().await; let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); + QueuedBroadcaster::new(broadcaster, batch_gas_limit, batch_size, broadcast_interval); let client = queued_broadcaster.client(); - let handle = tokio::spawn(queued_broadcaster.run()); + let _handle = tokio::spawn(queued_broadcaster.run()); + + let start_time = Instant::now(); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - drop(client); - assert!(handle.await.unwrap().is_ok()); + // Advance time by a small amount to allow processing + tokio::time::advance(Duration::from_millis(100)).await; + + let elapsed = start_time.elapsed(); + + // Assert that broadcasts happened faster than the interval + assert!(elapsed < interval_duration); } #[test(start_paused = true)] From f76dc8a775b8bb529cf50147bab9259d1ec7f784 Mon Sep 17 00:00:00 2001 From: eguajardo Date: Wed, 10 Jul 2024 16:34:14 -0600 Subject: [PATCH 065/168] fix(coordinator): update permission control to set active verifiers to only provers (#499) * update permission control to set verifiers * remove unnecessary index * remove unnecessary record * use macro to generate index list --- Cargo.lock | 10 +++ Cargo.toml | 2 +- contracts/coordinator/src/contract.rs | 83 ++++++++++++++++--- contracts/coordinator/src/contract/execute.rs | 4 +- contracts/coordinator/src/error.rs | 5 +- contracts/coordinator/src/msg.rs | 2 +- contracts/coordinator/src/state.rs | 64 +++++++++++--- 7 files changed, 138 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72914dc94..4bafdfa12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1721,6 +1721,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-storage-macro" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853c8ebf6d20542ea0dc57519ee458e7ee0caa3a1848beced2c603153d3f4dbe" +dependencies = [ + "syn 1.0.109", +] + [[package]] name = "cw-storage-plus" version = "0.15.1" @@ -1739,6 +1748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", + "cw-storage-macro", "schemars", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 770853dfd..13bb7d1fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ rust-version = "1.78.0" # be sure there is an optimizer release supporting this router = { version = "^0.3.3", path = "contracts/router" } cosmwasm-std = "1.5.5" cosmwasm-schema = "1.5.5" -cw-storage-plus = "1.2.0" +cw-storage-plus = { version = "1.2.0", features = ["iterator", "macro"] } cw2 = "1.1.0" ed25519-dalek = { version = "2.1.1", default-features = false } error-stack = { version = "0.4.0", features = ["eyre"] } diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 7055bad14..ce6e01f9c 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -5,10 +5,13 @@ mod migrations; use crate::contract::migrations::v0_2_0; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use axelar_wasm_std::permission_control; +use crate::state::load_chain_by_prover; +use axelar_wasm_std::{permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, +}; pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -50,7 +53,11 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg.ensure_permissions(deps.storage, &info.sender)? { + match msg.ensure_permissions( + deps.storage, + &info.sender, + find_prover_address(&info.sender), + )? { ExecuteMsg::RegisterProverContract { chain_name, new_prover_addr, @@ -62,6 +69,12 @@ pub fn execute( .map_err(axelar_wasm_std::ContractError::from) } +fn find_prover_address( + sender: &Addr, +) -> impl FnOnce(&dyn Storage, &ExecuteMsg) -> error_stack::Result + '_ { + |storage, _| load_chain_by_prover(storage, sender.clone())?.then(Ok) +} + #[cfg_attr(not(feature = "library"), entry_point)] #[allow(dead_code)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { @@ -76,9 +89,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Result { - PROVER_PER_CHAIN - .may_load(deps.storage, chain_name.clone())? - .ok_or(ContractError::NoProversRegisteredForChain(chain_name)) + #[test] + fn set_active_verifiers_from_prover_succeeds() { + let governance = "governance_for_coordinator"; + let mut test_setup = setup(governance); + + execute( + test_setup.deps.as_mut(), + test_setup.env.clone(), + mock_info(governance, &[]), + ExecuteMsg::RegisterProverContract { + chain_name: test_setup.chain_name.clone(), + new_prover_addr: test_setup.prover.clone(), + }, + ) + .unwrap(); + + let res = execute( + test_setup.deps.as_mut(), + test_setup.env, + mock_info(test_setup.prover.as_str(), &[]), + ExecuteMsg::SetActiveVerifiers { + verifiers: HashSet::new(), + }, + ); + assert!(res.is_ok(), "{:?}", res); + } + + #[test] + fn set_active_verifiers_from_random_address_fails() { + let governance = "governance_for_coordinator"; + let mut test_setup = setup(governance); + + let res = execute( + test_setup.deps.as_mut(), + test_setup.env, + mock_info(test_setup.prover.as_str(), &[]), + ExecuteMsg::SetActiveVerifiers { + verifiers: HashSet::new(), + }, + ); + assert!(res.unwrap_err().to_string().contains( + &axelar_wasm_std::ContractError::from(permission_control::Error::WhitelistNotFound { + sender: test_setup.prover + }) + .to_string() + )); } } diff --git a/contracts/coordinator/src/contract/execute.rs b/contracts/coordinator/src/contract/execute.rs index dc12643af..22cbcd7c6 100644 --- a/contracts/coordinator/src/contract/execute.rs +++ b/contracts/coordinator/src/contract/execute.rs @@ -4,14 +4,14 @@ use std::collections::HashSet; use router_api::ChainName; use crate::error::ContractError; -use crate::state::{update_verifier_set_for_prover, PROVER_PER_CHAIN}; +use crate::state::{save_prover_for_chain, update_verifier_set_for_prover}; pub fn register_prover( deps: DepsMut, chain_name: ChainName, new_prover_addr: Addr, ) -> Result { - PROVER_PER_CHAIN.save(deps.storage, chain_name.clone(), &(new_prover_addr))?; + save_prover_for_chain(deps.storage, chain_name, new_prover_addr)?; Ok(Response::new()) } diff --git a/contracts/coordinator/src/error.rs b/contracts/coordinator/src/error.rs index 79d2dc974..a9a986064 100644 --- a/contracts/coordinator/src/error.rs +++ b/contracts/coordinator/src/error.rs @@ -1,7 +1,6 @@ use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::StdError; use cw2::VersionError; -use router_api::ChainName; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] @@ -15,6 +14,6 @@ pub enum ContractError { #[error("caller not unauthorized to perform this action")] Unauthorized, - #[error("no provers registered for chain {0}")] - NoProversRegisteredForChain(ChainName), + #[error("prover is not registered")] + ProverNotRegistered, } diff --git a/contracts/coordinator/src/msg.rs b/contracts/coordinator/src/msg.rs index 559ea0905..50e3b61a0 100644 --- a/contracts/coordinator/src/msg.rs +++ b/contracts/coordinator/src/msg.rs @@ -17,7 +17,7 @@ pub enum ExecuteMsg { chain_name: ChainName, new_prover_addr: Addr, }, - #[permission(Any)] + #[permission(Specific(prover))] SetActiveVerifiers { verifiers: HashSet }, } diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index 0ddb792ec..cff86be3f 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -1,33 +1,71 @@ use crate::error::ContractError; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Order, Storage}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Map, MultiIndex}; +use cw_storage_plus::{index_list, IndexedMap, MultiIndex, UniqueIndex}; use router_api::ChainName; use std::collections::HashSet; type ProverAddress = Addr; +type VerifierAddress = Addr; -pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); +#[index_list(ProverAddress)] +struct ChainProverIndexes<'a> { + pub by_prover: UniqueIndex<'a, ProverAddress, ProverAddress, ChainName>, +} -pub struct VerifierSetIndex<'a> { - pub by_verifier: MultiIndex<'a, Addr, VerifierProverRecord, (Addr, Addr)>, +const CHAIN_PROVER_INDEXED_MAP: IndexedMap = + IndexedMap::new( + "chain_prover_map", + ChainProverIndexes { + by_prover: UniqueIndex::new(|prover| prover.clone(), "chain_prover_map_by_prover"), + }, + ); + +pub fn load_chain_by_prover( + storage: &dyn Storage, + prover_address: ProverAddress, +) -> Result { + CHAIN_PROVER_INDEXED_MAP + .idx + .by_prover + .item(storage, prover_address)? + .map(|(_, r)| r) + .ok_or(ContractError::ProverNotRegistered) } -impl<'a> IndexList for VerifierSetIndex<'a> { - fn get_indexes(&self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.by_verifier]; - Box::new(v.into_iter()) - } +#[allow(dead_code)] // Used in tests, might be useful in future query +pub fn load_prover_by_chain( + storage: &dyn Storage, + chain_name: ChainName, +) -> Result { + CHAIN_PROVER_INDEXED_MAP + .may_load(storage, chain_name)? + .ok_or(ContractError::ProverNotRegistered) +} + +pub fn save_prover_for_chain( + storage: &mut dyn Storage, + chain: ChainName, + prover: ProverAddress, +) -> Result<(), ContractError> { + CHAIN_PROVER_INDEXED_MAP.save(storage, chain.clone(), &prover)?; + Ok(()) +} + +#[index_list(VerifierProverRecord)] +pub struct VerifierSetIndex<'a> { + pub by_verifier: + MultiIndex<'a, VerifierAddress, VerifierProverRecord, (ProverAddress, VerifierAddress)>, } #[cw_serde] pub struct VerifierProverRecord { pub prover: ProverAddress, - pub verifier: Addr, + pub verifier: VerifierAddress, } pub const VERIFIER_PROVER_INDEXED_MAP: IndexedMap< - (Addr, Addr), + (ProverAddress, VerifierAddress), VerifierProverRecord, VerifierSetIndex, > = IndexedMap::new( @@ -44,13 +82,13 @@ pub const VERIFIER_PROVER_INDEXED_MAP: IndexedMap< pub fn update_verifier_set_for_prover( storage: &mut dyn Storage, prover_address: ProverAddress, - new_verifiers: HashSet, + new_verifiers: HashSet, ) -> Result<(), ContractError> { let existing_verifiers = VERIFIER_PROVER_INDEXED_MAP .prefix(prover_address.clone()) .keys(storage, None, None, Order::Ascending) .filter_map(Result::ok) - .collect::>(); + .collect::>(); for verifier in existing_verifiers.difference(&new_verifiers) { VERIFIER_PROVER_INDEXED_MAP From 17dd9a77e5c17bbba13f8f9341298cfe9cf233ec Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 11 Jul 2024 11:36:32 -0400 Subject: [PATCH 066/168] chore: add configuration for codecov patch checks (#503) --- codecov.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/codecov.yml b/codecov.yml index d81edca72..c4525eb0b 100644 --- a/codecov.yml +++ b/codecov.yml @@ -4,3 +4,7 @@ coverage: default: target: auto threshold: 0.25% + patch: + default: + target: auto + threshold: 1% From cdf477dcb1b4197d5861d5dff91856c48dbaae48 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Thu, 11 Jul 2024 11:40:55 -0400 Subject: [PATCH 067/168] fix(minor-ampd): multisig handler supports multiple key types (#504) --- ampd/src/handlers/errors.rs | 2 ++ ampd/src/handlers/multisig.rs | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ampd/src/handlers/errors.rs b/ampd/src/handlers/errors.rs index 876912a3b..bd04d31ef 100644 --- a/ampd/src/handlers/errors.rs +++ b/ampd/src/handlers/errors.rs @@ -10,4 +10,6 @@ pub enum Error { Sign, #[error("failed to get transaction receipts")] TxReceipts, + #[error("unsupported key type {0}")] + KeyType(String), } diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 1540ab235..00c013c0d 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -2,14 +2,15 @@ use std::collections::HashMap; use std::convert::TryInto; use async_trait::async_trait; -use cosmrs::cosmwasm::MsgExecuteContract; -use cosmrs::{tx::Msg, Any}; +use cosmrs::{ + cosmwasm::MsgExecuteContract, + {tx::Msg, Any}, +}; use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::VerifyingKey; -use error_stack::ResultExt; +use error_stack::{Report, ResultExt}; use hex::encode; -use serde::de::Error as DeserializeError; -use serde::{Deserialize, Deserializer}; +use serde::{de::Error as DeserializeError, Deserialize, Deserializer}; use tokio::sync::watch::Receiver; use tracing::info; @@ -20,10 +21,8 @@ use multisig::msg::ExecuteMsg; use crate::event_processor::EventHandler; use crate::handlers::errors::Error::{self, DeserializeEvent}; -use crate::tofnd::grpc::Multisig; -use crate::tofnd::{self, MessageDigest}; -use crate::types::PublicKey; -use crate::types::TMAddress; +use crate::tofnd::{self, grpc::Multisig, MessageDigest}; +use crate::types::{PublicKey, TMAddress}; #[derive(Debug, Deserialize)] #[try_from("wasm-signing_started")] @@ -150,13 +149,19 @@ where match pub_keys.get(&self.verifier) { Some(pub_key) => { + let key_type = match pub_key.type_url() { + PublicKey::ED25519_TYPE_URL => tofnd::Algorithm::Ed25519, + PublicKey::SECP256K1_TYPE_URL => tofnd::Algorithm::Ecdsa, + unspported => return Err(Report::from(Error::KeyType(unspported.to_string()))), + }; + let signature = self .signer .sign( self.multisig.to_string().as_str(), msg.clone(), pub_key, - tofnd::Algorithm::Ecdsa, + key_type, ) .await .change_context(Error::Sign)?; From 02dc15ea63938b3f1db7bcd636e1b818e9c2a524 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 11 Jul 2024 12:16:04 -0400 Subject: [PATCH 068/168] feat(minor-voting-verifier): added the source chain attribute to the PollEnded event (#502) --- contracts/voting-verifier/src/events.rs | 6 ++++++ contracts/voting-verifier/src/execute.rs | 1 + 2 files changed, 7 insertions(+) diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 15da8d871..427c868f5 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -211,6 +211,7 @@ impl From for Event { pub struct PollEnded { pub poll_id: PollId, + pub source_chain: ChainName, pub results: Vec>, } @@ -221,6 +222,11 @@ impl From for Event { "poll_id", serde_json::to_string(&other.poll_id).expect("failed to serialize poll_id"), ) + .add_attribute( + "source_chain", + serde_json::to_string(&other.source_chain) + .expect("failed to serialize source_chain"), + ) .add_attribute( "results", serde_json::to_string(&other.results).expect("failed to serialize results"), diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 618fb1b57..82a44ce88 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -316,6 +316,7 @@ pub fn end_poll(deps: DepsMut, env: Env, poll_id: PollId) -> Result Date: Thu, 11 Jul 2024 14:53:59 -0400 Subject: [PATCH 069/168] fix(router): whitelist nexus gateway to allow routing (#507) --- contracts/router/src/contract.rs | 35 ++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index f72938e8a..68be100fb 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -9,7 +9,7 @@ use crate::contract::migrations::v0_3_3; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; use crate::state; -use crate::state::{load_chain_by_gateway, Config}; +use crate::state::{load_chain_by_gateway, load_config, Config}; use axelar_wasm_std::{permission_control, FnExt}; use router_api::error::Error; use router_api::msg::{ExecuteMsg, QueryMsg}; @@ -109,11 +109,16 @@ pub fn execute( fn find_gateway_address( sender: &Addr, ) -> impl FnOnce(&dyn Storage, &ExecuteMsg) -> error_stack::Result + '_ { - |storage, _| { - load_chain_by_gateway(storage, sender)? - .gateway - .address - .then(Ok) + move |storage, _| { + let nexus_gateway = load_config(storage)?.nexus_gateway; + if nexus_gateway == sender { + Ok(nexus_gateway) + } else { + load_chain_by_gateway(storage, sender)? + .gateway + .address + .then(Ok) + } } } @@ -1731,4 +1736,22 @@ mod test { killswitch::disengage(deps.as_mut().storage, events::RoutingEnabled).unwrap(); assert!(is_enabled(deps.as_ref())); } + + #[test] + fn nexus_can_route_messages() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info(NEXUS_GATEWAY_ADDRESS, &[]), + ExecuteMsg::RouteMessages(generate_messages(ð, &polygon, &mut 0, 10)), + ) + .is_ok()); + } } From c60c1c98dc6331356b983df4bf5ac259d1464c61 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 11 Jul 2024 18:25:49 -0400 Subject: [PATCH 070/168] feat(minor-ampd): support tofnd v1 ed25519 sig encoding (#509) --- Cargo.lock | 9 +++------ Cargo.toml | 1 + README.md | 4 ++-- ampd/Cargo.toml | 3 +-- ampd/src/tofnd/grpc.rs | 20 +++----------------- contracts/coordinator/Cargo.toml | 2 +- integration-tests/Cargo.toml | 2 +- 7 files changed, 12 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bafdfa12..4cfa4e23f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,7 +144,6 @@ dependencies = [ "dirs", "ecdsa", "ed25519 2.2.3", - "ed25519-dalek", "elliptic-curve", "enum-display-derive", "error-stack", @@ -2182,9 +2181,7 @@ dependencies = [ "curve25519-dalek 4.1.3", "ed25519 2.2.3", "rand_core 0.6.4", - "serde", "sha2 0.10.8", - "signature 2.2.0", "subtle", "zeroize", ] @@ -7855,12 +7852,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tofn" -version = "0.2.0" -source = "git+https://github.com/axelarnetwork/tofn.git?branch=update-deps#88285a1ed5f5135aab20ae73e124a8af63087c35" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "255a99b697179124254f23d05c2bc394276ba870791d99a9f5896f7f60d40eb9" dependencies = [ "bincode", "crypto-bigint", - "der 0.7.9", "ecdsa", "ed25519 2.2.3", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index 13bb7d1fb..ad18c6023 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ ethers-core = "2.0.14" tokio = "1.38.0" tokio-stream = "0.1.11" tokio-util = "0.7.11" +tofn = { version = "1.1" } [workspace.lints.clippy] arithmetic_side_effects = "deny" diff --git a/README.md b/README.md index c5ea0e940..14a6fbc39 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The basic rules are as follows: ### Compatibility -For the amplifier preview with version numbers < 1.0.0, please refer to the following compatibility table to select versions of +For the amplifier preview with version numbers < 1.0.0, please refer to the following compatibility table to select versions of contracts and `ampd` that work well together. | Binary | Version | @@ -53,5 +53,5 @@ contracts and `ampd` that work well together. | router | 0.3.3 | | service-registry | 0.4.1 | | voting-verifier | 0.5.0 | -| [tofnd](https://github.com/axelarnetwork/tofnd) | TBD | +| [tofnd](https://github.com/axelarnetwork/tofnd) | v1.0.0 | | [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index faadfd5ba..c8cf4a05e 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -19,8 +19,7 @@ der = { version = "0.7.9", features = ["derive"] } deref-derive = "0.1.0" dirs = "5.0.1" ecdsa = { version = "0.16.6" } -ed25519 ={ version = "2.2.3", features = ["pem"], default-features = false } -ed25519-dalek = { workspace = true } +ed25519 = { version = "2.2.3", default-features = false } enum-display-derive = "0.1.1" error-stack = { workspace = true } ethers-contract = { workspace = true } diff --git a/ampd/src/tofnd/grpc.rs b/ampd/src/tofnd/grpc.rs index 0c934e423..5d385f5a6 100644 --- a/ampd/src/tofnd/grpc.rs +++ b/ampd/src/tofnd/grpc.rs @@ -2,8 +2,6 @@ use std::sync::Arc; use async_trait::async_trait; use cosmrs::tendermint::public_key::PublicKey as TMPublicKey; -use der::{asn1::BitStringRef, Sequence}; -use ed25519::pkcs8::spki::{der::Decode, AlgorithmIdentifierRef}; use error_stack::{Report, ResultExt}; use k256::Secp256k1; use mockall::automock; @@ -119,7 +117,9 @@ impl Multisig for MultisigClient { Algorithm::Ecdsa => ecdsa::Signature::::from_der(&signature) .map(|sig| sig.to_vec()) .change_context(Error::ParsingFailed), - Algorithm::Ed25519 => parse_der_ed25519_signature(&signature), + Algorithm::Ed25519 => ed25519::Signature::from_slice(&signature) + .map(|sig| sig.to_vec()) + .change_context(Error::ParsingFailed), }, SignResponse::Error(error_msg) => { @@ -128,17 +128,3 @@ impl Multisig for MultisigClient { }) } } - -#[derive(Sequence)] -struct Asn1Signature<'a> { - pub signature_algorithm: AlgorithmIdentifierRef<'a>, - pub signature: BitStringRef<'a>, -} - -fn parse_der_ed25519_signature(der_sig: &[u8]) -> Result { - let der_decoded = Asn1Signature::from_der(der_sig).change_context(Error::ParsingFailed)?; - - ed25519_dalek::Signature::from_slice(der_decoded.signature.raw_bytes()) - .map(|s| s.to_vec()) - .change_context(Error::ParsingFailed) -} diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index 00f4874ee..eca1f0e77 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -49,7 +49,7 @@ thiserror = { workspace = true } [dev-dependencies] cw-multi-test = "0.15.1" integration-tests = { workspace = true } -tofn = { git = "https://github.com/axelarnetwork/tofn.git", branch = "update-deps" } +tofn = { workspace = true } [lints] workspace = true diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 4ab645022..aa4c018a5 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -48,7 +48,7 @@ serde = { workspace = true } serde_json = { workspace = true } service-registry = { workspace = true } sha3 = { workspace = true } -tofn = { git = "https://github.com/axelarnetwork/tofn.git", branch = "update-deps" } +tofn = { workspace = true } voting-verifier = { workspace = true } [lints] From 6d4a31bc13098ccce4b17d738c17c6807019d55e Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:22:21 -0600 Subject: [PATCH 071/168] feat(minor-multisig)!: authorize and unauthorize vector of addresses (#497) --- contracts/multisig/src/contract.rs | 293 ++++++++++++++---- contracts/multisig/src/contract/execute.rs | 66 +++- .../src/contract/migrations/v0_4_1.rs | 61 +++- contracts/multisig/src/contract/query.rs | 8 +- contracts/multisig/src/error.rs | 4 + contracts/multisig/src/events.rs | 22 +- contracts/multisig/src/msg.rs | 37 ++- contracts/multisig/src/state.rs | 3 +- integration-tests/tests/test_utils/mod.rs | 7 +- .../axelar-wasm-std/src/permission_control.rs | 4 + 10 files changed, 390 insertions(+), 115 deletions(-) diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 9acef253a..c3d55300f 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -13,9 +13,10 @@ use axelar_wasm_std::{killswitch, permission_control}; use cosmwasm_std::entry_point; use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, - Uint64, + Storage, Uint64, }; -use error_stack::ResultExt; +use error_stack::{report, ResultExt}; +use itertools::Itertools; mod execute; mod migrations; @@ -31,8 +32,18 @@ pub fn migrate( msg: MigrationMsg, ) -> Result { let admin = deps.api.addr_validate(&msg.admin_address)?; - - migrations::v0_4_1::migrate(deps.storage, admin).change_context(ContractError::Migration)?; + let authorized_callers = msg + .authorized_callers + .into_iter() + .map(|(contract_address, chain_name)| { + deps.api + .addr_validate(&contract_address) + .map(|addr| (addr, chain_name)) + }) + .try_collect()?; + + migrations::v0_4_1::migrate(deps.storage, admin, authorized_callers) + .change_context(ContractError::Migration)?; // this needs to be the last thing to do during migration, // because previous migration steps should check the old version @@ -76,16 +87,17 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg.ensure_permissions(deps.storage, &info.sender)? { + match msg.ensure_permissions( + deps.storage, + &info.sender, + can_start_signing_session(&info.sender), + )? { ExecuteMsg::StartSigningSession { verifier_set_id, msg, chain_name, sig_verifier, } => { - // TODO: use new permission model - execute::require_authorized_caller(&deps, info.sender)?; - let sig_verifier = sig_verifier .map(|addr| deps.api.addr_validate(&addr)) .transpose()?; @@ -110,11 +122,27 @@ pub fn execute( public_key, signed_sender_address, } => execute::register_pub_key(deps, info, public_key, signed_sender_address), - ExecuteMsg::AuthorizeCaller { contract_address } => { - execute::authorize_caller(deps, contract_address) + ExecuteMsg::AuthorizeCallers { contracts } => { + let contracts = contracts + .into_iter() + .map(|(contract_address, chain_name)| { + deps.api + .addr_validate(&contract_address) + .map(|addr| (addr, chain_name)) + }) + .try_collect()?; + execute::authorize_callers(deps, contracts) } - ExecuteMsg::UnauthorizeCaller { contract_address } => { - execute::unauthorize_caller(deps, contract_address) + ExecuteMsg::UnauthorizeCallers { contracts } => { + let contracts = contracts + .into_iter() + .map(|(contract_address, chain_name)| { + deps.api + .addr_validate(&contract_address) + .map(|addr| (addr, chain_name)) + }) + .try_collect()?; + execute::unauthorize_callers(deps, contracts) } ExecuteMsg::DisableSigning => execute::disable_signing(deps), ExecuteMsg::EnableSigning => execute::enable_signing(deps), @@ -122,6 +150,19 @@ pub fn execute( .map_err(axelar_wasm_std::ContractError::from) } +fn can_start_signing_session( + sender: &Addr, +) -> impl FnOnce(&dyn Storage, &ExecuteMsg) -> error_stack::Result + '_ +{ + |storage, msg| match msg { + ExecuteMsg::StartSigningSession { chain_name, .. } => { + execute::require_authorized_caller(storage, sender, chain_name) + .change_context(permission_control::Error::Unauthorized) + } + _ => Err(report!(permission_control::Error::WrongVariant)), + } +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { @@ -139,16 +180,21 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { deps.api.addr_validate(&verifier_address)?, key_type, )?), - QueryMsg::IsCallerAuthorized { contract_address } => { - to_json_binary(&query::caller_authorized(deps, contract_address)?) - } + QueryMsg::IsCallerAuthorized { + contract_address, + chain_name, + } => to_json_binary(&query::caller_authorized( + deps, + deps.api.addr_validate(&contract_address)?, + chain_name, + )?), } } #[cfg(feature = "test")] #[cfg(test)] mod tests { - use std::vec; + use std::{collections::HashMap, vec}; use cosmwasm_std::{ from_json, @@ -269,25 +315,35 @@ mod tests { execute(deps, mock_env(), mock_info(verifier.as_str(), &[]), msg) } - fn do_authorize_caller( + fn do_authorize_callers( deps: DepsMut, - contract_address: Addr, + contracts: Vec<(Addr, ChainName)>, ) -> Result { let info = mock_info(GOVERNANCE, &[]); let env = mock_env(); - let msg = ExecuteMsg::AuthorizeCaller { contract_address }; + let msg = ExecuteMsg::AuthorizeCallers { + contracts: contracts + .into_iter() + .map(|(addr, chain_name)| (addr.to_string(), chain_name)) + .collect(), + }; execute(deps, env, info, msg) } fn do_unauthorize_caller( deps: DepsMut, - contract_address: Addr, + contracts: Vec<(Addr, ChainName)>, ) -> Result { let info = mock_info(GOVERNANCE, &[]); let env = mock_env(); - let msg = ExecuteMsg::UnauthorizeCaller { contract_address }; + let msg = ExecuteMsg::UnauthorizeCallers { + contracts: contracts + .into_iter() + .map(|(addr, chain_name)| (addr.to_string(), chain_name)) + .collect(), + }; execute(deps, env, info, msg) } @@ -441,18 +497,18 @@ mod tests { #[test] fn start_signing_session() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (i, subkey) in [ecdsa_subkey.clone(), ed25519_subkey.clone()] .into_iter() .enumerate() { - let res = do_start_signing_session( - deps.as_mut(), - PROVER, - &subkey, - "mock-chain".parse().unwrap(), - ); + let res = do_start_signing_session(deps.as_mut(), PROVER, &subkey, chain_name.clone()); assert!(res.is_ok()); @@ -501,7 +557,12 @@ mod tests { #[test] fn start_signing_session_wrong_sender() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); let sender = "someone else"; @@ -510,22 +571,25 @@ mod tests { deps.as_mut(), sender, &verifier_set_id, - "mock-chain".parse().unwrap(), + chain_name.clone(), ); assert!(res .unwrap_err() .to_string() - .contains(&ContractError::Unauthorized.to_string())); + .contains(&permission_control::Error::Unauthorized.to_string())); } } #[test] fn submit_signature() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); - let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (key_type, verifier_set_id, signers, session_id) in signature_test_data(&ecdsa_subkey, &ed25519_subkey) @@ -591,13 +655,17 @@ mod tests { #[test] fn submit_signature_completes_session() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (key_type, subkey, signers, session_id) in signature_test_data(&ecdsa_subkey, &ed25519_subkey) { - do_start_signing_session(deps.as_mut(), PROVER, subkey, "mock-chain".parse().unwrap()) - .unwrap(); + do_start_signing_session(deps.as_mut(), PROVER, subkey, chain_name.clone()).unwrap(); let signer = signers.first().unwrap().to_owned(); do_sign(deps.as_mut(), mock_env(), session_id, &signer).unwrap(); @@ -644,9 +712,12 @@ mod tests { #[test] fn submit_signature_before_expiry() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); - let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (_key_type, subkey, signers, session_id) in signature_test_data(&ecdsa_subkey, &ed25519_subkey) @@ -690,13 +761,18 @@ mod tests { #[test] fn submit_signature_after_expiry() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (_key_type, subkey, signers, session_id) in signature_test_data(&ecdsa_subkey, &ed25519_subkey) { - do_start_signing_session(deps.as_mut(), PROVER, subkey, "mock-chain".parse().unwrap()) - .unwrap(); + do_start_signing_session(deps.as_mut(), PROVER, subkey, chain_name.clone()).unwrap(); let signer = signers.first().unwrap().to_owned(); do_sign(deps.as_mut(), mock_env(), session_id, &signer).unwrap(); @@ -724,14 +800,13 @@ mod tests { #[test] fn submit_signature_wrong_session_id() { let (mut deps, ecdsa_subkey, _) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); - do_start_signing_session( + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( deps.as_mut(), - PROVER, - &ecdsa_subkey, - "mock-chain".parse().unwrap(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], ) .unwrap(); + do_start_signing_session(deps.as_mut(), PROVER, &ecdsa_subkey, chain_name.clone()).unwrap(); let invalid_session_id = Uint64::zero(); let signer = ecdsa_test_data::signers().first().unwrap().to_owned(); @@ -749,7 +824,12 @@ mod tests { #[test] fn query_signing_session() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (_key_type, subkey, signers, session_id) in signature_test_data(&ecdsa_subkey, &ed25519_subkey) @@ -1019,49 +1099,97 @@ mod tests { } #[test] - fn authorize_and_unauthorize_caller() { + fn authorize_and_unauthorize_callers() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); let prover_address = Addr::unchecked(PROVER); + let chain_name: ChainName = "mock-chain".parse().unwrap(); // authorize - do_authorize_caller(deps.as_mut(), prover_address.clone()).unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(prover_address.clone(), chain_name.clone())], + ) + .unwrap(); for verifier_set_id in [ecdsa_subkey.clone(), ed25519_subkey.clone()] { let res = do_start_signing_session( deps.as_mut(), PROVER, &verifier_set_id, - "mock-chain".parse().unwrap(), + chain_name.clone(), ); assert!(res.is_ok()); } let caller_authorization_status = - query::caller_authorized(deps.as_ref(), prover_address.clone()).unwrap(); + query::caller_authorized(deps.as_ref(), prover_address.clone(), chain_name.clone()) + .unwrap(); assert!(caller_authorization_status); // unauthorize - do_unauthorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); + do_unauthorize_caller( + deps.as_mut(), + vec![(prover_address.clone(), chain_name.clone())], + ) + .unwrap(); for verifier_set_id in [ecdsa_subkey, ed25519_subkey] { let res = do_start_signing_session( deps.as_mut(), PROVER, &verifier_set_id, - "mock-chain".parse().unwrap(), + chain_name.clone(), ); assert!(res .unwrap_err() .to_string() - .contains(&ContractError::Unauthorized.to_string())); + .contains(&permission_control::Error::Unauthorized.to_string())); } let caller_authorization_status = - query::caller_authorized(deps.as_ref(), prover_address).unwrap(); + query::caller_authorized(deps.as_ref(), prover_address, chain_name.clone()).unwrap(); assert!(!caller_authorization_status); } + #[test] + fn authorize_and_unauthorize_many_callers() { + let (mut deps, _, _) = setup(); + + let contracts = vec![ + (Addr::unchecked("addr1"), "chain1".parse().unwrap()), + (Addr::unchecked("addr2"), "chain2".parse().unwrap()), + (Addr::unchecked("addr3"), "chain3".parse().unwrap()), + ]; + do_authorize_callers(deps.as_mut(), contracts.clone()).unwrap(); + assert!(contracts + .iter() + .all(|(addr, chain_name)| query::caller_authorized( + deps.as_ref(), + addr.clone(), + chain_name.clone() + ) + .unwrap())); + let (authorized, unauthorized) = contracts.split_at(1); + do_unauthorize_caller(deps.as_mut(), unauthorized.to_vec()).unwrap(); + assert!(unauthorized + .iter() + .all(|(addr, chain_name)| !query::caller_authorized( + deps.as_ref(), + addr.clone(), + chain_name.clone() + ) + .unwrap())); + assert!(authorized + .iter() + .all(|(addr, chain_name)| query::caller_authorized( + deps.as_ref(), + addr.clone(), + chain_name.clone() + ) + .unwrap())); + } + #[test] fn authorize_caller_wrong_caller() { let mut deps = setup().0; @@ -1069,8 +1197,8 @@ mod tests { let info = mock_info("user", &[]); let env = mock_env(); - let msg = ExecuteMsg::AuthorizeCaller { - contract_address: Addr::unchecked(PROVER), + let msg = ExecuteMsg::AuthorizeCallers { + contracts: HashMap::from([(PROVER.to_string(), "mock-chain".parse().unwrap())]), }; let res = execute(deps.as_mut(), env, info, msg); @@ -1091,15 +1219,15 @@ mod tests { let info = mock_info("user", &[]); let env = mock_env(); - let msg = ExecuteMsg::UnauthorizeCaller { - contract_address: Addr::unchecked(PROVER), + let msg = ExecuteMsg::UnauthorizeCallers { + contracts: HashMap::from([(PROVER.to_string(), "mock-chain".parse().unwrap())]), }; let res = execute(deps.as_mut(), env, info, msg); assert_eq!( res.unwrap_err().to_string(), axelar_wasm_std::permission_control::Error::PermissionDenied { - expected: Permission::Governance.into(), + expected: Permission::Elevated.into(), actual: Permission::NoPrivilege.into() } .to_string() @@ -1110,9 +1238,14 @@ mod tests { fn disable_enable_signing() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); let prover_address = Addr::unchecked(PROVER); + let chain_name: ChainName = "mock-chain".parse().unwrap(); // authorize - do_authorize_caller(deps.as_mut(), prover_address.clone()).unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(prover_address.clone(), chain_name.clone())], + ) + .unwrap(); do_disable_signing(deps.as_mut(), ADMIN).unwrap(); @@ -1121,7 +1254,7 @@ mod tests { deps.as_mut(), PROVER, &verifier_set_id, - "mock-chain".parse().unwrap(), + chain_name.clone(), ); assert_eq!( @@ -1147,9 +1280,12 @@ mod tests { #[test] fn disable_signing_after_session_creation() { let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); - do_authorize_caller(deps.as_mut(), Addr::unchecked(PROVER)).unwrap(); - let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); for (_, verifier_set_id, signers, session_id) in signature_test_data(&ecdsa_subkey, &ed25519_subkey) @@ -1184,4 +1320,33 @@ mod tests { assert!(do_disable_signing(deps.as_mut(), GOVERNANCE).is_ok()); assert!(do_enable_signing(deps.as_mut(), GOVERNANCE).is_ok()); } + + #[test] + fn start_signing_session_wrong_chain() { + let (mut deps, ecdsa_subkey, ed25519_subkey) = setup(); + let chain_name: ChainName = "mock-chain".parse().unwrap(); + do_authorize_callers( + deps.as_mut(), + vec![(Addr::unchecked(PROVER), chain_name.clone())], + ) + .unwrap(); + + let wrong_chain_name: ChainName = "some-other-chain".parse().unwrap(); + + for verifier_set_id in [ecdsa_subkey, ed25519_subkey] { + let res = do_start_signing_session( + deps.as_mut(), + PROVER, + &verifier_set_id, + wrong_chain_name.clone(), + ); + + assert!(res.unwrap_err().to_string().contains( + &ContractError::WrongChainName { + expected: chain_name.clone() + } + .to_string() + )); + } + } } diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index 96c42b107..e3617e0f6 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -1,4 +1,6 @@ -use cosmwasm_std::{ensure, OverflowError, OverflowOperation, WasmMsg}; +use std::collections::HashMap; + +use cosmwasm_std::{ensure, OverflowError, OverflowOperation, Storage, WasmMsg}; use router_api::ChainName; use sha3::{Digest, Keccak256}; use signature_verifier_api::client::SignatureVerifier; @@ -11,7 +13,6 @@ use crate::{ signing::SigningSession, state::AUTHORIZED_CALLERS, }; -use error_stack::ResultExt; use super::*; @@ -182,27 +183,58 @@ pub fn register_pub_key( } pub fn require_authorized_caller( - deps: &DepsMut, - contract_address: Addr, -) -> error_stack::Result<(), ContractError> { - AUTHORIZED_CALLERS - .load(deps.storage, &contract_address) - .change_context(ContractError::Unauthorized) + storage: &dyn Storage, + contract_address: &Addr, + chain_name: &ChainName, +) -> Result { + let expected_chain_name = AUTHORIZED_CALLERS.load(storage, contract_address)?; + if expected_chain_name != *chain_name { + return Err(ContractError::WrongChainName { + expected: expected_chain_name, + }); + } + Ok(contract_address.clone()) } -pub fn authorize_caller(deps: DepsMut, contract_address: Addr) -> Result { - AUTHORIZED_CALLERS.save(deps.storage, &contract_address, &())?; - - Ok(Response::new().add_event(Event::CallerAuthorized { contract_address }.into())) +pub fn authorize_callers( + deps: DepsMut, + contracts: HashMap, +) -> Result { + contracts + .iter() + .map(|(contract_address, chain_name)| { + AUTHORIZED_CALLERS.save(deps.storage, contract_address, chain_name) + }) + .try_collect()?; + + Ok( + Response::new().add_events(contracts.into_iter().map(|(contract_address, chain_name)| { + Event::CallerAuthorized { + contract_address, + chain_name, + } + .into() + })), + ) } -pub fn unauthorize_caller( +pub fn unauthorize_callers( deps: DepsMut, - contract_address: Addr, + contracts: Vec<(Addr, ChainName)>, ) -> Result { - AUTHORIZED_CALLERS.remove(deps.storage, &contract_address); - - Ok(Response::new().add_event(Event::CallerUnauthorized { contract_address }.into())) + contracts.iter().for_each(|(contract_address, _)| { + AUTHORIZED_CALLERS.remove(deps.storage, contract_address) + }); + + Ok( + Response::new().add_events(contracts.into_iter().map(|(contract_address, chain_name)| { + Event::CallerUnauthorized { + contract_address, + chain_name, + } + .into() + })), + ) } pub fn enable_signing(deps: DepsMut) -> Result { diff --git a/contracts/multisig/src/contract/migrations/v0_4_1.rs b/contracts/multisig/src/contract/migrations/v0_4_1.rs index f71f1a8f9..1501a6366 100644 --- a/contracts/multisig/src/contract/migrations/v0_4_1.rs +++ b/contracts/multisig/src/contract/migrations/v0_4_1.rs @@ -4,8 +4,11 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdError, Storage}; use cw2::VersionError; use cw_storage_plus::Item; +use itertools::Itertools; +use router_api::ChainName; use crate::contract::CONTRACT_NAME; +use crate::state::AUTHORIZED_CALLERS; use axelar_wasm_std::killswitch::State; use axelar_wasm_std::{killswitch, nonempty, permission_control}; @@ -21,7 +24,11 @@ pub enum Error { NonEmpty(#[from] nonempty::Error), } -pub fn migrate(storage: &mut dyn Storage, admin: Addr) -> Result<(), Error> { +pub fn migrate( + storage: &mut dyn Storage, + admin: Addr, + authorized_callers: Vec<(Addr, ChainName)>, +) -> Result<(), Error> { cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; killswitch::init(storage, State::Disengaged)?; @@ -30,6 +37,21 @@ pub fn migrate(storage: &mut dyn Storage, admin: Addr) -> Result<(), Error> { permission_control::set_governance(storage, &config.governance)?; permission_control::set_admin(storage, &admin)?; migrate_config(storage, config)?; + migrate_authorized_callers(storage, authorized_callers)?; + Ok(()) +} + +fn migrate_authorized_callers( + storage: &mut dyn Storage, + authorized_callers: Vec<(Addr, ChainName)>, +) -> Result<(), Error> { + AUTHORIZED_CALLERS.clear(storage); + authorized_callers + .iter() + .map(|(contract_address, chain_name)| { + AUTHORIZED_CALLERS.save(storage, contract_address, chain_name) + }) + .try_collect()?; Ok(()) } @@ -71,10 +93,11 @@ mod tests { use cosmwasm_std::{Addr, DepsMut, Env, HexBinary, MessageInfo, Response, Uint64}; use axelar_wasm_std::nonempty; + use router_api::ChainName; use crate::contract::migrations::v0_4_1; use crate::contract::migrations::v0_4_1::BASE_VERSION; - use crate::contract::{execute, CONTRACT_NAME}; + use crate::contract::{execute, query, CONTRACT_NAME}; use crate::msg::ExecuteMsg::{DisableSigning, SubmitSignature}; use crate::state::SIGNING_SESSION_COUNTER; use crate::ContractError; @@ -96,11 +119,11 @@ mod tests { cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); - assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_err()); + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin"), vec![]).is_err()); cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, BASE_VERSION).unwrap(); - assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_ok()); + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin"), vec![]).is_ok()); } #[test] @@ -118,7 +141,7 @@ mod tests { ) .unwrap(); - assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_ok()); + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin"), vec![]).is_ok()); assert!(v0_4_1::CONFIG.load(deps.as_mut().storage).is_err()); @@ -146,7 +169,7 @@ mod tests { ) .unwrap(); - assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin")).is_ok()); + assert!(v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin"), vec![]).is_ok()); // contract is enabled assert!(!execute( @@ -199,6 +222,32 @@ mod tests { .contains(&ContractError::SigningDisabled.to_string())); } + #[test] + fn callers_are_authorized() { + let mut deps = mock_dependencies(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: "governance".to_string(), + rewards_address: "rewards".to_string(), + block_expiry: 100, + }, + ) + .unwrap(); + + let prover = Addr::unchecked("prover1"); + let chain_name: ChainName = "mock-chain".parse().unwrap(); + assert!(v0_4_1::migrate( + deps.as_mut().storage, + Addr::unchecked("admin"), + vec![(prover.clone(), chain_name.clone())] + ) + .is_ok()); + assert!(query::caller_authorized(deps.as_ref(), prover, chain_name).unwrap()); + } + #[deprecated(since = "0.4.1", note = "only used to test migration")] fn instantiate( deps: DepsMut, diff --git a/contracts/multisig/src/contract/query.rs b/contracts/multisig/src/contract/query.rs index b6a900ed6..e032e9c8c 100644 --- a/contracts/multisig/src/contract/query.rs +++ b/contracts/multisig/src/contract/query.rs @@ -1,3 +1,5 @@ +use router_api::ChainName; + use crate::{ key::{KeyType, PublicKey}, multisig::Multisig, @@ -29,9 +31,7 @@ pub fn get_public_key(deps: Deps, verifier: Addr, key_type: KeyType) -> StdResul Ok(PublicKey::try_from((key_type, raw)).expect("could not decode pub key")) } -pub fn caller_authorized(deps: Deps, address: Addr) -> StdResult { - let is_authorized = AUTHORIZED_CALLERS - .may_load(deps.storage, &address)? - .is_some(); +pub fn caller_authorized(deps: Deps, address: Addr, chain_name: ChainName) -> StdResult { + let is_authorized = AUTHORIZED_CALLERS.may_load(deps.storage, &address)? == Some(chain_name); Ok(is_authorized) } diff --git a/contracts/multisig/src/error.rs b/contracts/multisig/src/error.rs index 013fffa48..5efa1786a 100644 --- a/contracts/multisig/src/error.rs +++ b/contracts/multisig/src/error.rs @@ -1,6 +1,7 @@ use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::{OverflowError, StdError, Uint64}; use cw2::VersionError; +use router_api::ChainName; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] @@ -67,4 +68,7 @@ pub enum ContractError { #[error("signing is disabled")] SigningDisabled, + + #[error("specified chain name is incorrect. expected: {expected}")] + WrongChainName { expected: ChainName }, } diff --git a/contracts/multisig/src/events.rs b/contracts/multisig/src/events.rs index 935743824..cf6a4b884 100644 --- a/contracts/multisig/src/events.rs +++ b/contracts/multisig/src/events.rs @@ -36,9 +36,11 @@ pub enum Event { }, CallerAuthorized { contract_address: Addr, + chain_name: ChainName, }, CallerUnauthorized { contract_address: Addr, + chain_name: ChainName, }, SigningEnabled, SigningDisabled, @@ -91,14 +93,18 @@ impl From for cosmwasm_std::Event { "public_key", to_string(&public_key).expect("failed to serialize public key"), ), - Event::CallerAuthorized { contract_address } => { - cosmwasm_std::Event::new("caller_authorized") - .add_attribute("contract_address", contract_address) - } - Event::CallerUnauthorized { contract_address } => { - cosmwasm_std::Event::new("caller_unauthorized") - .add_attribute("contract_address", contract_address) - } + Event::CallerAuthorized { + contract_address, + chain_name, + } => cosmwasm_std::Event::new("caller_authorized") + .add_attribute("contract_address", contract_address) + .add_attribute("chain_name", chain_name), + Event::CallerUnauthorized { + contract_address, + chain_name, + } => cosmwasm_std::Event::new("caller_unauthorized") + .add_attribute("contract_address", contract_address) + .add_attribute("chain_name", chain_name), Event::SigningEnabled => cosmwasm_std::Event::new("signing_enabled"), Event::SigningDisabled => cosmwasm_std::Event::new("signing_disabled"), } diff --git a/contracts/multisig/src/msg.rs b/contracts/multisig/src/msg.rs index fe862673a..d875817ed 100644 --- a/contracts/multisig/src/msg.rs +++ b/contracts/multisig/src/msg.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use axelar_wasm_std::nonempty; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, HexBinary, Uint128, Uint64}; @@ -13,23 +15,25 @@ use crate::{ #[cw_serde] pub struct MigrationMsg { pub admin_address: String, + pub authorized_callers: HashMap, } #[cw_serde] pub struct InstantiateMsg { - // the governance address is allowed to modify the authorized caller list for this contract + /// the governance address is allowed to modify the authorized caller list for this contract pub governance_address: String, - // The admin address (or governance) is allowed to disable signing. Only governance can re-enable + /// The admin address (or governance) is allowed to disable signing and enable signing pub admin_address: String, pub rewards_address: String, - pub block_expiry: nonempty::Uint64, // number of blocks after which a signing session expires + /// number of blocks after which a signing session expires + pub block_expiry: nonempty::Uint64, } #[cw_serde] #[derive(EnsurePermissions)] pub enum ExecuteMsg { - // Can only be called by an authorized contract. - #[permission(Any)] + /// Can only be called by an authorized contract. + #[permission(Specific(authorized))] StartSigningSession { verifier_set_id: String, msg: HexBinary, @@ -52,16 +56,20 @@ pub enum ExecuteMsg { #[permission(Any)] RegisterPublicKey { public_key: PublicKey, - /* To prevent anyone from registering a public key that belongs to someone else, we require the sender - to sign their own address using the private key */ + /// To prevent anyone from registering a public key that belongs to someone else, we require the sender + /// to sign their own address using the private key signed_sender_address: HexBinary, }, - // Authorizes a contract to call StartSigningSession. Callable only by governance + /// Authorizes a set of contracts to call StartSigningSession. #[permission(Governance)] - AuthorizeCaller { contract_address: Addr }, - // Unauthorizes a contract, so it can no longer call StartSigningSession. Callable only by governance - #[permission(Governance)] - UnauthorizeCaller { contract_address: Addr }, + AuthorizeCallers { + contracts: HashMap, + }, + /// Unauthorizes a set of contracts, so they can no longer call StartSigningSession. + #[permission(Elevated)] + UnauthorizeCallers { + contracts: HashMap, + }, /// Emergency command to stop all amplifier signing #[permission(Elevated)] @@ -88,7 +96,10 @@ pub enum QueryMsg { }, #[returns(bool)] - IsCallerAuthorized { contract_address: Addr }, + IsCallerAuthorized { + contract_address: String, + chain_name: ChainName, + }, } #[cw_serde] diff --git a/contracts/multisig/src/state.rs b/contracts/multisig/src/state.rs index 8cd4ba7f9..a8a8e2d72 100644 --- a/contracts/multisig/src/state.rs +++ b/contracts/multisig/src/state.rs @@ -10,6 +10,7 @@ use axelar_wasm_std::nonempty; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Order, StdResult, Storage, Uint64}; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; +use router_api::ChainName; #[cw_serde] pub struct Config { @@ -110,7 +111,7 @@ pub fn save_pub_key( } // The keys represent the addresses that can start a signing session. -pub const AUTHORIZED_CALLERS: Map<&Addr, ()> = Map::new("authorized_callers"); +pub const AUTHORIZED_CALLERS: Map<&Addr, ChainName> = Map::new("authorized_callers"); #[cfg(test)] mod tests { diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index c785bd9fa..6b2c7d94e 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -684,8 +684,11 @@ pub fn setup_chain( let response = protocol.multisig.execute( &mut protocol.app, protocol.governance_address.clone(), - &multisig::msg::ExecuteMsg::AuthorizeCaller { - contract_address: multisig_prover.contract_addr.clone(), + &multisig::msg::ExecuteMsg::AuthorizeCallers { + contracts: HashMap::from([( + multisig_prover.contract_addr.to_string(), + chain_name.clone(), + )]), }, ); assert!(response.is_ok()); diff --git a/packages/axelar-wasm-std/src/permission_control.rs b/packages/axelar-wasm-std/src/permission_control.rs index 7693cbc65..047be9469 100644 --- a/packages/axelar-wasm-std/src/permission_control.rs +++ b/packages/axelar-wasm-std/src/permission_control.rs @@ -47,6 +47,10 @@ pub enum Error { AddressNotWhitelisted { expected: Vec, actual: Addr }, #[error("no whitelisting condition found for sender address '{sender}'")] WhitelistNotFound { sender: Addr }, + #[error("specific check called on wrong enum variant")] + WrongVariant, + #[error("sender is not authorized")] + Unauthorized, // generic error to handle errors that don't fall into the above cases } const ADMIN: Item = Item::new("permission_control_contract_admin_addr"); From 95257b06cddcb882e95260824dc7d18025dd7c32 Mon Sep 17 00:00:00 2001 From: eguajardo Date: Fri, 12 Jul 2024 09:45:24 -0600 Subject: [PATCH 072/168] feat(coordinator): add registered provers migration to new state (#506) --- contracts/coordinator/src/contract.rs | 13 +++- .../src/contract/migrations/mod.rs | 1 + .../src/contract/migrations/v0_2_0.rs | 66 ++++++++++++++++++- contracts/coordinator/src/state.rs | 9 ++- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index ce6e01f9c..9246c3d98 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -5,13 +5,14 @@ mod migrations; use crate::contract::migrations::v0_2_0; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::load_chain_by_prover; -use axelar_wasm_std::{permission_control, FnExt}; +use crate::state::is_prover_registered; +use axelar_wasm_std::permission_control; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, }; +use error_stack::report; pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -72,7 +73,13 @@ pub fn execute( fn find_prover_address( sender: &Addr, ) -> impl FnOnce(&dyn Storage, &ExecuteMsg) -> error_stack::Result + '_ { - |storage, _| load_chain_by_prover(storage, sender.clone())?.then(Ok) + |storage, _| { + if is_prover_registered(storage, sender.clone())? { + Ok(sender.clone()) + } else { + Err(report!(ContractError::ProverNotRegistered)) + } + } } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/coordinator/src/contract/migrations/mod.rs b/contracts/coordinator/src/contract/migrations/mod.rs index f12a530a4..693d0ab24 100644 --- a/contracts/coordinator/src/contract/migrations/mod.rs +++ b/contracts/coordinator/src/contract/migrations/mod.rs @@ -1 +1,2 @@ +#[allow(deprecated)] pub mod v0_2_0; diff --git a/contracts/coordinator/src/contract/migrations/v0_2_0.rs b/contracts/coordinator/src/contract/migrations/v0_2_0.rs index c073ca915..825cbbd84 100644 --- a/contracts/coordinator/src/contract/migrations/v0_2_0.rs +++ b/contracts/coordinator/src/contract/migrations/v0_2_0.rs @@ -1,9 +1,10 @@ -use crate::contract::CONTRACT_NAME; use crate::error::ContractError; +use crate::{contract::CONTRACT_NAME, state::save_prover_for_chain}; use axelar_wasm_std::permission_control; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; -use cw_storage_plus::Item; +use cw_storage_plus::{Item, Map}; +use router_api::ChainName; const BASE_VERSION: &str = "0.2.0"; @@ -11,6 +12,7 @@ pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; migrate_config_to_permission_control(storage)?; + migrate_registered_provers(storage)?; Ok(()) } @@ -21,23 +23,42 @@ fn migrate_config_to_permission_control(storage: &mut dyn Storage) -> Result<(), Ok(()) } +fn migrate_registered_provers(storage: &mut dyn Storage) -> Result<(), ContractError> { + PROVER_PER_CHAIN + .range(storage, None, None, cosmwasm_std::Order::Ascending) + .collect::, _>>()? + .into_iter() + .try_for_each(|(chain, prover)| save_prover_for_chain(storage, chain, prover))?; + + PROVER_PER_CHAIN.clear(storage); + Ok(()) +} + #[cw_serde] +#[deprecated(since = "0.2.0", note = "only used to test the migration")] pub struct Config { pub governance: Addr, } +#[deprecated(since = "0.2.0", note = "only used to test the migration")] pub const CONFIG: Item = Item::new("config"); +#[deprecated(since = "0.2.0", note = "only used to test the migration")] +pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); + #[cfg(test)] -#[allow(deprecated)] mod tests { use crate::contract::migrations::v0_2_0; use crate::contract::migrations::v0_2_0::BASE_VERSION; use crate::contract::{execute, CONTRACT_NAME}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg}; + use crate::state::{is_prover_registered, load_prover_by_chain}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; + use router_api::ChainName; + + use super::PROVER_PER_CHAIN; #[test] fn migrate_checks_contract_version() { @@ -87,6 +108,35 @@ mod tests { assert!(v0_2_0::CONFIG.may_load(&deps.storage).unwrap().is_none()) } + #[test] + fn ensure_registered_provers_are_migrated() { + let mut deps = mock_dependencies(); + instantiate_0_2_0_contract(deps.as_mut()).unwrap(); + + let provers: Vec<(ChainName, Addr)> = vec![ + ("chain1".parse().unwrap(), Addr::unchecked("addr1")), + ("chain2".parse().unwrap(), Addr::unchecked("addr2")), + ]; + + for (chain, prover) in &provers { + register_prover_0_2_0(deps.as_mut(), chain.clone(), prover.clone()).unwrap(); + } + + assert!(v0_2_0::migrate(deps.as_mut().storage).is_ok()); + + for (chain, prover) in provers { + assert_eq!( + load_prover_by_chain(deps.as_ref().storage, chain).unwrap(), + prover.clone() + ); + + // check index is working as well + assert!(is_prover_registered(deps.as_ref().storage, prover).unwrap()); + } + + assert!(PROVER_PER_CHAIN.is_empty(deps.as_ref().storage)); + } + fn instantiate_0_2_0_contract( deps: DepsMut, ) -> Result { @@ -116,4 +166,14 @@ mod tests { )?; Ok(Response::default()) } + + #[deprecated(since = "0.2.0", note = "only used to test the migration")] + fn register_prover_0_2_0( + deps: DepsMut, + chain_name: ChainName, + new_prover_addr: Addr, + ) -> Result { + PROVER_PER_CHAIN.save(deps.storage, chain_name.clone(), &(new_prover_addr))?; + Ok(Response::new()) + } } diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index cff86be3f..a1b9510e8 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -21,16 +21,15 @@ const CHAIN_PROVER_INDEXED_MAP: IndexedMap Result { - CHAIN_PROVER_INDEXED_MAP +) -> Result { + Ok(CHAIN_PROVER_INDEXED_MAP .idx .by_prover .item(storage, prover_address)? - .map(|(_, r)| r) - .ok_or(ContractError::ProverNotRegistered) + .is_some()) } #[allow(dead_code)] // Used in tests, might be useful in future query From 3a184af756addf2b2e4ed2797933a0e583a6d0f4 Mon Sep 17 00:00:00 2001 From: Sammy Date: Fri, 12 Jul 2024 13:15:20 -0400 Subject: [PATCH 073/168] feat(ampd): sui verify verifier set confirmation (#501) --- ampd/src/sui/verifier.rs | 310 +++++++++++++++++++++---- contracts/multisig/src/key.rs | 4 +- contracts/multisig/src/verifier_set.rs | 2 +- 3 files changed, 266 insertions(+), 50 deletions(-) diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index b31634685..f44349dd8 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -1,6 +1,9 @@ -use axelar_wasm_std::voting::Vote; +use std::collections::HashMap; + +use axelar_wasm_std::{self, voting::Vote}; +use cosmwasm_std::HexBinary; use move_core_types::language_storage::StructTag; -use serde::Deserialize; +use serde::{de::Error, Deserialize, Deserializer}; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockResponse}; use sui_types::base_types::SuiAddress; @@ -8,6 +11,56 @@ use crate::handlers::sui_verify_msg::Message; use crate::handlers::sui_verify_verifier_set::VerifierSetConfirmation; use crate::types::Hash; +fn deserialize_from_str<'de, D, R>(deserializer: D) -> Result +where + D: Deserializer<'de>, + R: std::str::FromStr, + R::Err: std::fmt::Display, +{ + let string: String = Deserialize::deserialize(deserializer)?; + + R::from_str(&string).map_err(D::Error::custom) +} + +fn deserialize_sui_bytes<'de, D, const LENGTH: usize>( + deserializer: D, +) -> Result<[u8; LENGTH], D::Error> +where + D: Deserializer<'de>, +{ + let bytes: HashMap = Deserialize::deserialize(deserializer)?; + let hex = bytes + .get("bytes") + .ok_or_else(|| D::Error::custom("missing bytes"))? + .trim_start_matches("0x"); + + hex::decode(hex) + .map_err(D::Error::custom)? + .try_into() + .map_err(|_| D::Error::custom(format!("failed deserialize into [u8; {}]", LENGTH))) +} + +#[derive(Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)] +struct WeightedSigner { + pub_key: Vec, + #[serde(deserialize_with = "deserialize_from_str")] + weight: u128, +} + +#[derive(Deserialize, Debug)] +struct WeightedSigners { + signers: Vec, + #[serde(deserialize_with = "deserialize_from_str")] + threshold: u128, + #[serde(deserialize_with = "deserialize_sui_bytes")] + nonce: [u8; 32], +} + +#[derive(Deserialize, Debug)] +struct SignersRotated { + signers: WeightedSigners, +} + #[derive(Deserialize)] struct ContractCall { pub source_id: SuiAddress, @@ -16,15 +69,9 @@ struct ContractCall { pub payload_hash: Hash, } -#[derive(Deserialize)] -struct OperatorshipTransferred { - #[allow(dead_code)] - pub payload: Vec, -} - enum EventType { ContractCall, - OperatorshipTransferred, + SignersRotated, } impl EventType { @@ -32,12 +79,12 @@ impl EventType { fn struct_tag(&self, gateway_address: &SuiAddress) -> StructTag { let event = match self { EventType::ContractCall => "ContractCall", - EventType::OperatorshipTransferred => "OperatorshipTransferred", + EventType::SignersRotated => "SignersRotated", }; let module = match self { EventType::ContractCall => "gateway", - EventType::OperatorshipTransferred => "validators", + EventType::SignersRotated => "auth", }; format!("{}::{}::{}", gateway_address, module, event) @@ -49,11 +96,16 @@ impl EventType { impl PartialEq<&Message> for &SuiEvent { fn eq(&self, msg: &&Message) -> bool { match serde_json::from_value::(self.parsed_json.clone()) { - Ok(contract_call) => { - contract_call.source_id == msg.source_address - && msg.destination_chain == contract_call.destination_chain - && contract_call.destination_address == msg.destination_address - && contract_call.payload_hash == msg.payload_hash + Ok(ContractCall { + source_id, + destination_chain, + destination_address, + payload_hash, + }) => { + msg.source_address == source_id + && msg.destination_chain == destination_chain + && msg.destination_address == destination_address + && msg.payload_hash == payload_hash } _ => false, } @@ -61,11 +113,38 @@ impl PartialEq<&Message> for &SuiEvent { } impl PartialEq<&VerifierSetConfirmation> for &SuiEvent { - fn eq(&self, _verifier_set: &&VerifierSetConfirmation) -> bool { - match serde_json::from_value::(self.parsed_json.clone()) { - Ok(_event) => { - // TODO: convert verifier set to Sui gateway V2 WeightedSigners struct - todo!() + fn eq(&self, verifier_set: &&VerifierSetConfirmation) -> bool { + let expected = &verifier_set.verifier_set; + + let mut expected_signers = expected + .signers + .values() + .map(|signer| WeightedSigner { + pub_key: HexBinary::from(signer.pub_key.clone()).to_vec(), + weight: signer.weight.u128(), + }) + .collect::>(); + expected_signers.sort(); + + let expected_created_at = [0u8; 24] + .into_iter() + .chain(expected.created_at.to_be_bytes()) + .collect::>(); + + match serde_json::from_value::(self.parsed_json.clone()) { + Ok(SignersRotated { + signers: + WeightedSigners { + mut signers, + threshold, + nonce, + }, + }) => { + signers.sort(); + + signers == expected_signers + && threshold == expected.threshold.u128() + && nonce.as_slice() == expected_created_at.as_slice() } _ => false, } @@ -109,8 +188,7 @@ pub fn verify_verifier_set( match find_event(transaction_block, confirmation.event_index as u64) { Some(event) if transaction_block.digest == confirmation.tx_id - && event.type_ - == EventType::OperatorshipTransferred.struct_tag(gateway_address) + && event.type_ == EventType::SignersRotated.struct_tag(gateway_address) && event == confirmation => { Vote::SucceededOnChain @@ -121,12 +199,14 @@ pub fn verify_verifier_set( #[cfg(test)] mod tests { - use std::collections::BTreeMap; - - use cosmwasm_std::Uint128; + use cosmrs::crypto::PublicKey; + use cosmwasm_std::{Addr, HexBinary, Uint128}; + use ecdsa::SigningKey; use ethers_core::abi::AbiEncode; use move_core_types::language_storage::StructTag; + use rand::rngs::OsRng; use random_string::generate; + use serde_json::json; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockEvents, SuiTransactionBlockResponse}; use sui_types::{ base_types::{SuiAddress, TransactionDigest}, @@ -134,14 +214,15 @@ mod tests { }; use axelar_wasm_std::voting::Vote; - use multisig::verifier_set::VerifierSet; + use multisig::{key::KeyType, msg::Signer, verifier_set::VerifierSet}; use router_api::ChainName; - use crate::handlers::{ - sui_verify_msg::Message, sui_verify_verifier_set::VerifierSetConfirmation, - }; use crate::sui::verifier::{verify_message, verify_verifier_set}; use crate::types::{EVMAddress, Hash}; + use crate::{ + handlers::{sui_verify_msg::Message, sui_verify_verifier_set::VerifierSetConfirmation}, + PREFIX, + }; #[test] fn should_not_verify_msg_if_tx_id_does_not_match() { @@ -218,17 +299,118 @@ mod tests { ); } - #[ignore = "TODO: remove ignore once integrated with Sui gateway v2"] #[test] - fn should_verify_verifier_set() { - let (gateway_address, tx_receipt, verifier_set) = get_matching_verifier_set_and_tx_block(); + fn should_verify_verifier_set_if_correct() { + let (gateway_address, tx_block, verifier_set) = get_matching_verifier_set_and_tx_block(); assert_eq!( - verify_verifier_set(&gateway_address, &tx_receipt, &verifier_set), + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), Vote::SucceededOnChain ); } + #[test] + fn should_not_verify_verifier_set_if_gateway_address_mismatch() { + let (_, tx_block, verifier_set) = get_matching_verifier_set_and_tx_block(); + + assert_eq!( + verify_verifier_set( + &SuiAddress::random_for_testing_only(), + &tx_block, + &verifier_set + ), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_tx_digest_mismatch() { + let (gateway_address, mut tx_block, verifier_set) = + get_matching_verifier_set_and_tx_block(); + tx_block.digest = TransactionDigest::random(); + + assert_eq!( + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_event_seq_mismatch() { + let (gateway_address, tx_block, mut verifier_set) = + get_matching_verifier_set_and_tx_block(); + verifier_set.event_index = rand::random(); + + assert_eq!( + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_struct_tag_mismatch() { + let (gateway_address, mut tx_block, verifier_set) = + get_matching_verifier_set_and_tx_block(); + tx_block + .events + .as_mut() + .unwrap() + .data + .first_mut() + .unwrap() + .type_ = StructTag { + address: SuiAddress::random_for_testing_only().into(), + module: "module".parse().unwrap(), + name: "Name".parse().unwrap(), + type_params: vec![], + }; + + assert_eq!( + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_threshold_mismatch() { + let (gateway_address, tx_block, mut verifier_set) = + get_matching_verifier_set_and_tx_block(); + verifier_set.verifier_set.threshold = Uint128::new(2); + + assert_eq!( + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_nonce_mismatch() { + let (gateway_address, tx_block, mut verifier_set) = + get_matching_verifier_set_and_tx_block(); + verifier_set.verifier_set.created_at = rand::random(); + + assert_eq!( + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_signers_mismatch() { + let (gateway_address, tx_block, mut verifier_set) = + get_matching_verifier_set_and_tx_block(); + let signer = random_signer(); + verifier_set + .verifier_set + .signers + .insert(signer.address.to_string(), signer); + + assert_eq!( + verify_verifier_set(&gateway_address, &tx_block, &verifier_set), + Vote::NotFound + ); + } + fn get_matching_msg_and_tx_block() -> (SuiAddress, SuiTransactionBlockResponse, Message) { let gateway_address = SuiAddress::random_for_testing_only(); @@ -279,28 +461,62 @@ mod tests { (gateway_address, tx_block, msg) } + fn random_signer() -> Signer { + let priv_key = SigningKey::random(&mut OsRng); + let pub_key: PublicKey = priv_key.verifying_key().into(); + let address = Addr::unchecked(pub_key.account_id(PREFIX).unwrap()); + let pub_key = (KeyType::Ecdsa, HexBinary::from(pub_key.to_bytes())) + .try_into() + .unwrap(); + + Signer { + address, + weight: Uint128::one(), + pub_key, + } + } + fn get_matching_verifier_set_and_tx_block() -> ( SuiAddress, SuiTransactionBlockResponse, VerifierSetConfirmation, ) { let gateway_address = SuiAddress::random_for_testing_only(); - + let signers = vec![random_signer(), random_signer(), random_signer()]; + let created_at = rand::random(); + let threshold = Uint128::one(); let verifier_set_confirmation = VerifierSetConfirmation { tx_id: TransactionDigest::random(), - event_index: rand::random::(), + event_index: rand::random(), verifier_set: VerifierSet { - signers: BTreeMap::new(), - threshold: Uint128::one(), - created_at: 2, + signers: signers + .iter() + .map(|signer| (signer.address.to_string(), signer.clone())) + .collect(), + threshold, + created_at, }, }; - let json_str = format!( - r#"{{"epoch": "{}", "payload":[9,33,2,28,79,35,229,96,199,254,112,157,252,157,33,86,76,80,174,125,71,132,149,100,185,195,50,28,56,168,173,27,148,211,13,33,2,48,84,180,104,180,217,232,81,68,34,87,5,170,93,208,110,70,34,106,18,170,230,232,84,177,96,70,223,39,33,69,243,33,2,111,165,50,83,196,229,202,139,167,22,144,71,12,136,118,134,248,101,250,219,73,67,12,46,149,223,204,58,134,78,12,140,33,2,117,97,196,77,216,94,31,8,169,159,77,164,26,249,18,252,106,73,134,164,49,179,32,156,241,200,236,219,119,96,154,174,33,2,211,238,247,108,49,105,73,69,232,85,66,59,29,114,68,216,13,187,208,76,45,190,112,127,63,78,201,189,207,232,137,80,33,2,253,243,145,109,216,125,193,53,124,210,124,157,62,195,2,187,26,78,51,29,236,222,0,247,71,157,177,44,59,201,201,110,33,3,13,71,41,67,81,196,128,14,128,66,129,231,226,77,127,173,123,58,83,198,102,149,143,165,189,207,7,26,146,127,120,223,33,3,179,111,82,200,141,104,219,127,177,163,157,28,106,41,141,191,105,54,200,199,63,140,125,57,134,20,90,19,183,153,55,68,33,3,250,161,172,32,115,91,220,86,71,57,15,155,185,167,99,209,57,194,132,114,11,176,91,70,232,219,84,202,119,5,157,125,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}}"#, - rand::random::(), - ); - let parsed: serde_json::Value = serde_json::from_str(json_str.as_str()).unwrap(); + let parsed_json = json!({ + "epoch": "1", + "signers": { + "nonce": { + "bytes": format!("0x{:0>64}", HexBinary::from(created_at.to_be_bytes()).to_hex()) + }, + + "signers": signers.into_iter().map(|signer| { + json!({ + "pub_key": HexBinary::from(signer.pub_key).to_vec(), + "weight": signer.weight.u128().to_string() + }) + }).collect::>(), + "threshold": threshold.to_string(), + }, + "signers_hash": { + "bytes": format!("0x{:0>64}", HexBinary::from(verifier_set_confirmation.verifier_set.hash()).to_hex()) + } + }); let event = SuiEvent { id: EventID { @@ -312,11 +528,11 @@ mod tests { sender: SuiAddress::random_for_testing_only(), type_: StructTag { address: gateway_address.into(), - module: "validators".parse().unwrap(), - name: "OperatorshipTransferred".parse().unwrap(), + module: "auth".parse().unwrap(), + name: "SignersRotated".parse().unwrap(), type_params: vec![], }, - parsed_json: parsed, + parsed_json, bcs: vec![], timestamp_ms: None, }; diff --git a/contracts/multisig/src/key.rs b/contracts/multisig/src/key.rs index f2793e0b9..dc5dff80e 100644 --- a/contracts/multisig/src/key.rs +++ b/contracts/multisig/src/key.rs @@ -312,8 +312,8 @@ impl AsRef<[u8]> for Signature { impl From for HexBinary { fn from(original: PublicKey) -> Self { match original { - PublicKey::Ecdsa(sig) => sig, - PublicKey::Ed25519(sig) => sig, + PublicKey::Ecdsa(key) => key, + PublicKey::Ed25519(key) => key, } } } diff --git a/contracts/multisig/src/verifier_set.rs b/contracts/multisig/src/verifier_set.rs index bde7c84af..f2e9f76ae 100644 --- a/contracts/multisig/src/verifier_set.rs +++ b/contracts/multisig/src/verifier_set.rs @@ -9,7 +9,7 @@ use sha3::{Digest, Keccak256}; #[cw_serde] pub struct VerifierSet { - // An ordered map with the signer's address as the key, and the signer as the value. + // An ordered map with the signer's axelar address as the key, and the signer as the value. pub signers: BTreeMap, pub threshold: Uint128, // for hash uniqueness. The same exact verifier set could be in use at two different times, From 7e878bb752c109c5be89f43c12227d8309d9dcfa Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 16 Jul 2024 13:18:40 -0400 Subject: [PATCH 074/168] chore: use different rust caches for each ci check (#518) --- .github/workflows/basic.yaml | 6 +++--- .github/workflows/codecov.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index ccf2a2086..eb77a0835 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -31,7 +31,7 @@ jobs: - name: Cache build artifacts uses: useblacksmith/rust-cache@v3 with: - shared-key: "cache" + shared-key: "cache-tests" - name: Run tests uses: actions-rs/cargo@v1 @@ -59,7 +59,7 @@ jobs: - name: Cache build artifacts uses: useblacksmith/rust-cache@v3 with: - shared-key: "cache" + shared-key: "cache-cosmwasm-compilation" - name: Build wasm release run: | @@ -100,7 +100,7 @@ jobs: - name: Cache build artifacts uses: useblacksmith/rust-cache@v3 with: - shared-key: "cache" + shared-key: "cache-lints" - name: Install cargo-sort uses: baptiste0928/cargo-install@v2 diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 95e88d5c6..e458bd9a1 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -33,7 +33,7 @@ jobs: - name: Cache build artifacts uses: useblacksmith/rust-cache@v3 with: - shared-key: "cache" + shared-key: "cache-codecov" - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov From 938c5cf063ed9511510b5531127eff832bbd19f8 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 16 Jul 2024 14:39:24 -0400 Subject: [PATCH 075/168] chore: force cosmwasm-check install for build wasm release check (#519) --- .github/workflows/basic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index eb77a0835..68c9e24f8 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -73,7 +73,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: install - args: --version 1.5.5 --locked cosmwasm-check + args: --version 1.5.5 --locked cosmwasm-check --force - name: Check wasm contracts run: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm From ed0327d61b8e85d7cb9f391664b4a510b7f6b717 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Tue, 16 Jul 2024 15:01:38 -0400 Subject: [PATCH 076/168] fix(multisig-prover): drop checksum check for destination chain (#513) Co-authored-by: Christian Gorenflo --- packages/evm-gateway/src/lib.rs | 72 ++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/packages/evm-gateway/src/lib.rs b/packages/evm-gateway/src/lib.rs index 177d50eb9..8383ed2f2 100644 --- a/packages/evm-gateway/src/lib.rs +++ b/packages/evm-gateway/src/lib.rs @@ -1,5 +1,7 @@ pub mod error; +use std::str::FromStr; + use cosmwasm_std::Uint256; use error_stack::{Report, ResultExt}; use ethers_contract::abigen; @@ -10,12 +12,12 @@ use ethers_core::{ Tokenize, }, types::{Address, Bytes, U256}, - utils::{parse_checksummed, public_key_to_address}, + utils::public_key_to_address, }; use k256::ecdsa::VerifyingKey; use sha3::{Digest, Keccak256}; -use axelar_wasm_std::hash::Hash; +use axelar_wasm_std::{hash::Hash, FnExt}; use multisig::{ key::PublicKey, msg::{Signer, SignerWithSig}, @@ -79,7 +81,11 @@ impl TryFrom<&RouterMessage> for Message { type Error = Report; fn try_from(msg: &RouterMessage) -> Result { - let contract_address = parse_checksummed(msg.destination_address.as_str(), None) + let contract_address = msg + .destination_address + .as_str() + .then(|addr| addr.strip_prefix("0x").unwrap_or(addr)) + .then(Address::from_str) .change_context(Error::InvalidAddress)?; Ok(Message { @@ -144,8 +150,9 @@ pub fn evm_address(pub_key: &PublicKey) -> Result> { #[cfg(test)] mod test { + use std::str::FromStr; + use cosmwasm_std::{Addr, HexBinary, Uint128}; - use ethers_core::utils::to_checksum; use axelar_wasm_std::{nonempty, snapshot::Participant}; use multisig::{key::PublicKey, verifier_set::VerifierSet}; @@ -172,32 +179,43 @@ mod test { let message_id = "0xff822c88807859ff226b58e24f24974a70f04b9442501ae38fd665b3c68f3834-0"; let source_address = "0x52444f1835Adc02086c37Cb226561605e2E1699b"; let destination_chain = "chain1"; - let destination_address = "0xA4f10f76B86E01B98daF66A3d02a65e14adb0767"; let payload_hash = "8c3685dc41c2eca11426f8035742fb97ea9f14931152670a5703f18fe8b392f0"; + let destination_addresses = vec![ + "0xa4f10f76b86e01b98daf66a3d02a65e14adb0767", // all lowercase + "0xA4f10f76B86E01B98daF66A3d02a65e14adb0767", // checksummed + "a4f10f76b86e01b98daf66a3d02a65e14adb0767", // no 0x prefix + ]; - let router_messages = RouterMessage { - cc_id: CrossChainId { - chain: source_chain.parse().unwrap(), - id: message_id.parse().unwrap(), - }, - source_address: source_address.parse().unwrap(), - destination_address: destination_address.parse().unwrap(), - destination_chain: destination_chain.parse().unwrap(), - payload_hash: HexBinary::from_hex(payload_hash) + for destination_address in destination_addresses { + let router_messages = RouterMessage { + cc_id: CrossChainId { + chain: source_chain.parse().unwrap(), + id: message_id.parse().unwrap(), + }, + source_address: source_address.parse().unwrap(), + destination_address: destination_address.parse().unwrap(), + destination_chain: destination_chain.parse().unwrap(), + payload_hash: HexBinary::from_hex(payload_hash) + .unwrap() + .to_array::<32>() + .unwrap(), + }; + + let gateway_message = Message::try_from(&router_messages).unwrap(); + assert_eq!(gateway_message.source_chain, source_chain); + assert_eq!(gateway_message.message_id, message_id); + assert_eq!(gateway_message.source_address, source_address); + assert_eq!( + gateway_message.contract_address, + ethers_core::types::Address::from_str( + destination_address + .strip_prefix("0x") + .unwrap_or(destination_address) + ) .unwrap() - .to_array::<32>() - .unwrap(), - }; - - let gateway_message = Message::try_from(&router_messages).unwrap(); - assert_eq!(gateway_message.source_chain, source_chain); - assert_eq!(gateway_message.message_id, message_id); - assert_eq!(gateway_message.source_address, source_address); - assert_eq!( - to_checksum(&gateway_message.contract_address, None), - destination_address - ); - assert_eq!(gateway_message.payload_hash, router_messages.payload_hash); + ); + assert_eq!(gateway_message.payload_hash, router_messages.payload_hash); + } } // Generate a worker set matches axelar-gmp-sdk-solidity repo test data From 5152aecedb39b7e1585cfdc68248d2d0cbaef505 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Tue, 16 Jul 2024 19:35:22 +0000 Subject: [PATCH 077/168] chore: release ampd 0.6.0 [skip ci] --- Cargo.lock | 2 +- ampd/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cfa4e23f..e3cfb0063 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ dependencies = [ [[package]] name = "ampd" -version = "0.5.0" +version = "0.6.0" dependencies = [ "async-trait", "axelar-wasm-std", diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index c8cf4a05e..cd8b7d5aa 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "ampd" -version = "0.5.0" +version = "0.6.0" rust-version = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 9c7990b27cdfb821cf92f312702a31f4c107325b Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 16 Jul 2024 16:37:07 -0400 Subject: [PATCH 078/168] feat(gateway): add permission control to gateway (#508) --- Cargo.lock | 4 ++++ contracts/gateway/src/contract.rs | 1 + packages/gateway-api/Cargo.toml | 4 ++++ packages/gateway-api/src/msg.rs | 6 ++++-- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3cfb0063..fe18ec4dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2962,7 +2962,11 @@ dependencies = [ name = "gateway-api" version = "0.1.0" dependencies = [ + "axelar-wasm-std", "cosmwasm-schema", + "cosmwasm-std", + "error-stack", + "msgs-derive", "router-api", ] diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index da85f155c..b0096a2ce 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -45,6 +45,7 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { + let msg = msg.ensure_permissions(deps.storage, &info.sender)?; Ok(internal::execute(deps, env, info, msg)?) } diff --git a/packages/gateway-api/Cargo.toml b/packages/gateway-api/Cargo.toml index 0ff5309ce..ba7fdbec0 100644 --- a/packages/gateway-api/Cargo.toml +++ b/packages/gateway-api/Cargo.toml @@ -6,7 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +axelar-wasm-std = { workspace = true } cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +error-stack = { workspace = true } +msgs-derive = { workspace = true } router-api = { workspace = true } [lints] diff --git a/packages/gateway-api/src/msg.rs b/packages/gateway-api/src/msg.rs index 601fb25a5..2911c2e3d 100644 --- a/packages/gateway-api/src/msg.rs +++ b/packages/gateway-api/src/msg.rs @@ -1,16 +1,18 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use msgs_derive::EnsurePermissions; use router_api::{CrossChainId, Message}; #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { - // Permissionless /// Before messages that are unknown to the system can be routed, they need to be verified. /// Use this call to trigger verification for any of the given messages that is still unverified. + #[permission(Any)] VerifyMessages(Vec), - // Permissionless /// Forward the given messages to the next step of the routing layer. If these messages are coming in from an external chain, /// they have to be verified first. + #[permission(Any)] RouteMessages(Vec), } From 681af1f1f1c12c69e1eee88e4efe90b9c6a3a1e5 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Tue, 16 Jul 2024 16:48:43 -0400 Subject: [PATCH 079/168] refactor(minor-integration-tests): use rewards query for contract wrapper creation (#511) --- integration-tests/src/rewards_contract.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/src/rewards_contract.rs b/integration-tests/src/rewards_contract.rs index 48f1f02dc..14809ed54 100644 --- a/integration-tests/src/rewards_contract.rs +++ b/integration-tests/src/rewards_contract.rs @@ -1,5 +1,5 @@ use crate::contract::Contract; -use cosmwasm_std::{Addr, Binary, Deps, Env, StdResult}; +use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; #[derive(Clone)] @@ -17,7 +17,7 @@ impl RewardsContract { let code = ContractWrapper::new( rewards::contract::execute, rewards::contract::instantiate, - |_: Deps, _: Env, _: rewards::msg::QueryMsg| -> StdResult { todo!() }, + rewards::contract::query, ); let code_id = app.store_code(Box::new(code)); From e4220a6501cd818c2b1c82a316e0a84fca14ab96 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Tue, 16 Jul 2024 17:39:09 -0400 Subject: [PATCH 080/168] feat(minor-voting-verifier): query poll by id (#505) Co-authored-by: Christian Gorenflo --- contracts/voting-verifier/src/client.rs | 4 +- contracts/voting-verifier/src/contract.rs | 4 +- contracts/voting-verifier/src/msg.rs | 17 +++-- contracts/voting-verifier/src/query.rs | 77 ++++++++++++++++++++++- contracts/voting-verifier/src/state.rs | 17 +++++ 5 files changed, 108 insertions(+), 11 deletions(-) diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index 4445044a0..84503a1a3 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -9,7 +9,7 @@ use axelar_wasm_std::{ use multisig::verifier_set::VerifierSet; use router_api::Message; -use crate::msg::{ExecuteMsg, MessageStatus, Poll, QueryMsg}; +use crate::msg::{ExecuteMsg, MessageStatus, PollResponse, QueryMsg}; type Result = error_stack::Result; @@ -62,7 +62,7 @@ impl<'a> Client<'a> { }) } - pub fn poll(&self, poll_id: PollId) -> Result { + pub fn poll(&self, poll_id: PollId) -> Result { self.client .query(&QueryMsg::GetPoll { poll_id }) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())) diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 61e35c6c5..12177df30 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -67,8 +67,8 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetPoll { poll_id: _ } => { - todo!() + QueryMsg::GetPoll { poll_id } => { + to_json_binary(&query::poll_response(deps, env.block.height, poll_id)?) } QueryMsg::GetMessagesStatus { messages } => { diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index 3e25cd51d..3bb142b93 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -1,9 +1,10 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use axelar_wasm_std::voting::PollStatus; use axelar_wasm_std::{ msg_id::MessageIdFormat, nonempty, - voting::{PollId, Vote}, + voting::{PollId, Vote, WeightedPoll}, MajorityThreshold, VerificationStatus, }; use multisig::verifier_set::VerifierSet; @@ -68,15 +69,21 @@ pub enum ExecuteMsg { } #[cw_serde] -pub struct Poll { - poll_id: PollId, - messages: Vec, +pub enum PollData { + Messages(Vec), + VerifierSet(VerifierSet), +} +#[cw_serde] +pub struct PollResponse { + pub poll: WeightedPoll, + pub data: PollData, + pub status: PollStatus, } #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(Poll)] + #[returns(PollResponse)] GetPoll { poll_id: PollId }, #[returns(Vec)] diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index 3a8ff8405..5337fcf35 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -1,5 +1,5 @@ use axelar_wasm_std::{ - voting::{PollStatus, Vote}, + voting::{PollId, PollStatus, Vote}, MajorityThreshold, VerificationStatus, }; use cosmwasm_std::Deps; @@ -11,7 +11,7 @@ use crate::{ state::{poll_messages, poll_verifier_sets, CONFIG}, }; use crate::{ - msg::MessageStatus, + msg::{MessageStatus, PollData, PollResponse}, state::{self, Poll, PollContent, POLLS}, }; @@ -48,6 +48,42 @@ pub fn message_status( )) } +pub fn poll_response( + deps: Deps, + current_block_height: u64, + poll_id: PollId, +) -> Result { + let poll = POLLS.load(deps.storage, poll_id)?; + let (data, status) = match &poll { + Poll::Messages(poll) => { + let msgs = poll_messages().idx.load_messages(deps.storage, poll_id)?; + assert_eq!( + poll.tallies.len(), + msgs.len(), + "data inconsistency for number of messages in poll {}", + poll.poll_id + ); + + (PollData::Messages(msgs), poll.status(current_block_height)) + } + Poll::ConfirmVerifierSet(poll) => ( + PollData::VerifierSet( + poll_verifier_sets() + .idx + .load_verifier_set(deps.storage, poll_id)? + .expect("verifier set not found in poll"), + ), + poll.status(current_block_height), + ), + }; + + Ok(PollResponse { + poll: poll.weighted_poll(), + data, + status, + }) +} + pub fn verifier_set_status( deps: Deps, verifier_set: &VerifierSet, @@ -122,7 +158,9 @@ mod tests { voting::{PollId, Tallies, Vote, WeightedPoll}, Participant, Snapshot, Threshold, }; + use cosmwasm_std::testing::mock_env; use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128, Uint64}; + use itertools::Itertools; use router_api::CrossChainId; use crate::state::PollContent; @@ -245,6 +283,41 @@ mod tests { ); } + #[test] + #[allow(clippy::cast_possible_truncation)] + fn poll_response() { + let mut deps = mock_dependencies(); + + let poll = poll(1); + POLLS + .save( + deps.as_mut().storage, + poll.poll_id, + &state::Poll::Messages(poll.clone()), + ) + .unwrap(); + + let messages = (0..poll.poll_size as u32).map(message); + messages.clone().enumerate().for_each(|(idx, msg)| { + poll_messages() + .save( + deps.as_mut().storage, + &msg.hash(), + &PollContent::::new(msg, poll.poll_id, idx), + ) + .unwrap() + }); + + assert_eq!( + PollResponse { + poll: poll.clone(), + data: PollData::Messages(messages.collect_vec()), + status: PollStatus::Expired + }, + super::poll_response(deps.as_ref(), mock_env().block.height, poll.poll_id).unwrap() + ); + } + fn message(id: u32) -> Message { Message { cc_id: CrossChainId { diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index fefdbaa49..7d5f438d6 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -46,6 +46,13 @@ impl Poll { Poll::ConfirmVerifierSet(poll) => Ok(Poll::ConfirmVerifierSet(func(poll)?)), } } + + pub fn weighted_poll(self) -> WeightedPoll { + match self { + Poll::Messages(poll) => poll, + Poll::ConfirmVerifierSet(poll) => poll, + } + } } #[cw_serde] @@ -116,6 +123,16 @@ impl<'a> PollMessagesIndex<'a> { _ => panic!("More than one message for poll_id and index_in_poll"), } } + + pub fn load_messages(&self, storage: &dyn Storage, poll_id: PollId) -> StdResult> { + poll_messages() + .idx + .0 + .sub_prefix(poll_id.to_string()) + .range(storage, None, None, Order::Ascending) + .map(|item| item.map(|(_, poll_content)| poll_content.content)) + .collect::>>() + } } const POLL_MESSAGES_PKEY_NAMESPACE: &str = "poll_messages"; From 7a53c19b8e67ab2564028be598d1bd1f787345f4 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 16 Jul 2024 17:42:58 -0400 Subject: [PATCH 081/168] feat(rewards): add permission control to rewards contract (#517) --- Cargo.lock | 1 + contracts/rewards/Cargo.toml | 1 + contracts/rewards/src/contract.rs | 17 +- contracts/rewards/src/contract/execute.rs | 195 ++++-------------- .../rewards/src/contract/migrations/mod.rs | 1 + .../rewards/src/contract/migrations/v0_4_0.rs | 153 ++++++++++++++ contracts/rewards/src/msg.rs | 6 + contracts/rewards/src/state.rs | 1 - .../router/src/contract/migrations/v0_3_3.rs | 8 +- packages/axelar-wasm-std/src/nonempty/uint.rs | 13 ++ 10 files changed, 225 insertions(+), 171 deletions(-) create mode 100644 contracts/rewards/src/contract/migrations/mod.rs create mode 100644 contracts/rewards/src/contract/migrations/v0_4_0.rs diff --git a/Cargo.lock b/Cargo.lock index fe18ec4dd..3c9907310 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6165,6 +6165,7 @@ dependencies = [ "cw2 1.1.2", "error-stack", "itertools 0.11.0", + "msgs-derive", "report", "router-api", "thiserror", diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index 8d955565d..2e14aa297 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -41,6 +41,7 @@ cw-storage-plus = { workspace = true } cw2 = { workspace = true } error-stack = { workspace = true } itertools = "0.11.0" +msgs-derive = { workspace = true } report = { workspace = true } router-api = { workspace = true } thiserror = { workspace = true } diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index 41f6f24b0..8b5993e7d 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::nonempty; +use axelar_wasm_std::{nonempty, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -7,6 +7,7 @@ use cosmwasm_std::{ use error_stack::ResultExt; use itertools::Itertools; +use crate::contract::migrations::v0_4_0; use crate::{ error::ContractError, msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, @@ -14,6 +15,7 @@ use crate::{ }; mod execute; +mod migrations; mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); @@ -25,6 +27,8 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { + v0_4_0::migrate(deps.storage)?; + // any version checks should be done before here cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -42,11 +46,11 @@ pub fn instantiate( cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let governance = deps.api.addr_validate(&msg.governance_address)?; + permission_control::set_governance(deps.storage, &governance)?; CONFIG.save( deps.storage, &Config { - governance, rewards_denom: msg.rewards_denom, }, )?; @@ -72,7 +76,7 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { + match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::RecordParticipation { chain_name, event_id, @@ -81,7 +85,7 @@ pub fn execute( let verifier_address = deps.api.addr_validate(&verifier_address)?; let pool_id = PoolId { chain_name, - contract: info.sender.clone(), + contract: info.sender, }; execute::record_participation( deps.storage, @@ -137,7 +141,7 @@ pub fn execute( Ok(Response::new().add_messages(msgs)) } ExecuteMsg::UpdateParams { params } => { - execute::update_params(deps.storage, params, env.block.height, info.sender)?; + execute::update_params(deps.storage, params, env.block.height)?; Ok(Response::new()) } @@ -181,11 +185,12 @@ mod tests { #[test] fn migrate_sets_contract_version() { let mut deps = mock_dependencies(); + v0_4_0::tests::instantiate_contract(deps.as_mut(), "denom"); migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, "rewards"); + assert_eq!(contract_version.contract, CONTRACT_NAME); assert_eq!(contract_version.version, CONTRACT_VERSION); } diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index 81ec427e3..a67d97d11 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -7,19 +7,12 @@ use error_stack::{Report, Result}; use crate::{ error::ContractError, msg::Params, - state::{self, Config, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, StorageState}, + state::{self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, StorageState}, }; const DEFAULT_EPOCHS_TO_PROCESS: u64 = 10; const EPOCH_PAYOUT_DELAY: u64 = 2; -fn require_governance(config: Config, sender: Addr) -> Result<(), ContractError> { - if config.governance != sender { - return Err(ContractError::Unauthorized.into()); - } - Ok(()) -} - pub(crate) fn record_participation( storage: &mut dyn Storage, event_id: nonempty::String, @@ -127,9 +120,7 @@ pub(crate) fn update_params( storage: &mut dyn Storage, new_params: Params, block_height: u64, - sender: Addr, ) -> Result<(), ContractError> { - require_governance(state::load_config(storage), sender)?; let cur_epoch = Epoch::current(&state::load_params(storage), block_height)?; // If the param update reduces the epoch duration such that the current epoch immediately ends, // start a new epoch at this block, incrementing the current epoch number by 1. @@ -228,9 +219,7 @@ mod test { use crate::{ error::ContractError, msg::Params, - state::{ - self, Config, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, RewardsPool, CONFIG, - }, + state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG}, }; /// Tests that the current epoch is computed correctly when the expected epoch is the same as the stored epoch @@ -239,7 +228,7 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - let (mock_deps, _) = setup(cur_epoch_num, block_height_started, epoch_duration); + let mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); let current_params = state::load_params(mock_deps.as_ref().storage); let new_epoch = Epoch::current(¤t_params, block_height_started).unwrap(); @@ -263,7 +252,7 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - let (mock_deps, _) = setup(cur_epoch_num, block_height_started, epoch_duration); + let mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); let current_params = state::load_params(mock_deps.as_ref().storage); assert!(Epoch::current(¤t_params, block_height_started - 1).is_err()); @@ -276,7 +265,7 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - let (mock_deps, _) = setup(cur_epoch_num, block_height_started, epoch_duration); + let mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); // elements are (height, expected epoch number, expected epoch start) let test_cases = vec![ @@ -318,7 +307,7 @@ mod test { let epoch_block_start = 250u64; let epoch_duration = 100u64; - let (mut mock_deps, _) = setup(cur_epoch_num, epoch_block_start, epoch_duration); + let mut mock_deps = setup(cur_epoch_num, epoch_block_start, epoch_duration); let pool_id = PoolId { chain_name: "mock-chain".parse().unwrap(), @@ -372,7 +361,7 @@ mod test { let block_height_started = 250u64; let epoch_duration = 100u64; - let (mut mock_deps, _) = setup(starting_epoch_num, block_height_started, epoch_duration); + let mut mock_deps = setup(starting_epoch_num, block_height_started, epoch_duration); let pool_id = PoolId { chain_name: "mock-chain".parse().unwrap(), @@ -434,7 +423,7 @@ mod test { let block_height_started = 250u64; let epoch_duration = 100u64; - let (mut mock_deps, _) = setup(cur_epoch_num, block_height_started, epoch_duration); + let mut mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); let mut simulated_participation = HashMap::new(); simulated_participation.insert( @@ -509,7 +498,7 @@ mod test { let initial_rewards_per_epoch = 100u128; let initial_participation_threshold = (1, 2); let epoch_duration = 100u64; - let (mut mock_deps, config) = setup_with_params( + let mut mock_deps = setup_with_params( initial_epoch_num, initial_epoch_start, epoch_duration, @@ -532,13 +521,7 @@ mod test { let expected_epoch = Epoch::current(&state::load_params(mock_deps.as_ref().storage), cur_height).unwrap(); - update_params( - mock_deps.as_mut().storage, - new_params.clone(), - cur_height, - config.governance.clone(), - ) - .unwrap(); + update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); let stored = state::load_params(mock_deps.as_ref().storage); assert_eq!(stored.params, new_params); @@ -555,40 +538,13 @@ mod test { assert_eq!(stored.created_at, cur_epoch); } - /// Test that rewards parameters cannot be updated by an address other than governance - #[test] - fn update_params_unauthorized() { - let initial_epoch_num = 1u64; - let initial_epoch_start = 250u64; - let epoch_duration = 100u64; - let (mut mock_deps, _) = setup(initial_epoch_num, initial_epoch_start, epoch_duration); - - let new_params = Params { - rewards_per_epoch: cosmwasm_std::Uint128::from(100u128).try_into().unwrap(), - participation_threshold: (Uint64::new(2), Uint64::new(3)).try_into().unwrap(), - epoch_duration: epoch_duration.try_into().unwrap(), - }; - - let res = update_params( - mock_deps.as_mut().storage, - new_params.clone(), - initial_epoch_start, - Addr::unchecked("some non governance address"), - ); - assert!(res.is_err()); - assert_eq!( - res.unwrap_err().current_context(), - &ContractError::Unauthorized - ); - } - /// Test extending the epoch duration. This should not change the current epoch #[test] fn extend_epoch_duration() { let initial_epoch_num = 1u64; let initial_epoch_start = 250u64; let initial_epoch_duration = 100u64; - let (mut mock_deps, config) = setup( + let mut mock_deps = setup( initial_epoch_num, initial_epoch_start, initial_epoch_duration, @@ -608,13 +564,7 @@ mod test { ..initial_params_snapshot.params // keep everything besides epoch duration the same }; - update_params( - mock_deps.as_mut().storage, - new_params.clone(), - cur_height, - config.governance.clone(), - ) - .unwrap(); + update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); let updated_params_snapshot = state::load_params(mock_deps.as_ref().storage); @@ -647,7 +597,7 @@ mod test { let initial_epoch_num = 1u64; let initial_epoch_start = 256u64; let initial_epoch_duration = 100u64; - let (mut mock_deps, config) = setup( + let mut mock_deps = setup( initial_epoch_num, initial_epoch_start, initial_epoch_duration, @@ -668,13 +618,7 @@ mod test { epoch_duration: new_epoch_duration.try_into().unwrap(), ..initial_params_snapshot.params }; - update_params( - mock_deps.as_mut().storage, - new_params.clone(), - cur_height, - config.governance.clone(), - ) - .unwrap(); + update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); let updated_params_snapshot = state::load_params(mock_deps.as_ref().storage); @@ -699,7 +643,7 @@ mod test { let initial_epoch_num = 1u64; let initial_epoch_start = 250u64; let initial_epoch_duration = 100u64; - let (mut mock_deps, config) = setup( + let mut mock_deps = setup( initial_epoch_num, initial_epoch_start, initial_epoch_duration, @@ -720,13 +664,7 @@ mod test { epoch_duration: 10.try_into().unwrap(), ..initial_params_snapshot.params }; - update_params( - mock_deps.as_mut().storage, - new_params.clone(), - cur_height, - config.governance.clone(), - ) - .unwrap(); + update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); let updated_params_snapshot = state::load_params(mock_deps.as_ref().storage); @@ -749,7 +687,7 @@ mod test { let block_height_started = 250u64; let epoch_duration = 100u64; - let (mut mock_deps, _) = setup(cur_epoch_num, block_height_started, epoch_duration); + let mut mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); let pool_id = PoolId { chain_name: "mock-chain".parse().unwrap(), @@ -790,7 +728,7 @@ mod test { let block_height_started = 250u64; let epoch_duration = 100u64; - let (mut mock_deps, _) = setup(cur_epoch_num, block_height_started, epoch_duration); + let mut mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); // a vector of (contract, rewards amounts) pairs let test_data = vec![ (Addr::unchecked("contract_1"), vec![100, 200, 50]), @@ -840,7 +778,7 @@ mod test { let rewards_per_epoch = 100u128; let participation_threshold = (2, 3); - let (mut mock_deps, _) = setup_with_params( + let mut mock_deps = setup_with_params( cur_epoch_num, block_height_started, epoch_duration, @@ -940,7 +878,7 @@ mod test { let rewards_per_epoch = 100u128; let participation_threshold = (1, 2); - let (mut mock_deps, _) = setup_with_params( + let mut mock_deps = setup_with_params( cur_epoch_num, block_height_started, epoch_duration, @@ -1019,7 +957,7 @@ mod test { let rewards_per_epoch = 100u128; let participation_threshold = (8, 10); - let (mut mock_deps, _) = setup_with_params( + let mut mock_deps = setup_with_params( cur_epoch_num, block_height_started, epoch_duration, @@ -1098,7 +1036,7 @@ mod test { let rewards_per_epoch = 100u128; let participation_threshold = (8, 10); - let (mut mock_deps, _) = setup_with_params( + let mut mock_deps = setup_with_params( cur_epoch_num, block_height_started, epoch_duration, @@ -1165,7 +1103,7 @@ mod test { let rewards_per_epoch = 100u128; let participation_threshold = (8, 10); - let (mut mock_deps, _) = setup_with_params( + let mut mock_deps = setup_with_params( cur_epoch_num, block_height_started, epoch_duration, @@ -1215,69 +1153,13 @@ mod test { type MockDeps = OwnedDeps; - fn set_initial_storage( - params_store: ParamsSnapshot, - events_store: Vec, - tally_store: Vec, - rewards_store: Vec, - watermark_store: HashMap, - ) -> (MockDeps, Config) { - let mut deps = mock_dependencies(); - let storage = deps.as_mut().storage; - - state::save_params(storage, ¶ms_store).unwrap(); - - events_store.iter().for_each(|event| { - state::save_event(storage, event).unwrap(); - }); - - tally_store.iter().for_each(|tally| { - state::save_epoch_tally(storage, tally).unwrap(); - }); - - rewards_store.iter().for_each(|pool| { - state::save_rewards_pool(storage, pool).unwrap(); - }); - - watermark_store - .into_iter() - .for_each(|(pool_id, epoch_num)| { - state::save_rewards_watermark(storage, pool_id, epoch_num).unwrap(); - }); - - let config = Config { - governance: Addr::unchecked("governance"), - rewards_denom: "AXL".to_string(), - }; - - CONFIG.save(storage, &config).unwrap(); - - (deps, config) - } - - fn setup_with_stores( - params_store: ParamsSnapshot, - events_store: Vec, - tally_store: Vec, - rewards_store: Vec, - watermark_store: HashMap, - ) -> (MockDeps, Config) { - set_initial_storage( - params_store, - events_store, - tally_store, - rewards_store, - watermark_store, - ) - } - fn setup_with_params( cur_epoch_num: u64, block_height_started: u64, epoch_duration: u64, rewards_per_epoch: u128, participation_threshold: (u64, u64), - ) -> (MockDeps, Config) { + ) -> MockDeps { let rewards_per_epoch: nonempty::Uint128 = cosmwasm_std::Uint128::from(rewards_per_epoch) .try_into() .unwrap(); @@ -1295,24 +1177,21 @@ mod test { created_at: current_epoch.clone(), }; - let rewards_store = Vec::new(); - let events_store = Vec::new(); - let tally_store = Vec::new(); - let watermark_store = HashMap::new(); - setup_with_stores( - params_snapshot, - events_store, - tally_store, - rewards_store, - watermark_store, - ) + let mut deps = mock_dependencies(); + let storage = deps.as_mut().storage; + + state::save_params(storage, ¶ms_snapshot).unwrap(); + + let config = Config { + rewards_denom: "AXL".to_string(), + }; + + CONFIG.save(storage, &config).unwrap(); + + deps } - fn setup( - cur_epoch_num: u64, - block_height_started: u64, - epoch_duration: u64, - ) -> (MockDeps, Config) { + fn setup(cur_epoch_num: u64, block_height_started: u64, epoch_duration: u64) -> MockDeps { let participation_threshold = (1, 2); let rewards_per_epoch = 100u128; setup_with_params( diff --git a/contracts/rewards/src/contract/migrations/mod.rs b/contracts/rewards/src/contract/migrations/mod.rs new file mode 100644 index 000000000..a73cc4eb4 --- /dev/null +++ b/contracts/rewards/src/contract/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v0_4_0; diff --git a/contracts/rewards/src/contract/migrations/v0_4_0.rs b/contracts/rewards/src/contract/migrations/v0_4_0.rs new file mode 100644 index 000000000..ff536c0c0 --- /dev/null +++ b/contracts/rewards/src/contract/migrations/v0_4_0.rs @@ -0,0 +1,153 @@ +#![allow(deprecated)] + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Storage}; +use cw_storage_plus::Item; + +use axelar_wasm_std::{permission_control, ContractError}; +use router_api::error::Error; + +use crate::contract::CONTRACT_NAME; +use crate::state; + +const BASE_VERSION: &str = "0.4.0"; + +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + set_generalized_permission_control(storage)?; + Ok(()) +} + +fn set_generalized_permission_control(storage: &mut dyn Storage) -> Result<(), Error> { + let old_config = CONFIG.load(storage)?; + + permission_control::set_governance(storage, &old_config.governance).map_err(Error::from)?; + + let new_config = &state::Config { + rewards_denom: old_config.rewards_denom, + }; + state::CONFIG.save(storage, new_config)?; + Ok(()) +} + +#[cw_serde] +#[deprecated(since = "0.4.0", note = "only used during migration")] +pub struct Config { + pub governance: Addr, + pub rewards_denom: String, +} + +#[deprecated(since = "0.4.0", note = "only used during migration")] +pub const CONFIG: Item = Item::new("config"); + +#[cfg(test)] +pub mod tests { + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; + + use crate::contract::migrations::v0_4_0; + use crate::contract::{execute, CONTRACT_NAME}; + use crate::msg::{ExecuteMsg, InstantiateMsg, Params}; + use crate::state; + use crate::state::{Epoch, ParamsSnapshot, PARAMS}; + + #[deprecated(since = "0.4.0", note = "only used during migration tests")] + fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_4_0::BASE_VERSION)?; + + let governance = deps.api.addr_validate(&msg.governance_address)?; + + v0_4_0::CONFIG.save( + deps.storage, + &v0_4_0::Config { + governance, + rewards_denom: msg.rewards_denom, + }, + )?; + + PARAMS.save( + deps.storage, + &ParamsSnapshot { + params: msg.params, + created_at: Epoch { + epoch_num: 0, + block_height_started: env.block.height, + }, + }, + )?; + + Ok(Response::new()) + } + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut(), "denom"); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_4_0::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_4_0::BASE_VERSION) + .unwrap(); + + assert!(v0_4_0::migrate(deps.as_mut().storage).is_ok()); + } + + #[test] + fn migrate_config() { + let mut deps = mock_dependencies(); + let denom = "denom".to_string(); + instantiate_contract(deps.as_mut(), &denom); + + v0_4_0::migrate(&mut deps.storage).unwrap(); + + let new_config = state::CONFIG.load(&deps.storage).unwrap(); + assert_eq!(denom, new_config.rewards_denom); + } + + #[test] + fn migrate_governance_permission() { + let mut deps = mock_dependencies(); + + instantiate_contract(deps.as_mut(), "denom"); + + v0_4_0::migrate(&mut deps.storage).unwrap(); + + let msg = ExecuteMsg::UpdateParams { + params: Params { + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: 1000u128.try_into().unwrap(), + participation_threshold: (1, 2).try_into().unwrap(), + }, + }; + assert!(execute( + deps.as_mut(), + mock_env(), + mock_info("anyone", &[]), + msg.clone(), + ) + .is_err()); + + assert!(execute(deps.as_mut(), mock_env(), mock_info("governance", &[]), msg).is_ok()); + } + + #[deprecated(since = "0.4.0", note = "only used during migration tests")] + pub fn instantiate_contract(deps: DepsMut, denom: impl Into) { + let msg = InstantiateMsg { + governance_address: "governance".to_string(), + rewards_denom: denom.into(), + params: Params { + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: 1000u128.try_into().unwrap(), + participation_threshold: (1, 2).try_into().unwrap(), + }, + }; + instantiate(deps, mock_env(), mock_info("anyone", &[]), msg).unwrap(); + } +} diff --git a/contracts/rewards/src/msg.rs b/contracts/rewards/src/msg.rs index cf2c596ac..64d46a317 100644 --- a/contracts/rewards/src/msg.rs +++ b/contracts/rewards/src/msg.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use axelar_wasm_std::{nonempty, Threshold}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, Uint128, Uint64}; +use msgs_derive::EnsurePermissions; use router_api::ChainName; use crate::state::{Epoch, PoolId}; @@ -31,6 +32,7 @@ pub struct Params { } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { /// Log a specific verifier as participating in a specific event. Verifier weights are ignored /// @@ -40,6 +42,7 @@ pub enum ExecuteMsg { /// verifier could choose to record the participation, but then the missed message is not recorded in any way. /// A possible solution to this is to add a weight to each event, where the voting verifier specifies the number /// of messages in a batch as well as the number of messages a particular verifier actually participated in. + #[permission(Any)] RecordParticipation { chain_name: ChainName, event_id: nonempty::String, @@ -47,6 +50,7 @@ pub enum ExecuteMsg { }, /// Distribute rewards up to epoch T - 2 (i.e. if we are currently in epoch 10, distribute all undistributed rewards for epochs 0-8) and send the required number of tokens to each verifier + #[permission(Any)] DistributeRewards { pool_id: PoolId, /// Maximum number of historical epochs for which to distribute rewards, starting with the oldest. If not specified, distribute rewards for 10 epochs. @@ -55,9 +59,11 @@ pub enum ExecuteMsg { /// Start a new reward pool for the given contract if none exists. Otherwise, add tokens to an existing reward pool. /// Any attached funds with a denom matching the rewards denom are added to the pool. + #[permission(Any)] AddRewards { pool_id: PoolId }, /// Overwrites the currently stored params. Callable only by governance. + #[permission(Governance)] UpdateParams { params: Params }, } diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index 070216bc0..1b043112a 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -12,7 +12,6 @@ use crate::{error::ContractError, msg::Params}; #[cw_serde] pub struct Config { - pub governance: Addr, pub rewards_denom: String, } diff --git a/contracts/router/src/contract/migrations/v0_3_3.rs b/contracts/router/src/contract/migrations/v0_3_3.rs index 2783cca7e..5b3d5d655 100644 --- a/contracts/router/src/contract/migrations/v0_3_3.rs +++ b/contracts/router/src/contract/migrations/v0_3_3.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdResult, Storage}; use cw_storage_plus::Item; @@ -25,7 +27,6 @@ struct Config { pub nexus_gateway: Addr, } -#[allow(deprecated)] fn set_generalized_permission_control(storage: &mut dyn Storage) -> Result<(), Error> { let old_config = CONFIG.load(storage)?; permission_control::set_admin(storage, &old_config.admin) @@ -44,11 +45,9 @@ fn set_router_state(storage: &mut dyn Storage) -> StdResult<()> { } #[deprecated(since = "0.3.3", note = "only used during migration")] -#[allow(deprecated)] const CONFIG: Item = Item::new("config"); #[cfg(test)] -#[allow(deprecated)] mod test { use std::collections::HashMap; @@ -106,7 +105,6 @@ mod test { } #[test] - #[allow(deprecated)] fn migration() { let mut deps = mock_dependencies(); let instantiate_msg = instantiate_0_3_3_contract(deps.as_mut()).unwrap(); @@ -185,7 +183,6 @@ mod test { .is_ok()); } - #[allow(deprecated)] fn instantiate_0_3_3_contract(deps: DepsMut) -> Result { let admin = "admin"; let governance = "governance"; @@ -201,7 +198,6 @@ mod test { } #[deprecated(since = "0.3.3", note = "only used to test the migration")] - #[allow(deprecated)] fn instantiate( deps: DepsMut, _env: Env, diff --git a/packages/axelar-wasm-std/src/nonempty/uint.rs b/packages/axelar-wasm-std/src/nonempty/uint.rs index 2f2a98fb1..1627d78d7 100644 --- a/packages/axelar-wasm-std/src/nonempty/uint.rs +++ b/packages/axelar-wasm-std/src/nonempty/uint.rs @@ -110,6 +110,13 @@ impl From for cosmwasm_std::Uint128 { } } +impl TryFrom for Uint128 { + type Error = Error; + fn try_from(value: u128) -> Result { + cosmwasm_std::Uint128::from(value).try_into() + } +} + impl Uint128 { pub const fn one() -> Self { Self(cosmwasm_std::Uint128::one()) @@ -190,4 +197,10 @@ mod tests { let converted: &cosmwasm_std::Uint256 = val.as_ref(); assert_eq!(&val.0, converted); } + + #[test] + fn convert_from_uint128_to_non_empty_uint128() { + assert!(Uint128::try_from(0u128).is_err()); + assert!(Uint128::try_from(1u128).is_ok()); + } } From 7393fa4aeeda6520320cd1a353efedc60ba900f3 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 17 Jul 2024 13:59:43 -0400 Subject: [PATCH 082/168] chore: give github workflows more fitting names (#520) --- .github/workflows/build-ampd-main.yaml | 2 +- .github/workflows/build-ampd-release.yaml | 2 +- ...-and-push-to-r2.yaml => build-contracts-and-push-to-r2.yaml} | 2 +- .github/workflows/release.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename .github/workflows/{build-ampd-and-push-to-r2.yaml => build-contracts-and-push-to-r2.yaml} (96%) diff --git a/.github/workflows/build-ampd-main.yaml b/.github/workflows/build-ampd-main.yaml index 18bc7d1aa..f273aca28 100644 --- a/.github/workflows/build-ampd-main.yaml +++ b/.github/workflows/build-ampd-main.yaml @@ -1,4 +1,4 @@ -name: Amplifier - Build main branch +name: ampd (push to main) - Build and push image to ECR on: push: diff --git a/.github/workflows/build-ampd-release.yaml b/.github/workflows/build-ampd-release.yaml index 35be5321a..bd5000733 100644 --- a/.github/workflows/build-ampd-release.yaml +++ b/.github/workflows/build-ampd-release.yaml @@ -1,4 +1,4 @@ -name: Amplifier - Build Release +name: ampd - Build and release binary and image on: workflow_dispatch: diff --git a/.github/workflows/build-ampd-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml similarity index 96% rename from .github/workflows/build-ampd-and-push-to-r2.yaml rename to .github/workflows/build-contracts-and-push-to-r2.yaml index 985b64414..0067c8f8d 100644 --- a/.github/workflows/build-ampd-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -1,4 +1,4 @@ -name: Upload ampd contracts to Cloudflare R2 bucket +name: Amplifier wasm contracts - Upload wasm binaries to Cloudflare R2 bucket on: push: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6b762fd79..c70bb6248 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -name: Release +name: Update and tag release version on: workflow_dispatch: From d8969522c3015e6cd3b5b525baf0ed898dc93ac9 Mon Sep 17 00:00:00 2001 From: Talal Ashraf Date: Wed, 17 Jul 2024 14:32:37 -0400 Subject: [PATCH 083/168] chore(infra): log crates.toml to figure out issues with caching and use blacksmith rust-cache 3.0.1 (#516) --- .github/workflows/basic.yaml | 21 ++++++++++++++++++--- .github/workflows/codecov.yaml | 7 ++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index 68c9e24f8..2c8b3e572 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -29,10 +29,15 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Cache build artifacts - uses: useblacksmith/rust-cache@v3 + uses: useblacksmith/rust-cache@v3.0.1 + id: cache with: shared-key: "cache-tests" + - name: Log crates.toml + if: steps.cache.outputs.cache-hit == 'true' + run: cat /home/runner/.cargo/.crates.toml + - name: Run tests uses: actions-rs/cargo@v1 with: @@ -57,10 +62,15 @@ jobs: override: true - name: Cache build artifacts - uses: useblacksmith/rust-cache@v3 + id: cache + uses: useblacksmith/rust-cache@v3.0.1 with: shared-key: "cache-cosmwasm-compilation" + - name: Log crates.toml + if: steps.cache.outputs.cache-hit == 'true' + run: cat /home/runner/.cargo/.crates.toml + - name: Build wasm release run: | for C in ./contracts/*/ @@ -98,10 +108,15 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Cache build artifacts - uses: useblacksmith/rust-cache@v3 + uses: useblacksmith/rust-cache@v3.0.1 + id: cache with: shared-key: "cache-lints" + - name: Log crates.toml + if: steps.cache.outputs.cache-hit == 'true' + run: cat /home/runner/.cargo/.crates.toml + - name: Install cargo-sort uses: baptiste0928/cargo-install@v2 with: diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index e458bd9a1..51a41df6d 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -31,10 +31,15 @@ jobs: run: sudo apt-get install libclang-dev - name: Cache build artifacts - uses: useblacksmith/rust-cache@v3 + uses: useblacksmith/rust-cache@v3.0.1 + id: cache with: shared-key: "cache-codecov" + - name: Log crates.toml + if: steps.cache.outputs.cache-hit == 'true' + run: cat /home/runner/.cargo/.crates.toml + - name: Install cargo-llvm-cov uses: taiki-e/install-action@cargo-llvm-cov From f8a7fe760e92339a3f69a38995461769d96765cf Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 17 Jul 2024 20:01:39 +0000 Subject: [PATCH 084/168] chore: release router 0.4.0 [skip ci] --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/router/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c9907310..7f01dedf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6265,7 +6265,7 @@ dependencies = [ [[package]] name = "router" -version = "0.3.3" +version = "0.4.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index ad18c6023..83a1c828c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ resolver = "2" rust-version = "1.78.0" # be sure there is an optimizer release supporting this version before updating. See https://github.com/CosmWasm/optimizer [workspace.dependencies] -router = { version = "^0.3.3", path = "contracts/router" } +router = { version = "^0.4.0", path = "contracts/router" } cosmwasm-std = "1.5.5" cosmwasm-schema = "1.5.5" cw-storage-plus = { version = "1.2.0", features = ["iterator", "macro"] } diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index bb681b9f0..4184fe32d 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "router" -version = "0.3.3" +version = "0.4.0" rust-version = { workspace = true } edition = "2021" description = "Router contract" From c1e80ca9d1a03d721122398fa67bf953aedb7412 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:01:46 -0600 Subject: [PATCH 085/168] chore: update compatibility matrix (#521) Co-authored-by: Milap Sheth --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 14a6fbc39..a445c43be 100644 --- a/README.md +++ b/README.md @@ -43,15 +43,15 @@ contracts and `ampd` that work well together. | Binary | Version | |-------------|---------| -| ampd | 0.5.0 | +| ampd | 0.6.0 | | coordinator | 0.2.0 | | gateway | 0.2.3 | | multisig-prover | 0.6.0 | | multisig | 0.4.1 | | nexus-gateway | 0.3.0 | | rewards | 0.4.0 | -| router | 0.3.3 | +| router | 0.4.0 | | service-registry | 0.4.1 | | voting-verifier | 0.5.0 | -| [tofnd](https://github.com/axelarnetwork/tofnd) | v1.0.0 | +| [tofnd](https://github.com/axelarnetwork/tofnd) | v1.0.1 | | [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | From 600f247b4cffefd1c855b76f63699289e32d2506 Mon Sep 17 00:00:00 2001 From: Sammy Date: Thu, 18 Jul 2024 02:49:40 -0400 Subject: [PATCH 086/168] feat(ampd): integrate ampd queued broadcaster with the axelar batch request (#474) --- ampd/build.rs | 8 + ampd/proto/axelar/README.md | 11 + .../axelar/auxiliary/v1beta1/events.proto | 12 + .../axelar/auxiliary/v1beta1/genesis.proto | 11 + .../axelar/auxiliary/v1beta1/service.proto | 20 + ampd/proto/axelar/auxiliary/v1beta1/tx.proto | 30 ++ .../axelar/axelarnet/v1beta1/events.proto | 131 ++++++ .../axelar/axelarnet/v1beta1/genesis.proto | 27 ++ .../axelar/axelarnet/v1beta1/params.proto | 33 ++ .../axelar/axelarnet/v1beta1/proposal.proto | 29 ++ .../axelar/axelarnet/v1beta1/query.proto | 39 ++ .../axelar/axelarnet/v1beta1/service.proto | 118 +++++ ampd/proto/axelar/axelarnet/v1beta1/tx.proto | 188 ++++++++ .../axelar/axelarnet/v1beta1/types.proto | 62 +++ ampd/proto/axelar/evm/v1beta1/events.proto | 340 ++++++++++++++ ampd/proto/axelar/evm/v1beta1/genesis.proto | 39 ++ ampd/proto/axelar/evm/v1beta1/params.proto | 37 ++ ampd/proto/axelar/evm/v1beta1/query.proto | 243 +++++++++++ ampd/proto/axelar/evm/v1beta1/service.proto | 208 +++++++++ ampd/proto/axelar/evm/v1beta1/tx.proto | 259 +++++++++++ ampd/proto/axelar/evm/v1beta1/types.proto | 375 ++++++++++++++++ .../multisig/exported/v1beta1/types.proto | 28 ++ .../axelar/multisig/v1beta1/events.proto | 127 ++++++ .../axelar/multisig/v1beta1/genesis.proto | 20 + .../axelar/multisig/v1beta1/params.proto | 21 + .../proto/axelar/multisig/v1beta1/query.proto | 114 +++++ .../axelar/multisig/v1beta1/service.proto | 92 ++++ ampd/proto/axelar/multisig/v1beta1/tx.proto | 86 ++++ .../proto/axelar/multisig/v1beta1/types.proto | 84 ++++ .../axelar/nexus/exported/v1beta1/types.proto | 129 ++++++ ampd/proto/axelar/nexus/v1beta1/events.proto | 66 +++ ampd/proto/axelar/nexus/v1beta1/genesis.proto | 32 ++ ampd/proto/axelar/nexus/v1beta1/params.proto | 22 + ampd/proto/axelar/nexus/v1beta1/query.proto | 175 ++++++++ ampd/proto/axelar/nexus/v1beta1/service.proto | 150 +++++++ ampd/proto/axelar/nexus/v1beta1/tx.proto | 87 ++++ ampd/proto/axelar/nexus/v1beta1/types.proto | 65 +++ .../permission/exported/v1beta1/types.proto | 24 + .../axelar/permission/v1beta1/genesis.proto | 19 + .../axelar/permission/v1beta1/params.proto | 10 + .../axelar/permission/v1beta1/query.proto | 27 ++ .../axelar/permission/v1beta1/service.proto | 54 +++ ampd/proto/axelar/permission/v1beta1/tx.proto | 41 ++ .../axelar/permission/v1beta1/types.proto | 15 + .../proto/axelar/reward/v1beta1/genesis.proto | 17 + ampd/proto/axelar/reward/v1beta1/params.proto | 20 + ampd/proto/axelar/reward/v1beta1/query.proto | 28 ++ .../proto/axelar/reward/v1beta1/service.proto | 42 ++ ampd/proto/axelar/reward/v1beta1/tx.proto | 24 + ampd/proto/axelar/reward/v1beta1/types.proto | 33 ++ .../snapshot/exported/v1beta1/types.proto | 39 ++ .../axelar/snapshot/v1beta1/genesis.proto | 18 + .../axelar/snapshot/v1beta1/params.proto | 11 + .../proto/axelar/snapshot/v1beta1/query.proto | 35 ++ .../axelar/snapshot/v1beta1/service.proto | 41 ++ ampd/proto/axelar/snapshot/v1beta1/tx.proto | 28 ++ .../proto/axelar/snapshot/v1beta1/types.proto | 17 + .../axelar/tss/exported/v1beta1/types.proto | 68 +++ .../axelar/tss/tofnd/v1beta1/common.proto | 28 ++ .../axelar/tss/tofnd/v1beta1/multisig.proto | 40 ++ .../axelar/tss/tofnd/v1beta1/tofnd.proto | 129 ++++++ ampd/proto/axelar/tss/v1beta1/genesis.proto | 12 + ampd/proto/axelar/tss/v1beta1/params.proto | 32 ++ ampd/proto/axelar/tss/v1beta1/query.proto | 14 + ampd/proto/axelar/tss/v1beta1/service.proto | 32 ++ ampd/proto/axelar/tss/v1beta1/tx.proto | 147 +++++++ ampd/proto/axelar/tss/v1beta1/types.proto | 63 +++ ampd/proto/axelar/utils/v1beta1/bitmap.proto | 16 + ampd/proto/axelar/utils/v1beta1/queuer.proto | 19 + .../axelar/utils/v1beta1/threshold.proto | 16 + .../axelar/vote/exported/v1beta1/types.proto | 73 ++++ ampd/proto/axelar/vote/v1beta1/events.proto | 16 + ampd/proto/axelar/vote/v1beta1/genesis.proto | 17 + ampd/proto/axelar/vote/v1beta1/params.proto | 16 + ampd/proto/axelar/vote/v1beta1/query.proto | 14 + ampd/proto/axelar/vote/v1beta1/service.proto | 30 ++ ampd/proto/axelar/vote/v1beta1/tx.proto | 31 ++ ampd/proto/axelar/vote/v1beta1/types.proto | 33 ++ ampd/proto/third_party/buf.yaml | 20 + .../cosmos/auth/v1beta1/auth.proto | 50 +++ .../cosmos/auth/v1beta1/genesis.proto | 17 + .../cosmos/auth/v1beta1/query.proto | 89 ++++ .../cosmos/authz/v1beta1/authz.proto | 39 ++ .../cosmos/authz/v1beta1/event.proto | 25 ++ .../cosmos/authz/v1beta1/genesis.proto | 13 + .../cosmos/authz/v1beta1/query.proto | 81 ++++ .../third_party/cosmos/authz/v1beta1/tx.proto | 70 +++ .../cosmos/bank/v1beta1/authz.proto | 19 + .../cosmos/bank/v1beta1/bank.proto | 96 ++++ .../cosmos/bank/v1beta1/genesis.proto | 39 ++ .../cosmos/bank/v1beta1/query.proto | 193 ++++++++ .../third_party/cosmos/bank/v1beta1/tx.proto | 42 ++ .../cosmos/base/abci/v1beta1/abci.proto | 144 ++++++ .../cosmos/base/kv/v1beta1/kv.proto | 17 + .../cosmos/base/node/v1beta1/query.proto | 22 + .../base/query/v1beta1/pagination.proto | 55 +++ .../base/reflection/v1beta1/reflection.proto | 44 ++ .../base/reflection/v2alpha1/reflection.proto | 218 +++++++++ .../base/snapshots/v1beta1/snapshot.proto | 57 +++ .../base/store/v1beta1/commit_info.proto | 29 ++ .../cosmos/base/store/v1beta1/listening.proto | 34 ++ .../base/tendermint/v1beta1/query.proto | 138 ++++++ .../cosmos/base/v1beta1/coin.proto | 40 ++ .../capability/v1beta1/capability.proto | 30 ++ .../cosmos/capability/v1beta1/genesis.proto | 26 ++ .../cosmos/crisis/v1beta1/genesis.proto | 15 + .../cosmos/crisis/v1beta1/tx.proto | 25 ++ .../cosmos/crypto/ed25519/keys.proto | 23 + .../cosmos/crypto/multisig/keys.proto | 18 + .../crypto/multisig/v1beta1/multisig.proto | 25 ++ .../cosmos/crypto/secp256k1/keys.proto | 22 + .../cosmos/crypto/secp256r1/keys.proto | 23 + .../distribution/v1beta1/distribution.proto | 157 +++++++ .../cosmos/distribution/v1beta1/genesis.proto | 155 +++++++ .../cosmos/distribution/v1beta1/query.proto | 218 +++++++++ .../cosmos/distribution/v1beta1/tx.proto | 79 ++++ .../cosmos/evidence/v1beta1/evidence.proto | 21 + .../cosmos/evidence/v1beta1/genesis.proto | 12 + .../cosmos/evidence/v1beta1/query.proto | 51 +++ .../cosmos/evidence/v1beta1/tx.proto | 32 ++ .../cosmos/feegrant/v1beta1/feegrant.proto | 78 ++++ .../cosmos/feegrant/v1beta1/genesis.proto | 13 + .../cosmos/feegrant/v1beta1/query.proto | 78 ++++ .../cosmos/feegrant/v1beta1/tx.proto | 49 +++ .../cosmos/genutil/v1beta1/genesis.proto | 16 + .../cosmos/gov/v1beta1/genesis.proto | 26 ++ .../third_party/cosmos/gov/v1beta1/gov.proto | 200 +++++++++ .../cosmos/gov/v1beta1/query.proto | 190 ++++++++ .../third_party/cosmos/gov/v1beta1/tx.proto | 99 +++++ .../cosmos/mint/v1beta1/genesis.proto | 16 + .../cosmos/mint/v1beta1/mint.proto | 53 +++ .../cosmos/mint/v1beta1/query.proto | 57 +++ .../cosmos/params/v1beta1/params.proto | 27 ++ .../cosmos/params/v1beta1/query.proto | 32 ++ .../cosmos/slashing/v1beta1/genesis.proto | 50 +++ .../cosmos/slashing/v1beta1/query.proto | 63 +++ .../cosmos/slashing/v1beta1/slashing.proto | 58 +++ .../cosmos/slashing/v1beta1/tx.proto | 26 ++ .../cosmos/staking/v1beta1/authz.proto | 47 ++ .../cosmos/staking/v1beta1/genesis.proto | 53 +++ .../cosmos/staking/v1beta1/query.proto | 348 +++++++++++++++ .../cosmos/staking/v1beta1/staking.proto | 334 ++++++++++++++ .../cosmos/staking/v1beta1/tx.proto | 123 ++++++ .../cosmos/tx/signing/v1beta1/signing.proto | 91 ++++ .../cosmos/tx/v1beta1/service.proto | 165 +++++++ .../third_party/cosmos/tx/v1beta1/tx.proto | 183 ++++++++ .../cosmos/upgrade/v1beta1/query.proto | 104 +++++ .../cosmos/upgrade/v1beta1/upgrade.proto | 78 ++++ .../cosmos/vesting/v1beta1/tx.proto | 31 ++ .../cosmos/vesting/v1beta1/vesting.proto | 85 ++++ .../third_party/cosmos_proto/cosmos.proto | 16 + .../third_party/cosmwasm/wasm/v1/authz.proto | 118 +++++ .../cosmwasm/wasm/v1/genesis.proto | 46 ++ .../third_party/cosmwasm/wasm/v1/ibc.proto | 37 ++ .../cosmwasm/wasm/v1/proposal.proto | 272 ++++++++++++ .../third_party/cosmwasm/wasm/v1/query.proto | 263 +++++++++++ .../third_party/cosmwasm/wasm/v1/tx.proto | 192 ++++++++ .../third_party/cosmwasm/wasm/v1/types.proto | 145 ++++++ ampd/proto/third_party/gogoproto/gogo.proto | 145 ++++++ .../third_party/google/api/annotations.proto | 31 ++ ampd/proto/third_party/google/api/http.proto | 379 ++++++++++++++++ .../applications/transfer/v1/genesis.proto | 19 + .../ibc/applications/transfer/v1/query.proto | 105 +++++ .../applications/transfer/v1/transfer.proto | 30 ++ .../ibc/applications/transfer/v1/tx.proto | 49 +++ .../ibc/applications/transfer/v2/packet.proto | 21 + .../ibc/core/channel/v1/channel.proto | 162 +++++++ .../ibc/core/channel/v1/genesis.proto | 32 ++ .../ibc/core/channel/v1/query.proto | 376 ++++++++++++++++ .../third_party/ibc/core/channel/v1/tx.proto | 245 +++++++++++ .../ibc/core/client/v1/client.proto | 103 +++++ .../ibc/core/client/v1/genesis.proto | 48 ++ .../ibc/core/client/v1/query.proto | 207 +++++++++ .../third_party/ibc/core/client/v1/tx.proto | 99 +++++ .../ibc/core/commitment/v1/commitment.proto | 41 ++ .../ibc/core/connection/v1/connection.proto | 114 +++++ .../ibc/core/connection/v1/genesis.proto | 18 + .../ibc/core/connection/v1/query.proto | 138 ++++++ .../ibc/core/connection/v1/tx.proto | 118 +++++ .../ibc/core/types/v1/genesis.proto | 23 + .../lightclients/localhost/v1/localhost.proto | 18 + .../solomachine/v1/solomachine.proto | 189 ++++++++ .../solomachine/v2/solomachine.proto | 189 ++++++++ .../tendermint/v1/tendermint.proto | 114 +++++ ampd/proto/third_party/proofs.proto | 234 ++++++++++ .../third_party/tendermint/abci/types.proto | 413 ++++++++++++++++++ .../third_party/tendermint/crypto/keys.proto | 17 + .../third_party/tendermint/crypto/proof.proto | 41 ++ .../tendermint/libs/bits/types.proto | 9 + .../third_party/tendermint/p2p/types.proto | 34 ++ .../third_party/tendermint/types/block.proto | 15 + .../tendermint/types/evidence.proto | 38 ++ .../third_party/tendermint/types/params.proto | 80 ++++ .../third_party/tendermint/types/types.proto | 157 +++++++ .../tendermint/types/validator.proto | 25 ++ .../tendermint/version/types.proto | 24 + ampd/src/broadcaster/confirm_tx.rs | 353 +++++++++++++++ ampd/src/broadcaster/mod.rs | 161 +------ ampd/src/lib.rs | 27 +- ampd/src/queue/mod.rs | 1 + ampd/src/queue/proto.rs | 42 ++ ampd/src/queue/queued_broadcaster.rs | 229 +++++++--- 202 files changed, 16004 insertions(+), 201 deletions(-) create mode 100644 ampd/proto/axelar/README.md create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/events.proto create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/service.proto create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/events.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/params.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/proposal.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/query.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/service.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/types.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/events.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/params.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/query.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/service.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/types.proto create mode 100644 ampd/proto/axelar/multisig/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/events.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/params.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/query.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/service.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/types.proto create mode 100644 ampd/proto/axelar/nexus/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/events.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/params.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/query.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/service.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/types.proto create mode 100644 ampd/proto/axelar/permission/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/params.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/query.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/service.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/types.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/params.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/query.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/service.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/types.proto create mode 100644 ampd/proto/axelar/snapshot/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/params.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/query.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/service.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/types.proto create mode 100644 ampd/proto/axelar/tss/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/common.proto create mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto create mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/params.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/query.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/service.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/types.proto create mode 100644 ampd/proto/axelar/utils/v1beta1/bitmap.proto create mode 100644 ampd/proto/axelar/utils/v1beta1/queuer.proto create mode 100644 ampd/proto/axelar/utils/v1beta1/threshold.proto create mode 100644 ampd/proto/axelar/vote/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/events.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/params.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/query.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/service.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/types.proto create mode 100644 ampd/proto/third_party/buf.yaml create mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto create mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/event.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto create mode 100644 ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto create mode 100644 ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto create mode 100644 ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto create mode 100644 ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto create mode 100644 ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto create mode 100644 ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto create mode 100644 ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto create mode 100644 ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/base/v1beta1/coin.proto create mode 100644 ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto create mode 100644 ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/multisig/keys.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto create mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/params/v1beta1/params.proto create mode 100644 ampd/proto/third_party/cosmos/params/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto create mode 100644 ampd/proto/third_party/cosmos/tx/v1beta1/service.proto create mode 100644 ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto create mode 100644 ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto create mode 100644 ampd/proto/third_party/cosmos_proto/cosmos.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/query.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/types.proto create mode 100644 ampd/proto/third_party/gogoproto/gogo.proto create mode 100644 ampd/proto/third_party/google/api/annotations.proto create mode 100644 ampd/proto/third_party/google/api/http.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/channel.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/client.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/connection.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/core/types/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto create mode 100644 ampd/proto/third_party/proofs.proto create mode 100644 ampd/proto/third_party/tendermint/abci/types.proto create mode 100644 ampd/proto/third_party/tendermint/crypto/keys.proto create mode 100644 ampd/proto/third_party/tendermint/crypto/proof.proto create mode 100644 ampd/proto/third_party/tendermint/libs/bits/types.proto create mode 100644 ampd/proto/third_party/tendermint/p2p/types.proto create mode 100644 ampd/proto/third_party/tendermint/types/block.proto create mode 100644 ampd/proto/third_party/tendermint/types/evidence.proto create mode 100644 ampd/proto/third_party/tendermint/types/params.proto create mode 100644 ampd/proto/third_party/tendermint/types/types.proto create mode 100644 ampd/proto/third_party/tendermint/types/validator.proto create mode 100644 ampd/proto/third_party/tendermint/version/types.proto create mode 100644 ampd/src/broadcaster/confirm_tx.rs create mode 100644 ampd/src/queue/proto.rs diff --git a/ampd/build.rs b/ampd/build.rs index 7581fa013..cd5acc3b9 100644 --- a/ampd/build.rs +++ b/ampd/build.rs @@ -8,5 +8,13 @@ fn main() -> Result<(), Box> { .build_client(true) .compile(&["proto/ampd.proto"], &["proto"])?; + tonic_build::configure() + .build_server(false) + .build_client(false) + .compile( + &["proto/axelar/auxiliary/v1beta1/tx.proto"], + &["proto", "proto/third_party"], + )?; + Ok(()) } diff --git a/ampd/proto/axelar/README.md b/ampd/proto/axelar/README.md new file mode 100644 index 000000000..519187b2b --- /dev/null +++ b/ampd/proto/axelar/README.md @@ -0,0 +1,11 @@ +# Axelar Protobufs + +This folder defines protobufs used by Axelar specific Cosmos SDK msg, event, and query types. + +## REST API + +The REST API (LCD) gets generated automatically from the gRPC service definitions. +The request/response types are defined in `query.proto` for the respective modules, and the query is defined in the `service.proto`. + +Note: The request types cannot make use of custom types encoded as bytes as that would be awkward +for REST-based calls. Instead, primitive types such as string is used (for e.g. when specifying addresses, instead of using sdk.AccAddress). diff --git a/ampd/proto/axelar/auxiliary/v1beta1/events.proto b/ampd/proto/axelar/auxiliary/v1beta1/events.proto new file mode 100644 index 000000000..90956b702 --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/events.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; +option (gogoproto.messagename_all) = true; + +import "gogoproto/gogo.proto"; + +message BatchedMessageFailed { + int32 index = 1; + string error = 2; +} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto b/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto new file mode 100644 index 000000000..0d766e10f --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState {} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/service.proto b/ampd/proto/axelar/auxiliary/v1beta1/service.proto new file mode 100644 index 000000000..6d2a08e9b --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/service.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/auxiliary/v1beta1/tx.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the nexus Msg service. +service MsgService { + rpc Batch(BatchRequest) returns (BatchResponse) { + option (google.api.http) = { + post : "/axelar/auxiliary/batch" + body : "*" + }; + } +} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/tx.proto b/ampd/proto/axelar/auxiliary/v1beta1/tx.proto new file mode 100644 index 000000000..065016da4 --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/tx.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; + +import "axelar/permission/exported/v1beta1/types.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; + +message BatchRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated google.protobuf.Any messages = 2 + [ (gogoproto.nullable) = false, (cosmos_proto.accepts_interface) = "cosmos.base.v1beta1.Msg" ]; +} + +message BatchResponse { + message Response { + oneof res { + cosmos.base.abci.v1beta1.Result result = 1; + string err = 2; + } + } + repeated Response responses = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/events.proto b/ampd/proto/axelar/axelarnet/v1beta1/events.proto new file mode 100644 index 000000000..a5e9e0a67 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/events.proto @@ -0,0 +1,131 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.messagename_all) = true; + +message IBCTransferSent { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string receipient = 2 [ deprecated = true ]; + cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; + uint64 sequence = 4; + string port_id = 5 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 6 [ (gogoproto.customname) = "ChannelID" ]; + string recipient = 7; +} + +message IBCTransferCompleted { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + uint64 sequence = 2; + string port_id = 3 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 4 [ (gogoproto.customname) = "ChannelID" ]; +} + +message IBCTransferFailed { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + uint64 sequence = 2; + string port_id = 3 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 4 [ (gogoproto.customname) = "ChannelID" ]; +} + +message IBCTransferRetried { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string receipient = 2 [ deprecated = true ]; + cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; + uint64 sequence = 4; + string port_id = 5 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 6 [ (gogoproto.customname) = "ChannelID" ]; + string recipient = 7; +} + +message AxelarTransferCompleted { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string receipient = 2 [ deprecated = true ]; + cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; + string recipient = 4; +} + +message FeeCollected { + bytes collector = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + cosmos.base.v1beta1.Coin fee = 2 [ (gogoproto.nullable) = false ]; +} + +message FeePaid { + string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; + bytes recipient = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + cosmos.base.v1beta1.Coin fee = 3 [ (gogoproto.nullable) = false ]; + string refund_recipient = 4; + string asset = 5; // registered asset name in nexus +} + +message ContractCallSubmitted { + string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; + string sender = 2; + string source_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 5; + bytes payload = 6; + bytes payload_hash = 7; +} + +message ContractCallWithTokenSubmitted { + string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; + string sender = 2; + string source_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 5; + bytes payload = 6; + bytes payload_hash = 7; + cosmos.base.v1beta1.Coin asset = 8 [ (gogoproto.nullable) = false ]; +} + +message TokenSent { + uint64 transfer_id = 1 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string sender = 2; + string source_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 5; + cosmos.base.v1beta1.Coin asset = 6 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto b/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto new file mode 100644 index 000000000..8cfea9cd5 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "axelar/axelarnet/v1beta1/params.proto"; +import "axelar/axelarnet/v1beta1/types.proto"; +import "axelar/utils/v1beta1/queuer.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GenesisState { + option (gogoproto.stable_marshaler) = true; + + Params params = 1 [ (gogoproto.nullable) = false ]; + bytes collector_address = 2 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated CosmosChain chains = 3 [ (gogoproto.nullable) = false ]; + reserved 4; // pending_transfers was removed in v0.20 + utils.v1beta1.QueueState transfer_queue = 5 [ (gogoproto.nullable) = false ]; + reserved 6; // failed_transfers was removed in v0.22 + repeated IBCTransfer ibc_transfers = 7 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "IBCTransfers" ]; + map seq_id_mapping = 8 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "SeqIDMapping" ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/params.proto b/ampd/proto/axelar/axelarnet/v1beta1/params.proto new file mode 100644 index 000000000..5d669fbc6 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/params.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + // IBC packet route timeout window + uint64 route_timeout_window = 1; + reserved 2; // transaction_fee_rate was removed in v0.15 + uint64 transfer_limit = 3; + uint64 end_blocker_limit = 4; + repeated CallContractProposalMinDeposit call_contracts_proposal_min_deposits = + 5 [ + (gogoproto.castrepeated) = "CallContractProposalMinDeposits", + (gogoproto.nullable) = false + ]; +} + +message CallContractProposalMinDeposit { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 2; + repeated cosmos.base.v1beta1.Coin min_deposits = 3 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto b/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto new file mode 100644 index 000000000..2994ca8c8 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package axelar.axelarnet.v1beta1; + +import "gogoproto/gogo.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; +option (gogoproto.goproto_getters_all) = false; + +// CallContractsProposal is a gov Content type for calling contracts on other +// chains +message CallContractsProposal { + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + repeated ContractCall contract_calls = 3 [ (gogoproto.nullable) = false ]; +} + +message ContractCall { + option (gogoproto.goproto_stringer) = false; + + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 2; + bytes payload = 3; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/query.proto b/ampd/proto/axelar/axelarnet/v1beta1/query.proto new file mode 100644 index 000000000..64fc7088d --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/query.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "axelar/axelarnet/v1beta1/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "axelar/nexus/v1beta1/query.proto"; +import "axelar/axelarnet/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message PendingIBCTransferCountRequest {} + +message PendingIBCTransferCountResponse { + map transfers_by_chain = 1 [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } + +// IBCPathRequest represents a message that queries the IBC path registered for +// a given chain +message IBCPathRequest { string chain = 1; } + +message IBCPathResponse { string ibc_path = 1 [ (gogoproto.customname) = "IBCPath" ]; } + +// ChainByIBCPathRequest represents a message that queries the chain that an IBC +// path is registered to +message ChainByIBCPathRequest { string ibc_path = 1; } + +message ChainByIBCPathResponse { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/service.proto b/ampd/proto/axelar/axelarnet/v1beta1/service.proto new file mode 100644 index 000000000..c2ed583e8 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/service.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/axelarnet/v1beta1/tx.proto"; +import "axelar/axelarnet/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the axelarnet Msg service. +service MsgService { + rpc Link(LinkRequest) returns (LinkResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/link" + body : "*" + }; + } + + rpc ConfirmDeposit(ConfirmDepositRequest) returns (ConfirmDepositResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/confirm_deposit" + body : "*" + }; + } + + rpc ExecutePendingTransfers(ExecutePendingTransfersRequest) + returns (ExecutePendingTransfersResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/execute_pending_transfers" + body : "*" + }; + } + + rpc AddCosmosBasedChain(AddCosmosBasedChainRequest) + returns (AddCosmosBasedChainResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/add_cosmos_based_chain" + body : "*" + }; + } + + rpc RegisterAsset(RegisterAssetRequest) returns (RegisterAssetResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/register_asset" + body : "*" + }; + } + + rpc RouteIBCTransfers(RouteIBCTransfersRequest) + returns (RouteIBCTransfersResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/route_ibc_transfers" + body : "*" + }; + } + + rpc RegisterFeeCollector(RegisterFeeCollectorRequest) + returns (RegisterFeeCollectorResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/register_fee_collector" + body : "*" + }; + } + + rpc RetryIBCTransfer(RetryIBCTransferRequest) + returns (RetryIBCTransferResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/retry_ibc_transfer" + body : "*" + }; + } + + rpc RouteMessage(RouteMessageRequest) returns (RouteMessageResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/route_message" + body : "*" + }; + } + + rpc CallContract(CallContractRequest) returns (CallContractResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/call_contract" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + + // PendingIBCTransferCount queries the pending ibc transfers for all chains + rpc PendingIBCTransferCount(PendingIBCTransferCountRequest) + returns (PendingIBCTransferCountResponse) { + option (google.api.http).get = + "/axelar/axelarnet/v1beta1/ibc_transfer_count"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/axelarnet/v1beta1/params" + }; + } + + rpc IBCPath(IBCPathRequest) returns (IBCPathResponse) { + option (google.api.http) = { + get : "/axelar/axelarnet/v1beta1/ibc_path/{chain}" + }; + } + + rpc ChainByIBCPath(ChainByIBCPathRequest) returns (ChainByIBCPathResponse) { + option (google.api.http) = { + get : "/axelar/axelarnet/v1beta1/chain_by_ibc_path/{ibc_path}" + }; + } +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/tx.proto b/ampd/proto/axelar/axelarnet/v1beta1/tx.proto new file mode 100644 index 000000000..95c5e5c7c --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/tx.proto @@ -0,0 +1,188 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/axelarnet/v1beta1/types.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// MsgLink represents a message to link a cross-chain address to an Axelar +// address +message LinkRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string recipient_addr = 2; + string recipient_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string asset = 4; +} + +message LinkResponse { string deposit_addr = 1; }; + +// MsgConfirmDeposit represents a deposit confirmation message +message ConfirmDepositRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + reserved 2; // tx_id was removed in v0.14 + + reserved 3; // token was removed in v0.15 + + bytes deposit_address = 4 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + string denom = 5; +} + +message ConfirmDepositResponse {} + +// MsgExecutePendingTransfers represents a message to trigger transfer all +// pending transfers +message ExecutePendingTransfersRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message ExecutePendingTransfersResponse {} + +// MSgRegisterIBCPath represents a message to register an IBC tracing path for +// a cosmos chain +message RegisterIBCPathRequest { + option deprecated = true; + + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string path = 3; +} + +message RegisterIBCPathResponse {} + +// MsgAddCosmosBasedChain represents a message to register a cosmos based chain +// to nexus +message AddCosmosBasedChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + nexus.exported.v1beta1.Chain chain = 2 [ + deprecated = true, + (gogoproto.nullable) = false + ]; // chain was deprecated in v0.27 + string addr_prefix = 3; + reserved 4; // min_amount was removed in v0.15 + repeated nexus.exported.v1beta1.Asset native_assets = 5 [ + deprecated = true, + (gogoproto.nullable) = false + ]; // native_assets was deprecated in v0.27 + // TODO: Rename this to `chain` after v1beta1 -> v1 version bump + string cosmos_chain = 6 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string ibc_path = 7 [ (gogoproto.customname) = "IBCPath" ]; +} + +message AddCosmosBasedChainResponse {} + +// RegisterAssetRequest represents a message to register an asset to a cosmos +// based chain +message RegisterAssetRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + nexus.exported.v1beta1.Asset asset = 3 [ (gogoproto.nullable) = false ]; + bytes limit = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration window = 5 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message RegisterAssetResponse {} + +// RouteIBCTransfersRequest represents a message to route pending transfers to +// cosmos based chains +message RouteIBCTransfersRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RouteIBCTransfersResponse {} + +// RegisterFeeCollectorRequest represents a message to register axelarnet fee +// collector account +message RegisterFeeCollectorRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes fee_collector = 2 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RegisterFeeCollectorResponse {} + +message RetryIBCTransferRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 [ + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName", + deprecated = true + ]; + uint64 id = 3 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; +} + +message RetryIBCTransferResponse {} + +message RouteMessageRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string id = 2 [ (gogoproto.customname) = "ID" ]; + bytes payload = 3; + bytes feegranter = 4 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RouteMessageResponse {} + +message CallContractRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 3; + bytes payload = 4; + Fee fee = 5; +} + +message CallContractResponse {} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/types.proto b/ampd/proto/axelar/axelarnet/v1beta1/types.proto new file mode 100644 index 000000000..b20ae2799 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/types.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message IBCTransfer { + enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "TransferNonExistent" ]; + STATUS_PENDING = 1 [ (gogoproto.enumvalue_customname) = "TransferPending" ]; + STATUS_COMPLETED = 2 + [ (gogoproto.enumvalue_customname) = "TransferCompleted" ]; + STATUS_FAILED = 3 [ (gogoproto.enumvalue_customname) = "TransferFailed" ]; + } + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string receiver = 2; + cosmos.base.v1beta1.Coin token = 3 [ (gogoproto.nullable) = false ]; + string port_id = 4 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 5 [ (gogoproto.customname) = "ChannelID" ]; + uint64 sequence = 6 [ deprecated = true ]; + uint64 id = 7 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + Status status = 8; +} + +message CosmosChain { + string name = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string ibc_path = 2 [ (gogoproto.customname) = "IBCPath" ]; + repeated Asset assets = 3 [ (gogoproto.nullable) = false, deprecated = true ]; + string addr_prefix = 4; +} + +message Asset { + option deprecated = true; + string denom = 1; + bytes min_amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message Fee { + cosmos.base.v1beta1.Coin amount = 1 [ (gogoproto.nullable) = false ]; + bytes recipient = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes refund_recipient = 3 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} diff --git a/ampd/proto/axelar/evm/v1beta1/events.proto b/ampd/proto/axelar/evm/v1beta1/events.proto new file mode 100644 index 000000000..bcdd74e99 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/events.proto @@ -0,0 +1,340 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; +option (gogoproto.messagename_all) = true; + +import "gogoproto/gogo.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +message PollFailed { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message PollExpired { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message PollCompleted { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message NoEventsConfirmed { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message ConfirmKeyTransferStarted { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 4; + vote.exported.v1beta1.PollParticipants participants = 5 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; +} + +message ConfirmGatewayTxStarted { + option deprecated = true; + + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 4; + vote.exported.v1beta1.PollParticipants participants = 5 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; +} + +message PollMapping { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + uint64 poll_id = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID" + ]; +} + +message ConfirmGatewayTxsStarted { + repeated PollMapping poll_mappings = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "poll_mappings,omitempty" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 4; + repeated bytes participants = 5 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +message ConfirmDepositStarted { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes deposit_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes token_address = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 5; + vote.exported.v1beta1.PollParticipants participants = 6 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; + string asset = 7; +} + +message ConfirmTokenStarted { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes token_address = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + evm.v1beta1.TokenDetails token_details = 5 [ (gogoproto.nullable) = false ]; + uint64 confirmation_height = 6; + vote.exported.v1beta1.PollParticipants participants = 7 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; +} + +message ChainAdded { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CommandBatchSigned { + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; +} + +message CommandBatchAborted { + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; +} + +message EVMEventConfirmed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message EVMEventCompleted { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message EVMEventFailed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message EVMEventRetryFailed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message ContractCallApproved { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + bytes command_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string sender = 4; + string destination_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 6; + bytes payload_hash = 7 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; +} + +message ContractCallFailed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string msg_id = 2 [ (gogoproto.customname) = "MessageID" ]; +} + +message ContractCallWithMintApproved { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + bytes command_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string sender = 4; + string destination_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 6; + bytes payload_hash = 7 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + cosmos.base.v1beta1.Coin asset = 8 [ (gogoproto.nullable) = false ]; +} + +message TokenSent { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + uint64 transfer_id = 3 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string sender = 4; + string destination_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 6; + cosmos.base.v1beta1.Coin asset = 7 [ (gogoproto.nullable) = false ]; +} + +message MintCommand { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 transfer_id = 2 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + bytes command_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 5; + cosmos.base.v1beta1.Coin asset = 6 [ (gogoproto.nullable) = false ]; +} + +message BurnCommand { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_id = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string destination_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string deposit_address = 4; + string asset = 5; +} diff --git a/ampd/proto/axelar/evm/v1beta1/genesis.proto b/ampd/proto/axelar/evm/v1beta1/genesis.proto new file mode 100644 index 000000000..3e0edc463 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/genesis.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "axelar/utils/v1beta1/queuer.proto"; +import "gogoproto/gogo.proto"; +import "axelar/evm/v1beta1/params.proto"; +import "axelar/evm/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + option (gogoproto.stable_marshaler) = true; + + message Chain { + Params params = 1 [ (gogoproto.nullable) = false ]; + repeated BurnerInfo burner_infos = 2 [ (gogoproto.nullable) = false ]; + utils.v1beta1.QueueState command_queue = 3 [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit confirmed_deposits = 4 + [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit burned_deposits = 5 [ (gogoproto.nullable) = false ]; + + repeated CommandBatchMetadata command_batches = 8 + [ (gogoproto.nullable) = false ]; + + Gateway gateway = 9 [ (gogoproto.nullable) = false ]; + repeated ERC20TokenMetadata tokens = 10 [ (gogoproto.nullable) = false ]; + repeated Event events = 11 [ (gogoproto.nullable) = false ]; + utils.v1beta1.QueueState confirmed_event_queue = 12 + [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit legacy_confirmed_deposits = 13 + [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit legacy_burned_deposits = 14 + [ (gogoproto.nullable) = false ]; + } + + repeated Chain chains = 3 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/evm/v1beta1/params.proto b/ampd/proto/axelar/evm/v1beta1/params.proto new file mode 100644 index 000000000..6fc387be1 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/params.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "gogoproto/gogo.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params is the parameter set for this module +message Params { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 confirmation_height = 2; + string network = 3; + reserved 4; // gateway_code was removed in v0.16 + bytes token_code = 5; + bytes burnable = 6; + int64 revote_locking_period = 7; + repeated evm.v1beta1.NetworkInfo networks = 8 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold voting_threshold = 9 [ (gogoproto.nullable) = false ]; + int64 min_voter_count = 10; + uint32 commands_gas_limit = 11; + reserved 12; // transaction_fee_rate was removed in v0.15 + int64 voting_grace_period = 13; + int64 end_blocker_limit = 14; + uint64 transfer_limit = 15; +} + +message PendingChain { + Params params = 1 [ (gogoproto.nullable) = false ]; + nexus.exported.v1beta1.Chain chain = 2 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/evm/v1beta1/query.proto b/ampd/proto/axelar/evm/v1beta1/query.proto new file mode 100644 index 000000000..61de10b01 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/query.proto @@ -0,0 +1,243 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "gogoproto/gogo.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "axelar/evm/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// DepositQueryParams describe the parameters used to query for an EVM +// deposit address +message DepositQueryParams { + string address = 1; + string asset = 2; + string chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message BatchedCommandsRequest { + string chain = 1; + // id defines an optional id for the commandsbatch. If not specified the + // latest will be returned + string id = 2; +} + +message BatchedCommandsResponse { + string id = 1 [ (gogoproto.customname) = "ID" ]; + string data = 2; + BatchedCommandsStatus status = 3; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + reserved 5; // signature was removed in v0.20.0 + string execute_data = 6; + string prev_batched_commands_id = 7 + [ (gogoproto.customname) = "PrevBatchedCommandsID" ]; + repeated string command_ids = 8 [ (gogoproto.customname) = "CommandIDs" ]; + Proof proof = 9; +} + +message KeyAddressRequest { + reserved 2, 3; + + string chain = 1; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeyAddressResponse { + message WeightedAddress { + string address = 1; + string weight = 2; + }; + + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + repeated WeightedAddress addresses = 2 [ (gogoproto.nullable) = false ]; + string threshold = 3; +} + +message QueryTokenAddressResponse { + option deprecated = true; // Deprecated in v19 + + string address = 1; + bool confirmed = 2; +} + +message QueryDepositStateParams { + option deprecated = true; + + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes burner_address = 2 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message DepositStateRequest { + option deprecated = true; + + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + QueryDepositStateParams params = 2; +} + +message DepositStateResponse { + option deprecated = true; + + DepositStatus status = 2; +} + +message EventRequest { + string chain = 1; + string event_id = 2; +} + +message EventResponse { Event event = 1; } + +message QueryBurnerAddressResponse { string address = 1; } + +enum ChainStatus { + option (gogoproto.goproto_enum_prefix) = false; + + CHAIN_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "StatusUnspecified" ]; + CHAIN_STATUS_ACTIVATED = 1 [ (gogoproto.enumvalue_customname) = "Activated" ]; + CHAIN_STATUS_DEACTIVATED = 2 + [ (gogoproto.enumvalue_customname) = "Deactivated" ]; +} + +message ChainsRequest { ChainStatus status = 1; } + +message ChainsResponse { + repeated string chains = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CommandRequest { + string chain = 1; + string id = 2 [ (gogoproto.customname) = "ID" ]; +} + +message CommandResponse { + string id = 1 [ (gogoproto.customname) = "ID" ]; + string type = 2; + map params = 3 [ (gogoproto.nullable) = false ]; + string key_id = 4 [ (gogoproto.customname) = "KeyID" ]; + uint32 max_gas_cost = 5; +} + +message PendingCommandsRequest { string chain = 1; } + +message PendingCommandsResponse { + repeated QueryCommandResponse commands = 1 [ (gogoproto.nullable) = false ]; +} + +message QueryCommandResponse { + string id = 1 [ (gogoproto.customname) = "ID" ]; + string type = 2; + map params = 3 [ (gogoproto.nullable) = false ]; + string key_id = 4 [ (gogoproto.customname) = "KeyID" ]; + uint32 max_gas_cost = 5; +} + +message BurnerInfoRequest { + bytes address = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message BurnerInfoResponse { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + BurnerInfo burner_info = 2; +} + +message ConfirmationHeightRequest { string chain = 1; } + +message ConfirmationHeightResponse { uint64 height = 1; } + +message GatewayAddressRequest { string chain = 1; } + +message GatewayAddressResponse { string address = 1; } + +message BytecodeRequest { + string chain = 1; + string contract = 2; +} + +message BytecodeResponse { string bytecode = 1; } + +enum TokenType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + TOKEN_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + TOKEN_TYPE_INTERNAL = 1 [ (gogoproto.enumvalue_customname) = "Internal" ]; + TOKEN_TYPE_EXTERNAL = 2 [ (gogoproto.enumvalue_customname) = "External" ]; +} + +// ERC20TokensRequest describes the chain for which the type of ERC20 tokens are +// requested. +message ERC20TokensRequest { + string chain = 1; + TokenType type = 2; +} + +// ERC20TokensResponse describes the asset and symbol for all +// ERC20 tokens requested for a chain +message ERC20TokensResponse { + message Token { + string asset = 1; + string symbol = 2; + } + + repeated Token tokens = 1 [ (gogoproto.nullable) = false ]; +} + +message TokenInfoRequest { + string chain = 1; + oneof find_by { + string asset = 2; + string symbol = 3; + string address = 4; + } +} + +message TokenInfoResponse { + string asset = 1; + TokenDetails details = 2 [ (gogoproto.nullable) = false ]; + string address = 3; + bool confirmed = 4; + bool is_external = 5; + string burner_code_hash = 6; +} + +message Proof { + repeated string addresses = 1; + repeated string weights = 2; + string threshold = 3; + repeated string signatures = 4; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest { string chain = 1; } + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/evm/v1beta1/service.proto b/ampd/proto/axelar/evm/v1beta1/service.proto new file mode 100644 index 000000000..6cc9b02f0 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/service.proto @@ -0,0 +1,208 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/evm/v1beta1/tx.proto"; +import "axelar/evm/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the evm Msg service. +service MsgService { + rpc SetGateway(SetGatewayRequest) returns (SetGatewayResponse) { + option (google.api.http) = { + post : "/axelar/evm/set_gateway" + body : "*" + }; + } + + // Deprecated: use ConfirmGatewayTxs instead + rpc ConfirmGatewayTx(ConfirmGatewayTxRequest) + returns (ConfirmGatewayTxResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_gateway_tx" + body : "*" + }; + } + + rpc ConfirmGatewayTxs(ConfirmGatewayTxsRequest) + returns (ConfirmGatewayTxsResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_gateway_txs" + body : "*" + }; + } + + rpc Link(LinkRequest) returns (LinkResponse) { + option (google.api.http) = { + post : "/axelar/evm/link" + body : "*" + }; + } + + rpc ConfirmToken(ConfirmTokenRequest) returns (ConfirmTokenResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_token" + body : "*" + }; + } + + rpc ConfirmDeposit(ConfirmDepositRequest) returns (ConfirmDepositResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_deposit" + body : "*" + }; + } + + rpc ConfirmTransferKey(ConfirmTransferKeyRequest) + returns (ConfirmTransferKeyResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_transfer_key" + body : "*" + }; + } + + rpc CreateDeployToken(CreateDeployTokenRequest) + returns (CreateDeployTokenResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_deploy_token" + body : "*" + }; + } + + rpc CreateBurnTokens(CreateBurnTokensRequest) + returns (CreateBurnTokensResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_burn_tokens" + body : "*" + }; + } + + rpc CreatePendingTransfers(CreatePendingTransfersRequest) + returns (CreatePendingTransfersResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_pending_transfers" + body : "*" + }; + } + + rpc CreateTransferOperatorship(CreateTransferOperatorshipRequest) + returns (CreateTransferOperatorshipResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_transfer_operatorship" + body : "*" + }; + } + + rpc SignCommands(SignCommandsRequest) returns (SignCommandsResponse) { + option (google.api.http) = { + post : "/axelar/evm/sign_commands" + body : "*" + }; + } + + rpc AddChain(AddChainRequest) returns (AddChainResponse) { + option (google.api.http) = { + post : "/axelar/evm/add_chain" + body : "*" + }; + } + + rpc RetryFailedEvent(RetryFailedEventRequest) + returns (RetryFailedEventResponse) { + option (google.api.http) = { + post : "/axelar/evm/retry-failed-event" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + + // BatchedCommands queries the batched commands for a specified chain and + // BatchedCommandsID if no BatchedCommandsID is specified, then it returns the + // latest batched commands + rpc BatchedCommands(BatchedCommandsRequest) + returns (BatchedCommandsResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/batched_commands/{chain}/{id}"; + } + + // BurnerInfo queries the burner info for the specified address + rpc BurnerInfo(BurnerInfoRequest) returns (BurnerInfoResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/burner_info"; + } + + // ConfirmationHeight queries the confirmation height for the specified chain + rpc ConfirmationHeight(ConfirmationHeightRequest) + returns (ConfirmationHeightResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/confirmation_height/{chain}"; + } + + // DepositState queries the state of the specified deposit + rpc DepositState(DepositStateRequest) returns (DepositStateResponse) { + option deprecated = true; + option (google.api.http).get = "/axelar/evm/v1beta1/deposit_state"; + } + + // PendingCommands queries the pending commands for the specified chain + rpc PendingCommands(PendingCommandsRequest) + returns (PendingCommandsResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/pending_commands/{chain}"; + } + + // Chains queries the available evm chains + rpc Chains(ChainsRequest) returns (ChainsResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/chains"; + } + + // Command queries the command of a chain provided the command id + rpc Command(CommandRequest) returns (CommandResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/command_request"; + } + + // KeyAddress queries the address of key of a chain + rpc KeyAddress(KeyAddressRequest) returns (KeyAddressResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/key_address/{chain}"; + } + + // GatewayAddress queries the address of axelar gateway at the specified + // chain + rpc GatewayAddress(GatewayAddressRequest) returns (GatewayAddressResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/gateway_address/{chain}"; + } + + // Bytecode queries the bytecode of a specified gateway at the specified + // chain + rpc Bytecode(BytecodeRequest) returns (BytecodeResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/bytecode/{chain}/{contract}"; + } + + // Event queries an event at the specified chain + rpc Event(EventRequest) returns (EventResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/event/{chain}/{event_id}"; + } + + // ERC20Tokens queries the ERC20 tokens registered for a chain + rpc ERC20Tokens(ERC20TokensRequest) returns (ERC20TokensResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/erc20_tokens/{chain}"; + } + + // TokenInfo queries the token info for a registered ERC20 Token + rpc TokenInfo(TokenInfoRequest) returns (TokenInfoResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/token_info/{chain}"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/params/{chain}"; + } +} diff --git a/ampd/proto/axelar/evm/v1beta1/tx.proto b/ampd/proto/axelar/evm/v1beta1/tx.proto new file mode 100644 index 000000000..9aaef12e4 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/tx.proto @@ -0,0 +1,259 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "gogoproto/gogo.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message SetGatewayRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message SetGatewayResponse {} + +message ConfirmGatewayTxRequest { + option deprecated = true; + + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; +} + +message ConfirmGatewayTxResponse { option deprecated = true; } + +message ConfirmGatewayTxsRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated bytes tx_ids = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxIDs" + ]; +} + +message ConfirmGatewayTxsResponse {} + +// MsgConfirmDeposit represents an erc20 deposit confirmation message +message ConfirmDepositRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes amount = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false, + deprecated = true + ]; + bytes burner_address = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message ConfirmDepositResponse {} + +// MsgConfirmToken represents a token deploy confirmation message +message ConfirmTokenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + Asset asset = 4 [ (gogoproto.nullable) = false ]; +} + +message ConfirmTokenResponse {} + +message ConfirmTransferKeyRequest { + reserved 4, 5; // transfer_type and key_id were deleted in v0.20 + + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; +} + +message ConfirmTransferKeyResponse {} + +// MsgLink represents the message that links a cross chain address to a burner +// address +message LinkRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string recipient_addr = 3; + string asset = 4; + string recipient_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message LinkResponse { string deposit_addr = 1; } + +// CreateBurnTokensRequest represents the message to create commands to burn +// tokens with AxelarGateway +message CreateBurnTokensRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CreateBurnTokensResponse {} + +// CreateDeployTokenRequest represents the message to create a deploy token +// command for AxelarGateway +message CreateDeployTokenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + Asset asset = 3 [ (gogoproto.nullable) = false ]; + TokenDetails token_details = 4 [ (gogoproto.nullable) = false ]; + reserved 5; // min_amount was removed in v0.15 + bytes address = 6 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string daily_mint_limit = 7; +} + +message CreateDeployTokenResponse {} + +// CreatePendingTransfersRequest represents a message to trigger the creation of +// commands handling all pending transfers +message CreatePendingTransfersRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CreatePendingTransfersResponse {} + +message CreateTransferOwnershipRequest { + option deprecated = true; + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message CreateTransferOwnershipResponse { option deprecated = true; } + +message CreateTransferOperatorshipRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message CreateTransferOperatorshipResponse {} + +message SignCommandsRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message SignCommandsResponse { + bytes batched_commands_id = 1 + [ (gogoproto.customname) = "BatchedCommandsID" ]; + uint32 command_count = 2; +} + +message AddChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + reserved 3; // native_asset was removed in v0.14 + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string name = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + tss.exported.v1beta1.KeyType key_type = 4 [ deprecated = true ]; + bytes params = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Params" ]; +} + +message AddChainResponse {} + +message RetryFailedEventRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 3 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; +} + +message RetryFailedEventResponse {} diff --git a/ampd/proto/axelar/evm/v1beta1/types.proto b/ampd/proto/axelar/evm/v1beta1/types.proto new file mode 100644 index 000000000..13a849cf9 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/types.proto @@ -0,0 +1,375 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/multisig/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message VoteEvents { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated Event events = 2 [ (gogoproto.nullable) = false ]; +} + +message Event { + enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "EventNonExistent" ]; + STATUS_CONFIRMED = 1 + [ (gogoproto.enumvalue_customname) = "EventConfirmed" ]; + STATUS_COMPLETED = 2 + [ (gogoproto.enumvalue_customname) = "EventCompleted" ]; + STATUS_FAILED = 3 [ (gogoproto.enumvalue_customname) = "EventFailed" ]; + } + + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 2 [ + (gogoproto.customname) = "TxID", + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash" + ]; + uint64 index = 3; + Status status = 4; + + oneof event { + EventTokenSent token_sent = 5; + EventContractCall contract_call = 6; + EventContractCallWithToken contract_call_with_token = 7; + EventTransfer transfer = 8; + EventTokenDeployed token_deployed = 9; + EventMultisigOwnershipTransferred multisig_ownership_transferred = 10 + [ deprecated = true ]; + EventMultisigOperatorshipTransferred multisig_operatorship_transferred = 11; + } + + reserved 12; // singlesig_ownership_transferred was removed in v0.23 + reserved 13; // singlesig_operatorship_transferred was removed in v0.23 +} + +message EventTokenSent { + bytes sender = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 3; + string symbol = 4; + bytes amount = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventContractCall { + bytes sender = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 3; + bytes payload_hash = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; +} + +message EventContractCallWithToken { + bytes sender = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 3; + bytes payload_hash = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + string symbol = 5; + bytes amount = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventTransfer { + bytes to = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventTokenDeployed { + string symbol = 1; + bytes token_address = 2 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message EventMultisigOwnershipTransferred { + option deprecated = true; + + repeated bytes pre_owners = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes prev_threshold = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + repeated bytes new_owners = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes new_threshold = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventMultisigOperatorshipTransferred { + reserved 1, 2; // pre_operators and prev_threshold were removed in v0.20 + + repeated bytes new_operators = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes new_threshold = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + repeated bytes new_weights = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +// NetworkInfo describes information about a network +message NetworkInfo { + string name = 1; + bytes id = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// BurnerInfo describes information required to burn token at an burner address +// that is deposited by an user +message BurnerInfo { + bytes burner_address = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes token_address = 2 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string symbol = 4; + string asset = 5; + bytes salt = 6 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; +} + +// ERC20Deposit contains information for an ERC20 deposit +message ERC20Deposit { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + string asset = 3; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes burner_address = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 log_index = 6; +} + +// ERC20TokenMetadata describes information about an ERC20 token +message ERC20TokenMetadata { + string asset = 1; + bytes chain_id = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.customname) = "ChainID", + (gogoproto.nullable) = false + ]; + TokenDetails details = 3 [ (gogoproto.nullable) = false ]; + string token_address = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string tx_hash = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + reserved 6; // min_amount was removed in v0.15 + Status status = 7; + bool is_external = 8; + bytes burner_code = 9; +} + +enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + // these enum values are used for bitwise operations, therefore they need to + // be powers of 2 + STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + STATUS_INITIALIZED = 1 [ (gogoproto.enumvalue_customname) = "Initialized" ]; + STATUS_PENDING = 2 [ (gogoproto.enumvalue_customname) = "Pending" ]; + STATUS_CONFIRMED = 4 [ (gogoproto.enumvalue_customname) = "Confirmed" ]; +} + +message TransactionMetadata { + bytes raw_tx = 1 [ (gogoproto.customname) = "RawTX" ]; + bytes pub_key = 2; +} + +enum CommandType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = false; + + COMMAND_TYPE_UNSPECIFIED = 0; + COMMAND_TYPE_MINT_TOKEN = 1; + COMMAND_TYPE_DEPLOY_TOKEN = 2; + COMMAND_TYPE_BURN_TOKEN = 3; + COMMAND_TYPE_TRANSFER_OPERATORSHIP = 4; + COMMAND_TYPE_APPROVE_CONTRACT_CALL_WITH_MINT = 5; + COMMAND_TYPE_APPROVE_CONTRACT_CALL = 6; +} + +message Command { + bytes id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "ID", + (gogoproto.customtype) = "CommandID" + ]; + string command = 2 [ deprecated = true ]; + bytes params = 3; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + uint32 max_gas_cost = 5; + CommandType type = 6; +} + +enum BatchedCommandsStatus { + option (gogoproto.goproto_enum_prefix) = false; + + BATCHED_COMMANDS_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "BatchNonExistent" ]; + BATCHED_COMMANDS_STATUS_SIGNING = 1 + [ (gogoproto.enumvalue_customname) = "BatchSigning" ]; + BATCHED_COMMANDS_STATUS_ABORTED = 2 + [ (gogoproto.enumvalue_customname) = "BatchAborted" ]; + BATCHED_COMMANDS_STATUS_SIGNED = 3 + [ (gogoproto.enumvalue_customname) = "BatchSigned" ]; +} + +message CommandBatchMetadata { + bytes id = 1 [ (gogoproto.customname) = "ID" ]; + repeated bytes command_ids = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandIDs", + (gogoproto.customtype) = "CommandID" + ]; + bytes data = 3; + bytes sig_hash = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + BatchedCommandsStatus status = 5; + string key_id = 6 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes prev_batched_commands_id = 7 + [ (gogoproto.customname) = "PrevBatchedCommandsID" ]; + google.protobuf.Any signature = 8 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +// SigMetadata stores necessary information for external apps to map signature +// results to evm relay transaction types +message SigMetadata { + SigType type = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; +} + +enum SigType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + SIG_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "None" ]; + SIG_TYPE_TX = 1 [ (gogoproto.enumvalue_customname) = "SigTx" ]; + SIG_TYPE_COMMAND = 2 [ (gogoproto.enumvalue_customname) = "SigCommand" ]; +} + +// TransferKey contains information for a transfer operatorship +message TransferKey { + reserved 2; // type was deleted in v0.20 + + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string next_key_id = 3 [ + (gogoproto.customname) = "NextKeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +enum DepositStatus { + option (gogoproto.goproto_enum_prefix) = true; + option (gogoproto.goproto_enum_stringer) = true; + + DEPOSIT_STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "None" ]; + DEPOSIT_STATUS_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + DEPOSIT_STATUS_CONFIRMED = 2 + [ (gogoproto.enumvalue_customname) = "Confirmed" ]; + DEPOSIT_STATUS_BURNED = 3 [ (gogoproto.enumvalue_customname) = "Burned" ]; +} + +message Asset { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string name = 2; +} + +message TokenDetails { + string token_name = 1; + string symbol = 2; + uint32 decimals = 3 [ (gogoproto.casttype) = "uint8" ]; + bytes capacity = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message Gateway { + reserved 2; // status was removed in v0.27 + + bytes address = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message PollMetadata { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 2 [ + (gogoproto.customname) = "TxID", + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash" + ]; +} diff --git a/ampd/proto/axelar/multisig/exported/v1beta1/types.proto b/ampd/proto/axelar/multisig/exported/v1beta1/types.proto new file mode 100644 index 000000000..97014922f --- /dev/null +++ b/ampd/proto/axelar/multisig/exported/v1beta1/types.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package axelar.multisig.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/exported"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +enum MultisigState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + MULTISIG_STATE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + MULTISIG_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + MULTISIG_STATE_COMPLETED = 2 + [ (gogoproto.enumvalue_customname) = "Completed" ]; +} + +enum KeyState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_STATE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "Inactive" ]; + KEY_STATE_ASSIGNED = 1 [ (gogoproto.enumvalue_customname) = "Assigned" ]; + KEY_STATE_ACTIVE = 2 [ (gogoproto.enumvalue_customname) = "Active" ]; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/events.proto b/ampd/proto/axelar/multisig/v1beta1/events.proto new file mode 100644 index 000000000..80607c48e --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/events.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; + +message KeygenStarted { + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + repeated bytes participants = 3 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +message KeygenCompleted { + option (gogoproto.messagename) = true; + + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeygenExpired { + option (gogoproto.messagename) = true; + + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message PubKeySubmitted { + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes participant = 3 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes pub_key = 4 [ + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; +} + +message SigningStarted { + option (gogoproto.stable_marshaler) = true; + + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + map pub_keys = 4 [ + (gogoproto.castvalue) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; + bytes payload_hash = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.Hash" ]; + string requesting_module = 6; +} + +message SigningCompleted { + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; +} + +message SigningExpired { + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; +} + +message SignatureSubmitted { + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + bytes participant = 3 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes signature = 4 [ (gogoproto.casttype) = "Signature" ]; +} + +message KeyAssigned { + string module = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeyRotated { + string module = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeygenOptOut { + bytes participant = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message KeygenOptIn { + bytes participant = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/genesis.proto b/ampd/proto/axelar/multisig/v1beta1/genesis.proto new file mode 100644 index 000000000..adbe82867 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/genesis.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "axelar/multisig/v1beta1/params.proto"; +import "axelar/multisig/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated KeygenSession keygen_sessions = 2 [ (gogoproto.nullable) = false ]; + repeated SigningSession signing_sessions = 3 [ (gogoproto.nullable) = false ]; + repeated Key keys = 4 [ (gogoproto.nullable) = false ]; + repeated KeyEpoch key_epochs = 5 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/params.proto b/ampd/proto/axelar/multisig/v1beta1/params.proto new file mode 100644 index 000000000..da500f485 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/params.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + utils.v1beta1.Threshold keygen_threshold = 1 [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold signing_threshold = 2 + [ (gogoproto.nullable) = false ]; + int64 keygen_timeout = 3; + int64 keygen_grace_period = 4; + int64 signing_timeout = 5; + int64 signing_grace_period = 6; + uint64 active_epoch_count = 7; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/query.proto b/ampd/proto/axelar/multisig/v1beta1/query.proto new file mode 100644 index 000000000..d3b33c622 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/query.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "axelar/multisig/exported/v1beta1/types.proto"; +import "axelar/multisig/v1beta1/types.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/multisig/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message KeyIDRequest { string chain = 1; } + +// KeyIDResponse contains the key ID of the key assigned to a given chain. +message KeyIDResponse { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message NextKeyIDRequest { string chain = 1; } + +// NextKeyIDResponse contains the key ID for the next rotation on the given +// chain +message NextKeyIDResponse { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeyRequest { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeygenParticipant { + string address = 1; + bytes weight = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint" + ]; + string pub_key = 3; +} + +// KeyResponse contains the key corresponding to a given key id. +message KeyResponse { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + multisig.exported.v1beta1.KeyState state = 2; + int64 started_at = 3; + google.protobuf.Timestamp started_at_timestamp = 4 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + bytes threshold_weight = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + bytes bonded_weight = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + // Keygen participants in descending order by weight + repeated KeygenParticipant participants = 7 [ (gogoproto.nullable) = false ]; +} + +message KeygenSessionRequest { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +// KeygenSessionResponse contains the keygen session info for a given key ID. +message KeygenSessionResponse { + int64 started_at = 1; + google.protobuf.Timestamp started_at_timestamp = 2 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + int64 expires_at = 3; + int64 completed_at = 4; + int64 grace_period = 5; + multisig.exported.v1beta1.MultisigState state = 6; + bytes keygen_threshold_weight = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + bytes signing_threshold_weight = 8 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + bytes bonded_weight = 9 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + // Keygen candidates in descending order by weight + repeated KeygenParticipant participants = 10 [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/multisig/v1beta1/service.proto b/ampd/proto/axelar/multisig/v1beta1/service.proto new file mode 100644 index 000000000..c7c39ae60 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/service.proto @@ -0,0 +1,92 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/multisig/v1beta1/tx.proto"; +import "axelar/multisig/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the multisig Msg service. +service MsgService { + rpc StartKeygen(StartKeygenRequest) returns (StartKeygenResponse) { + option (google.api.http) = { + post : "/axelar/multisig/start_keygen" + body : "*" + }; + } + + rpc SubmitPubKey(SubmitPubKeyRequest) returns (SubmitPubKeyResponse) { + option (google.api.http) = { + post : "/axelar/multisig/submit_pub_key" + body : "*" + }; + } + + rpc SubmitSignature(SubmitSignatureRequest) + returns (SubmitSignatureResponse) { + option (google.api.http) = { + post : "/axelar/multisig/submit_signature" + body : "*" + }; + } + + rpc RotateKey(RotateKeyRequest) returns (RotateKeyResponse) { + option (google.api.http) = { + post : "/axelar/multisig/rotate_key" + body : "*" + }; + } + + rpc KeygenOptOut(KeygenOptOutRequest) returns (KeygenOptOutResponse) { + option (google.api.http) = { + post : "/axelar/multisig/v1beta1/keygen_opt_out" + body : "*" + }; + } + + rpc KeygenOptIn(KeygenOptInRequest) returns (KeygenOptInResponse) { + option (google.api.http) = { + post : "/axelar/multisig/v1beta1/keygen_opt_in" + body : "*" + }; + } +} + +// Query defines the gRPC querier service. +service QueryService { + // KeyID returns the key ID of a key assigned to a given chain. + // If no key is assigned, it returns the grpc NOT_FOUND error. + rpc KeyID(KeyIDRequest) returns (KeyIDResponse) { + option (google.api.http).get = "/axelar/multisig/v1beta1/key_id/{chain}"; + } + + // NextKeyID returns the key ID assigned for the next rotation on a given + // chain. If no key rotation is in progress, it returns the grpc NOT_FOUND + // error. + rpc NextKeyID(NextKeyIDRequest) returns (NextKeyIDResponse) { + option (google.api.http).get = + "/axelar/multisig/v1beta1/next_key_id/{chain}"; + } + + // Key returns the key corresponding to a given key ID. + // If no key is found, it returns the grpc NOT_FOUND error. + rpc Key(KeyRequest) returns (KeyResponse) { + option (google.api.http).get = "/axelar/multisig/v1beta1/key"; + } + + // KeygenSession returns the keygen session info for a given key ID. + // If no key is found, it returns the grpc NOT_FOUND error. + rpc KeygenSession(KeygenSessionRequest) returns (KeygenSessionResponse) { + option (google.api.http).get = "/axelar/multisig/v1beta1/keygen_session"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/multisig/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/multisig/v1beta1/tx.proto b/ampd/proto/axelar/multisig/v1beta1/tx.proto new file mode 100644 index 000000000..f816389e3 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/tx.proto @@ -0,0 +1,86 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; +option (gogoproto.goproto_getters_all) = false; + +import "gogoproto/gogo.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +message StartKeygenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message StartKeygenResponse {} + +message SubmitPubKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes pub_key = 3 [ + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; + bytes signature = 4 [ (gogoproto.casttype) = "Signature" ]; +} + +message SubmitPubKeyResponse {} + +message SubmitSignatureRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + bytes signature = 3 [ (gogoproto.casttype) = "Signature" ]; +} + +message SubmitSignatureResponse {} + +message RotateKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message RotateKeyResponse {} + +message KeygenOptOutRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message KeygenOptOutResponse {} + +message KeygenOptInRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message KeygenOptInResponse {} diff --git a/ampd/proto/axelar/multisig/v1beta1/types.proto b/ampd/proto/axelar/multisig/v1beta1/types.proto new file mode 100644 index 000000000..fe32c3da6 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/types.proto @@ -0,0 +1,84 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/snapshot/exported/v1beta1/types.proto"; +import "axelar/multisig/exported/v1beta1/types.proto"; + +message Key { + option (gogoproto.stable_marshaler) = true; + + string id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + snapshot.exported.v1beta1.Snapshot snapshot = 2 + [ (gogoproto.nullable) = false ]; + map pub_keys = 3 [ + (gogoproto.castvalue) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; + utils.v1beta1.Threshold signing_threshold = 4 + [ (gogoproto.nullable) = false ]; + multisig.exported.v1beta1.KeyState state = 5; +} + +message KeygenSession { + option (gogoproto.stable_marshaler) = true; + + Key key = 1 [ (gogoproto.nullable) = false ]; + multisig.exported.v1beta1.MultisigState state = 2; + utils.v1beta1.Threshold keygen_threshold = 3 [ (gogoproto.nullable) = false ]; + int64 expires_at = 4; + int64 completed_at = 5; + map is_pub_key_received = 6; + int64 grace_period = 7; +} + +message MultiSig { + option (gogoproto.stable_marshaler) = true; + + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes payload_hash = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.Hash" ]; + map sigs = 3 [ (gogoproto.castvalue) = "Signature" ]; +} + +message SigningSession { + option (gogoproto.stable_marshaler) = true; + + uint64 id = 1 [ (gogoproto.customname) = "ID" ]; + MultiSig multi_sig = 2 [ (gogoproto.nullable) = false ]; + multisig.exported.v1beta1.MultisigState state = 3; + Key key = 4 [ (gogoproto.nullable) = false ]; + int64 expires_at = 5; + int64 completed_at = 6; + int64 grace_period = 7; + string module = 8; + google.protobuf.Any module_metadata = 9 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +message KeyEpoch { + uint64 epoch = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} diff --git a/ampd/proto/axelar/nexus/exported/v1beta1/types.proto b/ampd/proto/axelar/nexus/exported/v1beta1/types.proto new file mode 100644 index 000000000..f108c119f --- /dev/null +++ b/ampd/proto/axelar/nexus/exported/v1beta1/types.proto @@ -0,0 +1,129 @@ +syntax = "proto3"; +package axelar.nexus.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/exported"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Chain represents the properties of a registered blockchain +message Chain { + reserved 2; // native_asset was removed in 0.14 + + string name = 1 [ (gogoproto.casttype) = "ChainName" ]; + bool supports_foreign_assets = 3; + tss.exported.v1beta1.KeyType key_type = 4; + string module = 5; +} + +// CrossChainAddress represents a generalized address on any registered chain +message CrossChainAddress { + Chain chain = 1 [ (gogoproto.nullable) = false ]; + string address = 2; +} + +// CrossChainTransfer represents a generalized transfer of some asset to a +// registered blockchain +message CrossChainTransfer { + CrossChainAddress recipient = 1 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin asset = 2 [ (gogoproto.nullable) = false ]; + uint64 id = 3 + [ (gogoproto.customname) = "ID", (gogoproto.casttype) = "TransferID" ]; + TransferState state = 4; +} + +enum TransferState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + TRANSFER_STATE_UNSPECIFIED = 0; + TRANSFER_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + TRANSFER_STATE_ARCHIVED = 2 [ (gogoproto.enumvalue_customname) = "Archived" ]; + TRANSFER_STATE_INSUFFICIENT_AMOUNT = 3 + [ (gogoproto.enumvalue_customname) = "InsufficientAmount" ]; +} + +// TransferFee represents accumulated fees generated by the network +message TransferFee { + repeated cosmos.base.v1beta1.Coin coins = 1 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; +} + +message FeeInfo { + string chain = 1 [ (gogoproto.casttype) = "ChainName" ]; + string asset = 2; + bytes fee_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes min_fee = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + bytes max_fee = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message Asset { + string denom = 1; + reserved 2; // min_amount was removed in v0.15 + bool is_native_asset = 3; +} + +enum TransferDirection { + option (gogoproto.goproto_enum_prefix) = false; + + TRANSFER_DIRECTION_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + TRANSFER_DIRECTION_FROM = 1 + [ (gogoproto.enumvalue_customname) = "TransferDirectionFrom" ]; + TRANSFER_DIRECTION_TO = 2 + [ (gogoproto.enumvalue_customname) = "TransferDirectionTo" ]; +} + +message GeneralMessage { + enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + STATUS_APPROVED = 1 [ (gogoproto.enumvalue_customname) = "Approved" ]; + STATUS_PROCESSING = 2 [ (gogoproto.enumvalue_customname) = "Processing" ]; + STATUS_EXECUTED = 3 [ (gogoproto.enumvalue_customname) = "Executed" ]; + STATUS_FAILED = 4 [ (gogoproto.enumvalue_customname) = "Failed" ]; + } + + string id = 1 [ (gogoproto.customname) = "ID" ]; + CrossChainAddress sender = 2 [ (gogoproto.nullable) = false ]; + CrossChainAddress recipient = 3 [ (gogoproto.nullable) = false ]; + bytes payload_hash = 4; + Status status = 5; + cosmos.base.v1beta1.Coin asset = 6; + bytes source_tx_id = 7 [ (gogoproto.customname) = "SourceTxID" ]; + uint64 source_tx_index = 8; +} + +message WasmMessage { + string source_chain = 1 [ (gogoproto.casttype) = "ChainName" ]; + string source_address = 2; + string destination_chain = 3 [ (gogoproto.casttype) = "ChainName" ]; + string destination_address = 4; + bytes payload_hash = 5 [ (gogoproto.casttype) = "WasmBytes" ]; + bytes source_tx_id = 6 [ + (gogoproto.customname) = "SourceTxID", + (gogoproto.casttype) = "WasmBytes" + ]; + uint64 source_tx_index = 7 [ (gogoproto.jsontag) = "source_tx_index" ]; + bytes sender = 8 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string id = 9 [ + (gogoproto.customname) = "ID" + ]; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/events.proto b/ampd/proto/axelar/nexus/v1beta1/events.proto new file mode 100644 index 000000000..7ec5ec829 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/events.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; +option (gogoproto.messagename_all) = true; + +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; + +message FeeDeducted { + uint64 transfer_id = 1 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string recipient_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string recipient_address = 3; + cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin fee = 5 [ (gogoproto.nullable) = false ]; +} + +message InsufficientFee { + uint64 transfer_id = 1 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string recipient_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string recipient_address = 3; + cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin fee = 5 [ (gogoproto.nullable) = false ]; +} + +message RateLimitUpdated { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin limit = 2 [ (gogoproto.nullable) = false ]; + google.protobuf.Duration window = 3 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message MessageReceived { + string id = 1 [ (gogoproto.customname) = "ID" ]; + bytes payload_hash = 2; + exported.v1beta1.CrossChainAddress sender = 3 + [ (gogoproto.nullable) = false ]; + exported.v1beta1.CrossChainAddress recipient = 4 + [ (gogoproto.nullable) = false ]; +} + +message MessageProcessing { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message MessageExecuted { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message MessageFailed { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message WasmMessageRouted { + exported.v1beta1.WasmMessage message = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/genesis.proto b/ampd/proto/axelar/nexus/v1beta1/genesis.proto new file mode 100644 index 000000000..78011ebd7 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/genesis.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "gogoproto/gogo.proto"; +import "axelar/nexus/v1beta1/params.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/nexus/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + uint64 nonce = 2; + repeated nexus.exported.v1beta1.Chain chains = 3 + [ (gogoproto.nullable) = false ]; + repeated ChainState chain_states = 4 [ (gogoproto.nullable) = false ]; + repeated LinkedAddresses linked_addresses = 5 + [ (gogoproto.nullable) = false ]; + repeated nexus.exported.v1beta1.CrossChainTransfer transfers = 6 + [ (gogoproto.nullable) = false ]; + nexus.exported.v1beta1.TransferFee fee = 7 [ (gogoproto.nullable) = false ]; + repeated nexus.exported.v1beta1.FeeInfo fee_infos = 8 + [ (gogoproto.nullable) = false ]; + repeated RateLimit rate_limits = 9 [ (gogoproto.nullable) = false ]; + repeated TransferEpoch transfer_epochs = 10 [ (gogoproto.nullable) = false ]; + repeated nexus.exported.v1beta1.GeneralMessage messages = 11 + [ (gogoproto.nullable) = false ]; + uint64 message_nonce = 12; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/params.proto b/ampd/proto/axelar/nexus/v1beta1/params.proto new file mode 100644 index 000000000..30c9074fa --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/params.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + utils.v1beta1.Threshold chain_activation_threshold = 1 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold chain_maintainer_missing_vote_threshold = 2 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold chain_maintainer_incorrect_vote_threshold = 3 + [ (gogoproto.nullable) = false ]; + int32 chain_maintainer_check_window = 4; + bytes gateway = 5 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + uint64 end_blocker_limit = 6; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/query.proto b/ampd/proto/axelar/nexus/v1beta1/query.proto new file mode 100644 index 000000000..b6371f4a8 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/query.proto @@ -0,0 +1,175 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/nexus/v1beta1/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// ChainMaintainersRequest represents a message that queries +// the chain maintainers for the specified chain +message ChainMaintainersRequest { string chain = 1; } + +message ChainMaintainersResponse { + repeated bytes maintainers = 1 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +// LatestDepositAddressRequest represents a message that queries a deposit +// address by recipient address +message LatestDepositAddressRequest { + string recipient_addr = 1; + string recipient_chain = 2; + string deposit_chain = 3; +} + +message LatestDepositAddressResponse { string deposit_addr = 1; }; + +// TransfersForChainRequest represents a message that queries the +// transfers for the specified chain +message TransfersForChainRequest { + string chain = 1; + exported.v1beta1.TransferState state = 2; + cosmos.base.query.v1beta1.PageRequest pagination = 3; +} + +message TransfersForChainResponse { + repeated exported.v1beta1.CrossChainTransfer transfers = 1 + [ (gogoproto.nullable) = false ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// FeeInfoRequest represents a message that queries the transfer fees associated +// to an asset on a chain +message FeeInfoRequest { + string chain = 1; + string asset = 2; +} + +message FeeInfoResponse { exported.v1beta1.FeeInfo fee_info = 1; } + +// TransferFeeRequest represents a message that queries the fees charged by +// the network for a cross-chain transfer +message TransferFeeRequest { + string source_chain = 1; + string destination_chain = 2; + string amount = 3; +} + +message TransferFeeResponse { + cosmos.base.v1beta1.Coin fee = 1 [ (gogoproto.nullable) = false ]; +} + +enum ChainStatus { + option (gogoproto.goproto_enum_prefix) = false; + + CHAIN_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + CHAIN_STATUS_ACTIVATED = 1 [ (gogoproto.enumvalue_customname) = "Activated" ]; + CHAIN_STATUS_DEACTIVATED = 2 + [ (gogoproto.enumvalue_customname) = "Deactivated" ]; +} + +// ChainsRequest represents a message that queries the chains +// registered on the network +message ChainsRequest { ChainStatus status = 1; } + +message ChainsResponse { + repeated string chains = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +// AssetsRequest represents a message that queries the registered assets of a +// chain +message AssetsRequest { string chain = 1; } + +message AssetsResponse { repeated string assets = 1; } + +// ChainStateRequest represents a message that queries the state of a chain +// registered on the network +message ChainStateRequest { string chain = 1; } + +message ChainStateResponse { + ChainState state = 1 [ (gogoproto.nullable) = false ]; +} + +// ChainsByAssetRequest represents a message that queries the chains +// that support an asset on the network +message ChainsByAssetRequest { string asset = 1; } + +message ChainsByAssetResponse { + repeated string chains = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +// RecipientAddressRequest represents a message that queries the registered +// recipient address for a given deposit address +message RecipientAddressRequest { + string deposit_addr = 1; + string deposit_chain = 2; +} + +message RecipientAddressResponse { + string recipient_addr = 1; + string recipient_chain = 2; +}; + +// TransferRateLimitRequest represents a message that queries the registered +// transfer rate limit and current transfer amounts for a given chain and asset +message TransferRateLimitRequest { + string chain = 1; + string asset = 2; +} + +message TransferRateLimitResponse { TransferRateLimit transfer_rate_limit = 1; } + +message TransferRateLimit { + bytes limit = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration window = 2 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; + bytes incoming = 3 [ + deprecated = true, + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + bytes outgoing = 4 [ + deprecated = true, + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + // time_left indicates the time left in the rate limit window + google.protobuf.Duration time_left = 5 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; + bytes from = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + bytes to = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message MessageRequest { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message MessageResponse { + exported.v1beta1.GeneralMessage message = 1 [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/nexus/v1beta1/service.proto b/ampd/proto/axelar/nexus/v1beta1/service.proto new file mode 100644 index 000000000..881d2a4d7 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/service.proto @@ -0,0 +1,150 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/nexus/v1beta1/tx.proto"; +import "axelar/nexus/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the nexus Msg service. +service MsgService { + rpc RegisterChainMaintainer(RegisterChainMaintainerRequest) + returns (RegisterChainMaintainerResponse) { + option (google.api.http) = { + post : "/axelar/nexus/register_chain_maintainer" + body : "*" + }; + } + + rpc DeregisterChainMaintainer(DeregisterChainMaintainerRequest) + returns (DeregisterChainMaintainerResponse) { + option (google.api.http) = { + post : "/axelar/nexus/deregister_chain_maintainer" + body : "*" + }; + } + + rpc ActivateChain(ActivateChainRequest) returns (ActivateChainResponse) { + option (google.api.http) = { + post : "/axelar/nexus/activate_chain" + body : "*" + }; + } + + rpc DeactivateChain(axelar.nexus.v1beta1.DeactivateChainRequest) + returns (axelar.nexus.v1beta1.DeactivateChainResponse) { + option (google.api.http) = { + post : "/axelar/nexus/deactivate_chain" + body : "*" + }; + } + + rpc RegisterAssetFee(RegisterAssetFeeRequest) + returns (RegisterAssetFeeResponse) { + option (google.api.http) = { + post : "/axelar/nexus/register_asset_fee" + body : "*" + }; + } + + rpc SetTransferRateLimit(SetTransferRateLimitRequest) + returns (SetTransferRateLimitResponse) { + option (google.api.http) = { + post : "/axelar/nexus/set_transfer_rate_limit" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + // LatestDepositAddress queries the a deposit address by recipient + rpc LatestDepositAddress(LatestDepositAddressRequest) + returns (LatestDepositAddressResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/latest_deposit_address/" + "{recipient_addr}/{recipient_chain}/{deposit_chain}"; + } + + // TransfersForChain queries transfers by chain + rpc TransfersForChain(TransfersForChainRequest) + returns (TransfersForChainResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/transfers_for_chain/{chain}/{state}"; + } + + // FeeInfo queries the fee info by chain and asset + rpc FeeInfo(FeeInfoRequest) returns (FeeInfoResponse) { + option (google.api.http) = { + get : "/axelar/nexus/v1beta1/fee_info/{chain}/{asset}" + additional_bindings : {get : "/axelar/nexus/v1beta1/fee"} + }; + } + + // TransferFee queries the transfer fee by the source, destination chain, + // and amount. If amount is 0, the min fee is returned + rpc TransferFee(TransferFeeRequest) returns (TransferFeeResponse) { + option (google.api.http) = { + get : "/axelar/nexus/v1beta1/transfer_fee/{source_chain}/" + "{destination_chain}/{amount}" + additional_bindings : {get : "/axelar/nexus/v1beta1/transfer_fee"} + }; + } + + // Chains queries the chains registered on the network + rpc Chains(ChainsRequest) returns (ChainsResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/chains"; + } + + // Assets queries the assets registered for a chain + rpc Assets(AssetsRequest) returns (AssetsResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/assets/{chain}"; + } + + // ChainState queries the state of a registered chain on the network + rpc ChainState(ChainStateRequest) returns (ChainStateResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/chain_state/{chain}"; + } + + // ChainsByAsset queries the chains that support an asset on the network + rpc ChainsByAsset(ChainsByAssetRequest) returns (ChainsByAssetResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/chains_by_asset/{asset}"; + } + + // RecipientAddress queries the recipient address for a given deposit address + rpc RecipientAddress(RecipientAddressRequest) + returns (RecipientAddressResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/recipient_address/" + "{deposit_chain}/{deposit_addr}"; + } + + // ChainMaintainers queries the chain maintainers for a given chain + rpc ChainMaintainers(ChainMaintainersRequest) + returns (ChainMaintainersResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/chain_maintainers/{chain}"; + } + + // TransferRateLimit queries the transfer rate limit for a given chain and + // asset. If a rate limit is not set, nil is returned. + rpc TransferRateLimit(TransferRateLimitRequest) + returns (TransferRateLimitResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/transfer_rate_limit/" + "{chain}/{asset}"; + } + + rpc Message(MessageRequest) returns (MessageResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/message"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/nexus/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/nexus/v1beta1/tx.proto b/ampd/proto/axelar/nexus/v1beta1/tx.proto new file mode 100644 index 000000000..555930043 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/tx.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "google/api/annotations.proto"; +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message RegisterChainMaintainerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message RegisterChainMaintainerResponse {} + +message DeregisterChainMaintainerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message DeregisterChainMaintainerResponse {} + +// ActivateChainRequest represents a message to activate chains +message ActivateChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message ActivateChainResponse {} + +// DeactivateChainRequest represents a message to deactivate chains +message DeactivateChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message DeactivateChainResponse {} + +// RegisterAssetFeeRequest represents a message to register the transfer fee +// info associated to an asset on a chain +message RegisterAssetFeeRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + nexus.exported.v1beta1.FeeInfo fee_info = 2 [ (gogoproto.nullable) = false ]; +} + +message RegisterAssetFeeResponse {} + +// SetTransferRateLimitRequest represents a message to set rate limits on +// transfers +message SetTransferRateLimitRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin limit = 3 [ (gogoproto.nullable) = false ]; + google.protobuf.Duration window = 4 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message SetTransferRateLimitResponse {} diff --git a/ampd/proto/axelar/nexus/v1beta1/types.proto b/ampd/proto/axelar/nexus/v1beta1/types.proto new file mode 100644 index 000000000..14503683f --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/types.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/utils/v1beta1/bitmap.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message MaintainerState { + bytes address = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + axelar.utils.v1beta1.Bitmap missing_votes = 2 + [ (gogoproto.nullable) = false ]; + axelar.utils.v1beta1.Bitmap incorrect_votes = 3 + [ (gogoproto.nullable) = false ]; + string chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +// ChainState represents the state of a registered blockchain +message ChainState { + reserved 4; // total was removed in v0.13 + reserved 2; // maintainers was removed in v0.24 + + axelar.nexus.exported.v1beta1.Chain chain = 1 + [ (gogoproto.nullable) = false ]; + bool activated = 3; + repeated axelar.nexus.exported.v1beta1.Asset assets = 5 + [ (gogoproto.nullable) = false ]; + repeated MaintainerState maintainer_states = 6 + [ (gogoproto.nullable) = false, deprecated = true ]; +} + +message LinkedAddresses { + axelar.nexus.exported.v1beta1.CrossChainAddress deposit_address = 1 + [ (gogoproto.nullable) = false ]; + axelar.nexus.exported.v1beta1.CrossChainAddress recipient_address = 2 + [ (gogoproto.nullable) = false ]; +} + +message RateLimit { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin limit = 2 [ (gogoproto.nullable) = false ]; + google.protobuf.Duration window = 3 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message TransferEpoch { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; + uint64 epoch = 3; + axelar.nexus.exported.v1beta1.TransferDirection direction = + 4; // indicates whether the rate tracking is for transfers going + // to that chain or coming from it +} diff --git a/ampd/proto/axelar/permission/exported/v1beta1/types.proto b/ampd/proto/axelar/permission/exported/v1beta1/types.proto new file mode 100644 index 000000000..7251daa8e --- /dev/null +++ b/ampd/proto/axelar/permission/exported/v1beta1/types.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package axelar.permission.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/exported"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/descriptor.proto"; + +option (gogoproto.goproto_getters_all) = false; + +enum Role { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + ROLE_UNSPECIFIED = 0; + ROLE_UNRESTRICTED = 1; + ROLE_CHAIN_MANAGEMENT = 2; + ROLE_ACCESS_CONTROL = 3; +} + +extend google.protobuf.MessageOptions { + permission.exported.v1beta1.Role permission_role = + 50000; // 50000-99999 reserved for use withing individual organizations +} diff --git a/ampd/proto/axelar/permission/v1beta1/genesis.proto b/ampd/proto/axelar/permission/v1beta1/genesis.proto new file mode 100644 index 000000000..7eef9a82e --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/genesis.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/v1beta1/types.proto"; +import "axelar/permission/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 2; + repeated GovAccount gov_accounts = 3 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/permission/v1beta1/params.proto b/ampd/proto/axelar/permission/v1beta1/params.proto new file mode 100644 index 000000000..232900e1b --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/params.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params {} diff --git a/ampd/proto/axelar/permission/v1beta1/query.proto b/ampd/proto/axelar/permission/v1beta1/query.proto new file mode 100644 index 000000000..997d72a8a --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/query.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// QueryGovernanceKeyRequest is the request type for the +// Query/GovernanceKey RPC method +message QueryGovernanceKeyRequest {} + +// QueryGovernanceKeyResponse is the response type for the +// Query/GovernanceKey RPC method +message QueryGovernanceKeyResponse { + cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 1 + [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/permission/v1beta1/service.proto b/ampd/proto/axelar/permission/v1beta1/service.proto new file mode 100644 index 000000000..02767573f --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/service.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/permission/v1beta1/tx.proto"; +import "axelar/permission/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the gov Msg service. +service Msg { + rpc RegisterController(axelar.permission.v1beta1.RegisterControllerRequest) + returns (axelar.permission.v1beta1.RegisterControllerResponse) { + option (google.api.http) = { + post : "/axelar/permission/register_controller" + body : "*" + }; + } + + rpc DeregisterController( + axelar.permission.v1beta1.DeregisterControllerRequest) + returns (axelar.permission.v1beta1.DeregisterControllerResponse) { + option (google.api.http) = { + post : "/axelar/permission/deregister_controller" + body : "*" + }; + } + + rpc UpdateGovernanceKey(axelar.permission.v1beta1.UpdateGovernanceKeyRequest) + returns (axelar.permission.v1beta1.UpdateGovernanceKeyResponse) { + option (google.api.http) = { + post : "/axelar/permission/update_governance_key" + body : "*" + }; + } +} + +// Query defines the gRPC querier service. +service Query { + // GovernanceKey returns the multisig governance key + rpc GovernanceKey(QueryGovernanceKeyRequest) + returns (QueryGovernanceKeyResponse) { + option (google.api.http).get = "/axelar/permission/v1beta1/governance_key"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/permission/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/permission/v1beta1/tx.proto b/ampd/proto/axelar/permission/v1beta1/tx.proto new file mode 100644 index 000000000..c06b467f3 --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/tx.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message UpdateGovernanceKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 2 + [ (gogoproto.nullable) = false ]; +} + +message UpdateGovernanceKeyResponse {} + +// MsgRegisterController represents a message to register a controller account +message RegisterControllerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes controller = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RegisterControllerResponse {} + +// DeregisterController represents a message to deregister a controller account +message DeregisterControllerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes controller = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} +message DeregisterControllerResponse {} diff --git a/ampd/proto/axelar/permission/v1beta1/types.proto b/ampd/proto/axelar/permission/v1beta1/types.proto new file mode 100644 index 000000000..beb401ed0 --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/types.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GovAccount { + bytes address = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + permission.exported.v1beta1.Role role = 2; +} diff --git a/ampd/proto/axelar/reward/v1beta1/genesis.proto b/ampd/proto/axelar/reward/v1beta1/genesis.proto new file mode 100644 index 000000000..a805e07e9 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "axelar/reward/v1beta1/params.proto"; +import "axelar/reward/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated Pool pools = 2 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/reward/v1beta1/params.proto b/ampd/proto/axelar/reward/v1beta1/params.proto new file mode 100644 index 000000000..8fba73ecf --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/params.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + bytes external_chain_voting_inflation_rate = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes key_mgmt_relative_inflation_rate = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/axelar/reward/v1beta1/query.proto b/ampd/proto/axelar/reward/v1beta1/query.proto new file mode 100644 index 000000000..f3f7225ad --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/query.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "axelar/reward/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// InflationRateRequest represents a message that queries the Axelar specific +// inflation RPC method. Ideally, this would use ValAddress as the validator +// field type. However, this makes it awkward for REST-based calls, because it +// would expect a byte array as part of the url. So, the bech32 encoded address +// string is used for this request instead. +message InflationRateRequest { string validator = 1; } + +message InflationRateResponse { + bytes inflation_rate = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/reward/v1beta1/service.proto b/ampd/proto/axelar/reward/v1beta1/service.proto new file mode 100644 index 000000000..363f136e9 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/service.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/reward/v1beta1/tx.proto"; +import "axelar/reward/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the axelarnet Msg service. +service MsgService { + rpc RefundMsg(RefundMsgRequest) returns (RefundMsgResponse) { + option (google.api.http) = { + post : "/axelar/reward/refund_message" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + rpc InflationRate(InflationRateRequest) returns (InflationRateResponse) { + option (google.api.http) = { + get : "/axelar/reward/v1beta1/inflation_rate/{validator}", + additional_bindings : { + get : "/axelar/reward/v1beta1/inflation_rate" // query network inflation + // rate, without having to + // pass empty validator + // `.../inflation_rate//` + } + }; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/reward/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/reward/v1beta1/tx.proto b/ampd/proto/axelar/reward/v1beta1/tx.proto new file mode 100644 index 000000000..ec472dd52 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/tx.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message RefundMsgRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + google.protobuf.Any inner_message = 2 + [ (cosmos_proto.accepts_interface) = "Refundable" ]; +} + +message RefundMsgResponse { + bytes data = 1; + string log = 2; +} diff --git a/ampd/proto/axelar/reward/v1beta1/types.proto b/ampd/proto/axelar/reward/v1beta1/types.proto new file mode 100644 index 000000000..b025a95c0 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/types.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Pool { + message Reward { + bytes validator = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + repeated cosmos.base.v1beta1.Coin coins = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + } + + string name = 1; + repeated Reward rewards = 2 [ (gogoproto.nullable) = false ]; +} + +message Refund { + bytes payer = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + repeated cosmos.base.v1beta1.Coin fees = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} diff --git a/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto b/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto new file mode 100644 index 000000000..80d4a4435 --- /dev/null +++ b/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package axelar.snapshot.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/exported"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Participant { + bytes address = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message Snapshot { + reserved 1, 4, 5, 6, 7; // validators, total_share_count, counter and + // corruption_threshold were deleted in v0.26 + + option (gogoproto.stable_marshaler) = true; + + google.protobuf.Timestamp timestamp = 2 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + int64 height = 3; + map participants = 8 [ (gogoproto.nullable) = false ]; + bytes bonded_weight = 9 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/axelar/snapshot/v1beta1/genesis.proto b/ampd/proto/axelar/snapshot/v1beta1/genesis.proto new file mode 100644 index 000000000..08d954526 --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/genesis.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "axelar/snapshot/v1beta1/params.proto"; +import "axelar/snapshot/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated ProxiedValidator proxied_validators = 2 + [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/snapshot/v1beta1/params.proto b/ampd/proto/axelar/snapshot/v1beta1/params.proto new file mode 100644 index 000000000..c22c60186 --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/params.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { int64 min_proxy_balance = 1; } diff --git a/ampd/proto/axelar/snapshot/v1beta1/query.proto b/ampd/proto/axelar/snapshot/v1beta1/query.proto new file mode 100644 index 000000000..0e9f53def --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/query.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "axelar/snapshot/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message QueryValidatorsResponse { + message TssIllegibilityInfo { + bool tombstoned = 1; + bool jailed = 2; + bool missed_too_many_blocks = 3; + bool no_proxy_registered = 4; + bool tss_suspended = 5; + bool proxy_insuficient_funds = 6; + bool stale_tss_heartbeat = 7; + } + + message Validator { + string operator_address = 1; + string moniker = 2; + TssIllegibilityInfo tss_illegibility_info = 3 + [ (gogoproto.nullable) = false ]; + } + + repeated Validator validators = 1; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/snapshot/v1beta1/service.proto b/ampd/proto/axelar/snapshot/v1beta1/service.proto new file mode 100644 index 000000000..82f430fd9 --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/service.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/snapshot/v1beta1/tx.proto"; +import "axelar/snapshot/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the snapshot Msg service. +service MsgService { + // RegisterProxy defines a method for registering a proxy account that can act + // in a validator account's stead. + rpc RegisterProxy(RegisterProxyRequest) returns (RegisterProxyResponse) { + option (google.api.http) = { + post : "/axelar/snapshot/register_proxy" + body : "*" + }; + } + + // DeactivateProxy defines a method for deregistering a proxy account. + rpc DeactivateProxy(DeactivateProxyRequest) + returns (DeactivateProxyResponse) { + option (google.api.http) = { + post : "/axelar/snapshot/deactivate_proxy" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/snapshot/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/snapshot/v1beta1/tx.proto b/ampd/proto/axelar/snapshot/v1beta1/tx.proto new file mode 100644 index 000000000..70a1c2c0e --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/tx.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message RegisterProxyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes proxy_addr = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RegisterProxyResponse {} + +message DeactivateProxyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +message DeactivateProxyResponse {} diff --git a/ampd/proto/axelar/snapshot/v1beta1/types.proto b/ampd/proto/axelar/snapshot/v1beta1/types.proto new file mode 100644 index 000000000..279c6e6fd --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/types.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message ProxiedValidator { + bytes validator = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes proxy = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bool active = 3; +} diff --git a/ampd/proto/axelar/tss/exported/v1beta1/types.proto b/ampd/proto/axelar/tss/exported/v1beta1/types.proto new file mode 100644 index 000000000..4b0d8bf1d --- /dev/null +++ b/ampd/proto/axelar/tss/exported/v1beta1/types.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; +package axelar.tss.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/exported"; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "gogoproto/gogo.proto"; + +// KeyRequirement defines requirements for keys +message KeyRequirement { + KeyRole key_role = 1; + KeyType key_type = 2; + utils.v1beta1.Threshold min_keygen_threshold = 3 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold safety_threshold = 4 [ (gogoproto.nullable) = false ]; + KeyShareDistributionPolicy key_share_distribution_policy = 5; + int64 max_total_share_count = 6; + int64 min_total_share_count = 7; + utils.v1beta1.Threshold keygen_voting_threshold = 8 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold sign_voting_threshold = 9 + [ (gogoproto.nullable) = false ]; + int64 keygen_timeout = 10; + int64 sign_timeout = 11; +} + +enum KeyRole { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_ROLE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "Unknown" ]; + KEY_ROLE_MASTER_KEY = 1 [ (gogoproto.enumvalue_customname) = "MasterKey" ]; + KEY_ROLE_SECONDARY_KEY = 2 + [ (gogoproto.enumvalue_customname) = "SecondaryKey" ]; + KEY_ROLE_EXTERNAL_KEY = 3 + [ (gogoproto.enumvalue_customname) = "ExternalKey" ]; +} + +enum KeyType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_TYPE_UNSPECIFIED = 0; + KEY_TYPE_NONE = 1 [ (gogoproto.enumvalue_customname) = "None" ]; + KEY_TYPE_THRESHOLD = 2 [ (gogoproto.enumvalue_customname) = "Threshold" ]; + KEY_TYPE_MULTISIG = 3 [ (gogoproto.enumvalue_customname) = "Multisig" ]; +} + +enum KeyShareDistributionPolicy { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_SHARE_DISTRIBUTION_POLICY_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + KEY_SHARE_DISTRIBUTION_POLICY_WEIGHTED_BY_STAKE = 1 + [ (gogoproto.enumvalue_customname) = "WeightedByStake" ]; + KEY_SHARE_DISTRIBUTION_POLICY_ONE_PER_VALIDATOR = 2 + [ (gogoproto.enumvalue_customname) = "OnePerValidator" ]; +} + +// PubKeyInfo holds a pubkey and a signature +message SigKeyPair { + bytes pub_key = 1; + bytes signature = 2; +} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto new file mode 100644 index 000000000..0683c5189 --- /dev/null +++ b/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto @@ -0,0 +1,28 @@ +// File copied from golang tofnd with minor tweaks +syntax = "proto3"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; + +import "gogoproto/gogo.proto"; + +package axelar.tss.tofnd.v1beta1; + +// Key presence check types +message KeyPresenceRequest { + string key_uid = 1; + bytes pub_key = 2; // SEC1-encoded compressed pub key bytes to find the right + // mnemonic. Latest is used, if empty. +} + +message KeyPresenceResponse { + enum Response { + option (gogoproto.goproto_enum_prefix) = false; + + RESPONSE_UNSPECIFIED = 0; + RESPONSE_PRESENT = 1; + RESPONSE_ABSENT = 2; + RESPONSE_FAIL = 3; + } + + Response response = 1; +} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto new file mode 100644 index 000000000..82abaaf56 --- /dev/null +++ b/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto @@ -0,0 +1,40 @@ +// File copied from golang tofnd with minor tweaks +syntax = "proto3"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; +import "axelar/tss/tofnd/v1beta1/common.proto"; // import key presence request/response + +package axelar.tss.tofnd.v1beta1; + +// service Multisig { +// rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); +// rpc Keygen(KeygenRequest) returns (KeygenResponse); +// rpc Sign(SignRequest) returns (SignResponse); +//} + +message KeygenRequest { + string key_uid = 1; + string party_uid = 2; // used only for logging +} + +message KeygenResponse { + oneof keygen_response { + bytes pub_key = 1; // SEC1-encoded compressed curve point + string error = 2; // reply with an error message if keygen fails + } +} + +message SignRequest { + string key_uid = 1; + bytes msg_to_sign = 2; // 32-byte pre-hashed message digest + string party_uid = 3; // used only for logging + bytes pub_key = 4; // SEC1-encoded compressed pub key bytes to find the right + // mnemonic. Latest is used, if empty. +} + +message SignResponse { + oneof sign_response { + bytes signature = 1; // ASN.1 DER-encoded ECDSA signature + string error = 2; // reply with an error message if sign fails + } +} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto new file mode 100644 index 000000000..96140268a --- /dev/null +++ b/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto @@ -0,0 +1,129 @@ +// File copied from golang tofnd with minor tweaks +syntax = "proto3"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; +import "gogoproto/gogo.proto"; +import "axelar/tss/tofnd/v1beta1/common.proto"; // import key presence request/response + +package axelar.tss.tofnd.v1beta1; + +// TODO: figure out why gogoproto produces unusable services +// GG20 is the protocol https://eprint.iacr.org/2020/540 +// rpc definitions intended to wrap the API for this library: +// https://github.com/axelarnetwork/tofn +// service GG20 { +// rpc Recover(RecoverRequest) returns (RecoverResponse); +// rpc Keygen(stream MessageIn) returns (stream MessageOut); +// rpc Sign(stream MessageIn) returns (stream MessageOut); +// rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); +//} + +message RecoverRequest { + KeygenInit keygen_init = 1; + KeygenOutput keygen_output = 2; +} +message RecoverResponse { + enum Response { + RESPONSE_UNSPECIFIED = 0; + RESPONSE_SUCCESS = 1; + RESPONSE_FAIL = 2; + } + Response response = 1; +} + +// Keygen's success response +message KeygenOutput { + bytes pub_key = 1; // pub_key; common for all parties + bytes group_recover_info = + 2; // recover info of all parties' shares; common for all parties + bytes private_recover_info = + 3; // private recover info of this party's shares; unique for each party +} + +// generic message types shared by Keygen, Sign + +// TODO use nested message types +// eg. KeygenInit, SignInit should be defined inside MessageIn, etc. + +message MessageIn { + oneof data { // TODO don't reuse `data` + KeygenInit keygen_init = 1; // first message only, Keygen + SignInit sign_init = 2; // first message only, Sign + TrafficIn traffic = 3; // all subsequent messages + bool abort = 4; // abort the protocol, ignore the bool value + } +} + +message MessageOut { + oneof data { // TODO don't reuse `data` + TrafficOut traffic = 1; // all but final message + KeygenResult keygen_result = 2; // final message only, Keygen + SignResult sign_result = 3; // final message only, Sign + bool need_recover = 4; // issue recover from client + } + + // Keygen's response types + message KeygenResult { + oneof keygen_result_data { + KeygenOutput data = 1; // Success response + CriminalList criminals = 2; // Faiilure response + } + } + + // Sign's response types + message SignResult { + oneof sign_result_data { + bytes signature = 1; // Success response + CriminalList criminals = 2; // Failure response + } + } + + // Keygen/Sign failure response message + message CriminalList { + repeated Criminal criminals = 1; + + message Criminal { + string party_uid = 1; + + enum CrimeType { + option (gogoproto.goproto_enum_prefix) = false; + + CRIME_TYPE_UNSPECIFIED = 0; + CRIME_TYPE_NON_MALICIOUS = 1; + CRIME_TYPE_MALICIOUS = 2; + } + CrimeType crime_type = 2; + } + } +} + +message TrafficIn { + string from_party_uid = 1; + bytes payload = 2; + bool is_broadcast = 3; +} + +message TrafficOut { + string to_party_uid = 1; + bytes payload = 2; + bool is_broadcast = 3; +} + +// Keygen-specific message types + +message KeygenInit { + string new_key_uid = 1; + repeated string party_uids = 2; + repeated uint32 party_share_counts = 5; + uint32 my_party_index = 3; // parties[my_party_index] belongs to the server + uint32 threshold = 4; +} + +// Sign-specific message types + +message SignInit { + string new_sig_uid = 1; + string key_uid = 2; + repeated string party_uids = 3; // TODO replace this with a subset of indices? + bytes message_to_sign = 4; +} diff --git a/ampd/proto/axelar/tss/v1beta1/genesis.proto b/ampd/proto/axelar/tss/v1beta1/genesis.proto new file mode 100644 index 000000000..1e411bb56 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/genesis.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/v1beta1/params.proto"; +import "axelar/tss/v1beta1/types.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/tss/v1beta1/params.proto b/ampd/proto/axelar/tss/v1beta1/params.proto new file mode 100644 index 000000000..ab44ac748 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/params.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package axelar.tss.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params is the parameter set for this module +message Params { + // KeyRequirements defines the requirement for each key role + repeated tss.exported.v1beta1.KeyRequirement key_requirements = 1 + [ (gogoproto.nullable) = false ]; + // SuspendDurationInBlocks defines the number of blocks a + // validator is disallowed to participate in any TSS ceremony after + // committing a malicious behaviour during signing + int64 suspend_duration_in_blocks = 2; + // HeartBeatPeriodInBlocks defines the time period in blocks for tss to + // emit the event asking validators to send their heartbeats + int64 heartbeat_period_in_blocks = 3; + utils.v1beta1.Threshold max_missed_blocks_per_window = 4 + [ (gogoproto.nullable) = false ]; + int64 unbonding_locking_key_rotation_count = 5; + utils.v1beta1.Threshold external_multisig_threshold = 6 + [ (gogoproto.nullable) = false ]; + int64 max_sign_queue_size = 7; + int64 max_simultaneous_sign_shares = 8; + int64 tss_signed_blocks_window = 9; +} diff --git a/ampd/proto/axelar/tss/v1beta1/query.proto b/ampd/proto/axelar/tss/v1beta1/query.proto new file mode 100644 index 000000000..748cfefee --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/query.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/tss/v1beta1/service.proto b/ampd/proto/axelar/tss/v1beta1/service.proto new file mode 100644 index 000000000..01dfce6ec --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/service.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/snapshot/v1beta1/tx.proto"; +import "axelar/tss/v1beta1/tx.proto"; +import "axelar/tss/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the tss Msg service. +service MsgService { + rpc HeartBeat(axelar.tss.v1beta1.HeartBeatRequest) + returns (axelar.tss.v1beta1.HeartBeatResponse) { + option (google.api.http) = { + post : "/axelar/tss/heartbeat" + body : "*" + }; + } +} + +// Query defines the gRPC querier service. +service QueryService { + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/tss/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/tss/v1beta1/tx.proto b/ampd/proto/axelar/tss/v1beta1/tx.proto new file mode 100644 index 000000000..2cc6981d1 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/tx.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; +import "axelar/tss/v1beta1/types.proto"; +import "axelar/tss/tofnd/v1beta1/tofnd.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// StartKeygenRequest indicate the start of keygen +message StartKeygenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + tss.v1beta1.KeyInfo key_info = 2 [ (gogoproto.nullable) = false ]; +} + +message StartKeygenResponse {} + +message RotateKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + tss.exported.v1beta1.KeyRole key_role = 3; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; +} + +message RotateKeyResponse {} + +// ProcessKeygenTrafficRequest protocol message +message ProcessKeygenTrafficRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string session_id = 2 [ (gogoproto.customname) = "SessionID" ]; + tss.tofnd.v1beta1.TrafficOut payload = 3 [ (gogoproto.nullable) = false ]; +} + +message ProcessKeygenTrafficResponse {} + +// ProcessSignTrafficRequest protocol message +message ProcessSignTrafficRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string session_id = 2 [ (gogoproto.customname) = "SessionID" ]; + tss.tofnd.v1beta1.TrafficOut payload = 3 [ (gogoproto.nullable) = false ]; +} + +message ProcessSignTrafficResponse {} + +// VotePubKeyRequest represents the message to vote on a public key +message VotePubKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + vote.exported.v1beta1.PollKey poll_key = 2 [ (gogoproto.nullable) = false ]; + tss.tofnd.v1beta1.MessageOut.KeygenResult result = 3 + [ (gogoproto.nullable) = false ]; +} +message VotePubKeyResponse { string log = 1; } + +// VoteSigRequest represents a message to vote for a signature +message VoteSigRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + vote.exported.v1beta1.PollKey poll_key = 2 [ (gogoproto.nullable) = false ]; + tss.tofnd.v1beta1.MessageOut.SignResult result = 3 + [ (gogoproto.nullable) = false ]; +} + +message VoteSigResponse { string log = 1; } + +message HeartBeatRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + repeated string key_ids = 2 [ + (gogoproto.customname) = "KeyIDs", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; +} + +message HeartBeatResponse {} + +message RegisterExternalKeysRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + message ExternalKey { + string id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + bytes pub_key = 2; + } + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated ExternalKey external_keys = 3 [ (gogoproto.nullable) = false ]; +} + +message RegisterExternalKeysResponse {}; + +message SubmitMultisigPubKeysRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + repeated exported.v1beta1.SigKeyPair sig_key_pairs = 3 + [ (gogoproto.nullable) = false ]; +} + +message SubmitMultisigPubKeysResponse {} + +message SubmitMultisigSignaturesRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + + repeated bytes signatures = 3; +} + +message SubmitMultisigSignaturesResponse {} diff --git a/ampd/proto/axelar/tss/v1beta1/types.proto b/ampd/proto/axelar/tss/v1beta1/types.proto new file mode 100644 index 000000000..86fd8dae2 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/types.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +message KeygenVoteData { + bytes pub_key = 1; + bytes group_recovery_info = 2; +} + +// KeyInfo holds information about a key +message KeyInfo { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + tss.exported.v1beta1.KeyRole key_role = 2; + tss.exported.v1beta1.KeyType key_type = 3; +} + +message MultisigInfo { + message Info { + bytes participant = 1 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + repeated bytes data = 2; + } + string id = 1 [ (gogoproto.customname) = "ID" ]; + int64 timeout = 2; + int64 target_num = 3; + repeated Info infos = 4; +} + +message KeyRecoveryInfo { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + bytes public = 2; + map private = 3 [ (gogoproto.nullable) = false ]; +} + +message ExternalKeys { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated string key_ids = 2 [ + (gogoproto.customname) = "KeyIDs", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; +} + +message ValidatorStatus { + bytes validator = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + uint64 suspended_until = 2; +} diff --git a/ampd/proto/axelar/utils/v1beta1/bitmap.proto b/ampd/proto/axelar/utils/v1beta1/bitmap.proto new file mode 100644 index 000000000..4f9c714c2 --- /dev/null +++ b/ampd/proto/axelar/utils/v1beta1/bitmap.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package axelar.utils.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/utils"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Bitmap { CircularBuffer true_count_cache = 2; } + +message CircularBuffer { + repeated uint64 cumulative_value = 1; + int32 index = 2; + int32 max_size = 3; +} diff --git a/ampd/proto/axelar/utils/v1beta1/queuer.proto b/ampd/proto/axelar/utils/v1beta1/queuer.proto new file mode 100644 index 000000000..663d9b5a5 --- /dev/null +++ b/ampd/proto/axelar/utils/v1beta1/queuer.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package axelar.utils.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/utils"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message QueueState { + option (gogoproto.stable_marshaler) = true; + + message Item { + bytes key = 1; + bytes value = 2; + } + + map items = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/utils/v1beta1/threshold.proto b/ampd/proto/axelar/utils/v1beta1/threshold.proto new file mode 100644 index 000000000..3d0f17a70 --- /dev/null +++ b/ampd/proto/axelar/utils/v1beta1/threshold.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package axelar.utils.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/utils"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Threshold { + option (gogoproto.goproto_stringer) = false; + // split threshold into Numerator and denominator to avoid floating point + // errors down the line + int64 numerator = 1; + int64 denominator = 2; +} diff --git a/ampd/proto/axelar/vote/exported/v1beta1/types.proto b/ampd/proto/axelar/vote/exported/v1beta1/types.proto new file mode 100644 index 000000000..bc5e9f32e --- /dev/null +++ b/ampd/proto/axelar/vote/exported/v1beta1/types.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; +package axelar.vote.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/exported"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/snapshot/exported/v1beta1/types.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// PollMetadata represents a poll with write-in voting, i.e. the result of the +// vote can have any data type +message PollMetadata { + reserved 1, 8, 9, 14; // deleted poll key, total voting power, voters and + // module_metadata in 0.20.x + + int64 expires_at = 3; + google.protobuf.Any result = 4 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; + utils.v1beta1.Threshold voting_threshold = 5 [ (gogoproto.nullable) = false ]; + PollState state = 6; + int64 min_voter_count = 7; + string reward_pool_name = 10; + int64 grace_period = 11; + int64 completed_at = 12; + uint64 id = 13 [ + (gogoproto.customname) = "ID", + (gogoproto.customtype) = "PollID", + (gogoproto.nullable) = false + ]; + snapshot.exported.v1beta1.Snapshot snapshot = 15 + [ (gogoproto.nullable) = false ]; + string module = 16; + google.protobuf.Any module_metadata = 17 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +// PollKey represents the key data for a poll +message PollKey { + option deprecated = true; + option (gogoproto.goproto_stringer) = false; + + string module = 1; + string id = 2 [ (gogoproto.customname) = "ID" ]; +} + +enum PollState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + POLL_STATE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + POLL_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + POLL_STATE_COMPLETED = 2 [ (gogoproto.enumvalue_customname) = "Completed" ]; + POLL_STATE_FAILED = 3 [ (gogoproto.enumvalue_customname) = "Failed" ]; +} + +// PollParticipants should be embedded in poll events in other modules +message PollParticipants { + uint64 poll_id = 1 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = "PollID", + (gogoproto.nullable) = false + ]; + repeated bytes participants = 2 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} diff --git a/ampd/proto/axelar/vote/v1beta1/events.proto b/ampd/proto/axelar/vote/v1beta1/events.proto new file mode 100644 index 000000000..8a81dad60 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/events.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package axelar.vote.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Voted { + string module = 1; + string action = 2; + string poll = 3; + string voter = 4; + string state = 5; +} diff --git a/ampd/proto/axelar/vote/v1beta1/genesis.proto b/ampd/proto/axelar/vote/v1beta1/genesis.proto new file mode 100644 index 000000000..b26503c51 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package axelar.vote.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "axelar/vote/v1beta1/params.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated vote.exported.v1beta1.PollMetadata poll_metadatas = 2 + [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/vote/v1beta1/params.proto b/ampd/proto/axelar/vote/v1beta1/params.proto new file mode 100644 index 000000000..95f853532 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/params.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package axelar.vote.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + utils.v1beta1.Threshold default_voting_threshold = 1 + [ (gogoproto.nullable) = false ]; + int64 end_blocker_limit = 2; +} diff --git a/ampd/proto/axelar/vote/v1beta1/query.proto b/ampd/proto/axelar/vote/v1beta1/query.proto new file mode 100644 index 000000000..d99457a28 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/query.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "axelar/vote/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/vote/v1beta1/service.proto b/ampd/proto/axelar/vote/v1beta1/service.proto new file mode 100644 index 000000000..1dfd1574f --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/service.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/vote/v1beta1/tx.proto"; +import "axelar/vote/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the vote Msg service. +service MsgService { + rpc Vote(VoteRequest) returns (VoteResponse) { + option (google.api.http) = { + post : "/axelar/vote/vote" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/vote/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/vote/v1beta1/tx.proto b/ampd/proto/axelar/vote/v1beta1/tx.proto new file mode 100644 index 000000000..771005831 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/tx.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; +import "axelar/vote/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message VoteRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + reserved 2, 3; // poll_key and vote were removed in v0.20 + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + uint64 poll_id = 4 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; + google.protobuf.Any vote = 5 [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +message VoteResponse { string log = 1; } diff --git a/ampd/proto/axelar/vote/v1beta1/types.proto b/ampd/proto/axelar/vote/v1beta1/types.proto new file mode 100644 index 000000000..92b64ce57 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/types.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// TalliedVote represents a vote for a poll with the accumulated stake of all +// validators voting for the same data +message TalliedVote { + reserved 2; // voters is deleted in version 0.20.x + + option (gogoproto.stable_marshaler) = true; + + bytes tally = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + google.protobuf.Any data = 3 [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; + uint64 poll_id = 4 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; + map is_voter_late = 5; +} diff --git a/ampd/proto/third_party/buf.yaml b/ampd/proto/third_party/buf.yaml new file mode 100644 index 000000000..aae636f0a --- /dev/null +++ b/ampd/proto/third_party/buf.yaml @@ -0,0 +1,20 @@ +# Generated by "buf config migrate-v1beta1". Edit as necessary, and +# remove this comment when you're finished. +# +# This module represents the "proto" root found in +# the previous configuration. +version: v1 +breaking: + use: + - FILE +lint: + use: + - DEFAULT + - COMMENTS + - FILE_LOWER_SNAKE_CASE + except: + - UNARY_RPC + - COMMENT_FIELD + - SERVICE_SUFFIX + - PACKAGE_VERSION_SUFFIX + - RPC_REQUEST_STANDARD_NAME diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto new file mode 100644 index 000000000..72e1d9ec2 --- /dev/null +++ b/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// BaseAccount defines a base account type. It contains all the necessary fields +// for basic account functionality. Any custom account type should extend this +// type for additional functionality (e.g. vesting). +message BaseAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = false; + + option (cosmos_proto.implements_interface) = "AccountI"; + + string address = 1; + google.protobuf.Any pub_key = 2 + [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; + uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""]; + uint64 sequence = 4; +} + +// ModuleAccount defines an account for modules that holds coins on a pool. +message ModuleAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (cosmos_proto.implements_interface) = "ModuleAccountI"; + + BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; + string name = 2; + repeated string permissions = 3; +} + +// Params defines the parameters for the auth module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + uint64 max_memo_characters = 1 [(gogoproto.moretags) = "yaml:\"max_memo_characters\""]; + uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""]; + uint64 tx_size_cost_per_byte = 3 [(gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\""]; + uint64 sig_verify_cost_ed25519 = 4 + [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""]; + uint64 sig_verify_cost_secp256k1 = 5 + [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; +} diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto new file mode 100644 index 000000000..c88b94ee4 --- /dev/null +++ b/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// GenesisState defines the auth module's genesis state. +message GenesisState { + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // accounts are the accounts present at genesis. + repeated google.protobuf.Any accounts = 2; +} diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto new file mode 100644 index 000000000..79799a4b7 --- /dev/null +++ b/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto @@ -0,0 +1,89 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "cosmos/auth/v1beta1/auth.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// Query defines the gRPC querier service. +service Query { + // Accounts returns all the existing accounts + // + // Since: cosmos-sdk 0.43 + rpc Accounts(QueryAccountsRequest) returns (QueryAccountsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts"; + } + + // Account returns account details based on address. + rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; + } + + // Params queries all parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/params"; + } + + // ModuleAccountByName returns the module account info by module name + rpc ModuleAccountByName(QueryModuleAccountByNameRequest) returns (QueryModuleAccountByNameResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/module_accounts/{name}"; + } +} + +// QueryAccountsRequest is the request type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryAccountsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryAccountsResponse is the response type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryAccountsResponse { + // accounts are the existing accounts + repeated google.protobuf.Any accounts = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryAccountRequest is the request type for the Query/Account RPC method. +message QueryAccountRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address defines the address to query for. + string address = 1; +} + +// QueryAccountResponse is the response type for the Query/Account RPC method. +message QueryAccountResponse { + // account defines the account of the corresponding address. + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryModuleAccountByNameRequest is the request type for the Query/ModuleAccountByName RPC method. +message QueryModuleAccountByNameRequest { + string name = 1; +} + +// QueryModuleAccountByNameResponse is the response type for the Query/ModuleAccountByName RPC method. +message QueryModuleAccountByNameResponse { + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "ModuleAccountI"]; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto new file mode 100644 index 000000000..05b1feefa --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto @@ -0,0 +1,39 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; +option (gogoproto.goproto_getters_all) = false; + +// GenericAuthorization gives the grantee unrestricted permissions to execute +// the provided method on behalf of the granter's account. +message GenericAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // Msg, identified by it's type URL, to grant unrestricted permissions to execute + string msg = 1; +} + +// Grant gives permissions to execute +// the provide method with expiration time. +message Grant { + google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"]; + google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +// GrantAuthorization extends a grant with both the addresses of the grantee and granter. +// It is used in genesis.proto and query.proto +// +// Since: cosmos-sdk 0.45.2 +message GrantAuthorization { + string granter = 1; + string grantee = 2; + + google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"]; + google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto new file mode 100644 index 000000000..7a3cf7c8c --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto @@ -0,0 +1,25 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; + +// EventGrant is emitted on Msg/Grant +message EventGrant { + // Msg type URL for which an autorization is granted + string msg_type_url = 2; + // Granter account address + string granter = 3; + // Grantee account address + string grantee = 4; +} + +// EventRevoke is emitted on Msg/Revoke +message EventRevoke { + // Msg type URL for which an autorization is revoked + string msg_type_url = 2; + // Granter account address + string granter = 3; + // Grantee account address + string grantee = 4; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto new file mode 100644 index 000000000..310f62656 --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto @@ -0,0 +1,13 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/authz/v1beta1/authz.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; + +// GenesisState defines the authz module's genesis state. +message GenesisState { + repeated GrantAuthorization authorization = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto new file mode 100644 index 000000000..f668309be --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto @@ -0,0 +1,81 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "cosmos/authz/v1beta1/authz.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; + +// Query defines the gRPC querier service. +service Query { + // Returns list of `Authorization`, granted to the grantee by the granter. + rpc Grants(QueryGrantsRequest) returns (QueryGrantsResponse) { + option (google.api.http).get = "/cosmos/authz/v1beta1/grants"; + } + + // GranterGrants returns list of `GrantAuthorization`, granted by granter. + // + // Since: cosmos-sdk 0.45.2 + rpc GranterGrants(QueryGranterGrantsRequest) returns (QueryGranterGrantsResponse) { + option (google.api.http).get = "/cosmos/authz/v1beta1/grants/granter/{granter}"; + } + + // GranteeGrants returns a list of `GrantAuthorization` by grantee. + // + // Since: cosmos-sdk 0.45.2 + rpc GranteeGrants(QueryGranteeGrantsRequest) returns (QueryGranteeGrantsResponse) { + option (google.api.http).get = "/cosmos/authz/v1beta1/grants/grantee/{grantee}"; + } +} + +// QueryGrantsRequest is the request type for the Query/Grants RPC method. +message QueryGrantsRequest { + string granter = 1; + string grantee = 2; + // Optional, msg_type_url, when set, will query only grants matching given msg type. + string msg_type_url = 3; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryGrantsResponse is the response type for the Query/Authorizations RPC method. +message QueryGrantsResponse { + // authorizations is a list of grants granted for grantee by granter. + repeated Grant grants = 1; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryGranterGrantsRequest is the request type for the Query/GranterGrants RPC method. +message QueryGranterGrantsRequest { + string granter = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryGranterGrantsResponse is the response type for the Query/GranterGrants RPC method. +message QueryGranterGrantsResponse { + // grants is a list of grants granted by the granter. + repeated GrantAuthorization grants = 1; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryGranteeGrantsRequest is the request type for the Query/IssuedGrants RPC method. +message QueryGranteeGrantsRequest { + string grantee = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryGranteeGrantsResponse is the response type for the Query/GranteeGrants RPC method. +message QueryGranteeGrantsResponse { + // grants is a list of grants granted to the grantee. + repeated GrantAuthorization grants = 1; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto new file mode 100644 index 000000000..457f0d662 --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto @@ -0,0 +1,70 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/authz/v1beta1/authz.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; +option (gogoproto.goproto_getters_all) = false; + +// Msg defines the authz Msg service. +service Msg { + // Grant grants the provided authorization to the grantee on the granter's + // account with the provided expiration time. If there is already a grant + // for the given (granter, grantee, Authorization) triple, then the grant + // will be overwritten. + rpc Grant(MsgGrant) returns (MsgGrantResponse); + + // Exec attempts to execute the provided messages using + // authorizations granted to the grantee. Each message should have only + // one signer corresponding to the granter of the authorization. + rpc Exec(MsgExec) returns (MsgExecResponse); + + // Revoke revokes any authorization corresponding to the provided method name on the + // granter's account that has been granted to the grantee. + rpc Revoke(MsgRevoke) returns (MsgRevokeResponse); +} + +// MsgGrant is a request type for Grant method. It declares authorization to the grantee +// on behalf of the granter with the provided expiration time. +message MsgGrant { + string granter = 1; + string grantee = 2; + + cosmos.authz.v1beta1.Grant grant = 3 [(gogoproto.nullable) = false]; +} + +// MsgExecResponse defines the Msg/MsgExecResponse response type. +message MsgExecResponse { + repeated bytes results = 1; +} + +// MsgExec attempts to execute the provided messages using +// authorizations granted to the grantee. Each message should have only +// one signer corresponding to the granter of the authorization. +message MsgExec { + string grantee = 1; + // Authorization Msg requests to execute. Each msg must implement Authorization interface + // The x/authz will try to find a grant matching (msg.signers[0], grantee, MsgTypeURL(msg)) + // triple and validate it. + repeated google.protobuf.Any msgs = 2 [(cosmos_proto.accepts_interface) = "sdk.Msg, authz.Authorization"]; +} + +// MsgGrantResponse defines the Msg/MsgGrant response type. +message MsgGrantResponse {} + +// MsgRevoke revokes any authorization with the provided sdk.Msg type on the +// granter's account with that has been granted to the grantee. +message MsgRevoke { + string granter = 1; + string grantee = 2; + string msg_type_url = 3; +} + +// MsgRevokeResponse defines the Msg/MsgRevokeResponse response type. +message MsgRevokeResponse {} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto new file mode 100644 index 000000000..4f58b15e4 --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// SendAuthorization allows the grantee to spend up to spend_limit coins from +// the granter's account. +// +// Since: cosmos-sdk 0.43 +message SendAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + repeated cosmos.base.v1beta1.Coin spend_limit = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto new file mode 100644 index 000000000..df91008df --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto @@ -0,0 +1,96 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Params defines the parameters for the bank module. +message Params { + option (gogoproto.goproto_stringer) = false; + repeated SendEnabled send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled,omitempty\""]; + bool default_send_enabled = 2 [(gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\""]; +} + +// SendEnabled maps coin denom to a send_enabled status (whether a denom is +// sendable). +message SendEnabled { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + string denom = 1; + bool enabled = 2; +} + +// Input models transaction input. +message Input { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1; + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Output models transaction outputs. +message Output { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1; + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Supply represents a struct that passively keeps track of the total supply +// amounts in the network. +// This message is deprecated now that supply is indexed by denom. +message Supply { + option deprecated = true; + + option (gogoproto.equal) = true; + option (gogoproto.goproto_getters) = false; + + option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/legacy/v040.SupplyI"; + + repeated cosmos.base.v1beta1.Coin total = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// DenomUnit represents a struct that describes a given +// denomination unit of the basic token. +message DenomUnit { + // denom represents the string name of the given denom unit (e.g uatom). + string denom = 1; + // exponent represents power of 10 exponent that one must + // raise the base_denom to in order to equal the given DenomUnit's denom + // 1 denom = 1^exponent base_denom + // (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with + // exponent = 6, thus: 1 atom = 10^6 uatom). + uint32 exponent = 2; + // aliases is a list of string aliases for the given denom + repeated string aliases = 3; +} + +// Metadata represents a struct that describes +// a basic token. +message Metadata { + string description = 1; + // denom_units represents the list of DenomUnit's for a given coin + repeated DenomUnit denom_units = 2; + // base represents the base denom (should be the DenomUnit with exponent = 0). + string base = 3; + // display indicates the suggested denom that should be + // displayed in clients. + string display = 4; + // name defines the name of the token (eg: Cosmos Atom) + // + // Since: cosmos-sdk 0.43 + string name = 5; + // symbol is the token symbol usually shown on exchanges (eg: ATOM). This can + // be the same as the display. + // + // Since: cosmos-sdk 0.43 + string symbol = 6; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto new file mode 100644 index 000000000..8fd7329a0 --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// GenesisState defines the bank module's genesis state. +message GenesisState { + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // balances is an array containing the balances of all the accounts. + repeated Balance balances = 2 [(gogoproto.nullable) = false]; + + // supply represents the total supply. If it is left empty, then supply will be calculated based on the provided + // balances. Otherwise, it will be used to validate that the sum of the balances equals this amount. + repeated cosmos.base.v1beta1.Coin supply = 3 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; + + // denom_metadata defines the metadata of the differents coins. + repeated Metadata denom_metadata = 4 [(gogoproto.moretags) = "yaml:\"denom_metadata\"", (gogoproto.nullable) = false]; +} + +// Balance defines an account address and balance pair used in the bank module's +// genesis state. +message Balance { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address of the balance holder. + string address = 1; + + // coins defines the different coins this balance holds. + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto new file mode 100644 index 000000000..a567e073f --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto @@ -0,0 +1,193 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Query defines the gRPC querier service. +service Query { + // Balance queries the balance of a single coin for a single account. + rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}/by_denom"; + } + + // AllBalances queries the balance of all coins for a single account. + rpc AllBalances(QueryAllBalancesRequest) returns (QueryAllBalancesResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}"; + } + + // SpendableBalances queries the spenable balance of all coins for a single + // account. + rpc SpendableBalances(QuerySpendableBalancesRequest) returns (QuerySpendableBalancesResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/spendable_balances/{address}"; + } + + // TotalSupply queries the total supply of all coins. + rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/supply"; + } + + // SupplyOf queries the supply of a single coin. + rpc SupplyOf(QuerySupplyOfRequest) returns (QuerySupplyOfResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/supply/{denom}"; + } + + // Params queries the parameters of x/bank module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/params"; + } + + // DenomsMetadata queries the client metadata of a given coin denomination. + rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata/{denom}"; + } + + // DenomsMetadata queries the client metadata for all registered coin denominations. + rpc DenomsMetadata(QueryDenomsMetadataRequest) returns (QueryDenomsMetadataResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata"; + } +} + +// QueryBalanceRequest is the request type for the Query/Balance RPC method. +message QueryBalanceRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query balances for. + string address = 1; + + // denom is the coin denom to query balances for. + string denom = 2; +} + +// QueryBalanceResponse is the response type for the Query/Balance RPC method. +message QueryBalanceResponse { + // balance is the balance of the coin. + cosmos.base.v1beta1.Coin balance = 1; +} + +// QueryBalanceRequest is the request type for the Query/AllBalances RPC method. +message QueryAllBalancesRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query balances for. + string address = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC +// method. +message QueryAllBalancesResponse { + // balances is the balances of all the coins. + repeated cosmos.base.v1beta1.Coin balances = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QuerySpendableBalancesRequest defines the gRPC request structure for querying +// an account's spendable balances. +message QuerySpendableBalancesRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query spendable balances for. + string address = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QuerySpendableBalancesResponse defines the gRPC response structure for querying +// an account's spendable balances. +message QuerySpendableBalancesResponse { + // balances is the spendable balances of all the coins. + repeated cosmos.base.v1beta1.Coin balances = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC +// method. +message QueryTotalSupplyRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // pagination defines an optional pagination for the request. + // + // Since: cosmos-sdk 0.43 + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC +// method +message QueryTotalSupplyResponse { + // supply is the supply of the coins + repeated cosmos.base.v1beta1.Coin supply = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + // + // Since: cosmos-sdk 0.43 + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method. +message QuerySupplyOfRequest { + // denom is the coin denom to query balances for. + string denom = 1; +} + +// QuerySupplyOfResponse is the response type for the Query/SupplyOf RPC method. +message QuerySupplyOfResponse { + // amount is the supply of the coin. + cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; +} + +// QueryParamsRequest defines the request type for querying x/bank parameters. +message QueryParamsRequest {} + +// QueryParamsResponse defines the response type for querying x/bank parameters. +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method. +message QueryDenomsMetadataRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC +// method. +message QueryDenomsMetadataResponse { + // metadata provides the client information for all the registered tokens. + repeated Metadata metadatas = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method. +message QueryDenomMetadataRequest { + // denom is the coin denom to query the metadata for. + string denom = 1; +} + +// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC +// method. +message QueryDenomMetadataResponse { + // metadata describes and provides all the client information for the requested token. + Metadata metadata = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto new file mode 100644 index 000000000..26b2ab41f --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Msg defines the bank Msg service. +service Msg { + // Send defines a method for sending coins from one account to another account. + rpc Send(MsgSend) returns (MsgSendResponse); + + // MultiSend defines a method for sending coins from some accounts to other accounts. + rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse); +} + +// MsgSend represents a message to send coins from one account to another. +message MsgSend { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// MsgSendResponse defines the Msg/Send response type. +message MsgSendResponse {} + +// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +message MsgMultiSend { + option (gogoproto.equal) = false; + + repeated Input inputs = 1 [(gogoproto.nullable) = false]; + repeated Output outputs = 2 [(gogoproto.nullable) = false]; +} + +// MsgMultiSendResponse defines the Msg/MultiSend response type. +message MsgMultiSendResponse {} diff --git a/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto b/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto new file mode 100644 index 000000000..e24ae7bd5 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto @@ -0,0 +1,144 @@ +syntax = "proto3"; +package cosmos.base.abci.v1beta1; + +import "gogoproto/gogo.proto"; +import "tendermint/abci/types.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types"; +option (gogoproto.goproto_stringer_all) = false; + +// TxResponse defines a structure containing relevant tx data and metadata. The +// tags are stringified and the log is JSON decoded. +message TxResponse { + option (gogoproto.goproto_getters) = false; + // The block height + int64 height = 1; + // The transaction hash. + string txhash = 2 [(gogoproto.customname) = "TxHash"]; + // Namespace for the Code + string codespace = 3; + // Response code. + uint32 code = 4; + // Result bytes, if any. + string data = 5; + // The output of the application's logger (raw string). May be + // non-deterministic. + string raw_log = 6; + // The output of the application's logger (typed). May be non-deterministic. + repeated ABCIMessageLog logs = 7 [(gogoproto.castrepeated) = "ABCIMessageLogs", (gogoproto.nullable) = false]; + // Additional information. May be non-deterministic. + string info = 8; + // Amount of gas requested for transaction. + int64 gas_wanted = 9; + // Amount of gas consumed by transaction. + int64 gas_used = 10; + // The request transaction bytes. + google.protobuf.Any tx = 11; + // Time of the previous block. For heights > 1, it's the weighted median of + // the timestamps of the valid votes in the block.LastCommit. For height == 1, + // it's genesis time. + string timestamp = 12; + // Events defines all the events emitted by processing a transaction. Note, + // these events include those emitted by processing all the messages and those + // emitted from the ante handler. Whereas Logs contains the events, with + // additional metadata, emitted only by processing the messages. + // + // Since: cosmos-sdk 0.42.11, 0.44.5, 0.45 + repeated tendermint.abci.Event events = 13 [(gogoproto.nullable) = false]; +} + +// ABCIMessageLog defines a structure containing an indexed tx ABCI message log. +message ABCIMessageLog { + option (gogoproto.stringer) = true; + + uint32 msg_index = 1; + string log = 2; + + // Events contains a slice of Event objects that were emitted during some + // execution. + repeated StringEvent events = 3 [(gogoproto.castrepeated) = "StringEvents", (gogoproto.nullable) = false]; +} + +// StringEvent defines en Event object wrapper where all the attributes +// contain key/value pairs that are strings instead of raw bytes. +message StringEvent { + option (gogoproto.stringer) = true; + + string type = 1; + repeated Attribute attributes = 2 [(gogoproto.nullable) = false]; +} + +// Attribute defines an attribute wrapper where the key and value are +// strings instead of raw bytes. +message Attribute { + string key = 1; + string value = 2; +} + +// GasInfo defines tx execution gas context. +message GasInfo { + // GasWanted is the maximum units of work we allow this tx to perform. + uint64 gas_wanted = 1 [(gogoproto.moretags) = "yaml:\"gas_wanted\""]; + + // GasUsed is the amount of gas actually consumed. + uint64 gas_used = 2 [(gogoproto.moretags) = "yaml:\"gas_used\""]; +} + +// Result is the union of ResponseFormat and ResponseCheckTx. +message Result { + option (gogoproto.goproto_getters) = false; + + // Data is any data returned from message or handler execution. It MUST be + // length prefixed in order to separate data from multiple message executions. + bytes data = 1; + + // Log contains the log information from message or handler execution. + string log = 2; + + // Events contains a slice of Event objects that were emitted during message + // or handler execution. + repeated tendermint.abci.Event events = 3 [(gogoproto.nullable) = false]; +} + +// SimulationResponse defines the response generated when a transaction is +// successfully simulated. +message SimulationResponse { + GasInfo gas_info = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + Result result = 2; +} + +// MsgData defines the data returned in a Result object during message +// execution. +message MsgData { + option (gogoproto.stringer) = true; + + string msg_type = 1; + bytes data = 2; +} + +// TxMsgData defines a list of MsgData. A transaction will have a MsgData object +// for each message. +message TxMsgData { + option (gogoproto.stringer) = true; + + repeated MsgData data = 1; +} + +// SearchTxsResult defines a structure for querying txs pageable +message SearchTxsResult { + option (gogoproto.stringer) = true; + + // Count of all txs + uint64 total_count = 1 [(gogoproto.moretags) = "yaml:\"total_count\"", (gogoproto.jsontag) = "total_count"]; + // Count of txs in current page + uint64 count = 2; + // Index of current page, start from 1 + uint64 page_number = 3 [(gogoproto.moretags) = "yaml:\"page_number\"", (gogoproto.jsontag) = "page_number"]; + // Count of total pages + uint64 page_total = 4 [(gogoproto.moretags) = "yaml:\"page_total\"", (gogoproto.jsontag) = "page_total"]; + // Max count txs per page + uint64 limit = 5; + // List of txs in current page + repeated TxResponse txs = 6; +} diff --git a/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto b/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto new file mode 100644 index 000000000..4e9b8d285 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package cosmos.base.kv.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/kv"; + +// Pairs defines a repeated slice of Pair objects. +message Pairs { + repeated Pair pairs = 1 [(gogoproto.nullable) = false]; +} + +// Pair defines a key/value bytes tuple. +message Pair { + bytes key = 1; + bytes value = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto b/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto new file mode 100644 index 000000000..8070f7b90 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.base.node.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/node"; + +// Service defines the gRPC querier service for node related queries. +service Service { + // Config queries for the operator configuration. + rpc Config(ConfigRequest) returns (ConfigResponse) { + option (google.api.http).get = "/cosmos/base/node/v1beta1/config"; + } +} + +// ConfigRequest defines the request structure for the Config gRPC query. +message ConfigRequest {} + +// ConfigResponse defines the response structure for the Config gRPC query. +message ConfigResponse { + string minimum_gas_price = 1; +} diff --git a/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto b/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto new file mode 100644 index 000000000..cd5eb066d --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; +package cosmos.base.query.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/types/query"; + +// PageRequest is to be embedded in gRPC request messages for efficient +// pagination. Ex: +// +// message SomeRequest { +// Foo some_parameter = 1; +// PageRequest pagination = 2; +// } +message PageRequest { + // key is a value returned in PageResponse.next_key to begin + // querying the next page most efficiently. Only one of offset or key + // should be set. + bytes key = 1; + + // offset is a numeric offset that can be used when key is unavailable. + // It is less efficient than using key. Only one of offset or key should + // be set. + uint64 offset = 2; + + // limit is the total number of results to be returned in the result page. + // If left empty it will default to a value to be set by each app. + uint64 limit = 3; + + // count_total is set to true to indicate that the result set should include + // a count of the total number of items available for pagination in UIs. + // count_total is only respected when offset is used. It is ignored when key + // is set. + bool count_total = 4; + + // reverse is set to true if results are to be returned in the descending order. + // + // Since: cosmos-sdk 0.43 + bool reverse = 5; +} + +// PageResponse is to be embedded in gRPC response messages where the +// corresponding request message has used PageRequest. +// +// message SomeResponse { +// repeated Bar results = 1; +// PageResponse page = 2; +// } +message PageResponse { + // next_key is the key to be passed to PageRequest.key to + // query the next page most efficiently + bytes next_key = 1; + + // total is total number of results available if PageRequest.count_total + // was set, its value is undefined otherwise + uint64 total = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto b/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto new file mode 100644 index 000000000..22670e72b --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; +package cosmos.base.reflection.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/reflection"; + +// ReflectionService defines a service for interface reflection. +service ReflectionService { + // ListAllInterfaces lists all the interfaces registered in the interface + // registry. + rpc ListAllInterfaces(ListAllInterfacesRequest) returns (ListAllInterfacesResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces"; + }; + + // ListImplementations list all the concrete types that implement a given + // interface. + rpc ListImplementations(ListImplementationsRequest) returns (ListImplementationsResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/" + "{interface_name}/implementations"; + }; +} + +// ListAllInterfacesRequest is the request type of the ListAllInterfaces RPC. +message ListAllInterfacesRequest {} + +// ListAllInterfacesResponse is the response type of the ListAllInterfaces RPC. +message ListAllInterfacesResponse { + // interface_names is an array of all the registered interfaces. + repeated string interface_names = 1; +} + +// ListImplementationsRequest is the request type of the ListImplementations +// RPC. +message ListImplementationsRequest { + // interface_name defines the interface to query the implementations for. + string interface_name = 1; +} + +// ListImplementationsResponse is the response type of the ListImplementations +// RPC. +message ListImplementationsResponse { + repeated string implementation_message_names = 1; +} diff --git a/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto b/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto new file mode 100644 index 000000000..d5b048558 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto @@ -0,0 +1,218 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.base.reflection.v2alpha1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/server/grpc/reflection/v2alpha1"; + +// AppDescriptor describes a cosmos-sdk based application +message AppDescriptor { + // AuthnDescriptor provides information on how to authenticate transactions on the application + // NOTE: experimental and subject to change in future releases. + AuthnDescriptor authn = 1; + // chain provides the chain descriptor + ChainDescriptor chain = 2; + // codec provides metadata information regarding codec related types + CodecDescriptor codec = 3; + // configuration provides metadata information regarding the sdk.Config type + ConfigurationDescriptor configuration = 4; + // query_services provides metadata information regarding the available queriable endpoints + QueryServicesDescriptor query_services = 5; + // tx provides metadata information regarding how to send transactions to the given application + TxDescriptor tx = 6; +} + +// TxDescriptor describes the accepted transaction type +message TxDescriptor { + // fullname is the protobuf fullname of the raw transaction type (for instance the tx.Tx type) + // it is not meant to support polymorphism of transaction types, it is supposed to be used by + // reflection clients to understand if they can handle a specific transaction type in an application. + string fullname = 1; + // msgs lists the accepted application messages (sdk.Msg) + repeated MsgDescriptor msgs = 2; +} + +// AuthnDescriptor provides information on how to sign transactions without relying +// on the online RPCs GetTxMetadata and CombineUnsignedTxAndSignatures +message AuthnDescriptor { + // sign_modes defines the supported signature algorithm + repeated SigningModeDescriptor sign_modes = 1; +} + +// SigningModeDescriptor provides information on a signing flow of the application +// NOTE(fdymylja): here we could go as far as providing an entire flow on how +// to sign a message given a SigningModeDescriptor, but it's better to think about +// this another time +message SigningModeDescriptor { + // name defines the unique name of the signing mode + string name = 1; + // number is the unique int32 identifier for the sign_mode enum + int32 number = 2; + // authn_info_provider_method_fullname defines the fullname of the method to call to get + // the metadata required to authenticate using the provided sign_modes + string authn_info_provider_method_fullname = 3; +} + +// ChainDescriptor describes chain information of the application +message ChainDescriptor { + // id is the chain id + string id = 1; +} + +// CodecDescriptor describes the registered interfaces and provides metadata information on the types +message CodecDescriptor { + // interfaces is a list of the registerted interfaces descriptors + repeated InterfaceDescriptor interfaces = 1; +} + +// InterfaceDescriptor describes the implementation of an interface +message InterfaceDescriptor { + // fullname is the name of the interface + string fullname = 1; + // interface_accepting_messages contains information regarding the proto messages which contain the interface as + // google.protobuf.Any field + repeated InterfaceAcceptingMessageDescriptor interface_accepting_messages = 2; + // interface_implementers is a list of the descriptors of the interface implementers + repeated InterfaceImplementerDescriptor interface_implementers = 3; +} + +// InterfaceImplementerDescriptor describes an interface implementer +message InterfaceImplementerDescriptor { + // fullname is the protobuf queryable name of the interface implementer + string fullname = 1; + // type_url defines the type URL used when marshalling the type as any + // this is required so we can provide type safe google.protobuf.Any marshalling and + // unmarshalling, making sure that we don't accept just 'any' type + // in our interface fields + string type_url = 2; +} + +// InterfaceAcceptingMessageDescriptor describes a protobuf message which contains +// an interface represented as a google.protobuf.Any +message InterfaceAcceptingMessageDescriptor { + // fullname is the protobuf fullname of the type containing the interface + string fullname = 1; + // field_descriptor_names is a list of the protobuf name (not fullname) of the field + // which contains the interface as google.protobuf.Any (the interface is the same, but + // it can be in multiple fields of the same proto message) + repeated string field_descriptor_names = 2; +} + +// ConfigurationDescriptor contains metadata information on the sdk.Config +message ConfigurationDescriptor { + // bech32_account_address_prefix is the account address prefix + string bech32_account_address_prefix = 1; +} + +// MsgDescriptor describes a cosmos-sdk message that can be delivered with a transaction +message MsgDescriptor { + // msg_type_url contains the TypeURL of a sdk.Msg. + string msg_type_url = 1; +} + +// ReflectionService defines a service for application reflection. +service ReflectionService { + // GetAuthnDescriptor returns information on how to authenticate transactions in the application + // NOTE: this RPC is still experimental and might be subject to breaking changes or removal in + // future releases of the cosmos-sdk. + rpc GetAuthnDescriptor(GetAuthnDescriptorRequest) returns (GetAuthnDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/authn"; + } + // GetChainDescriptor returns the description of the chain + rpc GetChainDescriptor(GetChainDescriptorRequest) returns (GetChainDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/chain"; + }; + // GetCodecDescriptor returns the descriptor of the codec of the application + rpc GetCodecDescriptor(GetCodecDescriptorRequest) returns (GetCodecDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/codec"; + } + // GetConfigurationDescriptor returns the descriptor for the sdk.Config of the application + rpc GetConfigurationDescriptor(GetConfigurationDescriptorRequest) returns (GetConfigurationDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/configuration"; + } + // GetQueryServicesDescriptor returns the available gRPC queryable services of the application + rpc GetQueryServicesDescriptor(GetQueryServicesDescriptorRequest) returns (GetQueryServicesDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/query_services"; + } + // GetTxDescriptor returns information on the used transaction object and available msgs that can be used + rpc GetTxDescriptor(GetTxDescriptorRequest) returns (GetTxDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/tx_descriptor"; + } +} + +// GetAuthnDescriptorRequest is the request used for the GetAuthnDescriptor RPC +message GetAuthnDescriptorRequest {} +// GetAuthnDescriptorResponse is the response returned by the GetAuthnDescriptor RPC +message GetAuthnDescriptorResponse { + // authn describes how to authenticate to the application when sending transactions + AuthnDescriptor authn = 1; +} + +// GetChainDescriptorRequest is the request used for the GetChainDescriptor RPC +message GetChainDescriptorRequest {} +// GetChainDescriptorResponse is the response returned by the GetChainDescriptor RPC +message GetChainDescriptorResponse { + // chain describes application chain information + ChainDescriptor chain = 1; +} + +// GetCodecDescriptorRequest is the request used for the GetCodecDescriptor RPC +message GetCodecDescriptorRequest {} +// GetCodecDescriptorResponse is the response returned by the GetCodecDescriptor RPC +message GetCodecDescriptorResponse { + // codec describes the application codec such as registered interfaces and implementations + CodecDescriptor codec = 1; +} + +// GetConfigurationDescriptorRequest is the request used for the GetConfigurationDescriptor RPC +message GetConfigurationDescriptorRequest {} +// GetConfigurationDescriptorResponse is the response returned by the GetConfigurationDescriptor RPC +message GetConfigurationDescriptorResponse { + // config describes the application's sdk.Config + ConfigurationDescriptor config = 1; +} + +// GetQueryServicesDescriptorRequest is the request used for the GetQueryServicesDescriptor RPC +message GetQueryServicesDescriptorRequest {} +// GetQueryServicesDescriptorResponse is the response returned by the GetQueryServicesDescriptor RPC +message GetQueryServicesDescriptorResponse { + // queries provides information on the available queryable services + QueryServicesDescriptor queries = 1; +} + +// GetTxDescriptorRequest is the request used for the GetTxDescriptor RPC +message GetTxDescriptorRequest {} +// GetTxDescriptorResponse is the response returned by the GetTxDescriptor RPC +message GetTxDescriptorResponse { + // tx provides information on msgs that can be forwarded to the application + // alongside the accepted transaction protobuf type + TxDescriptor tx = 1; +} + +// QueryServicesDescriptor contains the list of cosmos-sdk queriable services +message QueryServicesDescriptor { + // query_services is a list of cosmos-sdk QueryServiceDescriptor + repeated QueryServiceDescriptor query_services = 1; +} + +// QueryServiceDescriptor describes a cosmos-sdk queryable service +message QueryServiceDescriptor { + // fullname is the protobuf fullname of the service descriptor + string fullname = 1; + // is_module describes if this service is actually exposed by an application's module + bool is_module = 2; + // methods provides a list of query service methods + repeated QueryMethodDescriptor methods = 3; +} + +// QueryMethodDescriptor describes a queryable method of a query service +// no other info is provided beside method name and tendermint queryable path +// because it would be redundant with the grpc reflection service +message QueryMethodDescriptor { + // name is the protobuf name (not fullname) of the method + string name = 1; + // full_query_path is the path that can be used to query + // this method via tendermint abci.Query + string full_query_path = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto b/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto new file mode 100644 index 000000000..6dcc4a933 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package cosmos.base.snapshots.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/snapshots/types"; + +// Snapshot contains Tendermint state sync snapshot info. +message Snapshot { + uint64 height = 1; + uint32 format = 2; + uint32 chunks = 3; + bytes hash = 4; + Metadata metadata = 5 [(gogoproto.nullable) = false]; +} + +// Metadata contains SDK-specific snapshot metadata. +message Metadata { + repeated bytes chunk_hashes = 1; // SHA-256 chunk hashes +} + +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +message SnapshotItem { + // item is the specific type of snapshot item. + oneof item { + SnapshotStoreItem store = 1; + SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; + SnapshotExtensionMeta extension = 3; + SnapshotExtensionPayload extension_payload = 4; + } +} + +// SnapshotStoreItem contains metadata about a snapshotted store. +message SnapshotStoreItem { + string name = 1; +} + +// SnapshotIAVLItem is an exported IAVL node. +message SnapshotIAVLItem { + bytes key = 1; + bytes value = 2; + // version is block height + int64 version = 3; + // height is depth of the tree. + int32 height = 4; +} + +// SnapshotExtensionMeta contains metadata about an external snapshotter. +message SnapshotExtensionMeta { + string name = 1; + uint32 format = 2; +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +message SnapshotExtensionPayload { + bytes payload = 1; +} diff --git a/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto b/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto new file mode 100644 index 000000000..98a33d30e --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; +package cosmos.base.store.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/store/types"; + +// CommitInfo defines commit information used by the multi-store when committing +// a version/height. +message CommitInfo { + int64 version = 1; + repeated StoreInfo store_infos = 2 [(gogoproto.nullable) = false]; +} + +// StoreInfo defines store-specific commit information. It contains a reference +// between a store name and the commit ID. +message StoreInfo { + string name = 1; + CommitID commit_id = 2 [(gogoproto.nullable) = false]; +} + +// CommitID defines the committment information when a specific store is +// committed. +message CommitID { + option (gogoproto.goproto_stringer) = false; + + int64 version = 1; + bytes hash = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto b/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto new file mode 100644 index 000000000..753f7c165 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package cosmos.base.store.v1beta1; + +import "tendermint/abci/types.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/store/types"; + +// StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) +// It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and +// Deletes +// +// Since: cosmos-sdk 0.43 +message StoreKVPair { + string store_key = 1; // the store key for the KVStore this pair originates from + bool delete = 2; // true indicates a delete operation, false indicates a set operation + bytes key = 3; + bytes value = 4; +} + +// BlockMetadata contains all the abci event data of a block +// the file streamer dump them into files together with the state changes. +message BlockMetadata { + // DeliverTx encapulate deliver tx request and response. + message DeliverTx { + tendermint.abci.RequestDeliverTx request = 1; + tendermint.abci.ResponseDeliverTx response = 2; + } + tendermint.abci.RequestBeginBlock request_begin_block = 1; + tendermint.abci.ResponseBeginBlock response_begin_block = 2; + repeated DeliverTx deliver_txs = 3; + tendermint.abci.RequestEndBlock request_end_block = 4; + tendermint.abci.ResponseEndBlock response_end_block = 5; + tendermint.abci.ResponseCommit response_commit = 6; +} diff --git a/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto b/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto new file mode 100644 index 000000000..98542d23d --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; +package cosmos.base.tendermint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "tendermint/p2p/types.proto"; +import "tendermint/types/block.proto"; +import "tendermint/types/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"; + +// Service defines the gRPC querier service for tendermint queries. +service Service { + // GetNodeInfo queries the current node info. + rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/node_info"; + } + // GetSyncing queries node syncing. + rpc GetSyncing(GetSyncingRequest) returns (GetSyncingResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/syncing"; + } + // GetLatestBlock returns the latest block. + rpc GetLatestBlock(GetLatestBlockRequest) returns (GetLatestBlockResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/latest"; + } + // GetBlockByHeight queries block for given height. + rpc GetBlockByHeight(GetBlockByHeightRequest) returns (GetBlockByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/{height}"; + } + + // GetLatestValidatorSet queries latest validator-set. + rpc GetLatestValidatorSet(GetLatestValidatorSetRequest) returns (GetLatestValidatorSetResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/latest"; + } + // GetValidatorSetByHeight queries validator-set at a given height. + rpc GetValidatorSetByHeight(GetValidatorSetByHeightRequest) returns (GetValidatorSetByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/{height}"; + } +} + +// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightRequest { + int64 height = 1; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetRequest { + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// Validator is the type for the validator-set. +message Validator { + string address = 1; + google.protobuf.Any pub_key = 2; + int64 voting_power = 3; + int64 proposer_priority = 4; +} + +// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightRequest { + int64 height = 1; +} + +// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightResponse { + .tendermint.types.BlockID block_id = 1; + .tendermint.types.Block block = 2; +} + +// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method. +message GetLatestBlockRequest {} + +// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method. +message GetLatestBlockResponse { + .tendermint.types.BlockID block_id = 1; + .tendermint.types.Block block = 2; +} + +// GetSyncingRequest is the request type for the Query/GetSyncing RPC method. +message GetSyncingRequest {} + +// GetSyncingResponse is the response type for the Query/GetSyncing RPC method. +message GetSyncingResponse { + bool syncing = 1; +} + +// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoRequest {} + +// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoResponse { + .tendermint.p2p.DefaultNodeInfo default_node_info = 1; + VersionInfo application_version = 2; +} + +// VersionInfo is the type for the GetNodeInfoResponse message. +message VersionInfo { + string name = 1; + string app_name = 2; + string version = 3; + string git_commit = 4; + string build_tags = 5; + string go_version = 6; + repeated Module build_deps = 7; + // Since: cosmos-sdk 0.43 + string cosmos_sdk_version = 8; +} + +// Module is the type for VersionInfo +message Module { + // module path + string path = 1; + // module version + string version = 2; + // checksum + string sum = 3; +} diff --git a/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto b/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto new file mode 100644 index 000000000..fab75284b --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package cosmos.base.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = false; + +// Coin defines a token with a denomination and an amount. +// +// NOTE: The amount field is an Int which implements the custom method +// signatures required by gogoproto. +message Coin { + option (gogoproto.equal) = true; + + string denom = 1; + string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; +} + +// DecCoin defines a token with a denomination and a decimal amount. +// +// NOTE: The amount field is an Dec which implements the custom method +// signatures required by gogoproto. +message DecCoin { + option (gogoproto.equal) = true; + + string denom = 1; + string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; +} + +// IntProto defines a Protobuf wrapper around an Int object. +message IntProto { + string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; +} + +// DecProto defines a Protobuf wrapper around a Dec object. +message DecProto { + string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto b/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto new file mode 100644 index 000000000..1c8332f34 --- /dev/null +++ b/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package cosmos.capability.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +import "gogoproto/gogo.proto"; + +// Capability defines an implementation of an object capability. The index +// provided to a Capability must be globally unique. +message Capability { + option (gogoproto.goproto_stringer) = false; + + uint64 index = 1 [(gogoproto.moretags) = "yaml:\"index\""]; +} + +// Owner defines a single capability owner. An owner is defined by the name of +// capability and the module name. +message Owner { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + string module = 1 [(gogoproto.moretags) = "yaml:\"module\""]; + string name = 2 [(gogoproto.moretags) = "yaml:\"name\""]; +} + +// CapabilityOwners defines a set of owners of a single Capability. The set of +// owners must be unique. +message CapabilityOwners { + repeated Owner owners = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto new file mode 100644 index 000000000..05bb0afc4 --- /dev/null +++ b/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.capability.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/capability/v1beta1/capability.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +// GenesisOwners defines the capability owners with their corresponding index. +message GenesisOwners { + // index is the index of the capability owner. + uint64 index = 1; + + // index_owners are the owners at the given index. + CapabilityOwners index_owners = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"index_owners\""]; +} + +// GenesisState defines the capability module's genesis state. +message GenesisState { + // index is the capability global index. + uint64 index = 1; + + // owners represents a map from index to owners of the capability index + // index key is string to allow amino marshalling. + repeated GenesisOwners owners = 2 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto new file mode 100644 index 000000000..5b0ff7ec7 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package cosmos.crisis.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// GenesisState defines the crisis module's genesis state. +message GenesisState { + // constant_fee is the fee used to verify the invariant in the crisis + // module. + cosmos.base.v1beta1.Coin constant_fee = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"constant_fee\""]; +} diff --git a/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto new file mode 100644 index 000000000..26457ad6d --- /dev/null +++ b/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package cosmos.crisis.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; + +import "gogoproto/gogo.proto"; + +// Msg defines the bank Msg service. +service Msg { + // VerifyInvariant defines a method to verify a particular invariance. + rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse); +} + +// MsgVerifyInvariant represents a message to verify a particular invariance. +message MsgVerifyInvariant { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string sender = 1; + string invariant_module_name = 2 [(gogoproto.moretags) = "yaml:\"invariant_module_name\""]; + string invariant_route = 3 [(gogoproto.moretags) = "yaml:\"invariant_route\""]; +} + +// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type. +message MsgVerifyInvariantResponse {} diff --git a/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto b/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto new file mode 100644 index 000000000..6ffec3448 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package cosmos.crypto.ed25519; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"; + +// PubKey is an ed25519 public key for handling Tendermint keys in SDK. +// It's needed for Any serialization and SDK compatibility. +// It must not be used in a non Tendermint key context because it doesn't implement +// ADR-28. Nevertheless, you will like to use ed25519 in app user level +// then you must create a new proto message and follow ADR-28 for Address construction. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PublicKey"]; +} + +// Deprecated: PrivKey defines a ed25519 private key. +// NOTE: ed25519 keys must not be used in SDK apps except in a tendermint validator context. +message PrivKey { + bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PrivateKey"]; +} diff --git a/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto b/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto new file mode 100644 index 000000000..f8398e805 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package cosmos.crypto.multisig; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"; + +// LegacyAminoPubKey specifies a public key type +// which nests multiple public keys and a threshold, +// it uses legacy amino address rules. +message LegacyAminoPubKey { + option (gogoproto.goproto_getters) = false; + + uint32 threshold = 1 [(gogoproto.moretags) = "yaml:\"threshold\""]; + repeated google.protobuf.Any public_keys = 2 + [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""]; +} diff --git a/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto b/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto new file mode 100644 index 000000000..bf671f171 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package cosmos.crypto.multisig.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/types"; + +// MultiSignature wraps the signatures from a multisig.LegacyAminoPubKey. +// See cosmos.tx.v1betata1.ModeInfo.Multi for how to specify which signers +// signed and with which modes. +message MultiSignature { + option (gogoproto.goproto_unrecognized) = true; + repeated bytes signatures = 1; +} + +// CompactBitArray is an implementation of a space efficient bit array. +// This is used to ensure that the encoded data takes up a minimal amount of +// space after proto encoding. +// This is not thread safe, and is not intended for concurrent usage. +message CompactBitArray { + option (gogoproto.goproto_stringer) = false; + + uint32 extra_bits_stored = 1; + bytes elems = 2; +} diff --git a/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto b/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto new file mode 100644 index 000000000..a22725713 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.crypto.secp256k1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"; + +// PubKey defines a secp256k1 public key +// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte +// if the y-coordinate is the lexicographically largest of the two associated with +// the x-coordinate. Otherwise the first byte is a 0x03. +// This prefix is followed with the x-coordinate. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1; +} + +// PrivKey defines a secp256k1 private key. +message PrivKey { + bytes key = 1; +} diff --git a/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto b/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto new file mode 100644 index 000000000..2e96c6e3c --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto @@ -0,0 +1,23 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.crypto.secp256r1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1"; +option (gogoproto.messagename_all) = true; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; + +// PubKey defines a secp256r1 ECDSA public key. +message PubKey { + // Point on secp256r1 curve in a compressed representation as specified in section + // 4.3.6 of ANSI X9.62: https://webstore.ansi.org/standards/ascx9/ansix9621998 + bytes key = 1 [(gogoproto.customtype) = "ecdsaPK"]; +} + +// PrivKey defines a secp256r1 ECDSA private key. +message PrivKey { + // secret number serialized using big-endian encoding + bytes secret = 1 [(gogoproto.customtype) = "ecdsaSK"]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto new file mode 100644 index 000000000..ae98ec0b9 --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Params defines the set of params for the distribution module. +message Params { + option (gogoproto.goproto_stringer) = false; + string community_tax = 1 [ + (gogoproto.moretags) = "yaml:\"community_tax\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string base_proposer_reward = 2 [ + (gogoproto.moretags) = "yaml:\"base_proposer_reward\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string bonus_proposer_reward = 3 [ + (gogoproto.moretags) = "yaml:\"bonus_proposer_reward\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bool withdraw_addr_enabled = 4 [(gogoproto.moretags) = "yaml:\"withdraw_addr_enabled\""]; +} + +// ValidatorHistoricalRewards represents historical rewards for a validator. +// Height is implicit within the store key. +// Cumulative reward ratio is the sum from the zeroeth period +// until this period of rewards / tokens, per the spec. +// The reference count indicates the number of objects +// which might need to reference this historical entry at any point. +// ReferenceCount = +// number of outstanding delegations which ended the associated period (and +// might need to read that record) +// + number of slashes which ended the associated period (and might need to +// read that record) +// + one per validator for the zeroeth period, set on initialization +message ValidatorHistoricalRewards { + repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [ + (gogoproto.moretags) = "yaml:\"cumulative_reward_ratio\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; + uint32 reference_count = 2 [(gogoproto.moretags) = "yaml:\"reference_count\""]; +} + +// ValidatorCurrentRewards represents current rewards and current +// period for a validator kept as a running counter and incremented +// each block as long as the validator's tokens remain constant. +message ValidatorCurrentRewards { + repeated cosmos.base.v1beta1.DecCoin rewards = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; + uint64 period = 2; +} + +// ValidatorAccumulatedCommission represents accumulated commission +// for a validator kept as a running counter, can be withdrawn at any time. +message ValidatorAccumulatedCommission { + repeated cosmos.base.v1beta1.DecCoin commission = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} + +// ValidatorOutstandingRewards represents outstanding (un-withdrawn) rewards +// for a validator inexpensive to track, allows simple sanity checks. +message ValidatorOutstandingRewards { + repeated cosmos.base.v1beta1.DecCoin rewards = 1 [ + (gogoproto.moretags) = "yaml:\"rewards\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; +} + +// ValidatorSlashEvent represents a validator slash event. +// Height is implicit within the store key. +// This is needed to calculate appropriate amount of staking tokens +// for delegations which are withdrawn after a slash has occurred. +message ValidatorSlashEvent { + uint64 validator_period = 1 [(gogoproto.moretags) = "yaml:\"validator_period\""]; + string fraction = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// ValidatorSlashEvents is a collection of ValidatorSlashEvent messages. +message ValidatorSlashEvents { + option (gogoproto.goproto_stringer) = false; + repeated ValidatorSlashEvent validator_slash_events = 1 + [(gogoproto.moretags) = "yaml:\"validator_slash_events\"", (gogoproto.nullable) = false]; +} + +// FeePool is the global fee pool for distribution. +message FeePool { + repeated cosmos.base.v1beta1.DecCoin community_pool = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.moretags) = "yaml:\"community_pool\"" + ]; +} + +// CommunityPoolSpendProposal details a proposal for use of community funds, +// together with how many coins are proposed to be spent, and to which +// recipient account. +message CommunityPoolSpendProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + string recipient = 3; + repeated cosmos.base.v1beta1.Coin amount = 4 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// DelegatorStartingInfo represents the starting info for a delegator reward +// period. It tracks the previous validator period, the delegation's amount of +// staking token, and the creation height (to check later on if any slashes have +// occurred). NOTE: Even though validators are slashed to whole staking tokens, +// the delegators within the validator may be left with less than a full token, +// thus sdk.Dec is used. +message DelegatorStartingInfo { + uint64 previous_period = 1 [(gogoproto.moretags) = "yaml:\"previous_period\""]; + string stake = 2 [ + (gogoproto.moretags) = "yaml:\"stake\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + uint64 height = 3 [(gogoproto.moretags) = "yaml:\"creation_height\"", (gogoproto.jsontag) = "creation_height"]; +} + +// DelegationDelegatorReward represents the properties +// of a delegator's delegation reward. +message DelegationDelegatorReward { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + repeated cosmos.base.v1beta1.DecCoin reward = 2 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} + +// CommunityPoolSpendProposalWithDeposit defines a CommunityPoolSpendProposal +// with a deposit +message CommunityPoolSpendProposalWithDeposit { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string title = 1 [(gogoproto.moretags) = "yaml:\"title\""]; + string description = 2 [(gogoproto.moretags) = "yaml:\"description\""]; + string recipient = 3 [(gogoproto.moretags) = "yaml:\"recipient\""]; + string amount = 4 [(gogoproto.moretags) = "yaml:\"amount\""]; + string deposit = 5 [(gogoproto.moretags) = "yaml:\"deposit\""]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto new file mode 100644 index 000000000..c0b17cdf1 --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto @@ -0,0 +1,155 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/distribution/v1beta1/distribution.proto"; + +// DelegatorWithdrawInfo is the address for where distributions rewards are +// withdrawn to by default this struct is only used at genesis to feed in +// default withdraw addresses. +message DelegatorWithdrawInfo { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address is the address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + + // withdraw_address is the address to withdraw the delegation rewards to. + string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; +} + +// ValidatorOutstandingRewardsRecord is used for import/export via genesis json. +message ValidatorOutstandingRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // outstanding_rewards represents the oustanding rewards of a validator. + repeated cosmos.base.v1beta1.DecCoin outstanding_rewards = 2 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"outstanding_rewards\"" + ]; +} + +// ValidatorAccumulatedCommissionRecord is used for import / export via genesis +// json. +message ValidatorAccumulatedCommissionRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // accumulated is the accumulated commission of a validator. + ValidatorAccumulatedCommission accumulated = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"accumulated\""]; +} + +// ValidatorHistoricalRewardsRecord is used for import / export via genesis +// json. +message ValidatorHistoricalRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // period defines the period the historical rewards apply to. + uint64 period = 2; + + // rewards defines the historical rewards of a validator. + ValidatorHistoricalRewards rewards = 3 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; +} + +// ValidatorCurrentRewardsRecord is used for import / export via genesis json. +message ValidatorCurrentRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // rewards defines the current rewards of a validator. + ValidatorCurrentRewards rewards = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; +} + +// DelegatorStartingInfoRecord used for import / export via genesis json. +message DelegatorStartingInfoRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address is the address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + + // validator_address is the address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // starting_info defines the starting info of a delegator. + DelegatorStartingInfo starting_info = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"starting_info\""]; +} + +// ValidatorSlashEventRecord is used for import / export via genesis json. +message ValidatorSlashEventRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // height defines the block height at which the slash event occured. + uint64 height = 2; + // period is the period of the slash event. + uint64 period = 3; + // validator_slash_event describes the slash event. + ValidatorSlashEvent validator_slash_event = 4 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"event\""]; +} + +// GenesisState defines the distribution module's genesis state. +message GenesisState { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"params\""]; + + // fee_pool defines the fee pool at genesis. + FeePool fee_pool = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"fee_pool\""]; + + // fee_pool defines the delegator withdraw infos at genesis. + repeated DelegatorWithdrawInfo delegator_withdraw_infos = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_withdraw_infos\""]; + + // fee_pool defines the previous proposer at genesis. + string previous_proposer = 4 [(gogoproto.moretags) = "yaml:\"previous_proposer\""]; + + // fee_pool defines the outstanding rewards of all validators at genesis. + repeated ValidatorOutstandingRewardsRecord outstanding_rewards = 5 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"outstanding_rewards\""]; + + // fee_pool defines the accumulated commisions of all validators at genesis. + repeated ValidatorAccumulatedCommissionRecord validator_accumulated_commissions = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_accumulated_commissions\""]; + + // fee_pool defines the historical rewards of all validators at genesis. + repeated ValidatorHistoricalRewardsRecord validator_historical_rewards = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_historical_rewards\""]; + + // fee_pool defines the current rewards of all validators at genesis. + repeated ValidatorCurrentRewardsRecord validator_current_rewards = 8 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_current_rewards\""]; + + // fee_pool defines the delegator starting infos at genesis. + repeated DelegatorStartingInfoRecord delegator_starting_infos = 9 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_starting_infos\""]; + + // fee_pool defines the validator slash events at genesis. + repeated ValidatorSlashEventRecord validator_slash_events = 10 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_slash_events\""]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto new file mode 100644 index 000000000..2991218d8 --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto @@ -0,0 +1,218 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/distribution/v1beta1/distribution.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; + +// Query defines the gRPC querier service for distribution module. +service Query { + // Params queries params of the distribution module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/params"; + } + + // ValidatorOutstandingRewards queries rewards of a validator address. + rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest) + returns (QueryValidatorOutstandingRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" + "{validator_address}/outstanding_rewards"; + } + + // ValidatorCommission queries accumulated commission for a validator. + rpc ValidatorCommission(QueryValidatorCommissionRequest) returns (QueryValidatorCommissionResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" + "{validator_address}/commission"; + } + + // ValidatorSlashes queries slash events of a validator. + rpc ValidatorSlashes(QueryValidatorSlashesRequest) returns (QueryValidatorSlashesResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes"; + } + + // DelegationRewards queries the total rewards accrued by a delegation. + rpc DelegationRewards(QueryDelegationRewardsRequest) returns (QueryDelegationRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards/" + "{validator_address}"; + } + + // DelegationTotalRewards queries the total rewards accrued by a each + // validator. + rpc DelegationTotalRewards(QueryDelegationTotalRewardsRequest) returns (QueryDelegationTotalRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards"; + } + + // DelegatorValidators queries the validators of a delegator. + rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" + "{delegator_address}/validators"; + } + + // DelegatorWithdrawAddress queries withdraw address of a delegator. + rpc DelegatorWithdrawAddress(QueryDelegatorWithdrawAddressRequest) returns (QueryDelegatorWithdrawAddressResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" + "{delegator_address}/withdraw_address"; + } + + // CommunityPool queries the community pool coins. + rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/community_pool"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorOutstandingRewardsRequest is the request type for the +// Query/ValidatorOutstandingRewards RPC method. +message QueryValidatorOutstandingRewardsRequest { + // validator_address defines the validator address to query for. + string validator_address = 1; +} + +// QueryValidatorOutstandingRewardsResponse is the response type for the +// Query/ValidatorOutstandingRewards RPC method. +message QueryValidatorOutstandingRewardsResponse { + ValidatorOutstandingRewards rewards = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorCommissionRequest is the request type for the +// Query/ValidatorCommission RPC method +message QueryValidatorCommissionRequest { + // validator_address defines the validator address to query for. + string validator_address = 1; +} + +// QueryValidatorCommissionResponse is the response type for the +// Query/ValidatorCommission RPC method +message QueryValidatorCommissionResponse { + // commission defines the commision the validator received. + ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorSlashesRequest is the request type for the +// Query/ValidatorSlashes RPC method +message QueryValidatorSlashesRequest { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + // validator_address defines the validator address to query for. + string validator_address = 1; + // starting_height defines the optional starting height to query the slashes. + uint64 starting_height = 2; + // starting_height defines the optional ending height to query the slashes. + uint64 ending_height = 3; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryValidatorSlashesResponse is the response type for the +// Query/ValidatorSlashes RPC method. +message QueryValidatorSlashesResponse { + // slashes defines the slashes the validator received. + repeated ValidatorSlashEvent slashes = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegationRewardsRequest is the request type for the +// Query/DelegationRewards RPC method. +message QueryDelegationRewardsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; + // validator_address defines the validator address to query for. + string validator_address = 2; +} + +// QueryDelegationRewardsResponse is the response type for the +// Query/DelegationRewards RPC method. +message QueryDelegationRewardsResponse { + // rewards defines the rewards accrued by a delegation. + repeated cosmos.base.v1beta1.DecCoin rewards = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; +} + +// QueryDelegationTotalRewardsRequest is the request type for the +// Query/DelegationTotalRewards RPC method. +message QueryDelegationTotalRewardsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegationTotalRewardsResponse is the response type for the +// Query/DelegationTotalRewards RPC method. +message QueryDelegationTotalRewardsResponse { + // rewards defines all the rewards accrued by a delegator. + repeated DelegationDelegatorReward rewards = 1 [(gogoproto.nullable) = false]; + // total defines the sum of all the rewards. + repeated cosmos.base.v1beta1.DecCoin total = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; +} + +// QueryDelegatorValidatorsRequest is the request type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegatorValidatorsResponse is the response type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validators defines the validators a delegator is delegating for. + repeated string validators = 1; +} + +// QueryDelegatorWithdrawAddressRequest is the request type for the +// Query/DelegatorWithdrawAddress RPC method. +message QueryDelegatorWithdrawAddressRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegatorWithdrawAddressResponse is the response type for the +// Query/DelegatorWithdrawAddress RPC method. +message QueryDelegatorWithdrawAddressResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // withdraw_address defines the delegator address to query for. + string withdraw_address = 1; +} + +// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC +// method. +message QueryCommunityPoolRequest {} + +// QueryCommunityPoolResponse is the response type for the Query/CommunityPool +// RPC method. +message QueryCommunityPoolResponse { + // pool defines community pool's coins. + repeated cosmos.base.v1beta1.DecCoin pool = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto new file mode 100644 index 000000000..e6ce478bc --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Msg defines the distribution Msg service. +service Msg { + // SetWithdrawAddress defines a method to change the withdraw address + // for a delegator (or validator self-delegation). + rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse); + + // WithdrawDelegatorReward defines a method to withdraw rewards of delegator + // from a single validator. + rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse); + + // WithdrawValidatorCommission defines a method to withdraw the + // full commission to the validator address. + rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse); + + // FundCommunityPool defines a method to allow an account to directly + // fund the community pool. + rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse); +} + +// MsgSetWithdrawAddress sets the withdraw address for +// a delegator (or validator self-delegation). +message MsgSetWithdrawAddress { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; +} + +// MsgSetWithdrawAddressResponse defines the Msg/SetWithdrawAddress response type. +message MsgSetWithdrawAddressResponse {} + +// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator +// from a single validator. +message MsgWithdrawDelegatorReward { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// MsgWithdrawDelegatorRewardResponse defines the Msg/WithdrawDelegatorReward response type. +message MsgWithdrawDelegatorRewardResponse {} + +// MsgWithdrawValidatorCommission withdraws the full commission to the validator +// address. +message MsgWithdrawValidatorCommission { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// MsgWithdrawValidatorCommissionResponse defines the Msg/WithdrawValidatorCommission response type. +message MsgWithdrawValidatorCommissionResponse {} + +// MsgFundCommunityPool allows an account to directly +// fund the community pool. +message MsgFundCommunityPool { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + repeated cosmos.base.v1beta1.Coin amount = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string depositor = 2; +} + +// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type. +message MsgFundCommunityPoolResponse {} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto new file mode 100644 index 000000000..14612c314 --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +// Equivocation implements the Evidence interface and defines evidence of double +// signing misbehavior. +message Equivocation { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + int64 height = 1; + google.protobuf.Timestamp time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + int64 power = 3; + string consensus_address = 4 [(gogoproto.moretags) = "yaml:\"consensus_address\""]; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto new file mode 100644 index 000000000..199f446f7 --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; + +import "google/protobuf/any.proto"; + +// GenesisState defines the evidence module's genesis state. +message GenesisState { + // evidence defines all the evidence at genesis. + repeated google.protobuf.Any evidence = 1; +} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto new file mode 100644 index 000000000..eda00544c --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; + +// Query defines the gRPC querier service. +service Query { + // Evidence queries evidence based on evidence hash. + rpc Evidence(QueryEvidenceRequest) returns (QueryEvidenceResponse) { + option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence/{evidence_hash}"; + } + + // AllEvidence queries all evidence. + rpc AllEvidence(QueryAllEvidenceRequest) returns (QueryAllEvidenceResponse) { + option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence"; + } +} + +// QueryEvidenceRequest is the request type for the Query/Evidence RPC method. +message QueryEvidenceRequest { + // evidence_hash defines the hash of the requested evidence. + bytes evidence_hash = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"]; +} + +// QueryEvidenceResponse is the response type for the Query/Evidence RPC method. +message QueryEvidenceResponse { + // evidence returns the requested evidence. + google.protobuf.Any evidence = 1; +} + +// QueryEvidenceRequest is the request type for the Query/AllEvidence RPC +// method. +message QueryAllEvidenceRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryAllEvidenceResponse is the response type for the Query/AllEvidence RPC +// method. +message QueryAllEvidenceResponse { + // evidence returns all evidences. + repeated google.protobuf.Any evidence = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto new file mode 100644 index 000000000..38795f25d --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; + +// Msg defines the evidence Msg service. +service Msg { + // SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or + // counterfactual signing. + rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse); +} + +// MsgSubmitEvidence represents a message that supports submitting arbitrary +// Evidence of misbehavior such as equivocation or counterfactual signing. +message MsgSubmitEvidence { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string submitter = 1; + google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"]; +} + +// MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type. +message MsgSubmitEvidenceResponse { + // hash defines the hash of the evidence. + bytes hash = 4; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto new file mode 100644 index 000000000..a86691f91 --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto @@ -0,0 +1,78 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// BasicAllowance implements Allowance with a one-time grant of tokens +// that optionally expires. The grantee can use up to SpendLimit to cover fees. +message BasicAllowance { + option (cosmos_proto.implements_interface) = "FeeAllowanceI"; + + // spend_limit specifies the maximum amount of tokens that can be spent + // by this allowance and will be updated as tokens are spent. If it is + // empty, there is no spend limit and any amount of coins can be spent. + repeated cosmos.base.v1beta1.Coin spend_limit = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // expiration specifies an optional time when this allowance expires + google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true]; +} + +// PeriodicAllowance extends Allowance to allow for both a maximum cap, +// as well as a limit per time period. +message PeriodicAllowance { + option (cosmos_proto.implements_interface) = "FeeAllowanceI"; + + // basic specifies a struct of `BasicAllowance` + BasicAllowance basic = 1 [(gogoproto.nullable) = false]; + + // period specifies the time duration in which period_spend_limit coins can + // be spent before that allowance is reset + google.protobuf.Duration period = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + + // period_spend_limit specifies the maximum number of coins that can be spent + // in the period + repeated cosmos.base.v1beta1.Coin period_spend_limit = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // period_can_spend is the number of coins left to be spent before the period_reset time + repeated cosmos.base.v1beta1.Coin period_can_spend = 4 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // period_reset is the time at which this period resets and a new one begins, + // it is calculated from the start time of the first transaction after the + // last period ended + google.protobuf.Timestamp period_reset = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +// AllowedMsgAllowance creates allowance only for specified message types. +message AllowedMsgAllowance { + option (gogoproto.goproto_getters) = false; + option (cosmos_proto.implements_interface) = "FeeAllowanceI"; + + // allowance can be any of basic and filtered fee allowance. + google.protobuf.Any allowance = 1 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; + + // allowed_messages are the messages for which the grantee has the access. + repeated string allowed_messages = 2; +} + +// Grant is stored in the KVStore to record a grant with full context +message Grant { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; + + // allowance can be any of basic and filtered fee allowance. + google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto new file mode 100644 index 000000000..5b1ac4ca5 --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto @@ -0,0 +1,13 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/feegrant/v1beta1/feegrant.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// GenesisState contains a set of fee allowances, persisted from the store +message GenesisState { + repeated Grant allowances = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto new file mode 100644 index 000000000..42d7a842d --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto @@ -0,0 +1,78 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "cosmos/feegrant/v1beta1/feegrant.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// Query defines the gRPC querier service. +service Query { + + // Allowance returns fee granted to the grantee by the granter. + rpc Allowance(QueryAllowanceRequest) returns (QueryAllowanceResponse) { + option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowance/{granter}/{grantee}"; + } + + // Allowances returns all the grants for address. + rpc Allowances(QueryAllowancesRequest) returns (QueryAllowancesResponse) { + option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowances/{grantee}"; + } + + // AllowancesByGranter returns all the grants given by an address + // Since v0.46 + rpc AllowancesByGranter(QueryAllowancesByGranterRequest) returns (QueryAllowancesByGranterResponse) { + option (google.api.http).get = "/cosmos/feegrant/v1beta1/issued/{granter}"; + } +} + +// QueryAllowanceRequest is the request type for the Query/Allowance RPC method. +message QueryAllowanceRequest { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; +} + +// QueryAllowanceResponse is the response type for the Query/Allowance RPC method. +message QueryAllowanceResponse { + // allowance is a allowance granted for grantee by granter. + cosmos.feegrant.v1beta1.Grant allowance = 1; +} + +// QueryAllowancesRequest is the request type for the Query/Allowances RPC method. +message QueryAllowancesRequest { + string grantee = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllowancesResponse is the response type for the Query/Allowances RPC method. +message QueryAllowancesResponse { + // allowances are allowance's granted for grantee by granter. + repeated cosmos.feegrant.v1beta1.Grant allowances = 1; + + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryAllowancesByGranterRequest is the request type for the Query/AllowancesByGranter RPC method. +message QueryAllowancesByGranterRequest { + string granter = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllowancesByGranterResponse is the response type for the Query/AllowancesByGranter RPC method. +message QueryAllowancesByGranterResponse { + // allowances that have been issued by the granter. + repeated cosmos.feegrant.v1beta1.Grant allowances = 1; + + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto new file mode 100644 index 000000000..2d875e922 --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto @@ -0,0 +1,49 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// Msg defines the feegrant msg service. +service Msg { + + // GrantAllowance grants fee allowance to the grantee on the granter's + // account with the provided expiration time. + rpc GrantAllowance(MsgGrantAllowance) returns (MsgGrantAllowanceResponse); + + // RevokeAllowance revokes any fee allowance of granter's account that + // has been granted to the grantee. + rpc RevokeAllowance(MsgRevokeAllowance) returns (MsgRevokeAllowanceResponse); +} + +// MsgGrantAllowance adds permission for Grantee to spend up to Allowance +// of fees from the account of Granter. +message MsgGrantAllowance { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; + + // allowance can be any of basic and filtered fee allowance. + google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; +} + +// MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type. +message MsgGrantAllowanceResponse {} + +// MsgRevokeAllowance removes any existing Allowance from Granter to Grantee. +message MsgRevokeAllowance { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; +} + +// MsgRevokeAllowanceResponse defines the Msg/RevokeAllowanceResponse response type. +message MsgRevokeAllowanceResponse {} diff --git a/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto new file mode 100644 index 000000000..a0207793d --- /dev/null +++ b/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos.genutil.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/genutil/types"; + +// GenesisState defines the raw genesis transaction in JSON. +message GenesisState { + // gen_txs defines the genesis transactions. + repeated bytes gen_txs = 1 [ + (gogoproto.casttype) = "encoding/json.RawMessage", + (gogoproto.jsontag) = "gentxs", + (gogoproto.moretags) = "yaml:\"gentxs\"" + ]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto new file mode 100644 index 000000000..a99950044 --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package cosmos.gov.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/gov/v1beta1/gov.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// GenesisState defines the gov module's genesis state. +message GenesisState { + // starting_proposal_id is the ID of the starting proposal. + uint64 starting_proposal_id = 1 [(gogoproto.moretags) = "yaml:\"starting_proposal_id\""]; + // deposits defines all the deposits present at genesis. + repeated Deposit deposits = 2 [(gogoproto.castrepeated) = "Deposits", (gogoproto.nullable) = false]; + // votes defines all the votes present at genesis. + repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false]; + // proposals defines all the proposals present at genesis. + repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false]; + // params defines all the paramaters of related to deposit. + DepositParams deposit_params = 5 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_params\""]; + // params defines all the paramaters of related to voting. + VotingParams voting_params = 6 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_params\""]; + // params defines all the paramaters of related to tally. + TallyParams tally_params = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"tally_params\""]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto new file mode 100644 index 000000000..01aebf950 --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto @@ -0,0 +1,200 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; + +// VoteOption enumerates the valid vote options for a given governance proposal. +enum VoteOption { + option (gogoproto.goproto_enum_prefix) = false; + + // VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + VOTE_OPTION_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "OptionEmpty"]; + // VOTE_OPTION_YES defines a yes vote option. + VOTE_OPTION_YES = 1 [(gogoproto.enumvalue_customname) = "OptionYes"]; + // VOTE_OPTION_ABSTAIN defines an abstain vote option. + VOTE_OPTION_ABSTAIN = 2 [(gogoproto.enumvalue_customname) = "OptionAbstain"]; + // VOTE_OPTION_NO defines a no vote option. + VOTE_OPTION_NO = 3 [(gogoproto.enumvalue_customname) = "OptionNo"]; + // VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option. + VOTE_OPTION_NO_WITH_VETO = 4 [(gogoproto.enumvalue_customname) = "OptionNoWithVeto"]; +} + +// WeightedVoteOption defines a unit of vote for vote split. +// +// Since: cosmos-sdk 0.43 +message WeightedVoteOption { + VoteOption option = 1; + string weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"weight\"" + ]; +} + +// TextProposal defines a standard text proposal whose changes need to be +// manually updated in case of approval. +message TextProposal { + option (cosmos_proto.implements_interface) = "Content"; + + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; +} + +// Deposit defines an amount deposited by an account address to an active +// proposal. +message Deposit { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string depositor = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Proposal defines the core field members of a governance proposal. +message Proposal { + option (gogoproto.equal) = true; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""]; + google.protobuf.Any content = 2 [(cosmos_proto.accepts_interface) = "Content"]; + ProposalStatus status = 3 [(gogoproto.moretags) = "yaml:\"proposal_status\""]; + TallyResult final_tally_result = 4 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"final_tally_result\""]; + google.protobuf.Timestamp submit_time = 5 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"submit_time\""]; + google.protobuf.Timestamp deposit_end_time = 6 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_end_time\""]; + repeated cosmos.base.v1beta1.Coin total_deposit = 7 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"total_deposit\"" + ]; + google.protobuf.Timestamp voting_start_time = 8 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_start_time\""]; + google.protobuf.Timestamp voting_end_time = 9 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_end_time\""]; +} + +// ProposalStatus enumerates the valid statuses of a proposal. +enum ProposalStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // PROPOSAL_STATUS_UNSPECIFIED defines the default propopsal status. + PROPOSAL_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusNil"]; + // PROPOSAL_STATUS_DEPOSIT_PERIOD defines a proposal status during the deposit + // period. + PROPOSAL_STATUS_DEPOSIT_PERIOD = 1 [(gogoproto.enumvalue_customname) = "StatusDepositPeriod"]; + // PROPOSAL_STATUS_VOTING_PERIOD defines a proposal status during the voting + // period. + PROPOSAL_STATUS_VOTING_PERIOD = 2 [(gogoproto.enumvalue_customname) = "StatusVotingPeriod"]; + // PROPOSAL_STATUS_PASSED defines a proposal status of a proposal that has + // passed. + PROPOSAL_STATUS_PASSED = 3 [(gogoproto.enumvalue_customname) = "StatusPassed"]; + // PROPOSAL_STATUS_REJECTED defines a proposal status of a proposal that has + // been rejected. + PROPOSAL_STATUS_REJECTED = 4 [(gogoproto.enumvalue_customname) = "StatusRejected"]; + // PROPOSAL_STATUS_FAILED defines a proposal status of a proposal that has + // failed. + PROPOSAL_STATUS_FAILED = 5 [(gogoproto.enumvalue_customname) = "StatusFailed"]; +} + +// TallyResult defines a standard tally for a governance proposal. +message TallyResult { + option (gogoproto.equal) = true; + + string yes = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string abstain = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string no = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string no_with_veto = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"no_with_veto\"" + ]; +} + +// Vote defines a vote on a governance proposal. +// A Vote consists of a proposal ID, the voter, and the vote option. +message Vote { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + // Deprecated: Prefer to use `options` instead. This field is set in queries + // if and only if `len(options) == 1` and that option has weight 1. In all + // other cases, this field will default to VOTE_OPTION_UNSPECIFIED. + VoteOption option = 3 [deprecated = true]; + // Since: cosmos-sdk 0.43 + repeated WeightedVoteOption options = 4 [(gogoproto.nullable) = false]; +} + +// DepositParams defines the params for deposits on governance proposals. +message DepositParams { + // Minimum deposit for a proposal to enter voting period. + repeated cosmos.base.v1beta1.Coin min_deposit = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"min_deposit\"", + (gogoproto.jsontag) = "min_deposit,omitempty" + ]; + + // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 + // months. + google.protobuf.Duration max_deposit_period = 2 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "max_deposit_period,omitempty", + (gogoproto.moretags) = "yaml:\"max_deposit_period\"" + ]; +} + +// VotingParams defines the params for voting on governance proposals. +message VotingParams { + // Length of the voting period. + google.protobuf.Duration voting_period = 1 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "voting_period,omitempty", + (gogoproto.moretags) = "yaml:\"voting_period\"" + ]; +} + +// TallyParams defines the params for tallying votes on governance proposals. +message TallyParams { + // Minimum percentage of total stake needed to vote for a result to be + // considered valid. + bytes quorum = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quorum,omitempty" + ]; + + // Minimum proportion of Yes votes for proposal to pass. Default value: 0.5. + bytes threshold = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "threshold,omitempty" + ]; + + // Minimum value of Veto votes to Total votes ratio for proposal to be + // vetoed. Default value: 1/3. + bytes veto_threshold = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "veto_threshold,omitempty", + (gogoproto.moretags) = "yaml:\"veto_threshold\"" + ]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto new file mode 100644 index 000000000..da62bdbad --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto @@ -0,0 +1,190 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/gov/v1beta1/gov.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// Query defines the gRPC querier service for gov module +service Query { + // Proposal queries proposal details based on ProposalID. + rpc Proposal(QueryProposalRequest) returns (QueryProposalResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}"; + } + + // Proposals queries all proposals based on given status. + rpc Proposals(QueryProposalsRequest) returns (QueryProposalsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals"; + } + + // Vote queries voted information based on proposalID, voterAddr. + rpc Vote(QueryVoteRequest) returns (QueryVoteResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}"; + } + + // Votes queries votes of a given proposal. + rpc Votes(QueryVotesRequest) returns (QueryVotesResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes"; + } + + // Params queries all parameters of the gov module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/params/{params_type}"; + } + + // Deposit queries single deposit information based proposalID, depositAddr. + rpc Deposit(QueryDepositRequest) returns (QueryDepositResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}"; + } + + // Deposits queries all deposits of a single proposal. + rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits"; + } + + // TallyResult queries the tally of a proposal vote. + rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/tally"; + } +} + +// QueryProposalRequest is the request type for the Query/Proposal RPC method. +message QueryProposalRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +// QueryProposalResponse is the response type for the Query/Proposal RPC method. +message QueryProposalResponse { + Proposal proposal = 1 [(gogoproto.nullable) = false]; +} + +// QueryProposalsRequest is the request type for the Query/Proposals RPC method. +message QueryProposalsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // proposal_status defines the status of the proposals. + ProposalStatus proposal_status = 1; + + // voter defines the voter address for the proposals. + string voter = 2; + + // depositor defines the deposit addresses from the proposals. + string depositor = 3; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryProposalsResponse is the response type for the Query/Proposals RPC +// method. +message QueryProposalsResponse { + repeated Proposal proposals = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryVoteRequest is the request type for the Query/Vote RPC method. +message QueryVoteRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // voter defines the oter address for the proposals. + string voter = 2; +} + +// QueryVoteResponse is the response type for the Query/Vote RPC method. +message QueryVoteResponse { + // vote defined the queried vote. + Vote vote = 1 [(gogoproto.nullable) = false]; +} + +// QueryVotesRequest is the request type for the Query/Votes RPC method. +message QueryVotesRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryVotesResponse is the response type for the Query/Votes RPC method. +message QueryVotesResponse { + // votes defined the queried votes. + repeated Vote votes = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest { + // params_type defines which parameters to query for, can be one of "voting", + // "tallying" or "deposit". + string params_type = 1; +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // voting_params defines the parameters related to voting. + VotingParams voting_params = 1 [(gogoproto.nullable) = false]; + // deposit_params defines the parameters related to deposit. + DepositParams deposit_params = 2 [(gogoproto.nullable) = false]; + // tally_params defines the parameters related to tally. + TallyParams tally_params = 3 [(gogoproto.nullable) = false]; +} + +// QueryDepositRequest is the request type for the Query/Deposit RPC method. +message QueryDepositRequest { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // depositor defines the deposit addresses from the proposals. + string depositor = 2; +} + +// QueryDepositResponse is the response type for the Query/Deposit RPC method. +message QueryDepositResponse { + // deposit defines the requested deposit. + Deposit deposit = 1 [(gogoproto.nullable) = false]; +} + +// QueryDepositsRequest is the request type for the Query/Deposits RPC method. +message QueryDepositsRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDepositsResponse is the response type for the Query/Deposits RPC method. +message QueryDepositsResponse { + repeated Deposit deposits = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTallyResultRequest is the request type for the Query/Tally RPC method. +message QueryTallyResultRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +// QueryTallyResultResponse is the response type for the Query/Tally RPC method. +message QueryTallyResultResponse { + // tally defines the requested tally. + TallyResult tally = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto new file mode 100644 index 000000000..36c0a95d2 --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/gov/v1beta1/gov.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// Msg defines the bank Msg service. +service Msg { + // SubmitProposal defines a method to create new proposal given a content. + rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse); + + // Vote defines a method to add a vote on a specific proposal. + rpc Vote(MsgVote) returns (MsgVoteResponse); + + // VoteWeighted defines a method to add a weighted vote on a specific proposal. + // + // Since: cosmos-sdk 0.43 + rpc VoteWeighted(MsgVoteWeighted) returns (MsgVoteWeightedResponse); + + // Deposit defines a method to add deposit on a specific proposal. + rpc Deposit(MsgDeposit) returns (MsgDepositResponse); +} + +// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary +// proposal Content. +message MsgSubmitProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"]; + repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"initial_deposit\"" + ]; + string proposer = 3; +} + +// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type. +message MsgSubmitProposalResponse { + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; +} + +// MsgVote defines a message to cast a vote. +message MsgVote { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + VoteOption option = 3; +} + +// MsgVoteResponse defines the Msg/Vote response type. +message MsgVoteResponse {} + +// MsgVoteWeighted defines a message to cast a vote. +// +// Since: cosmos-sdk 0.43 +message MsgVoteWeighted { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + repeated WeightedVoteOption options = 3 [(gogoproto.nullable) = false]; +} + +// MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. +// +// Since: cosmos-sdk 0.43 +message MsgVoteWeightedResponse {} + +// MsgDeposit defines a message to submit a deposit to an existing proposal. +message MsgDeposit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; + string depositor = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// MsgDepositResponse defines the Msg/Deposit response type. +message MsgDepositResponse {} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto new file mode 100644 index 000000000..4e783fb54 --- /dev/null +++ b/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/mint/v1beta1/mint.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +// GenesisState defines the mint module's genesis state. +message GenesisState { + // minter is a space for holding current inflation information. + Minter minter = 1 [(gogoproto.nullable) = false]; + + // params defines all the paramaters of the module. + Params params = 2 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto new file mode 100644 index 000000000..f94d4ae2e --- /dev/null +++ b/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +import "gogoproto/gogo.proto"; + +// Minter represents the minting state. +message Minter { + // current annual inflation rate + string inflation = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + // current annual expected provisions + string annual_provisions = 2 [ + (gogoproto.moretags) = "yaml:\"annual_provisions\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// Params holds parameters for the mint module. +message Params { + option (gogoproto.goproto_stringer) = false; + + // type of coin to mint + string mint_denom = 1; + // maximum annual change in inflation rate + string inflation_rate_change = 2 [ + (gogoproto.moretags) = "yaml:\"inflation_rate_change\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // maximum inflation rate + string inflation_max = 3 [ + (gogoproto.moretags) = "yaml:\"inflation_max\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // minimum inflation rate + string inflation_min = 4 [ + (gogoproto.moretags) = "yaml:\"inflation_min\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // goal of percent bonded atoms + string goal_bonded = 5 [ + (gogoproto.moretags) = "yaml:\"goal_bonded\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // expected blocks per year + uint64 blocks_per_year = 6 [(gogoproto.moretags) = "yaml:\"blocks_per_year\""]; +} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto new file mode 100644 index 000000000..acd341d77 --- /dev/null +++ b/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/mint/v1beta1/mint.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +// Query provides defines the gRPC querier service. +service Query { + // Params returns the total set of minting parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/params"; + } + + // Inflation returns the current minting inflation value. + rpc Inflation(QueryInflationRequest) returns (QueryInflationResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/inflation"; + } + + // AnnualProvisions current minting annual provisions value. + rpc AnnualProvisions(QueryAnnualProvisionsRequest) returns (QueryAnnualProvisionsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/annual_provisions"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryInflationRequest is the request type for the Query/Inflation RPC method. +message QueryInflationRequest {} + +// QueryInflationResponse is the response type for the Query/Inflation RPC +// method. +message QueryInflationResponse { + // inflation is the current minting inflation value. + bytes inflation = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// QueryAnnualProvisionsRequest is the request type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsRequest {} + +// QueryAnnualProvisionsResponse is the response type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsResponse { + // annual_provisions is the current minting annual provisions value. + bytes annual_provisions = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/params/v1beta1/params.proto b/ampd/proto/third_party/cosmos/params/v1beta1/params.proto new file mode 100644 index 000000000..5382fd799 --- /dev/null +++ b/ampd/proto/third_party/cosmos/params/v1beta1/params.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package cosmos.params.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; + +// ParameterChangeProposal defines a proposal to change one or more parameters. +message ParameterChangeProposal { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + repeated ParamChange changes = 3 [(gogoproto.nullable) = false]; +} + +// ParamChange defines an individual parameter change, for use in +// ParameterChangeProposal. +message ParamChange { + option (gogoproto.goproto_stringer) = false; + + string subspace = 1; + string key = 2; + string value = 3; +} diff --git a/ampd/proto/third_party/cosmos/params/v1beta1/query.proto b/ampd/proto/third_party/cosmos/params/v1beta1/query.proto new file mode 100644 index 000000000..1078e02ae --- /dev/null +++ b/ampd/proto/third_party/cosmos/params/v1beta1/query.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package cosmos.params.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/params/v1beta1/params.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; + +// Query defines the gRPC querier service. +service Query { + // Params queries a specific parameter of a module, given its subspace and + // key. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/params/v1beta1/params"; + } +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest { + // subspace defines the module to query the parameter for. + string subspace = 1; + + // key defines the key of the parameter in the subspace. + string key = 2; +} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // param defines the queried parameter. + ParamChange param = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto new file mode 100644 index 000000000..a7aebcfba --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/slashing/v1beta1/slashing.proto"; + +// GenesisState defines the slashing module's genesis state. +message GenesisState { + // params defines all the paramaters of related to deposit. + Params params = 1 [(gogoproto.nullable) = false]; + + // signing_infos represents a map between validator addresses and their + // signing infos. + repeated SigningInfo signing_infos = 2 + [(gogoproto.moretags) = "yaml:\"signing_infos\"", (gogoproto.nullable) = false]; + + // missed_blocks represents a map between validator addresses and their + // missed blocks. + repeated ValidatorMissedBlocks missed_blocks = 3 + [(gogoproto.moretags) = "yaml:\"missed_blocks\"", (gogoproto.nullable) = false]; +} + +// SigningInfo stores validator signing info of corresponding address. +message SigningInfo { + // address is the validator address. + string address = 1; + // validator_signing_info represents the signing info of this validator. + ValidatorSigningInfo validator_signing_info = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_signing_info\""]; +} + +// ValidatorMissedBlocks contains array of missed blocks of corresponding +// address. +message ValidatorMissedBlocks { + // address is the validator address. + string address = 1; + // missed_blocks is an array of missed blocks by the validator. + repeated MissedBlock missed_blocks = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"missed_blocks\""]; +} + +// MissedBlock contains height and missed status as boolean. +message MissedBlock { + // index is the height at which the block was missed. + int64 index = 1; + // missed is the missed status. + bool missed = 2; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto new file mode 100644 index 000000000..869049a0e --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/slashing/v1beta1/slashing.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; + +// Query provides defines the gRPC querier service +service Query { + // Params queries the parameters of slashing module + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/params"; + } + + // SigningInfo queries the signing info of given cons address + rpc SigningInfo(QuerySigningInfoRequest) returns (QuerySigningInfoResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos/{cons_address}"; + } + + // SigningInfos queries signing info of all validators + rpc SigningInfos(QuerySigningInfosRequest) returns (QuerySigningInfosResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC +// method +message QuerySigningInfoRequest { + // cons_address is the address to query signing info of + string cons_address = 1; +} + +// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC +// method +message QuerySigningInfoResponse { + // val_signing_info is the signing info of requested val cons address + ValidatorSigningInfo val_signing_info = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC +// method +message QuerySigningInfosRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC +// method +message QuerySigningInfosResponse { + // info is the signing info of all validators + repeated cosmos.slashing.v1beta1.ValidatorSigningInfo info = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto new file mode 100644 index 000000000..882a0fb60 --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +// ValidatorSigningInfo defines a validator's signing info for monitoring their +// liveness activity. +message ValidatorSigningInfo { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string address = 1; + // Height at which validator was first a candidate OR was unjailed + int64 start_height = 2 [(gogoproto.moretags) = "yaml:\"start_height\""]; + // Index which is incremented each time the validator was a bonded + // in a block and may have signed a precommit or not. This in conjunction with the + // `SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`. + int64 index_offset = 3 [(gogoproto.moretags) = "yaml:\"index_offset\""]; + // Timestamp until which the validator is jailed due to liveness downtime. + google.protobuf.Timestamp jailed_until = 4 + [(gogoproto.moretags) = "yaml:\"jailed_until\"", (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + // Whether or not a validator has been tombstoned (killed out of validator set). It is set + // once the validator commits an equivocation or for any other configured misbehiavor. + bool tombstoned = 5; + // A counter kept to avoid unnecessary array reads. + // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. + int64 missed_blocks_counter = 6 [(gogoproto.moretags) = "yaml:\"missed_blocks_counter\""]; +} + +// Params represents the parameters used for by the slashing module. +message Params { + int64 signed_blocks_window = 1 [(gogoproto.moretags) = "yaml:\"signed_blocks_window\""]; + bytes min_signed_per_window = 2 [ + (gogoproto.moretags) = "yaml:\"min_signed_per_window\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration downtime_jail_duration = 3 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.moretags) = "yaml:\"downtime_jail_duration\"" + ]; + bytes slash_fraction_double_sign = 4 [ + (gogoproto.moretags) = "yaml:\"slash_fraction_double_sign\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes slash_fraction_downtime = 5 [ + (gogoproto.moretags) = "yaml:\"slash_fraction_downtime\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto new file mode 100644 index 000000000..4d63370ec --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; + +// Msg defines the slashing Msg service. +service Msg { + // Unjail defines a method for unjailing a jailed validator, thus returning + // them into the bonded validator set, so they can begin receiving provisions + // and rewards again. + rpc Unjail(MsgUnjail) returns (MsgUnjailResponse); +} + +// MsgUnjail defines the Msg/Unjail request type +message MsgUnjail { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string validator_addr = 1 [(gogoproto.moretags) = "yaml:\"address\"", (gogoproto.jsontag) = "address"]; +} + +// MsgUnjailResponse defines the Msg/Unjail response type +message MsgUnjailResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto new file mode 100644 index 000000000..d50c329c9 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// StakeAuthorization defines authorization for delegate/undelegate/redelegate. +// +// Since: cosmos-sdk 0.43 +message StakeAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // max_tokens specifies the maximum amount of tokens can be delegate to a validator. If it is + // empty, there is no spend limit and any amount of coins can be delegated. + cosmos.base.v1beta1.Coin max_tokens = 1 [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"]; + // validators is the oneof that represents either allow_list or deny_list + oneof validators { + // allow_list specifies list of validator addresses to whom grantee can delegate tokens on behalf of granter's + // account. + Validators allow_list = 2; + // deny_list specifies list of validator addresses to whom grantee can not delegate tokens. + Validators deny_list = 3; + } + // Validators defines list of validator addresses. + message Validators { + repeated string address = 1; + } + // authorization_type defines one of AuthorizationType. + AuthorizationType authorization_type = 4; +} + +// AuthorizationType defines the type of staking module authorization type +// +// Since: cosmos-sdk 0.43 +enum AuthorizationType { + // AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type + AUTHORIZATION_TYPE_UNSPECIFIED = 0; + // AUTHORIZATION_TYPE_DELEGATE defines an authorization type for Msg/Delegate + AUTHORIZATION_TYPE_DELEGATE = 1; + // AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for Msg/Undelegate + AUTHORIZATION_TYPE_UNDELEGATE = 2; + // AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for Msg/BeginRedelegate + AUTHORIZATION_TYPE_REDELEGATE = 3; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto new file mode 100644 index 000000000..d1563dbc5 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +// GenesisState defines the staking module's genesis state. +message GenesisState { + // params defines all the paramaters of related to deposit. + Params params = 1 [(gogoproto.nullable) = false]; + + // last_total_power tracks the total amounts of bonded tokens recorded during + // the previous end block. + bytes last_total_power = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"last_total_power\"", + (gogoproto.nullable) = false + ]; + + // last_validator_powers is a special index that provides a historical list + // of the last-block's bonded validators. + repeated LastValidatorPower last_validator_powers = 3 + [(gogoproto.moretags) = "yaml:\"last_validator_powers\"", (gogoproto.nullable) = false]; + + // delegations defines the validator set at genesis. + repeated Validator validators = 4 [(gogoproto.nullable) = false]; + + // delegations defines the delegations active at genesis. + repeated Delegation delegations = 5 [(gogoproto.nullable) = false]; + + // unbonding_delegations defines the unbonding delegations active at genesis. + repeated UnbondingDelegation unbonding_delegations = 6 + [(gogoproto.moretags) = "yaml:\"unbonding_delegations\"", (gogoproto.nullable) = false]; + + // redelegations defines the redelegations active at genesis. + repeated Redelegation redelegations = 7 [(gogoproto.nullable) = false]; + + bool exported = 8; +} + +// LastValidatorPower required for validator set update logic. +message LastValidatorPower { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address of the validator. + string address = 1; + + // power defines the power of the validator. + int64 power = 2; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto new file mode 100644 index 000000000..4852c5353 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto @@ -0,0 +1,348 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// Query defines the gRPC querier service. +service Query { + // Validators queries all validators that match the given status. + rpc Validators(QueryValidatorsRequest) returns (QueryValidatorsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators"; + } + + // Validator queries validator info for given validator address. + rpc Validator(QueryValidatorRequest) returns (QueryValidatorResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}"; + } + + // ValidatorDelegations queries delegate info for given validator. + rpc ValidatorDelegations(QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations"; + } + + // ValidatorUnbondingDelegations queries unbonding delegations of a validator. + rpc ValidatorUnbondingDelegations(QueryValidatorUnbondingDelegationsRequest) + returns (QueryValidatorUnbondingDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/" + "{validator_addr}/unbonding_delegations"; + } + + // Delegation queries delegate info for given validator delegator pair. + rpc Delegation(QueryDelegationRequest) returns (QueryDelegationResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" + "{delegator_addr}"; + } + + // UnbondingDelegation queries unbonding info for given validator delegator + // pair. + rpc UnbondingDelegation(QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" + "{delegator_addr}/unbonding_delegation"; + } + + // DelegatorDelegations queries all delegations of a given delegator address. + rpc DelegatorDelegations(QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegations/{delegator_addr}"; + } + + // DelegatorUnbondingDelegations queries all unbonding delegations of a given + // delegator address. + rpc DelegatorUnbondingDelegations(QueryDelegatorUnbondingDelegationsRequest) + returns (QueryDelegatorUnbondingDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/" + "{delegator_addr}/unbonding_delegations"; + } + + // Redelegations queries redelegations of given address. + rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/redelegations"; + } + + // DelegatorValidators queries all validators info for given delegator + // address. + rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators"; + } + + // DelegatorValidator queries validator info for given delegator validator + // pair. + rpc DelegatorValidator(QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators/" + "{validator_addr}"; + } + + // HistoricalInfo queries the historical info for given height. + rpc HistoricalInfo(QueryHistoricalInfoRequest) returns (QueryHistoricalInfoResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/historical_info/{height}"; + } + + // Pool queries the pool info. + rpc Pool(QueryPoolRequest) returns (QueryPoolResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/pool"; + } + + // Parameters queries the staking parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/params"; + } +} + +// QueryValidatorsRequest is request type for Query/Validators RPC method. +message QueryValidatorsRequest { + // status enables to query for validators matching a given status. + string status = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorsResponse is response type for the Query/Validators RPC method +message QueryValidatorsResponse { + // validators contains all the queried validators. + repeated Validator validators = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryValidatorRequest is response type for the Query/Validator RPC method +message QueryValidatorRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; +} + +// QueryValidatorResponse is response type for the Query/Validator RPC method +message QueryValidatorResponse { + // validator defines the the validator info. + Validator validator = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorDelegationsRequest is request type for the +// Query/ValidatorDelegations RPC method +message QueryValidatorDelegationsRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorDelegationsResponse is response type for the +// Query/ValidatorDelegations RPC method +message QueryValidatorDelegationsResponse { + repeated DelegationResponse delegation_responses = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "DelegationResponses"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryValidatorUnbondingDelegationsRequest is required type for the +// Query/ValidatorUnbondingDelegations RPC method +message QueryValidatorUnbondingDelegationsRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorUnbondingDelegationsResponse is response type for the +// Query/ValidatorUnbondingDelegations RPC method. +message QueryValidatorUnbondingDelegationsResponse { + repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegationRequest is request type for the Query/Delegation RPC method. +message QueryDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegationResponse is response type for the Query/Delegation RPC method. +message QueryDelegationResponse { + // delegation_responses defines the delegation info of a delegation. + DelegationResponse delegation_response = 1; +} + +// QueryUnbondingDelegationRequest is request type for the +// Query/UnbondingDelegation RPC method. +message QueryUnbondingDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegationResponse is response type for the Query/UnbondingDelegation +// RPC method. +message QueryUnbondingDelegationResponse { + // unbond defines the unbonding information of a delegation. + UnbondingDelegation unbond = 1 [(gogoproto.nullable) = false]; +} + +// QueryDelegatorDelegationsRequest is request type for the +// Query/DelegatorDelegations RPC method. +message QueryDelegatorDelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDelegatorDelegationsResponse is response type for the +// Query/DelegatorDelegations RPC method. +message QueryDelegatorDelegationsResponse { + // delegation_responses defines all the delegations' info of a delegator. + repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorUnbondingDelegationsRequest is request type for the +// Query/DelegatorUnbondingDelegations RPC method. +message QueryDelegatorUnbondingDelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryUnbondingDelegatorDelegationsResponse is response type for the +// Query/UnbondingDelegatorDelegations RPC method. +message QueryDelegatorUnbondingDelegationsResponse { + repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryRedelegationsRequest is request type for the Query/Redelegations RPC +// method. +message QueryRedelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // src_validator_addr defines the validator address to redelegate from. + string src_validator_addr = 2; + + // dst_validator_addr defines the validator address to redelegate to. + string dst_validator_addr = 3; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryRedelegationsResponse is response type for the Query/Redelegations RPC +// method. +message QueryRedelegationsResponse { + repeated RedelegationResponse redelegation_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorValidatorsRequest is request type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDelegatorValidatorsResponse is response type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsResponse { + // validators defines the the validators' info of a delegator. + repeated Validator validators = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorValidatorRequest is request type for the +// Query/DelegatorValidator RPC method. +message QueryDelegatorValidatorRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegatorValidatorResponse response type for the +// Query/DelegatorValidator RPC method. +message QueryDelegatorValidatorResponse { + // validator defines the the validator info. + Validator validator = 1 [(gogoproto.nullable) = false]; +} + +// QueryHistoricalInfoRequest is request type for the Query/HistoricalInfo RPC +// method. +message QueryHistoricalInfoRequest { + // height defines at which height to query the historical info. + int64 height = 1; +} + +// QueryHistoricalInfoResponse is response type for the Query/HistoricalInfo RPC +// method. +message QueryHistoricalInfoResponse { + // hist defines the historical info at the given height. + HistoricalInfo hist = 1; +} + +// QueryPoolRequest is request type for the Query/Pool RPC method. +message QueryPoolRequest {} + +// QueryPoolResponse is response type for the Query/Pool RPC method. +message QueryPoolResponse { + // pool defines the pool info. + Pool pool = 1 [(gogoproto.nullable) = false]; +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // params holds all the parameters of this module. + Params params = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto new file mode 100644 index 000000000..76e9599e2 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto @@ -0,0 +1,334 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "tendermint/types/types.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// HistoricalInfo contains header and validator information for a given block. +// It is stored as part of staking module's state, which persists the `n` most +// recent HistoricalInfo +// (`n` is set by the staking module's `historical_entries` parameter). +message HistoricalInfo { + tendermint.types.Header header = 1 [(gogoproto.nullable) = false]; + repeated Validator valset = 2 [(gogoproto.nullable) = false]; +} + +// CommissionRates defines the initial commission rates to be used for creating +// a validator. +message CommissionRates { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // rate is the commission rate charged to delegators, as a fraction. + string rate = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + // max_rate defines the maximum commission rate which validator can ever charge, as a fraction. + string max_rate = 2 [ + (gogoproto.moretags) = "yaml:\"max_rate\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // max_change_rate defines the maximum daily increase of the validator commission, as a fraction. + string max_change_rate = 3 [ + (gogoproto.moretags) = "yaml:\"max_change_rate\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// Commission defines commission parameters for a given validator. +message Commission { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // commission_rates defines the initial commission rates to be used for creating a validator. + CommissionRates commission_rates = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // update_time is the last time the commission rate was changed. + google.protobuf.Timestamp update_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"update_time\""]; +} + +// Description defines a validator description. +message Description { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // moniker defines a human-readable name for the validator. + string moniker = 1; + // identity defines an optional identity signature (ex. UPort or Keybase). + string identity = 2; + // website defines an optional website link. + string website = 3; + // security_contact defines an optional email for security contact. + string security_contact = 4 [(gogoproto.moretags) = "yaml:\"security_contact\""]; + // details define other optional details. + string details = 5; +} + +// Validator defines a validator, together with the total amount of the +// Validator's bond shares and their exchange rate to coins. Slashing results in +// a decrease in the exchange rate, allowing correct calculation of future +// undelegations without iterating over delegators. When coins are delegated to +// this validator, the validator is credited with a delegation whose number of +// bond shares is based on the amount of coins delegated divided by the current +// exchange rate. Voting power can be calculated as total bonded shares +// multiplied by exchange rate. +message Validator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + // operator_address defines the address of the validator's operator; bech encoded in JSON. + string operator_address = 1 [(gogoproto.moretags) = "yaml:\"operator_address\""]; + // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. + google.protobuf.Any consensus_pubkey = 2 + [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\""]; + // jailed defined whether the validator has been jailed from bonded status or not. + bool jailed = 3; + // status is the validator status (bonded/unbonding/unbonded). + BondStatus status = 4; + // tokens define the delegated tokens (incl. self-delegation). + string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + // delegator_shares defines total shares issued to a validator's delegators. + string delegator_shares = 6 [ + (gogoproto.moretags) = "yaml:\"delegator_shares\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // description defines the description terms for the validator. + Description description = 7 [(gogoproto.nullable) = false]; + // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding. + int64 unbonding_height = 8 [(gogoproto.moretags) = "yaml:\"unbonding_height\""]; + // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding. + google.protobuf.Timestamp unbonding_time = 9 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; + // commission defines the commission parameters. + Commission commission = 10 [(gogoproto.nullable) = false]; + // min_self_delegation is the validator's self declared minimum self delegation. + string min_self_delegation = 11 [ + (gogoproto.moretags) = "yaml:\"min_self_delegation\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// BondStatus is the status of a validator. +enum BondStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // UNSPECIFIED defines an invalid validator status. + BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"]; + // UNBONDED defines a validator that is not bonded. + BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"]; + // UNBONDING defines a validator that is unbonding. + BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"]; + // BONDED defines a validator that is bonded. + BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"]; +} + +// ValAddresses defines a repeated set of validator addresses. +message ValAddresses { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = true; + + repeated string addresses = 1; +} + +// DVPair is struct that just has a delegator-validator pair with no other data. +// It is intended to be used as a marshalable pointer. For example, a DVPair can +// be used to construct the key to getting an UnbondingDelegation from state. +message DVPair { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// DVPairs defines an array of DVPair objects. +message DVPairs { + repeated DVPair pairs = 1 [(gogoproto.nullable) = false]; +} + +// DVVTriplet is struct that just has a delegator-validator-validator triplet +// with no other data. It is intended to be used as a marshalable pointer. For +// example, a DVVTriplet can be used to construct the key to getting a +// Redelegation from state. +message DVVTriplet { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; +} + +// DVVTriplets defines an array of DVVTriplet objects. +message DVVTriplets { + repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false]; +} + +// Delegation represents the bond with tokens held by an account. It is +// owned by one delegator, and is associated with the voting power of one +// validator. +message Delegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_address is the bech32-encoded address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // shares define the delegation shares received. + string shares = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// UnbondingDelegation stores all of a single delegator's unbonding bonds +// for a single validator in an time-ordered list. +message UnbondingDelegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_address is the bech32-encoded address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // entries are the unbonding delegation entries. + repeated UnbondingDelegationEntry entries = 3 [(gogoproto.nullable) = false]; // unbonding delegation entries +} + +// UnbondingDelegationEntry defines an unbonding object with relevant metadata. +message UnbondingDelegationEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // creation_height is the height which the unbonding took place. + int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; + // completion_time is the unix time for unbonding completion. + google.protobuf.Timestamp completion_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; + // initial_balance defines the tokens initially scheduled to receive at completion. + string initial_balance = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"initial_balance\"" + ]; + // balance defines the tokens to receive at completion. + string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; +} + +// RedelegationEntry defines a redelegation object with relevant metadata. +message RedelegationEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // creation_height defines the height which the redelegation took place. + int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; + // completion_time defines the unix time for redelegation completion. + google.protobuf.Timestamp completion_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; + // initial_balance defines the initial balance when redelegation started. + string initial_balance = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"initial_balance\"" + ]; + // shares_dst is the amount of destination-validator shares created by redelegation. + string shares_dst = 4 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// Redelegation contains the list of a particular delegator's redelegating bonds +// from a particular source validator to a particular destination validator. +message Redelegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_src_address is the validator redelegation source operator address. + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + // validator_dst_address is the validator redelegation destination operator address. + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; + // entries are the redelegation entries. + repeated RedelegationEntry entries = 4 [(gogoproto.nullable) = false]; // redelegation entries +} + +// Params defines the parameters for the staking module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // unbonding_time is the time duration of unbonding. + google.protobuf.Duration unbonding_time = 1 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; + // max_validators is the maximum number of validators. + uint32 max_validators = 2 [(gogoproto.moretags) = "yaml:\"max_validators\""]; + // max_entries is the max entries for either unbonding delegation or redelegation (per pair/trio). + uint32 max_entries = 3 [(gogoproto.moretags) = "yaml:\"max_entries\""]; + // historical_entries is the number of historical entries to persist. + uint32 historical_entries = 4 [(gogoproto.moretags) = "yaml:\"historical_entries\""]; + // bond_denom defines the bondable coin denomination. + string bond_denom = 5 [(gogoproto.moretags) = "yaml:\"bond_denom\""]; +} + +// DelegationResponse is equivalent to Delegation except that it contains a +// balance in addition to shares which is more suitable for client responses. +message DelegationResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + + Delegation delegation = 1 [(gogoproto.nullable) = false]; + + cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false]; +} + +// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it +// contains a balance in addition to shares which is more suitable for client +// responses. +message RedelegationEntryResponse { + option (gogoproto.equal) = true; + + RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false]; + string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; +} + +// RedelegationResponse is equivalent to a Redelegation except that its entries +// contain a balance in addition to shares which is more suitable for client +// responses. +message RedelegationResponse { + option (gogoproto.equal) = false; + + Redelegation redelegation = 1 [(gogoproto.nullable) = false]; + repeated RedelegationEntryResponse entries = 2 [(gogoproto.nullable) = false]; +} + +// Pool is used for tracking bonded and not-bonded token supply of the bond +// denomination. +message Pool { + option (gogoproto.description) = true; + option (gogoproto.equal) = true; + string not_bonded_tokens = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.jsontag) = "not_bonded_tokens", + (gogoproto.nullable) = false + ]; + string bonded_tokens = 2 [ + (gogoproto.jsontag) = "bonded_tokens", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"bonded_tokens\"" + ]; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto new file mode 100644 index 000000000..d074fe010 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto @@ -0,0 +1,123 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; + +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// Msg defines the staking Msg service. +service Msg { + // CreateValidator defines a method for creating a new validator. + rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse); + + // EditValidator defines a method for editing an existing validator. + rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse); + + // Delegate defines a method for performing a delegation of coins + // from a delegator to a validator. + rpc Delegate(MsgDelegate) returns (MsgDelegateResponse); + + // BeginRedelegate defines a method for performing a redelegation + // of coins from a delegator and source validator to a destination validator. + rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse); + + // Undelegate defines a method for performing an undelegation from a + // delegate and a validator. + rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse); +} + +// MsgCreateValidator defines a SDK message for creating a new validator. +message MsgCreateValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Description description = 1 [(gogoproto.nullable) = false]; + CommissionRates commission = 2 [(gogoproto.nullable) = false]; + string min_self_delegation = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"min_self_delegation\"", + (gogoproto.nullable) = false + ]; + string delegator_address = 4 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 5 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"]; + cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false]; +} + +// MsgCreateValidatorResponse defines the Msg/CreateValidator response type. +message MsgCreateValidatorResponse {} + +// MsgEditValidator defines a SDK message for editing an existing validator. +message MsgEditValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Description description = 1 [(gogoproto.nullable) = false]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"address\""]; + + // We pass a reference to the new commission rate and min self delegation as + // it's not mandatory to update. If not updated, the deserialized rate will be + // zero with no way to distinguish if an update was intended. + // REF: #2373 + string commission_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.moretags) = "yaml:\"commission_rate\"" + ]; + string min_self_delegation = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"min_self_delegation\"" + ]; +} + +// MsgEditValidatorResponse defines the Msg/EditValidator response type. +message MsgEditValidatorResponse {} + +// MsgDelegate defines a SDK message for performing a delegation of coins +// from a delegator to a validator. +message MsgDelegate { + option (gogoproto.equal) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; +} + +// MsgDelegateResponse defines the Msg/Delegate response type. +message MsgDelegateResponse {} + +// MsgBeginRedelegate defines a SDK message for performing a redelegation +// of coins from a delegator and source validator to a destination validator. +message MsgBeginRedelegate { + option (gogoproto.equal) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; + cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false]; +} + +// MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type. +message MsgBeginRedelegateResponse { + google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +// MsgUndelegate defines a SDK message for performing an undelegation from a +// delegate and a validator. +message MsgUndelegate { + option (gogoproto.equal) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; +} + +// MsgUndelegateResponse defines the Msg/Undelegate response type. +message MsgUndelegateResponse { + google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} diff --git a/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto b/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto new file mode 100644 index 000000000..50de89c8f --- /dev/null +++ b/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto @@ -0,0 +1,91 @@ +syntax = "proto3"; +package cosmos.tx.signing.v1beta1; + +import "cosmos/crypto/multisig/v1beta1/multisig.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx/signing"; + +// SignMode represents a signing mode with its own security guarantees. +enum SignMode { + // SIGN_MODE_UNSPECIFIED specifies an unknown signing mode and will be + // rejected + SIGN_MODE_UNSPECIFIED = 0; + + // SIGN_MODE_DIRECT specifies a signing mode which uses SignDoc and is + // verified with raw bytes from Tx + SIGN_MODE_DIRECT = 1; + + // SIGN_MODE_TEXTUAL is a future signing mode that will verify some + // human-readable textual representation on top of the binary representation + // from SIGN_MODE_DIRECT + SIGN_MODE_TEXTUAL = 2; + + // SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses + // Amino JSON and will be removed in the future + SIGN_MODE_LEGACY_AMINO_JSON = 127; + + // SIGN_MODE_EIP_191 specifies the sign mode for EIP 191 signing on the Cosmos + // SDK. Ref: https://eips.ethereum.org/EIPS/eip-191 + // + // Currently, SIGN_MODE_EIP_191 is registered as a SignMode enum variant, + // but is not implemented on the SDK by default. To enable EIP-191, you need + // to pass a custom `TxConfig` that has an implementation of + // `SignModeHandler` for EIP-191. The SDK may decide to fully support + // EIP-191 in the future. + // + // Since: cosmos-sdk 0.45.2 + SIGN_MODE_EIP_191 = 191; +} + +// SignatureDescriptors wraps multiple SignatureDescriptor's. +message SignatureDescriptors { + // signatures are the signature descriptors + repeated SignatureDescriptor signatures = 1; +} + +// SignatureDescriptor is a convenience type which represents the full data for +// a signature including the public key of the signer, signing modes and the +// signature itself. It is primarily used for coordinating signatures between +// clients. +message SignatureDescriptor { + // public_key is the public key of the signer + google.protobuf.Any public_key = 1; + + Data data = 2; + + // sequence is the sequence of the account, which describes the + // number of committed transactions signed by a given address. It is used to prevent + // replay attacks. + uint64 sequence = 3; + + // Data represents signature data + message Data { + // sum is the oneof that specifies whether this represents single or multi-signature data + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a multisig signer + Multi multi = 2; + } + + // Single is the signature data for a single signer + message Single { + // mode is the signing mode of the single signer + SignMode mode = 1; + + // signature is the raw signature bytes + bytes signature = 2; + } + + // Multi is the signature data for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; + + // signatures is the signatures of the multi-signature + repeated Data signatures = 2; + } + } +} diff --git a/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto b/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto new file mode 100644 index 000000000..d9f828f76 --- /dev/null +++ b/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto @@ -0,0 +1,165 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "google/api/annotations.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/tx/v1beta1/tx.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "tendermint/types/block.proto"; +import "tendermint/types/types.proto"; + +option (gogoproto.goproto_registration) = true; +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Service defines a gRPC service for interacting with transactions. +service Service { + // Simulate simulates executing a transaction for estimating gas usage. + rpc Simulate(SimulateRequest) returns (SimulateResponse) { + option (google.api.http) = { + post: "/cosmos/tx/v1beta1/simulate" + body: "*" + }; + } + // GetTx fetches a tx by hash. + rpc GetTx(GetTxRequest) returns (GetTxResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs/{hash}"; + } + // BroadcastTx broadcast transaction. + rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) { + option (google.api.http) = { + post: "/cosmos/tx/v1beta1/txs" + body: "*" + }; + } + // GetTxsEvent fetches txs by event. + rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs"; + } + // GetBlockWithTxs fetches a block with decoded txs. + // + // Since: cosmos-sdk 0.45.2 + rpc GetBlockWithTxs(GetBlockWithTxsRequest) returns (GetBlockWithTxsResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs/block/{height}"; + } +} + +// GetTxsEventRequest is the request type for the Service.TxsByEvents +// RPC method. +message GetTxsEventRequest { + // events is the list of transaction event type. + repeated string events = 1; + // pagination defines a pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; + OrderBy order_by = 3; +} + +// OrderBy defines the sorting order +enum OrderBy { + // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. + ORDER_BY_UNSPECIFIED = 0; + // ORDER_BY_ASC defines ascending order + ORDER_BY_ASC = 1; + // ORDER_BY_DESC defines descending order + ORDER_BY_DESC = 2; +} + +// GetTxsEventResponse is the response type for the Service.TxsByEvents +// RPC method. +message GetTxsEventResponse { + // txs is the list of queried transactions. + repeated cosmos.tx.v1beta1.Tx txs = 1; + // tx_responses is the list of queried TxResponses. + repeated cosmos.base.abci.v1beta1.TxResponse tx_responses = 2; + // pagination defines a pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest +// RPC method. +message BroadcastTxRequest { + // tx_bytes is the raw transaction. + bytes tx_bytes = 1; + BroadcastMode mode = 2; +} + +// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. +enum BroadcastMode { + // zero-value for mode ordering + BROADCAST_MODE_UNSPECIFIED = 0; + // BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for + // the tx to be committed in a block. + BROADCAST_MODE_BLOCK = 1; + // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for + // a CheckTx execution response only. + BROADCAST_MODE_SYNC = 2; + // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns + // immediately. + BROADCAST_MODE_ASYNC = 3; +} + +// BroadcastTxResponse is the response type for the +// Service.BroadcastTx method. +message BroadcastTxResponse { + // tx_response is the queried TxResponses. + cosmos.base.abci.v1beta1.TxResponse tx_response = 1; +} + +// SimulateRequest is the request type for the Service.Simulate +// RPC method. +message SimulateRequest { + // tx is the transaction to simulate. + // Deprecated. Send raw tx bytes instead. + cosmos.tx.v1beta1.Tx tx = 1 [deprecated = true]; + // tx_bytes is the raw transaction. + // + // Since: cosmos-sdk 0.43 + bytes tx_bytes = 2; +} + +// SimulateResponse is the response type for the +// Service.SimulateRPC method. +message SimulateResponse { + // gas_info is the information about gas used in the simulation. + cosmos.base.abci.v1beta1.GasInfo gas_info = 1; + // result is the result of the simulation. + cosmos.base.abci.v1beta1.Result result = 2; +} + +// GetTxRequest is the request type for the Service.GetTx +// RPC method. +message GetTxRequest { + // hash is the tx hash to query, encoded as a hex string. + string hash = 1; +} + +// GetTxResponse is the response type for the Service.GetTx method. +message GetTxResponse { + // tx is the queried transaction. + cosmos.tx.v1beta1.Tx tx = 1; + // tx_response is the queried TxResponses. + cosmos.base.abci.v1beta1.TxResponse tx_response = 2; +} + +// GetBlockWithTxsRequest is the request type for the Service.GetBlockWithTxs +// RPC method. +// +// Since: cosmos-sdk 0.45.2 +message GetBlockWithTxsRequest { + // height is the height of the block to query. + int64 height = 1; + // pagination defines a pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method. +// +// Since: cosmos-sdk 0.45.2 +message GetBlockWithTxsResponse { + // txs are the transactions in the block. + repeated cosmos.tx.v1beta1.Tx txs = 1; + .tendermint.types.BlockID block_id = 2; + .tendermint.types.Block block = 3; + // pagination defines a pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 4; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto new file mode 100644 index 000000000..6d5caf12c --- /dev/null +++ b/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto @@ -0,0 +1,183 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/v1beta1/multisig.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/tx/signing/v1beta1/signing.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Tx is the standard type used for broadcasting transactions. +message Tx { + // body is the processable content of the transaction + TxBody body = 1; + + // auth_info is the authorization related content of the transaction, + // specifically signers, signer modes and fee + AuthInfo auth_info = 2; + + // signatures is a list of signatures that matches the length and order of + // AuthInfo's signer_infos to allow connecting signature meta information like + // public key and signing mode by position. + repeated bytes signatures = 3; +} + +// TxRaw is a variant of Tx that pins the signer's exact binary representation +// of body and auth_info. This is used for signing, broadcasting and +// verification. The binary `serialize(tx: TxRaw)` is stored in Tendermint and +// the hash `sha256(serialize(tx: TxRaw))` becomes the "txhash", commonly used +// as the transaction ID. +message TxRaw { + // body_bytes is a protobuf serialization of a TxBody that matches the + // representation in SignDoc. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the + // representation in SignDoc. + bytes auth_info_bytes = 2; + + // signatures is a list of signatures that matches the length and order of + // AuthInfo's signer_infos to allow connecting signature meta information like + // public key and signing mode by position. + repeated bytes signatures = 3; +} + +// SignDoc is the type used for generating sign bytes for SIGN_MODE_DIRECT. +message SignDoc { + // body_bytes is protobuf serialization of a TxBody that matches the + // representation in TxRaw. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the + // representation in TxRaw. + bytes auth_info_bytes = 2; + + // chain_id is the unique identifier of the chain this transaction targets. + // It prevents signed transactions from being used on another chain by an + // attacker + string chain_id = 3; + + // account_number is the account number of the account in state + uint64 account_number = 4; +} + +// TxBody is the body of a transaction that all signers sign over. +message TxBody { + // messages is a list of messages to be executed. The required signers of + // those messages define the number and order of elements in AuthInfo's + // signer_infos and Tx's signatures. Each required signer address is added to + // the list only the first time it occurs. + // By convention, the first required signer (usually from the first message) + // is referred to as the primary signer and pays the fee for the whole + // transaction. + repeated google.protobuf.Any messages = 1; + + // memo is any arbitrary note/comment to be added to the transaction. + // WARNING: in clients, any publicly exposed text should not be called memo, + // but should be called `note` instead (see https://github.com/cosmos/cosmos-sdk/issues/9122). + string memo = 2; + + // timeout is the block height after which this transaction will not + // be processed by the chain + uint64 timeout_height = 3; + + // extension_options are arbitrary options that can be added by chains + // when the default options are not sufficient. If any of these are present + // and can't be handled, the transaction will be rejected + repeated google.protobuf.Any extension_options = 1023; + + // extension_options are arbitrary options that can be added by chains + // when the default options are not sufficient. If any of these are present + // and can't be handled, they will be ignored + repeated google.protobuf.Any non_critical_extension_options = 2047; +} + +// AuthInfo describes the fee and signer modes that are used to sign a +// transaction. +message AuthInfo { + // signer_infos defines the signing modes for the required signers. The number + // and order of elements must match the required signers from TxBody's + // messages. The first element is the primary signer and the one which pays + // the fee. + repeated SignerInfo signer_infos = 1; + + // Fee is the fee and gas limit for the transaction. The first signer is the + // primary signer and the one which pays the fee. The fee can be calculated + // based on the cost of evaluating the body and doing signature verification + // of the signers. This can be estimated via simulation. + Fee fee = 2; +} + +// SignerInfo describes the public key and signing mode of a single top-level +// signer. +message SignerInfo { + // public_key is the public key of the signer. It is optional for accounts + // that already exist in state. If unset, the verifier can use the required \ + // signer address for this position and lookup the public key. + google.protobuf.Any public_key = 1; + + // mode_info describes the signing mode of the signer and is a nested + // structure to support nested multisig pubkey's + ModeInfo mode_info = 2; + + // sequence is the sequence of the account, which describes the + // number of committed transactions signed by a given address. It is used to + // prevent replay attacks. + uint64 sequence = 3; +} + +// ModeInfo describes the signing mode of a single or nested multisig signer. +message ModeInfo { + // sum is the oneof that specifies whether this represents a single or nested + // multisig signer + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a nested multisig signer + Multi multi = 2; + } + + // Single is the mode info for a single signer. It is structured as a message + // to allow for additional fields such as locale for SIGN_MODE_TEXTUAL in the + // future + message Single { + // mode is the signing mode of the single signer + cosmos.tx.signing.v1beta1.SignMode mode = 1; + } + + // Multi is the mode info for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; + + // mode_infos is the corresponding modes of the signers of the multisig + // which could include nested multisig public keys + repeated ModeInfo mode_infos = 2; + } +} + +// Fee includes the amount of coins paid in fees and the maximum +// gas to be used by the transaction. The ratio yields an effective "gasprice", +// which must be above some miminum to be accepted into the mempool. +message Fee { + // amount is the amount of coins to be paid as a fee + repeated cosmos.base.v1beta1.Coin amount = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // gas_limit is the maximum gas that can be used in transaction processing + // before an out of gas error occurs + uint64 gas_limit = 2; + + // if unset, the first signer is responsible for paying the fees. If set, the specified account must pay the fees. + // the payer must be a tx signer (and thus have signed this field in AuthInfo). + // setting this field does *not* change the ordering of required signers for the transaction. + string payer = 3; + + // if set, the fee payer (either the first signer or the value of the payer field) requests that a fee grant be used + // to pay fees instead of the fee payer's own balance. If an appropriate fee grant does not exist or the chain does + // not support fee grants, this will fail + string granter = 4; +} diff --git a/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto b/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto new file mode 100644 index 000000000..dd14ba640 --- /dev/null +++ b/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto @@ -0,0 +1,104 @@ +syntax = "proto3"; +package cosmos.upgrade.v1beta1; + +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; + +// Query defines the gRPC upgrade querier service. +service Query { + // CurrentPlan queries the current upgrade plan. + rpc CurrentPlan(QueryCurrentPlanRequest) returns (QueryCurrentPlanResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/current_plan"; + } + + // AppliedPlan queries a previously applied upgrade plan by its name. + rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}"; + } + + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + // This rpc is deprecated now that IBC has its own replacement + // (https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option deprecated = true; + option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}"; + } + + // ModuleVersions queries the list of module versions from state. + // + // Since: cosmos-sdk 0.43 + rpc ModuleVersions(QueryModuleVersionsRequest) returns (QueryModuleVersionsResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/module_versions"; + } +} + +// QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC +// method. +message QueryCurrentPlanRequest {} + +// QueryCurrentPlanResponse is the response type for the Query/CurrentPlan RPC +// method. +message QueryCurrentPlanResponse { + // plan is the current upgrade plan. + Plan plan = 1; +} + +// QueryCurrentPlanRequest is the request type for the Query/AppliedPlan RPC +// method. +message QueryAppliedPlanRequest { + // name is the name of the applied plan to query for. + string name = 1; +} + +// QueryAppliedPlanResponse is the response type for the Query/AppliedPlan RPC +// method. +message QueryAppliedPlanResponse { + // height is the block height at which the plan was applied. + int64 height = 1; +} + +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateRequest { + option deprecated = true; + + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + int64 last_height = 1; +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateResponse { + option deprecated = true; + reserved 1; + + // Since: cosmos-sdk 0.43 + bytes upgraded_consensus_state = 2; +} + +// QueryModuleVersionsRequest is the request type for the Query/ModuleVersions +// RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryModuleVersionsRequest { + // module_name is a field to query a specific module + // consensus version from state. Leaving this empty will + // fetch the full list of module versions from state + string module_name = 1; +} + +// QueryModuleVersionsResponse is the response type for the Query/ModuleVersions +// RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryModuleVersionsResponse { + // module_versions is a list of module names with their consensus versions. + repeated ModuleVersion module_versions = 1; +} diff --git a/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto b/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto new file mode 100644 index 000000000..e888b393d --- /dev/null +++ b/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto @@ -0,0 +1,78 @@ +syntax = "proto3"; +package cosmos.upgrade.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; +option (gogoproto.goproto_getters_all) = false; + +// Plan specifies information about a planned upgrade and when it should occur. +message Plan { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // Sets the name for the upgrade. This name will be used by the upgraded + // version of the software to apply any special "on-upgrade" commands during + // the first BeginBlock method after the upgrade is applied. It is also used + // to detect whether a software version can handle a given upgrade. If no + // upgrade handler with this name has been set in the software, it will be + // assumed that the software is out-of-date when the upgrade Time or Height is + // reached and the software will exit. + string name = 1; + + // Deprecated: Time based upgrades have been deprecated. Time based upgrade logic + // has been removed from the SDK. + // If this field is not empty, an error will be thrown. + google.protobuf.Timestamp time = 2 [deprecated = true, (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + + // The height at which the upgrade must be performed. + // Only used if Time is not set. + int64 height = 3; + + // Any application specific upgrade info to be included on-chain + // such as a git commit that validators could automatically upgrade to + string info = 4; + + // Deprecated: UpgradedClientState field has been deprecated. IBC upgrade logic has been + // moved to the IBC module in the sub module 02-client. + // If this field is not empty, an error will be thrown. + google.protobuf.Any upgraded_client_state = 5 + [deprecated = true, (gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} + +// SoftwareUpgradeProposal is a gov Content type for initiating a software +// upgrade. +message SoftwareUpgradeProposal { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + Plan plan = 3 [(gogoproto.nullable) = false]; +} + +// CancelSoftwareUpgradeProposal is a gov Content type for cancelling a software +// upgrade. +message CancelSoftwareUpgradeProposal { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; +} + +// ModuleVersion specifies a module and its consensus version. +// +// Since: cosmos-sdk 0.43 +message ModuleVersion { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + // name of the app module + string name = 1; + + // consensus version of the app module + uint64 version = 2; +} diff --git a/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto new file mode 100644 index 000000000..c49be802a --- /dev/null +++ b/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package cosmos.vesting.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; + +// Msg defines the bank Msg service. +service Msg { + // CreateVestingAccount defines a method that enables creating a vesting + // account. + rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse); +} + +// MsgCreateVestingAccount defines a message that enables creating a vesting +// account. +message MsgCreateVestingAccount { + option (gogoproto.equal) = true; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + int64 end_time = 4 [(gogoproto.moretags) = "yaml:\"end_time\""]; + bool delayed = 5; +} + +// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. +message MsgCreateVestingAccountResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto b/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto new file mode 100644 index 000000000..e9f661f93 --- /dev/null +++ b/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto @@ -0,0 +1,85 @@ +syntax = "proto3"; +package cosmos.vesting.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; + +// BaseVestingAccount implements the VestingAccount interface. It contains all +// the necessary fields needed for any vesting account implementation. +message BaseVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + repeated cosmos.base.v1beta1.Coin original_vesting = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"original_vesting\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_free = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_free\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_vesting = 4 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_vesting\"" + ]; + int64 end_time = 5 [(gogoproto.moretags) = "yaml:\"end_time\""]; +} + +// ContinuousVestingAccount implements the VestingAccount interface. It +// continuously vests by unlocking coins linearly with respect to time. +message ContinuousVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; +} + +// DelayedVestingAccount implements the VestingAccount interface. It vests all +// coins after a specific time, but non prior. In other words, it keeps them +// locked until a specified time. +message DelayedVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; +} + +// Period defines a length of time and amount of coins that will vest. +message Period { + option (gogoproto.goproto_stringer) = false; + + int64 length = 1; + repeated cosmos.base.v1beta1.Coin amount = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// PeriodicVestingAccount implements the VestingAccount interface. It +// periodically vests by unlocking coins during each specified period. +message PeriodicVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; + repeated Period vesting_periods = 3 [(gogoproto.moretags) = "yaml:\"vesting_periods\"", (gogoproto.nullable) = false]; +} + +// PermanentLockedAccount implements the VestingAccount interface. It does +// not ever release coins, locking them indefinitely. Coins in this account can +// still be used for delegating and for governance votes even while locked. +// +// Since: cosmos-sdk 0.43 +message PermanentLockedAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; +} diff --git a/ampd/proto/third_party/cosmos_proto/cosmos.proto b/ampd/proto/third_party/cosmos_proto/cosmos.proto new file mode 100644 index 000000000..167b17075 --- /dev/null +++ b/ampd/proto/third_party/cosmos_proto/cosmos.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos_proto; + +import "google/protobuf/descriptor.proto"; + +option go_package = "github.com/regen-network/cosmos-proto"; + +extend google.protobuf.MessageOptions { + string interface_type = 93001; + + string implements_interface = 93002; +} + +extend google.protobuf.FieldOptions { + string accepts_interface = 93001; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto new file mode 100644 index 000000000..97a82275d --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// ContractExecutionAuthorization defines authorization for wasm execute. +// Since: wasmd 0.30 +message ContractExecutionAuthorization { + option (cosmos_proto.implements_interface) = + "cosmos.authz.v1beta1.Authorization"; + + // Grants for contract executions + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} + +// ContractMigrationAuthorization defines authorization for wasm contract +// migration. Since: wasmd 0.30 +message ContractMigrationAuthorization { + option (cosmos_proto.implements_interface) = + "cosmos.authz.v1beta1.Authorization"; + + // Grants for contract migrations + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} + +// ContractGrant a granted permission for a single contract +// Since: wasmd 0.30 +message ContractGrant { + // Contract is the bech32 address of the smart contract + string contract = 1; + + // Limit defines execution limits that are enforced and updated when the grant + // is applied. When the limit lapsed the grant is removed. + google.protobuf.Any limit = 2 [ (cosmos_proto.accepts_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX" ]; + + // Filter define more fine-grained control on the message payload passed + // to the contract in the operation. When no filter applies on execution, the + // operation is prohibited. + google.protobuf.Any filter = 3 + [ (cosmos_proto.accepts_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX" ]; +} + +// MaxCallsLimit limited number of calls to the contract. No funds transferable. +// Since: wasmd 0.30 +message MaxCallsLimit { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX"; + + // Remaining number that is decremented on each execution + uint64 remaining = 1; +} + +// MaxFundsLimit defines the maximal amounts that can be sent to the contract. +// Since: wasmd 0.30 +message MaxFundsLimit { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX"; + + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// CombinedLimit defines the maximal amounts that can be sent to a contract and +// the maximal number of calls executable. Both need to remain >0 to be valid. +// Since: wasmd 0.30 +message CombinedLimit { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX"; + + // Remaining number that is decremented on each execution + uint64 calls_remaining = 1; + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// AllowAllMessagesFilter is a wildcard to allow any type of contract payload +// message. +// Since: wasmd 0.30 +message AllowAllMessagesFilter { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX"; +} + +// AcceptedMessageKeysFilter accept only the specific contract message keys in +// the json object to be executed. +// Since: wasmd 0.30 +message AcceptedMessageKeysFilter { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX"; + + // Messages is the list of unique keys + repeated string keys = 1; +} + +// AcceptedMessagesFilter accept only the specific raw contract messages to be +// executed. +// Since: wasmd 0.30 +message AcceptedMessagesFilter { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX"; + + // Messages is the list of raw contract messages + repeated bytes messages = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto new file mode 100644 index 000000000..4e728ff4b --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmwasm/wasm/v1/types.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; + +// GenesisState - genesis state of x/wasm +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + repeated Code codes = 2 + [ (gogoproto.nullable) = false, (gogoproto.jsontag) = "codes,omitempty" ]; + repeated Contract contracts = 3 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "contracts,omitempty" + ]; + repeated Sequence sequences = 4 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "sequences,omitempty" + ]; +} + +// Code struct encompasses CodeInfo and CodeBytes +message Code { + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + CodeInfo code_info = 2 [ (gogoproto.nullable) = false ]; + bytes code_bytes = 3; + // Pinned to wasmvm cache + bool pinned = 4; +} + +// Contract struct encompasses ContractAddress, ContractInfo, and ContractState +message Contract { + string contract_address = 1; + ContractInfo contract_info = 2 [ (gogoproto.nullable) = false ]; + repeated Model contract_state = 3 [ (gogoproto.nullable) = false ]; + repeated ContractCodeHistoryEntry contract_code_history = 4 + [ (gogoproto.nullable) = false ]; +} + +// Sequence key and value of an id generation counter +message Sequence { + bytes id_key = 1 [ (gogoproto.customname) = "IDKey" ]; + uint64 value = 2; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto new file mode 100644 index 000000000..feaad2936 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// MsgIBCSend +message MsgIBCSend { + // the channel by which the packet will be sent + string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; + + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + uint64 timeout_height = 4 + [ (gogoproto.moretags) = "yaml:\"timeout_height\"" ]; + // Timeout timestamp (in nanoseconds) relative to the current block timestamp. + // The timeout is disabled when set to 0. + uint64 timeout_timestamp = 5 + [ (gogoproto.moretags) = "yaml:\"timeout_timestamp\"" ]; + + // Data is the payload to transfer. We must not make assumption what format or + // content is in here. + bytes data = 6; +} + +// MsgIBCSendResponse +message MsgIBCSendResponse { + // Sequence number of the IBC packet sent + uint64 sequence = 1; +} + +// MsgIBCCloseChannel port and channel need to be owned by the contract +message MsgIBCCloseChannel { + string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto new file mode 100644 index 000000000..b1c484bc9 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto @@ -0,0 +1,272 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmwasm/wasm/v1/types.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = true; + +// StoreCodeProposal gov proposal content type to submit WASM code to the system +message StoreCodeProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; + // Used in v1beta1 + reserved 5, 6; + // InstantiatePermission to apply on contract creation, optional + AccessConfig instantiate_permission = 7; + // UnpinCode code on upload, optional + bool unpin_code = 8; + // Source is the URL where the code is hosted + string source = 9; + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + string builder = 10; + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + bytes code_hash = 11; +} + +// InstantiateContractProposal gov proposal content type to instantiate a +// contract. +message InstantiateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // Admin is an optional address that can execute migrations + string admin = 4; + // CodeID is the reference to the stored WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a constract instance. + string label = 6; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 8 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// InstantiateContract2Proposal gov proposal content type to instantiate +// contract 2 +message InstantiateContract2Proposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's enviroment as sender + string run_as = 3; + // Admin is an optional address that can execute migrations + string admin = 4; + // CodeID is the reference to the stored WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a constract instance. + string label = 6; + // Msg json encode message to be passed to the contract on instantiation + bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 8 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. + bytes salt = 9; + // FixMsg include the msg value into the hash for the predictable address. + // Default is false + bool fix_msg = 10; +} + +// MigrateContractProposal gov proposal content type to migrate a contract. +message MigrateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // Note: skipping 3 as this was previously used for unneeded run_as + + // Contract is the address of the smart contract + string contract = 4; + // CodeID references the new WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Msg json encoded message to be passed to the contract on migration + bytes msg = 6 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// SudoContractProposal gov proposal content type to call sudo on a contract. +message SudoContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // Contract is the address of the smart contract + string contract = 3; + // Msg json encoded message to be passed to the contract as sudo + bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// ExecuteContractProposal gov proposal content type to call execute on a +// contract. +message ExecuteContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // Contract is the address of the smart contract + string contract = 4; + // Msg json encoded message to be passed to the contract as execute + bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 6 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// UpdateAdminProposal gov proposal content type to set an admin for a contract. +message UpdateAdminProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // NewAdmin address to be set + string new_admin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; + // Contract is the address of the smart contract + string contract = 4; +} + +// ClearAdminProposal gov proposal content type to clear the admin of a +// contract. +message ClearAdminProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // Contract is the address of the smart contract + string contract = 3; +} + +// PinCodesProposal gov proposal content type to pin a set of code ids in the +// wasmvm cache. +message PinCodesProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + // Description is a human readable text + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // CodeIDs references the new WASM codes + repeated uint64 code_ids = 3 [ + (gogoproto.customname) = "CodeIDs", + (gogoproto.moretags) = "yaml:\"code_ids\"" + ]; +} + +// UnpinCodesProposal gov proposal content type to unpin a set of code ids in +// the wasmvm cache. +message UnpinCodesProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + // Description is a human readable text + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // CodeIDs references the WASM codes + repeated uint64 code_ids = 3 [ + (gogoproto.customname) = "CodeIDs", + (gogoproto.moretags) = "yaml:\"code_ids\"" + ]; +} + +// AccessConfigUpdate contains the code id and the access config to be +// applied. +message AccessConfigUpdate { + // CodeID is the reference to the stored WASM code to be updated + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + // InstantiatePermission to apply to the set of code ids + AccessConfig instantiate_permission = 2 [ (gogoproto.nullable) = false ]; +} + +// UpdateInstantiateConfigProposal gov proposal content type to update +// instantiate config to a set of code ids. +message UpdateInstantiateConfigProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + // Description is a human readable text + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // AccessConfigUpdate contains the list of code ids and the access config + // to be applied. + repeated AccessConfigUpdate access_config_updates = 3 + [ (gogoproto.nullable) = false ]; +} + +// StoreAndInstantiateContractProposal gov proposal content type to store +// and instantiate the contract. +message StoreAndInstantiateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; + // InstantiatePermission to apply on contract creation, optional + AccessConfig instantiate_permission = 5; + // UnpinCode code on upload, optional + bool unpin_code = 6; + // Admin is an optional address that can execute migrations + string admin = 7; + // Label is optional metadata to be stored with a constract instance. + string label = 8; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 9 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 10 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Source is the URL where the code is hosted + string source = 11; + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + string builder = 12; + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + bytes code_hash = 13; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto new file mode 100644 index 000000000..ffe48d242 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto @@ -0,0 +1,263 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmwasm/wasm/v1/types.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = false; + +// Query provides defines the gRPC querier service +service Query { + // ContractInfo gets the contract meta data + rpc ContractInfo(QueryContractInfoRequest) + returns (QueryContractInfoResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/contract/{address}"; + } + // ContractHistory gets the contract code history + rpc ContractHistory(QueryContractHistoryRequest) + returns (QueryContractHistoryResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contract/{address}/history"; + } + // ContractsByCode lists all smart contracts for a code id + rpc ContractsByCode(QueryContractsByCodeRequest) + returns (QueryContractsByCodeResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}/contracts"; + } + // AllContractState gets all raw store data for a single contract + rpc AllContractState(QueryAllContractStateRequest) + returns (QueryAllContractStateResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/contract/{address}/state"; + } + // RawContractState gets single key from the raw store data of a contract + rpc RawContractState(QueryRawContractStateRequest) + returns (QueryRawContractStateResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}"; + } + // SmartContractState get smart query result from the contract + rpc SmartContractState(QuerySmartContractStateRequest) + returns (QuerySmartContractStateResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}"; + } + // Code gets the binary code and metadata for a singe wasm code + rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}"; + } + // Codes gets the metadata for all stored wasm codes + rpc Codes(QueryCodesRequest) returns (QueryCodesResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/code"; + } + + // PinnedCodes gets the pinned code ids + rpc PinnedCodes(QueryPinnedCodesRequest) returns (QueryPinnedCodesResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/codes/pinned"; + } + + // Params gets the module params + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/codes/params"; + } + + // ContractsByCreator gets the contracts by creator + rpc ContractsByCreator(QueryContractsByCreatorRequest) + returns (QueryContractsByCreatorResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contracts/creator/{creator_address}"; + } +} + +// QueryContractInfoRequest is the request type for the Query/ContractInfo RPC +// method +message QueryContractInfoRequest { + // address is the address of the contract to query + string address = 1; +} +// QueryContractInfoResponse is the response type for the Query/ContractInfo RPC +// method +message QueryContractInfoResponse { + option (gogoproto.equal) = true; + + // address is the address of the contract + string address = 1; + ContractInfo contract_info = 2 [ + (gogoproto.embed) = true, + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "" + ]; +} + +// QueryContractHistoryRequest is the request type for the Query/ContractHistory +// RPC method +message QueryContractHistoryRequest { + // address is the address of the contract to query + string address = 1; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractHistoryResponse is the response type for the +// Query/ContractHistory RPC method +message QueryContractHistoryResponse { + repeated ContractCodeHistoryEntry entries = 1 + [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryContractsByCodeRequest is the request type for the Query/ContractsByCode +// RPC method +message QueryContractsByCodeRequest { + uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractsByCodeResponse is the response type for the +// Query/ContractsByCode RPC method +message QueryContractsByCodeResponse { + // contracts are a set of contract addresses + repeated string contracts = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryAllContractStateRequest is the request type for the +// Query/AllContractState RPC method +message QueryAllContractStateRequest { + // address is the address of the contract + string address = 1; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllContractStateResponse is the response type for the +// Query/AllContractState RPC method +message QueryAllContractStateResponse { + repeated Model models = 1 [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryRawContractStateRequest is the request type for the +// Query/RawContractState RPC method +message QueryRawContractStateRequest { + // address is the address of the contract + string address = 1; + bytes query_data = 2; +} + +// QueryRawContractStateResponse is the response type for the +// Query/RawContractState RPC method +message QueryRawContractStateResponse { + // Data contains the raw store data + bytes data = 1; +} + +// QuerySmartContractStateRequest is the request type for the +// Query/SmartContractState RPC method +message QuerySmartContractStateRequest { + // address is the address of the contract + string address = 1; + // QueryData contains the query data passed to the contract + bytes query_data = 2 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// QuerySmartContractStateResponse is the response type for the +// Query/SmartContractState RPC method +message QuerySmartContractStateResponse { + // Data contains the json data returned from the smart contract + bytes data = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// QueryCodeRequest is the request type for the Query/Code RPC method +message QueryCodeRequest { + uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID +} + +// CodeInfoResponse contains code meta data from CodeInfo +message CodeInfoResponse { + option (gogoproto.equal) = true; + + uint64 code_id = 1 [ + (gogoproto.customname) = "CodeID", + (gogoproto.jsontag) = "id" + ]; // id for legacy support + string creator = 2; + bytes data_hash = 3 + [ (gogoproto.casttype) = + "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; + // Used in v1beta1 + reserved 4, 5; + AccessConfig instantiate_permission = 6 [ (gogoproto.nullable) = false ]; +} + +// QueryCodeResponse is the response type for the Query/Code RPC method +message QueryCodeResponse { + option (gogoproto.equal) = true; + CodeInfoResponse code_info = 1 + [ (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + bytes data = 2 [ (gogoproto.jsontag) = "data" ]; +} + +// QueryCodesRequest is the request type for the Query/Codes RPC method +message QueryCodesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryCodesResponse is the response type for the Query/Codes RPC method +message QueryCodesResponse { + repeated CodeInfoResponse code_infos = 1 [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryPinnedCodesRequest is the request type for the Query/PinnedCodes +// RPC method +message QueryPinnedCodesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryPinnedCodesResponse is the response type for the +// Query/PinnedCodes RPC method +message QueryPinnedCodesResponse { + repeated uint64 code_ids = 1 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "CodeIDs" ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +// QueryContractsByCreatorRequest is the request type for the +// Query/ContractsByCreator RPC method. +message QueryContractsByCreatorRequest { + // CreatorAddress is the address of contract creator + string creator_address = 1; + // Pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractsByCreatorResponse is the response type for the +// Query/ContractsByCreator RPC method. +message QueryContractsByCreatorResponse { + // ContractAddresses result set + repeated string contract_addresses = 1; + // Pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto new file mode 100644 index 000000000..741fbc494 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto @@ -0,0 +1,192 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "cosmwasm/wasm/v1/types.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// Msg defines the wasm Msg service. +service Msg { + // StoreCode to submit Wasm code to the system + rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); + // InstantiateContract creates a new smart contract instance for the given + // code id. + rpc InstantiateContract(MsgInstantiateContract) + returns (MsgInstantiateContractResponse); + // InstantiateContract2 creates a new smart contract instance for the given + // code id with a predictable address + rpc InstantiateContract2(MsgInstantiateContract2) + returns (MsgInstantiateContract2Response); + // Execute submits the given message data to a smart contract + rpc ExecuteContract(MsgExecuteContract) returns (MsgExecuteContractResponse); + // Migrate runs a code upgrade/ downgrade for a smart contract + rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); + // UpdateAdmin sets a new admin for a smart contract + rpc UpdateAdmin(MsgUpdateAdmin) returns (MsgUpdateAdminResponse); + // ClearAdmin removes any admin stored for a smart contract + rpc ClearAdmin(MsgClearAdmin) returns (MsgClearAdminResponse); + // UpdateInstantiateConfig updates instantiate config for a smart contract + rpc UpdateInstantiateConfig(MsgUpdateInstantiateConfig) + returns (MsgUpdateInstantiateConfigResponse); +} + +// MsgStoreCode submit Wasm code to the system +message MsgStoreCode { + // Sender is the actor that signed the messages + string sender = 1; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 2 [ (gogoproto.customname) = "WASMByteCode" ]; + // Used in v1beta1 + reserved 3, 4; + // InstantiatePermission access control to apply on contract creation, + // optional + AccessConfig instantiate_permission = 5; +} +// MsgStoreCodeResponse returns store result data. +message MsgStoreCodeResponse { + // CodeID is the reference to the stored WASM code + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + // Checksum is the sha256 hash of the stored code + bytes checksum = 2; +} + +// MsgInstantiateContract create a new smart contract instance for the given +// code id. +message MsgInstantiateContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Admin is an optional address that can execute migrations + string admin = 2; + // CodeID is the reference to the stored WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a contract instance. + string label = 4; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 6 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// MsgInstantiateContract2 create a new smart contract instance for the given +// code id with a predicable address. +message MsgInstantiateContract2 { + // Sender is the that actor that signed the messages + string sender = 1; + // Admin is an optional address that can execute migrations + string admin = 2; + // CodeID is the reference to the stored WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a contract instance. + string label = 4; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 6 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. + bytes salt = 7; + // FixMsg include the msg value into the hash for the predictable address. + // Default is false + bool fix_msg = 8; +} + +// MsgInstantiateContractResponse return instantiation result data +message MsgInstantiateContractResponse { + // Address is the bech32 address of the new contract instance. + string address = 1; + // Data contains bytes to returned from the contract + bytes data = 2; +} + +// MsgInstantiateContract2Response return instantiation result data +message MsgInstantiateContract2Response { + // Address is the bech32 address of the new contract instance. + string address = 1; + // Data contains bytes to returned from the contract + bytes data = 2; +} + +// MsgExecuteContract submits the given message data to a smart contract +message MsgExecuteContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 2; + // Msg json encoded message to be passed to the contract + bytes msg = 3 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on execution + repeated cosmos.base.v1beta1.Coin funds = 5 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// MsgExecuteContractResponse returns execution result data. +message MsgExecuteContractResponse { + // Data contains bytes to returned from the contract + bytes data = 1; +} + +// MsgMigrateContract runs a code upgrade/ downgrade for a smart contract +message MsgMigrateContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 2; + // CodeID references the new WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // Msg json encoded message to be passed to the contract on migration + bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// MsgMigrateContractResponse returns contract migration result data. +message MsgMigrateContractResponse { + // Data contains same raw bytes returned as data from the wasm contract. + // (May be empty) + bytes data = 1; +} + +// MsgUpdateAdmin sets a new admin for a smart contract +message MsgUpdateAdmin { + // Sender is the that actor that signed the messages + string sender = 1; + // NewAdmin address to be set + string new_admin = 2; + // Contract is the address of the smart contract + string contract = 3; +} + +// MsgUpdateAdminResponse returns empty data +message MsgUpdateAdminResponse {} + +// MsgClearAdmin removes any admin stored for a smart contract +message MsgClearAdmin { + // Sender is the actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 3; +} + +// MsgClearAdminResponse returns empty data +message MsgClearAdminResponse {} + +// MsgUpdateInstantiateConfig updates instantiate config for a smart contract +message MsgUpdateInstantiateConfig { + // Sender is the that actor that signed the messages + string sender = 1; + // CodeID references the stored WASM code + uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; + // NewInstantiatePermission is the new access control + AccessConfig new_instantiate_permission = 3; +} + +// MsgUpdateInstantiateConfigResponse returns empty data +message MsgUpdateInstantiateConfigResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto new file mode 100644 index 000000000..b68179e2e --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto @@ -0,0 +1,145 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = true; + +// AccessType permission types +enum AccessType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = false; + // AccessTypeUnspecified placeholder for empty value + ACCESS_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "AccessTypeUnspecified" ]; + // AccessTypeNobody forbidden + ACCESS_TYPE_NOBODY = 1 + [ (gogoproto.enumvalue_customname) = "AccessTypeNobody" ]; + // AccessTypeOnlyAddress restricted to a single address + // Deprecated: use AccessTypeAnyOfAddresses instead + ACCESS_TYPE_ONLY_ADDRESS = 2 + [ (gogoproto.enumvalue_customname) = "AccessTypeOnlyAddress" ]; + // AccessTypeEverybody unrestricted + ACCESS_TYPE_EVERYBODY = 3 + [ (gogoproto.enumvalue_customname) = "AccessTypeEverybody" ]; + // AccessTypeAnyOfAddresses allow any of the addresses + ACCESS_TYPE_ANY_OF_ADDRESSES = 4 + [ (gogoproto.enumvalue_customname) = "AccessTypeAnyOfAddresses" ]; +} + +// AccessTypeParam +message AccessTypeParam { + option (gogoproto.goproto_stringer) = true; + AccessType value = 1 [ (gogoproto.moretags) = "yaml:\"value\"" ]; +} + +// AccessConfig access control type. +message AccessConfig { + option (gogoproto.goproto_stringer) = true; + AccessType permission = 1 [ (gogoproto.moretags) = "yaml:\"permission\"" ]; + + // Address + // Deprecated: replaced by addresses + string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + repeated string addresses = 3 [ (gogoproto.moretags) = "yaml:\"addresses\"" ]; +} + +// Params defines the set of wasm parameters. +message Params { + option (gogoproto.goproto_stringer) = false; + AccessConfig code_upload_access = 1 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"code_upload_access\"" + ]; + AccessType instantiate_default_permission = 2 + [ (gogoproto.moretags) = "yaml:\"instantiate_default_permission\"" ]; +} + +// CodeInfo is data for the uploaded contract WASM code +message CodeInfo { + // CodeHash is the unique identifier created by wasmvm + bytes code_hash = 1; + // Creator address who initially stored the code + string creator = 2; + // Used in v1beta1 + reserved 3, 4; + // InstantiateConfig access control to apply on contract creation, optional + AccessConfig instantiate_config = 5 [ (gogoproto.nullable) = false ]; +} + +// ContractInfo stores a WASM contract instance +message ContractInfo { + option (gogoproto.equal) = true; + + // CodeID is the reference to the stored Wasm code + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + // Creator address who initially instantiated the contract + string creator = 2; + // Admin is an optional address that can execute migrations + string admin = 3; + // Label is optional metadata to be stored with a contract instance. + string label = 4; + // Created Tx position when the contract was instantiated. + AbsoluteTxPosition created = 5; + string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; + + // Extension is an extension point to store custom metadata within the + // persistence model. + google.protobuf.Any extension = 7 + [ (cosmos_proto.accepts_interface) = + "cosmwasm.wasm.v1.ContractInfoExtension" ]; +} + +// ContractCodeHistoryOperationType actions that caused a code change +enum ContractCodeHistoryOperationType { + option (gogoproto.goproto_enum_prefix) = false; + // ContractCodeHistoryOperationTypeUnspecified placeholder for empty value + CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeUnspecified" ]; + // ContractCodeHistoryOperationTypeInit on chain contract instantiation + CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT = 1 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeInit" ]; + // ContractCodeHistoryOperationTypeMigrate code migration + CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE = 2 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeMigrate" ]; + // ContractCodeHistoryOperationTypeGenesis based on genesis data + CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS = 3 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeGenesis" ]; +} + +// ContractCodeHistoryEntry metadata to a contract. +message ContractCodeHistoryEntry { + ContractCodeHistoryOperationType operation = 1; + // CodeID is the reference to the stored WASM code + uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; + // Updated Tx position when the operation was executed. + AbsoluteTxPosition updated = 3; + bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// AbsoluteTxPosition is a unique transaction position that allows for global +// ordering of transactions. +message AbsoluteTxPosition { + // BlockHeight is the block the contract was created at + uint64 block_height = 1; + // TxIndex is a monotonic counter within the block (actual transaction index, + // or gas consumed) + uint64 tx_index = 2; +} + +// Model is a struct that holds a KV pair +message Model { + // hex-encode key to read it better (this is often ascii) + bytes key = 1 [ (gogoproto.casttype) = + "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; + // base64-encode raw value + bytes value = 2; +} diff --git a/ampd/proto/third_party/gogoproto/gogo.proto b/ampd/proto/third_party/gogoproto/gogo.proto new file mode 100644 index 000000000..49e78f99f --- /dev/null +++ b/ampd/proto/third_party/gogoproto/gogo.proto @@ -0,0 +1,145 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; +package gogoproto; + +import "google/protobuf/descriptor.proto"; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "GoGoProtos"; +option go_package = "github.com/gogo/protobuf/gogoproto"; + +extend google.protobuf.EnumOptions { + optional bool goproto_enum_prefix = 62001; + optional bool goproto_enum_stringer = 62021; + optional bool enum_stringer = 62022; + optional string enum_customname = 62023; + optional bool enumdecl = 62024; +} + +extend google.protobuf.EnumValueOptions { + optional string enumvalue_customname = 66001; +} + +extend google.protobuf.FileOptions { + optional bool goproto_getters_all = 63001; + optional bool goproto_enum_prefix_all = 63002; + optional bool goproto_stringer_all = 63003; + optional bool verbose_equal_all = 63004; + optional bool face_all = 63005; + optional bool gostring_all = 63006; + optional bool populate_all = 63007; + optional bool stringer_all = 63008; + optional bool onlyone_all = 63009; + + optional bool equal_all = 63013; + optional bool description_all = 63014; + optional bool testgen_all = 63015; + optional bool benchgen_all = 63016; + optional bool marshaler_all = 63017; + optional bool unmarshaler_all = 63018; + optional bool stable_marshaler_all = 63019; + + optional bool sizer_all = 63020; + + optional bool goproto_enum_stringer_all = 63021; + optional bool enum_stringer_all = 63022; + + optional bool unsafe_marshaler_all = 63023; + optional bool unsafe_unmarshaler_all = 63024; + + optional bool goproto_extensions_map_all = 63025; + optional bool goproto_unrecognized_all = 63026; + optional bool gogoproto_import = 63027; + optional bool protosizer_all = 63028; + optional bool compare_all = 63029; + optional bool typedecl_all = 63030; + optional bool enumdecl_all = 63031; + + optional bool goproto_registration = 63032; + optional bool messagename_all = 63033; + + optional bool goproto_sizecache_all = 63034; + optional bool goproto_unkeyed_all = 63035; +} + +extend google.protobuf.MessageOptions { + optional bool goproto_getters = 64001; + optional bool goproto_stringer = 64003; + optional bool verbose_equal = 64004; + optional bool face = 64005; + optional bool gostring = 64006; + optional bool populate = 64007; + optional bool stringer = 67008; + optional bool onlyone = 64009; + + optional bool equal = 64013; + optional bool description = 64014; + optional bool testgen = 64015; + optional bool benchgen = 64016; + optional bool marshaler = 64017; + optional bool unmarshaler = 64018; + optional bool stable_marshaler = 64019; + + optional bool sizer = 64020; + + optional bool unsafe_marshaler = 64023; + optional bool unsafe_unmarshaler = 64024; + + optional bool goproto_extensions_map = 64025; + optional bool goproto_unrecognized = 64026; + + optional bool protosizer = 64028; + optional bool compare = 64029; + + optional bool typedecl = 64030; + + optional bool messagename = 64033; + + optional bool goproto_sizecache = 64034; + optional bool goproto_unkeyed = 64035; +} + +extend google.protobuf.FieldOptions { + optional bool nullable = 65001; + optional bool embed = 65002; + optional string customtype = 65003; + optional string customname = 65004; + optional string jsontag = 65005; + optional string moretags = 65006; + optional string casttype = 65007; + optional string castkey = 65008; + optional string castvalue = 65009; + + optional bool stdtime = 65010; + optional bool stdduration = 65011; + optional bool wktpointer = 65012; + + optional string castrepeated = 65013; +} diff --git a/ampd/proto/third_party/google/api/annotations.proto b/ampd/proto/third_party/google/api/annotations.proto new file mode 100644 index 000000000..efdab3db6 --- /dev/null +++ b/ampd/proto/third_party/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/ampd/proto/third_party/google/api/http.proto b/ampd/proto/third_party/google/api/http.proto new file mode 100644 index 000000000..31d867a27 --- /dev/null +++ b/ampd/proto/third_party/google/api/http.proto @@ -0,0 +1,379 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They +// are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL +// query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP +// request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto new file mode 100644 index 000000000..34672fdeb --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +import "ibc/applications/transfer/v1/transfer.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the ibc-transfer genesis state +message GenesisState { + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + repeated DenomTrace denom_traces = 2 [ + (gogoproto.castrepeated) = "Traces", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"denom_traces\"" + ]; + Params params = 3 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto new file mode 100644 index 000000000..52f2f2400 --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto @@ -0,0 +1,105 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/applications/transfer/v1/transfer.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +// Query provides defines the gRPC querier service. +service Query { + // DenomTraces queries all denomination traces. + rpc DenomTraces(QueryDenomTracesRequest) returns (QueryDenomTracesResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces"; + } + + // DenomTrace queries a denomination trace information. + rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; + } + + // Params queries all parameters of the ibc-transfer module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/params"; + } + + // DenomHash queries a denomination hash information. + rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace=**}"; + } + + // EscrowAddress returns the escrow address for a particular port and channel id. + rpc EscrowAddress(QueryEscrowAddressRequest) returns (QueryEscrowAddressResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address"; + } +} + +// QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC +// method +message QueryDenomTraceRequest { + // hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. + string hash = 1; +} + +// QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC +// method. +message QueryDenomTraceResponse { + // denom_trace returns the requested denomination trace information. + DenomTrace denom_trace = 1; +} + +// QueryConnectionsRequest is the request type for the Query/DenomTraces RPC +// method +message QueryDenomTracesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryConnectionsResponse is the response type for the Query/DenomTraces RPC +// method. +message QueryDenomTracesResponse { + // denom_traces returns all denominations trace information. + repeated DenomTrace denom_traces = 1 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +// QueryDenomHashRequest is the request type for the Query/DenomHash RPC +// method +message QueryDenomHashRequest { + // The denomination trace ([port_id]/[channel_id])+/[denom] + string trace = 1; +} + +// QueryDenomHashResponse is the response type for the Query/DenomHash RPC +// method. +message QueryDenomHashResponse { + // hash (in hex format) of the denomination trace information. + string hash = 1; +} + +// QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. +message QueryEscrowAddressRequest { + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; +} + +// QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. +message QueryEscrowAddressResponse { + // the escrow account address + string escrow_address = 1; +} \ No newline at end of file diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto new file mode 100644 index 000000000..1f92e81a6 --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +import "gogoproto/gogo.proto"; + +// DenomTrace contains the base denomination for ICS20 fungible tokens and the +// source tracing information path. +message DenomTrace { + // path defines the chain of port/channel identifiers used for tracing the + // source of the fungible token. + string path = 1; + // base denomination of the relayed fungible token. + string base_denom = 2; +} + +// Params defines the set of IBC transfer parameters. +// NOTE: To prevent a single token from being transferred, set the +// TransfersEnabled parameter to true and then set the bank module's SendEnabled +// parameter for the denomination to false. +message Params { + // send_enabled enables or disables all cross-chain token transfers from this + // chain. + bool send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled\""]; + // receive_enabled enables or disables all cross-chain token transfers to this + // chain. + bool receive_enabled = 2 [(gogoproto.moretags) = "yaml:\"receive_enabled\""]; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto new file mode 100644 index 000000000..44e068d69 --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "ibc/core/client/v1/client.proto"; + +// Msg defines the ibc/transfer Msg service. +service Msg { + // Transfer defines a rpc handler method for MsgTransfer. + rpc Transfer(MsgTransfer) returns (MsgTransferResponse); +} + +// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between +// ICS20 enabled chains. See ICS Spec here: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message MsgTransfer { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // the port on which the packet will be sent + string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""]; + // the channel by which the packet will be sent + string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + // the tokens to be transferred + cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false]; + // the sender address + string sender = 4; + // the recipient address on the destination chain + string receiver = 5; + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + ibc.core.client.v1.Height timeout_height = 6 + [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + // Timeout timestamp in absolute nanoseconds since unix epoch. + // The timeout is disabled when set to 0. + uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; + // optional memo + string memo = 8; +} + +// MsgTransferResponse defines the Msg/Transfer response type. +message MsgTransferResponse { + // sequence number of the transfer packet sent + uint64 sequence = 1; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto b/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto new file mode 100644 index 000000000..129815ebc --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v2; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +// FungibleTokenPacketData defines a struct for the packet payload +// See FungibleTokenPacketData spec: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message FungibleTokenPacketData { + // the token denomination to be transferred + string denom = 1; + // the token amount to be transferred + string amount = 2; + // the sender address + string sender = 3; + // the recipient address on the destination chain + string receiver = 4; + // optional memo + string memo = 5; +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/channel.proto b/ampd/proto/third_party/ibc/core/channel/v1/channel.proto new file mode 100644 index 000000000..646884d57 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/channel.proto @@ -0,0 +1,162 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +// Channel defines pipeline for exactly-once packet delivery between specific +// modules on separate blockchains, which has at least one end capable of +// sending packets and one end capable of receiving packets. +message Channel { + option (gogoproto.goproto_getters) = false; + + // current state of the channel end + State state = 1; + // whether the channel is ordered or unordered + Order ordering = 2; + // counterparty channel end + Counterparty counterparty = 3 [(gogoproto.nullable) = false]; + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; + // opaque channel version, which is agreed upon during the handshake + string version = 5; +} + +// IdentifiedChannel defines a channel with additional port and channel +// identifier fields. +message IdentifiedChannel { + option (gogoproto.goproto_getters) = false; + + // current state of the channel end + State state = 1; + // whether the channel is ordered or unordered + Order ordering = 2; + // counterparty channel end + Counterparty counterparty = 3 [(gogoproto.nullable) = false]; + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; + // opaque channel version, which is agreed upon during the handshake + string version = 5; + // port identifier + string port_id = 6; + // channel identifier + string channel_id = 7; +} + +// State defines if a channel is in one of the following states: +// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. +enum State { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; + // A channel has just started the opening handshake. + STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; + // A channel has acknowledged the handshake step on the counterparty chain. + STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; + // A channel has completed the handshake. Open channels are + // ready to send and receive packets. + STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; + // A channel has been closed and can no longer be used to send or receive + // packets. + STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; +} + +// Order defines if a channel is ORDERED or UNORDERED +enum Order { + option (gogoproto.goproto_enum_prefix) = false; + + // zero-value for channel ordering + ORDER_NONE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "NONE"]; + // packets can be delivered in any order, which may differ from the order in + // which they were sent. + ORDER_UNORDERED = 1 [(gogoproto.enumvalue_customname) = "UNORDERED"]; + // packets are delivered exactly in the order which they were sent + ORDER_ORDERED = 2 [(gogoproto.enumvalue_customname) = "ORDERED"]; +} + +// Counterparty defines a channel end counterparty +message Counterparty { + option (gogoproto.goproto_getters) = false; + + // port on the counterparty chain which owns the other end of the channel. + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // channel end on the counterparty chain + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; +} + +// Packet defines a type that carries data across different chains through IBC +message Packet { + option (gogoproto.goproto_getters) = false; + + // number corresponds to the order of sends and receives, where a Packet + // with an earlier sequence number must be sent and received before a Packet + // with a later sequence number. + uint64 sequence = 1; + // identifies the port on the sending chain. + string source_port = 2 [(gogoproto.moretags) = "yaml:\"source_port\""]; + // identifies the channel end on the sending chain. + string source_channel = 3 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + // identifies the port on the receiving chain. + string destination_port = 4 [(gogoproto.moretags) = "yaml:\"destination_port\""]; + // identifies the channel end on the receiving chain. + string destination_channel = 5 [(gogoproto.moretags) = "yaml:\"destination_channel\""]; + // actual opaque bytes transferred directly to the application module + bytes data = 6; + // block height after which the packet times out + ibc.core.client.v1.Height timeout_height = 7 + [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + // block timestamp (in nanoseconds) after which the packet times out + uint64 timeout_timestamp = 8 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; +} + +// PacketState defines the generic type necessary to retrieve and store +// packet commitments, acknowledgements, and receipts. +// Caller is responsible for knowing the context necessary to interpret this +// state as a commitment, acknowledgement, or a receipt. +message PacketState { + option (gogoproto.goproto_getters) = false; + + // channel port identifier. + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // channel unique identifier. + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + // packet sequence. + uint64 sequence = 3; + // embedded data that represents packet state. + bytes data = 4; +} + +// PacketId is an identifer for a unique Packet +// Source chains refer to packets by source port/channel +// Destination chains refer to packets by destination port/channel +message PacketId { + option (gogoproto.goproto_getters) = false; + + // channel port identifier + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // channel unique identifier + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + // packet sequence + uint64 sequence = 3; +} + +// Acknowledgement is the recommended acknowledgement format to be used by +// app-specific protocols. +// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental +// conflicts with other protobuf message formats used for acknowledgements. +// The first byte of any message with this format will be the non-ASCII values +// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: +// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope +message Acknowledgement { + // response contains either a result or an error and must be non-empty + oneof response { + bytes result = 21; + string error = 22; + } +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto b/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto new file mode 100644 index 000000000..1c0ff6ee8 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// GenesisState defines the ibc channel submodule's genesis state. +message GenesisState { + repeated IdentifiedChannel channels = 1 [(gogoproto.casttype) = "IdentifiedChannel", (gogoproto.nullable) = false]; + repeated PacketState acknowledgements = 2 [(gogoproto.nullable) = false]; + repeated PacketState commitments = 3 [(gogoproto.nullable) = false]; + repeated PacketState receipts = 4 [(gogoproto.nullable) = false]; + repeated PacketSequence send_sequences = 5 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"send_sequences\""]; + repeated PacketSequence recv_sequences = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; + repeated PacketSequence ack_sequences = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; + // the sequence for the next generated channel identifier + uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; +} + +// PacketSequence defines the genesis type necessary to retrieve and store +// next send and receive sequences. +message PacketSequence { + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + uint64 sequence = 3; +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/query.proto b/ampd/proto/third_party/ibc/core/channel/v1/query.proto new file mode 100644 index 000000000..986633173 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/query.proto @@ -0,0 +1,376 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "ibc/core/client/v1/client.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; + +// Query provides defines the gRPC querier service +service Query { + // Channel queries an IBC Channel. + rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}"; + } + + // Channels queries all the IBC channels of a chain. + rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels"; + } + + // ConnectionChannels queries all the channels associated with a connection + // end. + rpc ConnectionChannels(QueryConnectionChannelsRequest) returns (QueryConnectionChannelsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/connections/{connection}/channels"; + } + + // ChannelClientState queries for the client state for the channel associated + // with the provided channel identifiers. + rpc ChannelClientState(QueryChannelClientStateRequest) returns (QueryChannelClientStateResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/client_state"; + } + + // ChannelConsensusState queries for the consensus state for the channel + // associated with the provided channel identifiers. + rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/consensus_state/revision/" + "{revision_number}/height/{revision_height}"; + } + + // PacketCommitment queries a stored packet commitment hash. + rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" + "packet_commitments/{sequence}"; + } + + // PacketCommitments returns all the packet commitments hashes associated + // with a channel. + rpc PacketCommitments(QueryPacketCommitmentsRequest) returns (QueryPacketCommitmentsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_commitments"; + } + + // PacketReceipt queries if a given packet sequence has been received on the + // queried chain + rpc PacketReceipt(QueryPacketReceiptRequest) returns (QueryPacketReceiptResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_receipts/{sequence}"; + } + + // PacketAcknowledgement queries a stored packet acknowledgement hash. + rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest) returns (QueryPacketAcknowledgementResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_acks/{sequence}"; + } + + // PacketAcknowledgements returns all the packet acknowledgements associated + // with a channel. + rpc PacketAcknowledgements(QueryPacketAcknowledgementsRequest) returns (QueryPacketAcknowledgementsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_acknowledgements"; + } + + // UnreceivedPackets returns all the unreceived IBC packets associated with a + // channel and sequences. + rpc UnreceivedPackets(QueryUnreceivedPacketsRequest) returns (QueryUnreceivedPacketsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" + "packet_commitments/" + "{packet_commitment_sequences}/unreceived_packets"; + } + + // UnreceivedAcks returns all the unreceived IBC acknowledgements associated + // with a channel and sequences. + rpc UnreceivedAcks(QueryUnreceivedAcksRequest) returns (QueryUnreceivedAcksResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_commitments/" + "{packet_ack_sequences}/unreceived_acks"; + } + + // NextSequenceReceive returns the next receive sequence for a given channel. + rpc NextSequenceReceive(QueryNextSequenceReceiveRequest) returns (QueryNextSequenceReceiveResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/next_sequence"; + } +} + +// QueryChannelRequest is the request type for the Query/Channel RPC method +message QueryChannelRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryChannelResponse is the response type for the Query/Channel RPC method. +// Besides the Channel end, it includes a proof and the height from which the +// proof was retrieved. +message QueryChannelResponse { + // channel associated with the request identifiers + ibc.core.channel.v1.Channel channel = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelsRequest is the request type for the Query/Channels RPC method +message QueryChannelsRequest { + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryChannelsResponse is the response type for the Query/Channels RPC method. +message QueryChannelsResponse { + // list of stored channels of the chain. + repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionChannelsRequest is the request type for the +// Query/QueryConnectionChannels RPC method +message QueryConnectionChannelsRequest { + // connection unique identifier + string connection = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConnectionChannelsResponse is the Response type for the +// Query/QueryConnectionChannels RPC method +message QueryConnectionChannelsResponse { + // list of channels associated with a connection. + repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelClientStateRequest is the request type for the Query/ClientState +// RPC method +message QueryChannelClientStateRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryChannelClientStateResponse is the Response type for the +// Query/QueryChannelClientState RPC method +message QueryChannelClientStateResponse { + // client state associated with the channel + ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelConsensusStateRequest is the request type for the +// Query/ConsensusState RPC method +message QueryChannelConsensusStateRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // revision number of the consensus state + uint64 revision_number = 3; + // revision height of the consensus state + uint64 revision_height = 4; +} + +// QueryChannelClientStateResponse is the Response type for the +// Query/QueryChannelClientState RPC method +message QueryChannelConsensusStateResponse { + // consensus state associated with the channel + google.protobuf.Any consensus_state = 1; + // client ID associated with the consensus state + string client_id = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryPacketCommitmentRequest is the request type for the +// Query/PacketCommitment RPC method +message QueryPacketCommitmentRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketCommitmentResponse defines the client query response for a packet +// which also includes a proof and the height from which the proof was +// retrieved +message QueryPacketCommitmentResponse { + // packet associated with the request fields + bytes commitment = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketCommitmentsRequest is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketCommitmentsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 3; +} + +// QueryPacketCommitmentsResponse is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketCommitmentsResponse { + repeated ibc.core.channel.v1.PacketState commitments = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketReceiptRequest is the request type for the +// Query/PacketReceipt RPC method +message QueryPacketReceiptRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketReceiptResponse defines the client query response for a packet +// receipt which also includes a proof, and the height from which the proof was +// retrieved +message QueryPacketReceiptResponse { + // success flag for if receipt exists + bool received = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryPacketAcknowledgementRequest is the request type for the +// Query/PacketAcknowledgement RPC method +message QueryPacketAcknowledgementRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketAcknowledgementResponse defines the client query response for a +// packet which also includes a proof and the height from which the +// proof was retrieved +message QueryPacketAcknowledgementResponse { + // packet associated with the request fields + bytes acknowledgement = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketAcknowledgementsRequest is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketAcknowledgementsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 3; + // list of packet sequences + repeated uint64 packet_commitment_sequences = 4; +} + +// QueryPacketAcknowledgemetsResponse is the request type for the +// Query/QueryPacketAcknowledgements RPC method +message QueryPacketAcknowledgementsResponse { + repeated ibc.core.channel.v1.PacketState acknowledgements = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUnreceivedPacketsRequest is the request type for the +// Query/UnreceivedPackets RPC method +message QueryUnreceivedPacketsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // list of packet sequences + repeated uint64 packet_commitment_sequences = 3; +} + +// QueryUnreceivedPacketsResponse is the response type for the +// Query/UnreceivedPacketCommitments RPC method +message QueryUnreceivedPacketsResponse { + // list of unreceived packet sequences + repeated uint64 sequences = 1; + // query block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} + +// QueryUnreceivedAcks is the request type for the +// Query/UnreceivedAcks RPC method +message QueryUnreceivedAcksRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // list of acknowledgement sequences + repeated uint64 packet_ack_sequences = 3; +} + +// QueryUnreceivedAcksResponse is the response type for the +// Query/UnreceivedAcks RPC method +message QueryUnreceivedAcksResponse { + // list of unreceived acknowledgement sequences + repeated uint64 sequences = 1; + // query block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} + +// QueryNextSequenceReceiveRequest is the request type for the +// Query/QueryNextSequenceReceiveRequest RPC method +message QueryNextSequenceReceiveRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QuerySequenceResponse is the request type for the +// Query/QueryNextSequenceReceiveResponse RPC method +message QueryNextSequenceReceiveResponse { + // next sequence receive number + uint64 next_sequence_receive = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/tx.proto b/ampd/proto/third_party/ibc/core/channel/v1/tx.proto new file mode 100644 index 000000000..75248aeb5 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/tx.proto @@ -0,0 +1,245 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Msg defines the ibc/channel Msg service. +service Msg { + // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. + rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse); + + // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. + rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse); + + // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. + rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse); + + // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. + rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse); + + // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. + rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse); + + // ChannelCloseConfirm defines a rpc handler method for + // MsgChannelCloseConfirm. + rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse); + + // RecvPacket defines a rpc handler method for MsgRecvPacket. + rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse); + + // Timeout defines a rpc handler method for MsgTimeout. + rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse); + + // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. + rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse); + + // Acknowledgement defines a rpc handler method for MsgAcknowledgement. + rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); +} + +// ResponseResultType defines the possible outcomes of the execution of a message +enum ResponseResultType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default zero value enumeration + RESPONSE_RESULT_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) + RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; + // The message was executed successfully + RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; +} + +// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It +// is called by a relayer on Chain A. +message MsgChannelOpenInit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + Channel channel = 2 [(gogoproto.nullable) = false]; + string signer = 3; +} + +// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. +message MsgChannelOpenInitResponse { + string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string version = 2; +} + +// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel +// on Chain B. The version field within the Channel field has been deprecated. Its +// value will be ignored by core IBC. +message MsgChannelOpenTry { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. + string previous_channel_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_channel_id\""]; + // NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. + Channel channel = 3 [(gogoproto.nullable) = false]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 6 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. +message MsgChannelOpenTryResponse { + string version = 1; +} + +// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge +// the change of channel state to TRYOPEN on Chain B. +message MsgChannelOpenAck { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_try = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""]; + ibc.core.client.v1.Height proof_height = 6 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. +message MsgChannelOpenAckResponse {} + +// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to +// acknowledge the change of channel state to OPEN on Chain A. +message MsgChannelOpenConfirm { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + bytes proof_ack = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response +// type. +message MsgChannelOpenConfirmResponse {} + +// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A +// to close a channel with Chain B. +message MsgChannelCloseInit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string signer = 3; +} + +// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type. +message MsgChannelCloseInitResponse {} + +// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B +// to acknowledge the change of channel state to CLOSED on Chain A. +message MsgChannelCloseConfirm { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + bytes proof_init = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response +// type. +message MsgChannelCloseConfirmResponse {} + +// MsgRecvPacket receives incoming IBC packet +message MsgRecvPacket { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; + ibc.core.client.v1.Height proof_height = 3 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgRecvPacketResponse defines the Msg/RecvPacket response type. +message MsgRecvPacketResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgTimeout receives timed-out packet +message MsgTimeout { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + ibc.core.client.v1.Height proof_height = 3 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; + string signer = 5; +} + +// MsgTimeoutResponse defines the Msg/Timeout response type. +message MsgTimeoutResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgTimeoutOnClose timed-out packet upon counterparty channel closure. +message MsgTimeoutOnClose { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; + string signer = 6; +} + +// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. +message MsgTimeoutOnCloseResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgAcknowledgement receives incoming IBC acknowledgement +message MsgAcknowledgement { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes acknowledgement = 2; + bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. +message MsgAcknowledgementResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/client.proto b/ampd/proto/third_party/ibc/core/client/v1/client.proto new file mode 100644 index 000000000..2ec41ed0c --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/client.proto @@ -0,0 +1,103 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; +import "cosmos_proto/cosmos.proto"; + +// IdentifiedClientState defines a client state with an additional client +// identifier field. +message IdentifiedClientState { + // client identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // client state + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; +} + +// ConsensusStateWithHeight defines a consensus state with an additional height +// field. +message ConsensusStateWithHeight { + // consensus state height + Height height = 1 [(gogoproto.nullable) = false]; + // consensus state + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ClientConsensusStates defines all the stored consensus states for a given +// client. +message ClientConsensusStates { + // client identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // consensus states and their heights associated with the client + repeated ConsensusStateWithHeight consensus_states = 2 + [(gogoproto.moretags) = "yaml:\"consensus_states\"", (gogoproto.nullable) = false]; +} + +// ClientUpdateProposal is a governance proposal. If it passes, the substitute +// client's latest consensus state is copied over to the subject client. The proposal +// handler may fail if the subject and the substitute do not match in client and +// chain parameters (with exception to latest height, frozen height, and chain-id). +message ClientUpdateProposal { + option (gogoproto.goproto_getters) = false; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // the title of the update proposal + string title = 1; + // the description of the proposal + string description = 2; + // the client identifier for the client to be updated if the proposal passes + string subject_client_id = 3 [(gogoproto.moretags) = "yaml:\"subject_client_id\""]; + // the substitute client identifier for the client standing in for the subject + // client + string substitute_client_id = 4 [(gogoproto.moretags) = "yaml:\"substitute_client_id\""]; +} + +// UpgradeProposal is a gov Content type for initiating an IBC breaking +// upgrade. +message UpgradeProposal { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = true; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + string title = 1; + string description = 2; + cosmos.upgrade.v1beta1.Plan plan = 3 [(gogoproto.nullable) = false]; + + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state + // before the upgrade occurs, so that connecting chains can verify that the + // new upgraded client is valid by verifying a proof on the previous version + // of the chain. This will allow IBC connections to persist smoothly across + // planned chain upgrades + google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} + +// Height is a monotonically increasing data type +// that can be compared against another Height for the purposes of updating and +// freezing clients +// +// Normally the RevisionHeight is incremented at each height while keeping +// RevisionNumber the same. However some consensus algorithms may choose to +// reset the height in certain conditions e.g. hard forks, state-machine +// breaking changes In these cases, the RevisionNumber is incremented so that +// height continues to be monitonically increasing even as the RevisionHeight +// gets reset +message Height { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // the revision that the client is currently on + uint64 revision_number = 1 [(gogoproto.moretags) = "yaml:\"revision_number\""]; + // the height within the given revision + uint64 revision_height = 2 [(gogoproto.moretags) = "yaml:\"revision_height\""]; +} + +// Params defines the set of IBC light client parameters. +message Params { + // allowed_clients defines the list of allowed client state types. + repeated string allowed_clients = 1 [(gogoproto.moretags) = "yaml:\"allowed_clients\""]; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/genesis.proto b/ampd/proto/third_party/ibc/core/client/v1/genesis.proto new file mode 100644 index 000000000..b2930c484 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/genesis.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "ibc/core/client/v1/client.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the ibc client submodule's genesis state. +message GenesisState { + // client states with their corresponding identifiers + repeated IdentifiedClientState clients = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; + // consensus states from each client + repeated ClientConsensusStates clients_consensus = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "ClientsConsensusStates", + (gogoproto.moretags) = "yaml:\"clients_consensus\"" + ]; + // metadata from each client + repeated IdentifiedGenesisMetadata clients_metadata = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"clients_metadata\""]; + Params params = 4 [(gogoproto.nullable) = false]; + // create localhost on initialization + bool create_localhost = 5 [(gogoproto.moretags) = "yaml:\"create_localhost\""]; + // the sequence for the next generated client identifier + uint64 next_client_sequence = 6 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""]; +} + +// GenesisMetadata defines the genesis type for metadata that clients may return +// with ExportMetadata +message GenesisMetadata { + option (gogoproto.goproto_getters) = false; + + // store key of metadata without clientID-prefix + bytes key = 1; + // metadata value + bytes value = 2; +} + +// IdentifiedGenesisMetadata has the client metadata with the corresponding +// client id. +message IdentifiedGenesisMetadata { + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + repeated GenesisMetadata client_metadata = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_metadata\""]; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/query.proto b/ampd/proto/third_party/ibc/core/client/v1/query.proto new file mode 100644 index 000000000..2c9618bc8 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/query.proto @@ -0,0 +1,207 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/client/v1/client.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; + +// Query provides defines the gRPC querier service +service Query { + // ClientState queries an IBC light client. + rpc ClientState(QueryClientStateRequest) returns (QueryClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_states/{client_id}"; + } + + // ClientStates queries all the IBC light clients of a chain. + rpc ClientStates(QueryClientStatesRequest) returns (QueryClientStatesResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_states"; + } + + // ConsensusState queries a consensus state associated with a client state at + // a given height. + rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/" + "{client_id}/revision/{revision_number}/" + "height/{revision_height}"; + } + + // ConsensusStates queries all the consensus state associated with a given + // client. + rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}"; + } + + // ConsensusStateHeights queries the height of every consensus states associated with a given client. + rpc ConsensusStateHeights(QueryConsensusStateHeightsRequest) returns (QueryConsensusStateHeightsResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}/heights"; + } + + // Status queries the status of an IBC client. + rpc ClientStatus(QueryClientStatusRequest) returns (QueryClientStatusResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; + } + + // ClientParams queries all parameters of the ibc client. + rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { + option (google.api.http).get = "/ibc/client/v1/params"; + } + + // UpgradedClientState queries an Upgraded IBC light client. + rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states"; + } + + // UpgradedConsensusState queries an Upgraded IBC consensus state. + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_consensus_states"; + } +} + +// QueryClientStateRequest is the request type for the Query/ClientState RPC +// method +message QueryClientStateRequest { + // client state unique identifier + string client_id = 1; +} + +// QueryClientStateResponse is the response type for the Query/ClientState RPC +// method. Besides the client state, it includes a proof and the height from +// which the proof was retrieved. +message QueryClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryClientStatesRequest is the request type for the Query/ClientStates RPC +// method +message QueryClientStatesRequest { + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryClientStatesResponse is the response type for the Query/ClientStates RPC +// method. +message QueryClientStatesResponse { + // list of stored ClientStates of the chain. + repeated IdentifiedClientState client_states = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryConsensusStateRequest is the request type for the Query/ConsensusState +// RPC method. Besides the consensus state, it includes a proof and the height +// from which the proof was retrieved. +message QueryConsensusStateRequest { + // client identifier + string client_id = 1; + // consensus state revision number + uint64 revision_number = 2; + // consensus state revision height + uint64 revision_height = 3; + // latest_height overrrides the height field and queries the latest stored + // ConsensusState + bool latest_height = 4; +} + +// QueryConsensusStateResponse is the response type for the Query/ConsensusState +// RPC method +message QueryConsensusStateResponse { + // consensus state associated with the client identifier at the given height + google.protobuf.Any consensus_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConsensusStatesRequest is the request type for the Query/ConsensusStates +// RPC method. +message QueryConsensusStatesRequest { + // client identifier + string client_id = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConsensusStatesResponse is the response type for the +// Query/ConsensusStates RPC method +message QueryConsensusStatesResponse { + // consensus states associated with the identifier + repeated ConsensusStateWithHeight consensus_states = 1 [(gogoproto.nullable) = false]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights +// RPC method. +message QueryConsensusStateHeightsRequest { + // client identifier + string client_id = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConsensusStateHeightsResponse is the response type for the +// Query/ConsensusStateHeights RPC method +message QueryConsensusStateHeightsResponse { + // consensus state heights + repeated Height consensus_state_heights = 1 [(gogoproto.nullable) = false]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC +// method +message QueryClientStatusRequest { + // client unique identifier + string client_id = 1; +} + +// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC +// method. It returns the current status of the IBC client. +message QueryClientStatusResponse { + string status = 1; +} + +// QueryClientParamsRequest is the request type for the Query/ClientParams RPC +// method. +message QueryClientParamsRequest {} + +// QueryClientParamsResponse is the response type for the Query/ClientParams RPC +// method. +message QueryClientParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +// QueryUpgradedClientStateRequest is the request type for the +// Query/UpgradedClientState RPC method +message QueryUpgradedClientStateRequest {} + +// QueryUpgradedClientStateResponse is the response type for the +// Query/UpgradedClientState RPC method. +message QueryUpgradedClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any upgraded_client_state = 1; +} + +// QueryUpgradedConsensusStateRequest is the request type for the +// Query/UpgradedConsensusState RPC method +message QueryUpgradedConsensusStateRequest {} + +// QueryUpgradedConsensusStateResponse is the response type for the +// Query/UpgradedConsensusState RPC method. +message QueryUpgradedConsensusStateResponse { + // Consensus state associated with the request identifier + google.protobuf.Any upgraded_consensus_state = 1; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/tx.proto b/ampd/proto/third_party/ibc/core/client/v1/tx.proto new file mode 100644 index 000000000..11dfdadea --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/tx.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// Msg defines the ibc/client Msg service. +service Msg { + // CreateClient defines a rpc handler method for MsgCreateClient. + rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); + + // UpdateClient defines a rpc handler method for MsgUpdateClient. + rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse); + + // UpgradeClient defines a rpc handler method for MsgUpgradeClient. + rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse); + + // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. + rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); +} + +// MsgCreateClient defines a message to create an IBC client +message MsgCreateClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // light client state + google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""]; + // consensus state associated with the client that corresponds to a given + // height. + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // signer address + string signer = 3; +} + +// MsgCreateClientResponse defines the Msg/CreateClient response type. +message MsgCreateClientResponse {} + +// MsgUpdateClient defines an sdk.Msg to update a IBC client state using +// the given header. +message MsgUpdateClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // header to update the light client + google.protobuf.Any header = 2; + // signer address + string signer = 3; +} + +// MsgUpdateClientResponse defines the Msg/UpdateClient response type. +message MsgUpdateClientResponse {} + +// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client +// state +message MsgUpgradeClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // upgraded client state + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; + // upgraded consensus state, only contains enough information to serve as a + // basis of trust in update logic + google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // proof that old chain committed to new client + bytes proof_upgrade_client = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade_client\""]; + // proof that old chain committed to new consensus state + bytes proof_upgrade_consensus_state = 5 [(gogoproto.moretags) = "yaml:\"proof_upgrade_consensus_state\""]; + // signer address + string signer = 6; +} + +// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. +message MsgUpgradeClientResponse {} + +// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for +// light client misbehaviour. +message MsgSubmitMisbehaviour { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // misbehaviour used for freezing the light client + google.protobuf.Any misbehaviour = 2; + // signer address + string signer = 3; +} + +// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response +// type. +message MsgSubmitMisbehaviourResponse {} diff --git a/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto b/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto new file mode 100644 index 000000000..b6a68a99f --- /dev/null +++ b/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +package ibc.core.commitment.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types"; + +import "gogoproto/gogo.proto"; +import "proofs.proto"; + +// MerkleRoot defines a merkle root hash. +// In the Cosmos SDK, the AppHash of a block header becomes the root. +message MerkleRoot { + option (gogoproto.goproto_getters) = false; + + bytes hash = 1; +} + +// MerklePrefix is merkle path prefixed to the key. +// The constructed key from the Path and the key will be append(Path.KeyPath, +// append(Path.KeyPrefix, key...)) +message MerklePrefix { + bytes key_prefix = 1 [(gogoproto.moretags) = "yaml:\"key_prefix\""]; +} + +// MerklePath is the path used to verify commitment proofs, which can be an +// arbitrary structured object (defined by a commitment type). +// MerklePath is represented from root-to-leaf +message MerklePath { + option (gogoproto.goproto_stringer) = false; + + repeated string key_path = 1 [(gogoproto.moretags) = "yaml:\"key_path\""]; +} + +// MerkleProof is a wrapper type over a chain of CommitmentProofs. +// It demonstrates membership or non-membership for an element or set of +// elements, verifiable in conjunction with a known commitment root. Proofs +// should be succinct. +// MerkleProofs are ordered from leaf-to-root +message MerkleProof { + repeated ics23.CommitmentProof proofs = 1; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/connection.proto b/ampd/proto/third_party/ibc/core/connection/v1/connection.proto new file mode 100644 index 000000000..8360af988 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/connection.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/commitment/v1/commitment.proto"; + +// ICS03 - Connection Data Structures as defined in +// https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#data-structures + +// ConnectionEnd defines a stateful object on a chain connected to another +// separate one. +// NOTE: there must only be 2 defined ConnectionEnds to establish +// a connection between two chains. +message ConnectionEnd { + option (gogoproto.goproto_getters) = false; + // client associated with this connection. + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // IBC version which can be utilised to determine encodings or protocols for + // channels or packets utilising this connection. + repeated Version versions = 2; + // current state of the connection end. + State state = 3; + // counterparty chain associated with this connection. + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + // delay period that must pass before a consensus state can be used for + // packet-verification NOTE: delay period logic is only implemented by some + // clients. + uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; +} + +// IdentifiedConnection defines a connection with additional connection +// identifier field. +message IdentifiedConnection { + option (gogoproto.goproto_getters) = false; + // connection identifier. + string id = 1 [(gogoproto.moretags) = "yaml:\"id\""]; + // client associated with this connection. + string client_id = 2 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // IBC version which can be utilised to determine encodings or protocols for + // channels or packets utilising this connection + repeated Version versions = 3; + // current state of the connection end. + State state = 4; + // counterparty chain associated with this connection. + Counterparty counterparty = 5 [(gogoproto.nullable) = false]; + // delay period associated with this connection. + uint64 delay_period = 6 [(gogoproto.moretags) = "yaml:\"delay_period\""]; +} + +// State defines if a connection is in one of the following states: +// INIT, TRYOPEN, OPEN or UNINITIALIZED. +enum State { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; + // A connection end has just started the opening handshake. + STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; + // A connection end has acknowledged the handshake step on the counterparty + // chain. + STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; + // A connection end has completed the handshake. + STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; +} + +// Counterparty defines the counterparty chain associated with a connection end. +message Counterparty { + option (gogoproto.goproto_getters) = false; + + // identifies the client on the counterparty chain associated with a given + // connection. + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // identifies the connection end on the counterparty chain associated with a + // given connection. + string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + // commitment merkle prefix of the counterparty chain. + ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; +} + +// ClientPaths define all the connection paths for a client state. +message ClientPaths { + // list of connection paths + repeated string paths = 1; +} + +// ConnectionPaths define all the connection paths for a given client state. +message ConnectionPaths { + // client state unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // list of connection paths + repeated string paths = 2; +} + +// Version defines the versioning scheme used to negotiate the IBC verison in +// the connection handshake. +message Version { + option (gogoproto.goproto_getters) = false; + + // unique version identifier + string identifier = 1; + // list of features compatible with the specified identifier + repeated string features = 2; +} + +// Params defines the set of Connection parameters. +message Params { + // maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the + // largest amount of time that the chain might reasonably take to produce the next block under normal operating + // conditions. A safe choice is 3-5x the expected time per block. + uint64 max_expected_time_per_block = 1 [(gogoproto.moretags) = "yaml:\"max_expected_time_per_block\""]; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto b/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto new file mode 100644 index 000000000..f616ae67e --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/connection/v1/connection.proto"; + +// GenesisState defines the ibc connection submodule's genesis state. +message GenesisState { + repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; + repeated ConnectionPaths client_connection_paths = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; + // the sequence for the next generated connection identifier + uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; + Params params = 4 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/query.proto b/ampd/proto/third_party/ibc/core/connection/v1/query.proto new file mode 100644 index 000000000..129f30a71 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/query.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/connection/v1/connection.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; + +// Query provides defines the gRPC querier service +service Query { + // Connection queries an IBC connection end. + rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}"; + } + + // Connections queries all the IBC connections of a chain. + rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections"; + } + + // ClientConnections queries the connection paths associated with a client + // state. + rpc ClientConnections(QueryClientConnectionsRequest) returns (QueryClientConnectionsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/client_connections/{client_id}"; + } + + // ConnectionClientState queries the client state associated with the + // connection. + rpc ConnectionClientState(QueryConnectionClientStateRequest) returns (QueryConnectionClientStateResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/client_state"; + } + + // ConnectionConsensusState queries the consensus state associated with the + // connection. + rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/consensus_state/" + "revision/{revision_number}/height/{revision_height}"; + } +} + +// QueryConnectionRequest is the request type for the Query/Connection RPC +// method +message QueryConnectionRequest { + // connection unique identifier + string connection_id = 1; +} + +// QueryConnectionResponse is the response type for the Query/Connection RPC +// method. Besides the connection end, it includes a proof and the height from +// which the proof was retrieved. +message QueryConnectionResponse { + // connection associated with the request identifier + ibc.core.connection.v1.ConnectionEnd connection = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionsRequest is the request type for the Query/Connections RPC +// method +message QueryConnectionsRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryConnectionsResponse is the response type for the Query/Connections RPC +// method. +message QueryConnectionsResponse { + // list of stored connections of the chain. + repeated ibc.core.connection.v1.IdentifiedConnection connections = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryClientConnectionsRequest is the request type for the +// Query/ClientConnections RPC method +message QueryClientConnectionsRequest { + // client identifier associated with a connection + string client_id = 1; +} + +// QueryClientConnectionsResponse is the response type for the +// Query/ClientConnections RPC method +message QueryClientConnectionsResponse { + // slice of all the connection paths associated with a client. + repeated string connection_paths = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was generated + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionClientStateRequest is the request type for the +// Query/ConnectionClientState RPC method +message QueryConnectionClientStateRequest { + // connection identifier + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; +} + +// QueryConnectionClientStateResponse is the response type for the +// Query/ConnectionClientState RPC method +message QueryConnectionClientStateResponse { + // client state associated with the channel + ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionConsensusStateRequest is the request type for the +// Query/ConnectionConsensusState RPC method +message QueryConnectionConsensusStateRequest { + // connection identifier + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + uint64 revision_number = 2; + uint64 revision_height = 3; +} + +// QueryConnectionConsensusStateResponse is the response type for the +// Query/ConnectionConsensusState RPC method +message QueryConnectionConsensusStateResponse { + // consensus state associated with the channel + google.protobuf.Any consensus_state = 1; + // client ID associated with the consensus state + string client_id = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/tx.proto b/ampd/proto/third_party/ibc/core/connection/v1/tx.proto new file mode 100644 index 000000000..b2fea632c --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/tx.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/connection/v1/connection.proto"; + +// Msg defines the ibc/connection Msg service. +service Msg { + // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. + rpc ConnectionOpenInit(MsgConnectionOpenInit) returns (MsgConnectionOpenInitResponse); + + // ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry. + rpc ConnectionOpenTry(MsgConnectionOpenTry) returns (MsgConnectionOpenTryResponse); + + // ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck. + rpc ConnectionOpenAck(MsgConnectionOpenAck) returns (MsgConnectionOpenAckResponse); + + // ConnectionOpenConfirm defines a rpc handler method for + // MsgConnectionOpenConfirm. + rpc ConnectionOpenConfirm(MsgConnectionOpenConfirm) returns (MsgConnectionOpenConfirmResponse); +} + +// MsgConnectionOpenInit defines the msg sent by an account on Chain A to +// initialize a connection with Chain B. +message MsgConnectionOpenInit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + Version version = 3; + uint64 delay_period = 4 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + string signer = 5; +} + +// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response +// type. +message MsgConnectionOpenInitResponse {} + +// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a +// connection on Chain B. +message MsgConnectionOpenTry { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. + string previous_connection_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_connection_id\""]; + google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; + ibc.core.client.v1.Height proof_height = 7 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + // proof of the initialization the connection on Chain A: `UNITIALIZED -> + // INIT` + bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + // proof of client state included in message + bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + // proof of client consensus state + bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 11 + [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; + string signer = 12; +} + +// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. +message MsgConnectionOpenTryResponse {} + +// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to +// acknowledge the change of connection state to TRYOPEN on Chain B. +message MsgConnectionOpenAck { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string counterparty_connection_id = 2 [(gogoproto.moretags) = "yaml:\"counterparty_connection_id\""]; + Version version = 3; + google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; + ibc.core.client.v1.Height proof_height = 5 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + // proof of the initialization the connection on Chain B: `UNITIALIZED -> + // TRYOPEN` + bytes proof_try = 6 [(gogoproto.moretags) = "yaml:\"proof_try\""]; + // proof of client state included in message + bytes proof_client = 7 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + // proof of client consensus state + bytes proof_consensus = 8 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 9 + [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; + string signer = 10; +} + +// MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. +message MsgConnectionOpenAckResponse {} + +// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to +// acknowledge the change of connection state to OPEN on Chain A. +message MsgConnectionOpenConfirm { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + // proof for the change of the connection state on Chain A: `INIT -> OPEN` + bytes proof_ack = 2 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; + ibc.core.client.v1.Height proof_height = 3 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm +// response type. +message MsgConnectionOpenConfirmResponse {} diff --git a/ampd/proto/third_party/ibc/core/types/v1/genesis.proto b/ampd/proto/third_party/ibc/core/types/v1/genesis.proto new file mode 100644 index 000000000..4cc931d32 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/types/v1/genesis.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package ibc.core.types.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/genesis.proto"; +import "ibc/core/connection/v1/genesis.proto"; +import "ibc/core/channel/v1/genesis.proto"; + +// GenesisState defines the ibc module's genesis state. +message GenesisState { + // ICS002 - Clients genesis state + ibc.core.client.v1.GenesisState client_genesis = 1 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_genesis\""]; + // ICS003 - Connections genesis state + ibc.core.connection.v1.GenesisState connection_genesis = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"connection_genesis\""]; + // ICS004 - Channel genesis state + ibc.core.channel.v1.GenesisState channel_genesis = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"channel_genesis\""]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto b/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto new file mode 100644 index 000000000..9eda835eb --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package ibc.lightclients.localhost.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +// ClientState defines a loopback (localhost) client. It requires (read-only) +// access to keys outside the client prefix. +message ClientState { + option (gogoproto.goproto_getters) = false; + // self chain ID + string chain_id = 1 [(gogoproto.moretags) = "yaml:\"chain_id\""]; + // self latest block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto b/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto new file mode 100644 index 000000000..37bd81e92 --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto @@ -0,0 +1,189 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100"; + +import "ibc/core/connection/v1/connection.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + uint64 frozen_sequence = 2 [(gogoproto.moretags) = "yaml:\"frozen_sequence\""]; + ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // when set to true, will allow governance to update a solo machine client. + // The client will be unfrozen if it is frozen. + bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + // sequence to update solo machine public key at + uint64 sequence = 1; + uint64 timestamp = 2; + bytes signature = 3; + google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; + string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + bytes signature = 1; + DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + uint64 timestamp = 2; + string diversifier = 3; + // type of the data used + DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; + // marshaled data + bytes data = 5; +} + +// DataType defines the type of solo machine proof being created. This is done +// to preserve uniqueness of different data sign byte encodings. +enum DataType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // Data type for client state verification + DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; + // Data type for consensus state verification + DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; + // Data type for connection state verification + DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; + // Data type for channel state verification + DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; + // Data type for packet commitment verification + DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; + // Data type for packet acknowledgement verification + DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; + // Data type for packet receipt absence verification + DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; + // Data type for next sequence recv verification + DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; + // Data type for header verification + DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + // header diversifier + string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// ClientStateData returns the SignBytes data for client state verification. +message ClientStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; +} + +// ConsensusStateData returns the SignBytes data for consensus state +// verification. +message ConsensusStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ConnectionStateData returns the SignBytes data for connection state +// verification. +message ConnectionStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.connection.v1.ConnectionEnd connection = 2; +} + +// ChannelStateData returns the SignBytes data for channel state +// verification. +message ChannelStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.channel.v1.Channel channel = 2; +} + +// PacketCommitmentData returns the SignBytes data for packet commitment +// verification. +message PacketCommitmentData { + bytes path = 1; + bytes commitment = 2; +} + +// PacketAcknowledgementData returns the SignBytes data for acknowledgement +// verification. +message PacketAcknowledgementData { + bytes path = 1; + bytes acknowledgement = 2; +} + +// PacketReceiptAbsenceData returns the SignBytes data for +// packet receipt absence verification. +message PacketReceiptAbsenceData { + bytes path = 1; +} + +// NextSequenceRecvData returns the SignBytes data for verification of the next +// sequence to be received. +message NextSequenceRecvData { + bytes path = 1; + uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto b/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto new file mode 100644 index 000000000..c735fdddd --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto @@ -0,0 +1,189 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v2; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types"; + +import "ibc/core/connection/v1/connection.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; + ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // when set to true, will allow governance to update a solo machine client. + // The client will be unfrozen if it is frozen. + bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + // sequence to update solo machine public key at + uint64 sequence = 1; + uint64 timestamp = 2; + bytes signature = 3; + google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; + string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + bytes signature = 1; + DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + uint64 timestamp = 2; + string diversifier = 3; + // type of the data used + DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; + // marshaled data + bytes data = 5; +} + +// DataType defines the type of solo machine proof being created. This is done +// to preserve uniqueness of different data sign byte encodings. +enum DataType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // Data type for client state verification + DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; + // Data type for consensus state verification + DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; + // Data type for connection state verification + DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; + // Data type for channel state verification + DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; + // Data type for packet commitment verification + DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; + // Data type for packet acknowledgement verification + DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; + // Data type for packet receipt absence verification + DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; + // Data type for next sequence recv verification + DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; + // Data type for header verification + DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + // header diversifier + string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// ClientStateData returns the SignBytes data for client state verification. +message ClientStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; +} + +// ConsensusStateData returns the SignBytes data for consensus state +// verification. +message ConsensusStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ConnectionStateData returns the SignBytes data for connection state +// verification. +message ConnectionStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.connection.v1.ConnectionEnd connection = 2; +} + +// ChannelStateData returns the SignBytes data for channel state +// verification. +message ChannelStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.channel.v1.Channel channel = 2; +} + +// PacketCommitmentData returns the SignBytes data for packet commitment +// verification. +message PacketCommitmentData { + bytes path = 1; + bytes commitment = 2; +} + +// PacketAcknowledgementData returns the SignBytes data for acknowledgement +// verification. +message PacketAcknowledgementData { + bytes path = 1; + bytes acknowledgement = 2; +} + +// PacketReceiptAbsenceData returns the SignBytes data for +// packet receipt absence verification. +message PacketReceiptAbsenceData { + bytes path = 1; +} + +// NextSequenceRecvData returns the SignBytes data for verification of the next +// sequence to be received. +message NextSequenceRecvData { + bytes path = 1; + uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto b/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto new file mode 100644 index 000000000..55a4e0690 --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package ibc.lightclients.tendermint.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types"; + +import "tendermint/types/validator.proto"; +import "tendermint/types/types.proto"; +import "proofs.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/commitment/v1/commitment.proto"; +import "gogoproto/gogo.proto"; + +// ClientState from Tendermint tracks the current validator set, latest height, +// and a possible frozen height. +message ClientState { + option (gogoproto.goproto_getters) = false; + + string chain_id = 1; + Fraction trust_level = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trust_level\""]; + // duration of the period since the LastestTimestamp during which the + // submitted headers are valid for upgrade + google.protobuf.Duration trusting_period = 3 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"trusting_period\""]; + // duration of the staking unbonding period + google.protobuf.Duration unbonding_period = 4 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.moretags) = "yaml:\"unbonding_period\"" + ]; + // defines how much new (untrusted) header's Time can drift into the future. + google.protobuf.Duration max_clock_drift = 5 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"max_clock_drift\""]; + // Block height when the client was frozen due to a misbehaviour + ibc.core.client.v1.Height frozen_height = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"frozen_height\""]; + // Latest height the client was updated to + ibc.core.client.v1.Height latest_height = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"latest_height\""]; + + // Proof specifications used in verifying counterparty state + repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; + + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the + // chained proof. NOTE: ClientState must stored under + // `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored + // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using + // the default upgrade module, upgrade_path should be []string{"upgrade", + // "upgradedIBCState"}` + repeated string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; + + // allow_update_after_expiry is deprecated + bool allow_update_after_expiry = 10 [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_expiry\""]; + // allow_update_after_misbehaviour is deprecated + bool allow_update_after_misbehaviour = 11 + [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_misbehaviour\""]; +} + +// ConsensusState defines the consensus state from Tendermint. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + + // timestamp that corresponds to the block height in which the ConsensusState + // was stored. + google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + // commitment root (i.e app hash) + ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; + bytes next_validators_hash = 3 [ + (gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes", + (gogoproto.moretags) = "yaml:\"next_validators_hash\"" + ]; +} + +// Misbehaviour is a wrapper over two conflicting Headers +// that implements Misbehaviour interface expected by ICS-02 +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; + Header header_2 = 3 [(gogoproto.customname) = "Header2", (gogoproto.moretags) = "yaml:\"header_2\""]; +} + +// Header defines the Tendermint client consensus Header. +// It encapsulates all the information necessary to update from a trusted +// Tendermint ConsensusState. The inclusion of TrustedHeight and +// TrustedValidators allows this update to process correctly, so long as the +// ConsensusState for the TrustedHeight exists, this removes race conditions +// among relayers The SignedHeader and ValidatorSet are the new untrusted update +// fields for the client. The TrustedHeight is the height of a stored +// ConsensusState on the client that will be used to verify the new untrusted +// header. The Trusted ConsensusState must be within the unbonding period of +// current time in order to correctly verify, and the TrustedValidators must +// hash to TrustedConsensusState.NextValidatorsHash since that is the last +// trusted validator set at the TrustedHeight. +message Header { + .tendermint.types.SignedHeader signed_header = 1 + [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"signed_header\""]; + + .tendermint.types.ValidatorSet validator_set = 2 [(gogoproto.moretags) = "yaml:\"validator_set\""]; + ibc.core.client.v1.Height trusted_height = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trusted_height\""]; + .tendermint.types.ValidatorSet trusted_validators = 4 [(gogoproto.moretags) = "yaml:\"trusted_validators\""]; +} + +// Fraction defines the protobuf message type for tmmath.Fraction that only +// supports positive values. +message Fraction { + uint64 numerator = 1; + uint64 denominator = 2; +} diff --git a/ampd/proto/third_party/proofs.proto b/ampd/proto/third_party/proofs.proto new file mode 100644 index 000000000..88b50c1b3 --- /dev/null +++ b/ampd/proto/third_party/proofs.proto @@ -0,0 +1,234 @@ +syntax = "proto3"; + +package ics23; +option go_package = "github.com/confio/ics23/go"; +enum HashOp { + // NO_HASH is the default if no data passed. Note this is an illegal argument some places. + NO_HASH = 0; + SHA256 = 1; + SHA512 = 2; + KECCAK = 3; + RIPEMD160 = 4; + BITCOIN = 5; // ripemd160(sha256(x)) + SHA512_256 = 6; +} + +/** +LengthOp defines how to process the key and value of the LeafOp +to include length information. After encoding the length with the given +algorithm, the length will be prepended to the key and value bytes. +(Each one with it's own encoded length) +*/ +enum LengthOp { + // NO_PREFIX don't include any length info + NO_PREFIX = 0; + // VAR_PROTO uses protobuf (and go-amino) varint encoding of the length + VAR_PROTO = 1; + // VAR_RLP uses rlp int encoding of the length + VAR_RLP = 2; + // FIXED32_BIG uses big-endian encoding of the length as a 32 bit integer + FIXED32_BIG = 3; + // FIXED32_LITTLE uses little-endian encoding of the length as a 32 bit integer + FIXED32_LITTLE = 4; + // FIXED64_BIG uses big-endian encoding of the length as a 64 bit integer + FIXED64_BIG = 5; + // FIXED64_LITTLE uses little-endian encoding of the length as a 64 bit integer + FIXED64_LITTLE = 6; + // REQUIRE_32_BYTES is like NONE, but will fail if the input is not exactly 32 bytes (sha256 output) + REQUIRE_32_BYTES = 7; + // REQUIRE_64_BYTES is like NONE, but will fail if the input is not exactly 64 bytes (sha512 output) + REQUIRE_64_BYTES = 8; +} + +/** +ExistenceProof takes a key and a value and a set of steps to perform on it. +The result of peforming all these steps will provide a "root hash", which can +be compared to the value in a header. + +Since it is computationally infeasible to produce a hash collission for any of the used +cryptographic hash functions, if someone can provide a series of operations to transform +a given key and value into a root hash that matches some trusted root, these key and values +must be in the referenced merkle tree. + +The only possible issue is maliablity in LeafOp, such as providing extra prefix data, +which should be controlled by a spec. Eg. with lengthOp as NONE, + prefix = FOO, key = BAR, value = CHOICE +and + prefix = F, key = OOBAR, value = CHOICE +would produce the same value. + +With LengthOp this is tricker but not impossible. Which is why the "leafPrefixEqual" field +in the ProofSpec is valuable to prevent this mutability. And why all trees should +length-prefix the data before hashing it. +*/ +message ExistenceProof { + bytes key = 1; + bytes value = 2; + LeafOp leaf = 3; + repeated InnerOp path = 4; +} + +/* +NonExistenceProof takes a proof of two neighbors, one left of the desired key, +one right of the desired key. If both proofs are valid AND they are neighbors, +then there is no valid proof for the given key. +*/ +message NonExistenceProof { + bytes key = 1; // TODO: remove this as unnecessary??? we prove a range + ExistenceProof left = 2; + ExistenceProof right = 3; +} + +/* +CommitmentProof is either an ExistenceProof or a NonExistenceProof, or a Batch of such messages +*/ +message CommitmentProof { + oneof proof { + ExistenceProof exist = 1; + NonExistenceProof nonexist = 2; + BatchProof batch = 3; + CompressedBatchProof compressed = 4; + } +} + +/** +LeafOp represents the raw key-value data we wish to prove, and +must be flexible to represent the internal transformation from +the original key-value pairs into the basis hash, for many existing +merkle trees. + +key and value are passed in. So that the signature of this operation is: + leafOp(key, value) -> output + +To process this, first prehash the keys and values if needed (ANY means no hash in this case): + hkey = prehashKey(key) + hvalue = prehashValue(value) + +Then combine the bytes, and hash it + output = hash(prefix || length(hkey) || hkey || length(hvalue) || hvalue) +*/ +message LeafOp { + HashOp hash = 1; + HashOp prehash_key = 2; + HashOp prehash_value = 3; + LengthOp length = 4; + // prefix is a fixed bytes that may optionally be included at the beginning to differentiate + // a leaf node from an inner node. + bytes prefix = 5; +} + +/** +InnerOp represents a merkle-proof step that is not a leaf. +It represents concatenating two children and hashing them to provide the next result. + +The result of the previous step is passed in, so the signature of this op is: + innerOp(child) -> output + +The result of applying InnerOp should be: + output = op.hash(op.prefix || child || op.suffix) + + where the || operator is concatenation of binary data, +and child is the result of hashing all the tree below this step. + +Any special data, like prepending child with the length, or prepending the entire operation with +some value to differentiate from leaf nodes, should be included in prefix and suffix. +If either of prefix or suffix is empty, we just treat it as an empty string +*/ +message InnerOp { + HashOp hash = 1; + bytes prefix = 2; + bytes suffix = 3; +} + + +/** +ProofSpec defines what the expected parameters are for a given proof type. +This can be stored in the client and used to validate any incoming proofs. + + verify(ProofSpec, Proof) -> Proof | Error + +As demonstrated in tests, if we don't fix the algorithm used to calculate the +LeafHash for a given tree, there are many possible key-value pairs that can +generate a given hash (by interpretting the preimage differently). +We need this for proper security, requires client knows a priori what +tree format server uses. But not in code, rather a configuration object. +*/ +message ProofSpec { + // any field in the ExistenceProof must be the same as in this spec. + // except Prefix, which is just the first bytes of prefix (spec can be longer) + LeafOp leaf_spec = 1; + InnerSpec inner_spec = 2; + // max_depth (if > 0) is the maximum number of InnerOps allowed (mainly for fixed-depth tries) + int32 max_depth = 3; + // min_depth (if > 0) is the minimum number of InnerOps allowed (mainly for fixed-depth tries) + int32 min_depth = 4; +} + +/* +InnerSpec contains all store-specific structure info to determine if two proofs from a +given store are neighbors. + +This enables: + + isLeftMost(spec: InnerSpec, op: InnerOp) + isRightMost(spec: InnerSpec, op: InnerOp) + isLeftNeighbor(spec: InnerSpec, left: InnerOp, right: InnerOp) +*/ +message InnerSpec { + // Child order is the ordering of the children node, must count from 0 + // iavl tree is [0, 1] (left then right) + // merk is [0, 2, 1] (left, right, here) + repeated int32 child_order = 1; + int32 child_size = 2; + int32 min_prefix_length = 3; + int32 max_prefix_length = 4; + // empty child is the prehash image that is used when one child is nil (eg. 20 bytes of 0) + bytes empty_child = 5; + // hash is the algorithm that must be used for each InnerOp + HashOp hash = 6; +} + +/* +BatchProof is a group of multiple proof types than can be compressed +*/ +message BatchProof { + repeated BatchEntry entries = 1; +} + +// Use BatchEntry not CommitmentProof, to avoid recursion +message BatchEntry { + oneof proof { + ExistenceProof exist = 1; + NonExistenceProof nonexist = 2; + } +} + + +/****** all items here are compressed forms *******/ + +message CompressedBatchProof { + repeated CompressedBatchEntry entries = 1; + repeated InnerOp lookup_inners = 2; +} + +// Use BatchEntry not CommitmentProof, to avoid recursion +message CompressedBatchEntry { + oneof proof { + CompressedExistenceProof exist = 1; + CompressedNonExistenceProof nonexist = 2; + } +} + +message CompressedExistenceProof { + bytes key = 1; + bytes value = 2; + LeafOp leaf = 3; + // these are indexes into the lookup_inners table in CompressedBatchProof + repeated int32 path = 4; +} + +message CompressedNonExistenceProof { + bytes key = 1; // TODO: remove this as unnecessary??? we prove a range + CompressedExistenceProof left = 2; + CompressedExistenceProof right = 3; +} diff --git a/ampd/proto/third_party/tendermint/abci/types.proto b/ampd/proto/third_party/tendermint/abci/types.proto new file mode 100644 index 000000000..44f861129 --- /dev/null +++ b/ampd/proto/third_party/tendermint/abci/types.proto @@ -0,0 +1,413 @@ +syntax = "proto3"; +package tendermint.abci; + +option go_package = "github.com/tendermint/tendermint/abci/types"; + +// For more information on gogo.proto, see: +// https://github.com/gogo/protobuf/blob/master/extensions.md +import "tendermint/crypto/proof.proto"; +import "tendermint/types/types.proto"; +import "tendermint/crypto/keys.proto"; +import "tendermint/types/params.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; + +// This file is copied from http://github.com/tendermint/abci +// NOTE: When using custom types, mind the warnings. +// https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues + +//---------------------------------------- +// Request types + +message Request { + oneof value { + RequestEcho echo = 1; + RequestFlush flush = 2; + RequestInfo info = 3; + RequestSetOption set_option = 4; + RequestInitChain init_chain = 5; + RequestQuery query = 6; + RequestBeginBlock begin_block = 7; + RequestCheckTx check_tx = 8; + RequestDeliverTx deliver_tx = 9; + RequestEndBlock end_block = 10; + RequestCommit commit = 11; + RequestListSnapshots list_snapshots = 12; + RequestOfferSnapshot offer_snapshot = 13; + RequestLoadSnapshotChunk load_snapshot_chunk = 14; + RequestApplySnapshotChunk apply_snapshot_chunk = 15; + } +} + +message RequestEcho { + string message = 1; +} + +message RequestFlush {} + +message RequestInfo { + string version = 1; + uint64 block_version = 2; + uint64 p2p_version = 3; +} + +// nondeterministic +message RequestSetOption { + string key = 1; + string value = 2; +} + +message RequestInitChain { + google.protobuf.Timestamp time = 1 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + string chain_id = 2; + ConsensusParams consensus_params = 3; + repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false]; + bytes app_state_bytes = 5; + int64 initial_height = 6; +} + +message RequestQuery { + bytes data = 1; + string path = 2; + int64 height = 3; + bool prove = 4; +} + +message RequestBeginBlock { + bytes hash = 1; + tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; + LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; + repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; +} + +enum CheckTxType { + NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; + RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; +} + +message RequestCheckTx { + bytes tx = 1; + CheckTxType type = 2; +} + +message RequestDeliverTx { + bytes tx = 1; +} + +message RequestEndBlock { + int64 height = 1; +} + +message RequestCommit {} + +// lists available snapshots +message RequestListSnapshots {} + +// offers a snapshot to the application +message RequestOfferSnapshot { + Snapshot snapshot = 1; // snapshot offered by peers + bytes app_hash = 2; // light client-verified app hash for snapshot height +} + +// loads a snapshot chunk +message RequestLoadSnapshotChunk { + uint64 height = 1; + uint32 format = 2; + uint32 chunk = 3; +} + +// Applies a snapshot chunk +message RequestApplySnapshotChunk { + uint32 index = 1; + bytes chunk = 2; + string sender = 3; +} + +//---------------------------------------- +// Response types + +message Response { + oneof value { + ResponseException exception = 1; + ResponseEcho echo = 2; + ResponseFlush flush = 3; + ResponseInfo info = 4; + ResponseSetOption set_option = 5; + ResponseInitChain init_chain = 6; + ResponseQuery query = 7; + ResponseBeginBlock begin_block = 8; + ResponseCheckTx check_tx = 9; + ResponseDeliverTx deliver_tx = 10; + ResponseEndBlock end_block = 11; + ResponseCommit commit = 12; + ResponseListSnapshots list_snapshots = 13; + ResponseOfferSnapshot offer_snapshot = 14; + ResponseLoadSnapshotChunk load_snapshot_chunk = 15; + ResponseApplySnapshotChunk apply_snapshot_chunk = 16; + } +} + +// nondeterministic +message ResponseException { + string error = 1; +} + +message ResponseEcho { + string message = 1; +} + +message ResponseFlush {} + +message ResponseInfo { + string data = 1; + + string version = 2; + uint64 app_version = 3; + + int64 last_block_height = 4; + bytes last_block_app_hash = 5; +} + +// nondeterministic +message ResponseSetOption { + uint32 code = 1; + // bytes data = 2; + string log = 3; + string info = 4; +} + +message ResponseInitChain { + ConsensusParams consensus_params = 1; + repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false]; + bytes app_hash = 3; +} + +message ResponseQuery { + uint32 code = 1; + // bytes data = 2; // use "value" instead. + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 index = 5; + bytes key = 6; + bytes value = 7; + tendermint.crypto.ProofOps proof_ops = 8; + int64 height = 9; + string codespace = 10; +} + +message ResponseBeginBlock { + repeated Event events = 1 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; +} + +message ResponseCheckTx { + uint32 code = 1; + bytes data = 2; + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 gas_wanted = 5 [json_name = "gas_wanted"]; + int64 gas_used = 6 [json_name = "gas_used"]; + repeated Event events = 7 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; + string codespace = 8; + string sender = 9; + int64 priority = 10; + + // mempool_error is set by CometBFT. + // ABCI applictions creating a ResponseCheckTX should not set mempool_error. + string mempool_error = 11; +} + +message ResponseDeliverTx { + uint32 code = 1; + bytes data = 2; + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 gas_wanted = 5 [json_name = "gas_wanted"]; + int64 gas_used = 6 [json_name = "gas_used"]; + repeated Event events = 7 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "events,omitempty" + ]; // nondeterministic + string codespace = 8; +} + +message ResponseEndBlock { + repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; + ConsensusParams consensus_param_updates = 2; + repeated Event events = 3 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; +} + +message ResponseCommit { + // reserve 1 + bytes data = 2; + int64 retain_height = 3; +} + +message ResponseListSnapshots { + repeated Snapshot snapshots = 1; +} + +message ResponseOfferSnapshot { + Result result = 1; + + enum Result { + UNKNOWN = 0; // Unknown result, abort all snapshot restoration + ACCEPT = 1; // Snapshot accepted, apply chunks + ABORT = 2; // Abort all snapshot restoration + REJECT = 3; // Reject this specific snapshot, try others + REJECT_FORMAT = 4; // Reject all snapshots of this format, try others + REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others + } +} + +message ResponseLoadSnapshotChunk { + bytes chunk = 1; +} + +message ResponseApplySnapshotChunk { + Result result = 1; + repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply + repeated string reject_senders = 3; // Chunk senders to reject and ban + + enum Result { + UNKNOWN = 0; // Unknown result, abort all snapshot restoration + ACCEPT = 1; // Chunk successfully accepted + ABORT = 2; // Abort all snapshot restoration + RETRY = 3; // Retry chunk (combine with refetch and reject) + RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject) + REJECT_SNAPSHOT = 5; // Reject this snapshot, try others + } +} + +//---------------------------------------- +// Misc. + +// ConsensusParams contains all consensus-relevant parameters +// that can be adjusted by the abci app +message ConsensusParams { + BlockParams block = 1; + tendermint.types.EvidenceParams evidence = 2; + tendermint.types.ValidatorParams validator = 3; + tendermint.types.VersionParams version = 4; +} + +// BlockParams contains limits on the block size. +message BlockParams { + // Note: must be greater than 0 + int64 max_bytes = 1; + // Note: must be greater or equal to -1 + int64 max_gas = 2; +} + +message LastCommitInfo { + int32 round = 1; + repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; +} + +// Event allows application developers to attach additional information to +// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. +// Later, transactions may be queried using these events. +message Event { + string type = 1; + repeated EventAttribute attributes = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "attributes,omitempty" + ]; +} + +// EventAttribute is a single key-value pair, associated with an event. +message EventAttribute { + bytes key = 1; + bytes value = 2; + bool index = 3; // nondeterministic +} + +// TxResult contains results of executing the transaction. +// +// One usage is indexing transaction results. +message TxResult { + int64 height = 1; + uint32 index = 2; + bytes tx = 3; + ResponseDeliverTx result = 4 [(gogoproto.nullable) = false]; +} + +//---------------------------------------- +// Blockchain Types + +// Validator +message Validator { + bytes address = 1; // The first 20 bytes of SHA256(public key) + // PubKey pub_key = 2 [(gogoproto.nullable)=false]; + int64 power = 3; // The voting power +} + +// ValidatorUpdate +message ValidatorUpdate { + tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; + int64 power = 2; +} + +// VoteInfo +message VoteInfo { + Validator validator = 1 [(gogoproto.nullable) = false]; + bool signed_last_block = 2; +} + +enum EvidenceType { + UNKNOWN = 0; + DUPLICATE_VOTE = 1; + LIGHT_CLIENT_ATTACK = 2; +} + +message Evidence { + EvidenceType type = 1; + // The offending validator + Validator validator = 2 [(gogoproto.nullable) = false]; + // The height when the offense occurred + int64 height = 3; + // The corresponding time where the offense occurred + google.protobuf.Timestamp time = 4 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + // Total voting power of the validator set in case the ABCI application does + // not store historical validators. + // https://github.com/tendermint/tendermint/issues/4581 + int64 total_voting_power = 5; +} + +//---------------------------------------- +// State Sync Types + +message Snapshot { + uint64 height = 1; // The height at which the snapshot was taken + uint32 format = 2; // The application-specific snapshot format + uint32 chunks = 3; // Number of chunks in the snapshot + bytes hash = 4; // Arbitrary snapshot hash, equal only if identical + bytes metadata = 5; // Arbitrary application metadata +} + +//---------------------------------------- +// Service Definition + +service ABCIApplication { + rpc Echo(RequestEcho) returns (ResponseEcho); + rpc Flush(RequestFlush) returns (ResponseFlush); + rpc Info(RequestInfo) returns (ResponseInfo); + rpc SetOption(RequestSetOption) returns (ResponseSetOption); + rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); + rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); + rpc Query(RequestQuery) returns (ResponseQuery); + rpc Commit(RequestCommit) returns (ResponseCommit); + rpc InitChain(RequestInitChain) returns (ResponseInitChain); + rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); + rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); + rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); + rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); + rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) + returns (ResponseLoadSnapshotChunk); + rpc ApplySnapshotChunk(RequestApplySnapshotChunk) + returns (ResponseApplySnapshotChunk); +} diff --git a/ampd/proto/third_party/tendermint/crypto/keys.proto b/ampd/proto/third_party/tendermint/crypto/keys.proto new file mode 100644 index 000000000..5b94ddaec --- /dev/null +++ b/ampd/proto/third_party/tendermint/crypto/keys.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package tendermint.crypto; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; + +import "gogoproto/gogo.proto"; + +// PublicKey defines the keys available for use with Validators +message PublicKey { + option (gogoproto.compare) = true; + option (gogoproto.equal) = true; + + oneof sum { + bytes ed25519 = 1; + bytes secp256k1 = 2; + } +} diff --git a/ampd/proto/third_party/tendermint/crypto/proof.proto b/ampd/proto/third_party/tendermint/crypto/proof.proto new file mode 100644 index 000000000..975df7685 --- /dev/null +++ b/ampd/proto/third_party/tendermint/crypto/proof.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +package tendermint.crypto; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; + +import "gogoproto/gogo.proto"; + +message Proof { + int64 total = 1; + int64 index = 2; + bytes leaf_hash = 3; + repeated bytes aunts = 4; +} + +message ValueOp { + // Encoded in ProofOp.Key. + bytes key = 1; + + // To encode in ProofOp.Data + Proof proof = 2; +} + +message DominoOp { + string key = 1; + string input = 2; + string output = 3; +} + +// ProofOp defines an operation used for calculating Merkle root +// The data could be arbitrary format, providing nessecary data +// for example neighbouring node hash +message ProofOp { + string type = 1; + bytes key = 2; + bytes data = 3; +} + +// ProofOps is Merkle proof defined by the list of ProofOps +message ProofOps { + repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/tendermint/libs/bits/types.proto b/ampd/proto/third_party/tendermint/libs/bits/types.proto new file mode 100644 index 000000000..3111d113a --- /dev/null +++ b/ampd/proto/third_party/tendermint/libs/bits/types.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package tendermint.libs.bits; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits"; + +message BitArray { + int64 bits = 1; + repeated uint64 elems = 2; +} diff --git a/ampd/proto/third_party/tendermint/p2p/types.proto b/ampd/proto/third_party/tendermint/p2p/types.proto new file mode 100644 index 000000000..0d42ea400 --- /dev/null +++ b/ampd/proto/third_party/tendermint/p2p/types.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package tendermint.p2p; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; + +import "gogoproto/gogo.proto"; + +message NetAddress { + string id = 1 [(gogoproto.customname) = "ID"]; + string ip = 2 [(gogoproto.customname) = "IP"]; + uint32 port = 3; +} + +message ProtocolVersion { + uint64 p2p = 1 [(gogoproto.customname) = "P2P"]; + uint64 block = 2; + uint64 app = 3; +} + +message DefaultNodeInfo { + ProtocolVersion protocol_version = 1 [(gogoproto.nullable) = false]; + string default_node_id = 2 [(gogoproto.customname) = "DefaultNodeID"]; + string listen_addr = 3; + string network = 4; + string version = 5; + bytes channels = 6; + string moniker = 7; + DefaultNodeInfoOther other = 8 [(gogoproto.nullable) = false]; +} + +message DefaultNodeInfoOther { + string tx_index = 1; + string rpc_address = 2 [(gogoproto.customname) = "RPCAddress"]; +} diff --git a/ampd/proto/third_party/tendermint/types/block.proto b/ampd/proto/third_party/tendermint/types/block.proto new file mode 100644 index 000000000..84e9bb15d --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/block.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "tendermint/types/types.proto"; +import "tendermint/types/evidence.proto"; + +message Block { + Header header = 1 [(gogoproto.nullable) = false]; + Data data = 2 [(gogoproto.nullable) = false]; + tendermint.types.EvidenceList evidence = 3 [(gogoproto.nullable) = false]; + Commit last_commit = 4; +} diff --git a/ampd/proto/third_party/tendermint/types/evidence.proto b/ampd/proto/third_party/tendermint/types/evidence.proto new file mode 100644 index 000000000..451b8dca3 --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/evidence.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "tendermint/types/types.proto"; +import "tendermint/types/validator.proto"; + +message Evidence { + oneof sum { + DuplicateVoteEvidence duplicate_vote_evidence = 1; + LightClientAttackEvidence light_client_attack_evidence = 2; + } +} + +// DuplicateVoteEvidence contains evidence of a validator signed two conflicting votes. +message DuplicateVoteEvidence { + tendermint.types.Vote vote_a = 1; + tendermint.types.Vote vote_b = 2; + int64 total_voting_power = 3; + int64 validator_power = 4; + google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +// LightClientAttackEvidence contains evidence of a set of validators attempting to mislead a light client. +message LightClientAttackEvidence { + tendermint.types.LightBlock conflicting_block = 1; + int64 common_height = 2; + repeated tendermint.types.Validator byzantine_validators = 3; + int64 total_voting_power = 4; + google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +message EvidenceList { + repeated Evidence evidence = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/tendermint/types/params.proto b/ampd/proto/third_party/tendermint/types/params.proto new file mode 100644 index 000000000..0de7d846f --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/params.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; + +option (gogoproto.equal_all) = true; + +// ConsensusParams contains consensus critical parameters that determine the +// validity of blocks. +message ConsensusParams { + BlockParams block = 1 [(gogoproto.nullable) = false]; + EvidenceParams evidence = 2 [(gogoproto.nullable) = false]; + ValidatorParams validator = 3 [(gogoproto.nullable) = false]; + VersionParams version = 4 [(gogoproto.nullable) = false]; +} + +// BlockParams contains limits on the block size. +message BlockParams { + // Max block size, in bytes. + // Note: must be greater than 0 + int64 max_bytes = 1; + // Max gas per block. + // Note: must be greater or equal to -1 + int64 max_gas = 2; + // Minimum time increment between consecutive blocks (in milliseconds) If the + // block header timestamp is ahead of the system clock, decrease this value. + // + // Not exposed to the application. + int64 time_iota_ms = 3; +} + +// EvidenceParams determine how we handle evidence of malfeasance. +message EvidenceParams { + // Max age of evidence, in blocks. + // + // The basic formula for calculating this is: MaxAgeDuration / {average block + // time}. + int64 max_age_num_blocks = 1; + + // Max age of evidence, in time. + // + // It should correspond with an app's "unbonding period" or other similar + // mechanism for handling [Nothing-At-Stake + // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). + google.protobuf.Duration max_age_duration = 2 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + + // This sets the maximum size of total evidence in bytes that can be committed in a single block. + // and should fall comfortably under the max block bytes. + // Default is 1048576 or 1MB + int64 max_bytes = 3; +} + +// ValidatorParams restrict the public key types validators can use. +// NOTE: uses ABCI pubkey naming, not Amino names. +message ValidatorParams { + option (gogoproto.populate) = true; + option (gogoproto.equal) = true; + + repeated string pub_key_types = 1; +} + +// VersionParams contains the ABCI application version. +message VersionParams { + option (gogoproto.populate) = true; + option (gogoproto.equal) = true; + + uint64 app_version = 1; +} + +// HashedParams is a subset of ConsensusParams. +// +// It is hashed into the Header.ConsensusHash. +message HashedParams { + int64 block_max_bytes = 1; + int64 block_max_gas = 2; +} diff --git a/ampd/proto/third_party/tendermint/types/types.proto b/ampd/proto/third_party/tendermint/types/types.proto new file mode 100644 index 000000000..3ce169459 --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/types.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "tendermint/crypto/proof.proto"; +import "tendermint/version/types.proto"; +import "tendermint/types/validator.proto"; + +// BlockIdFlag indicates which BlcokID the signature is for +enum BlockIDFlag { + option (gogoproto.goproto_enum_stringer) = true; + option (gogoproto.goproto_enum_prefix) = false; + + BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; + BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; + BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; + BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; +} + +// SignedMsgType is a type of signed message in the consensus. +enum SignedMsgType { + option (gogoproto.goproto_enum_stringer) = true; + option (gogoproto.goproto_enum_prefix) = false; + + SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"]; + // Votes + SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"]; + SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"]; + + // Proposals + SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"]; +} + +// PartsetHeader +message PartSetHeader { + uint32 total = 1; + bytes hash = 2; +} + +message Part { + uint32 index = 1; + bytes bytes = 2; + tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; +} + +// BlockID +message BlockID { + bytes hash = 1; + PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; +} + +// -------------------------------- + +// Header defines the structure of a block header. +message Header { + // basic block info + tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; + string chain_id = 2 [(gogoproto.customname) = "ChainID"]; + int64 height = 3; + google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + + // prev block info + BlockID last_block_id = 5 [(gogoproto.nullable) = false]; + + // hashes of block data + bytes last_commit_hash = 6; // commit from validators from the last block + bytes data_hash = 7; // transactions + + // hashes from the app output from the prev block + bytes validators_hash = 8; // validators for the current block + bytes next_validators_hash = 9; // validators for the next block + bytes consensus_hash = 10; // consensus params for current block + bytes app_hash = 11; // state after txs from the previous block + bytes last_results_hash = 12; // root hash of all results from the txs from the previous block + + // consensus info + bytes evidence_hash = 13; // evidence included in the block + bytes proposer_address = 14; // original proposer of the block +} + +// Data contains the set of transactions included in the block +message Data { + // Txs that will be applied by state @ block.Height+1. + // NOTE: not all txs here are valid. We're just agreeing on the order first. + // This means that block.AppHash does not include these txs. + repeated bytes txs = 1; +} + +// Vote represents a prevote, precommit, or commit vote from validators for +// consensus. +message Vote { + SignedMsgType type = 1; + int64 height = 2; + int32 round = 3; + BlockID block_id = 4 + [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil. + google.protobuf.Timestamp timestamp = 5 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes validator_address = 6; + int32 validator_index = 7; + bytes signature = 8; +} + +// Commit contains the evidence that a block was committed by a set of validators. +message Commit { + int64 height = 1; + int32 round = 2; + BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; + repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; +} + +// CommitSig is a part of the Vote included in a Commit. +message CommitSig { + BlockIDFlag block_id_flag = 1; + bytes validator_address = 2; + google.protobuf.Timestamp timestamp = 3 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes signature = 4; +} + +message Proposal { + SignedMsgType type = 1; + int64 height = 2; + int32 round = 3; + int32 pol_round = 4; + BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; + google.protobuf.Timestamp timestamp = 6 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes signature = 7; +} + +message SignedHeader { + Header header = 1; + Commit commit = 2; +} + +message LightBlock { + SignedHeader signed_header = 1; + tendermint.types.ValidatorSet validator_set = 2; +} + +message BlockMeta { + BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; + int64 block_size = 2; + Header header = 3 [(gogoproto.nullable) = false]; + int64 num_txs = 4; +} + +// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree. +message TxProof { + bytes root_hash = 1; + bytes data = 2; + tendermint.crypto.Proof proof = 3; +} diff --git a/ampd/proto/third_party/tendermint/types/validator.proto b/ampd/proto/third_party/tendermint/types/validator.proto new file mode 100644 index 000000000..49860b96d --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/validator.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "tendermint/crypto/keys.proto"; + +message ValidatorSet { + repeated Validator validators = 1; + Validator proposer = 2; + int64 total_voting_power = 3; +} + +message Validator { + bytes address = 1; + tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; + int64 voting_power = 3; + int64 proposer_priority = 4; +} + +message SimpleValidator { + tendermint.crypto.PublicKey pub_key = 1; + int64 voting_power = 2; +} diff --git a/ampd/proto/third_party/tendermint/version/types.proto b/ampd/proto/third_party/tendermint/version/types.proto new file mode 100644 index 000000000..6061868bd --- /dev/null +++ b/ampd/proto/third_party/tendermint/version/types.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package tendermint.version; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; + +import "gogoproto/gogo.proto"; + +// App includes the protocol and software version for the application. +// This information is included in ResponseInfo. The App.Protocol can be +// updated in ResponseEndBlock. +message App { + uint64 protocol = 1; + string software = 2; +} + +// Consensus captures the consensus rules for processing a block in the blockchain, +// including all blockchain data structures and the rules of the application's +// state transition machine. +message Consensus { + option (gogoproto.equal) = true; + + uint64 block = 1; + uint64 app = 2; +} diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs new file mode 100644 index 000000000..5de50051f --- /dev/null +++ b/ampd/src/broadcaster/confirm_tx.rs @@ -0,0 +1,353 @@ +use std::time::Duration; + +use axelar_wasm_std::FnExt; +use cosmrs::proto::cosmos::tx::v1beta1::{GetTxRequest, GetTxResponse}; +use error_stack::{report, Report, Result}; +use futures::{StreamExt, TryFutureExt}; +use thiserror::Error; +use tokio::{ + sync::{mpsc, Mutex}, + time, +}; +use tokio_stream::wrappers::ReceiverStream; +use tonic::Status; +use tracing::error; + +use super::cosmos; + +#[derive(Debug, PartialEq)] +pub enum TxStatus { + Success, + Failure, +} + +impl From for TxStatus { + fn from(code: u32) -> Self { + match code { + 0 => Self::Success, + _ => Self::Failure, + } + } +} + +#[derive(Debug, PartialEq)] +pub struct TxResponse { + pub status: TxStatus, + pub response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse, +} + +impl From for TxResponse { + fn from(response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse) -> Self { + Self { + status: response.code.into(), + response, + } + } +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("failed confirming tx due to tx not found: {tx_hash}")] + Confirmation { tx_hash: String }, + #[error("failed confirming tx due to grpc error {status}: {tx_hash}")] + Grpc { status: Status, tx_hash: String }, + #[error("failed sending tx response")] + SendTxRes(#[from] Box>), +} + +enum ConfirmationResult { + Confirmed(Box), + NotFound, + GRPCError(Status), +} + +pub struct TxConfirmer +where + T: cosmos::BroadcastClient, +{ + client: T, + sleep: Duration, + max_attempts: u32, + tx_hash_receiver: mpsc::Receiver, + tx_res_sender: mpsc::Sender, +} + +impl TxConfirmer +where + T: cosmos::BroadcastClient, +{ + pub fn new( + client: T, + sleep: Duration, + max_attempts: u32, + tx_hash_receiver: mpsc::Receiver, + tx_res_sender: mpsc::Sender, + ) -> Self { + Self { + client, + sleep, + max_attempts, + tx_hash_receiver, + tx_res_sender, + } + } + + pub async fn run(self) -> Result<(), Error> { + let Self { + client, + sleep, + max_attempts, + tx_hash_receiver, + tx_res_sender, + } = self; + let limit = tx_hash_receiver.capacity(); + let client = Mutex::new(client); + let mut tx_hash_stream = ReceiverStream::new(tx_hash_receiver) + .map(|tx_hash| { + confirm_tx(&client, tx_hash, sleep, max_attempts).and_then(|tx| async { + tx_res_sender + .send(tx) + .await + .map_err(Box::new) + .map_err(Into::into) + .map_err(Report::new) + }) + }) + .buffer_unordered(limit); + + while let Some(res) = tx_hash_stream.next().await { + res?; + } + + Ok(()) + } +} + +async fn confirm_tx( + client: &Mutex, + tx_hash: String, + sleep: Duration, + attempts: u32, +) -> Result +where + T: cosmos::BroadcastClient, +{ + for i in 0..attempts { + let req = GetTxRequest { + hash: tx_hash.clone(), + }; + + match client + .lock() + .await + .get_tx(req) + .await + .then(evaluate_tx_response) + { + ConfirmationResult::Confirmed(tx) => return Ok(*tx), + ConfirmationResult::NotFound if i == attempts.saturating_sub(1) => { + return Err(report!(Error::Confirmation { tx_hash })) + } + ConfirmationResult::GRPCError(status) if i == attempts.saturating_sub(1) => { + return Err(report!(Error::Grpc { status, tx_hash })) + } + _ => time::sleep(sleep).await, + } + } + + unreachable!("confirmation loop should have returned by now") +} + +fn evaluate_tx_response( + response: core::result::Result, +) -> ConfirmationResult { + match response { + Err(status) => ConfirmationResult::GRPCError(status), + Ok(GetTxResponse { + tx_response: None, .. + }) => ConfirmationResult::NotFound, + Ok(GetTxResponse { + tx_response: Some(response), + .. + }) => ConfirmationResult::Confirmed(Box::new(response.into())), + } +} + +#[cfg(test)] +mod test { + use std::time::Duration; + + use cosmrs::proto::cosmos::tx::v1beta1::GetTxRequest; + use mockall::predicate; + use tokio::{sync::mpsc, test}; + + use super::{Error, TxConfirmer, TxResponse, TxStatus}; + use crate::broadcaster::cosmos::MockBroadcastClient; + + #[test] + async fn should_confirm_successful_tx_and_send_it_back() { + let tx_hash = "tx_hash".to_string(); + let tx_response = cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse { + code: 0, + txhash: tx_hash.clone(), + ..Default::default() + }; + let tx_res = cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse { + tx_response: Some(tx_response.clone()), + ..Default::default() + }; + + let mut client = MockBroadcastClient::new(); + client + .expect_get_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .return_once(|_| Ok(tx_res)); + + let sleep = Duration::from_secs(5); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, mut tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash).await.unwrap(); + assert_eq!( + tx_res_receiver.recv().await.unwrap(), + TxResponse { + status: TxStatus::Success, + response: tx_response + } + ); + drop(tx_confirmer_sender); + assert!(handle.await.unwrap().is_ok()); + } + + #[test] + async fn should_confirm_failed_tx_and_send_it_back() { + let tx_hash = "tx_hash".to_string(); + let tx_response = cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse { + code: 1, + txhash: tx_hash.clone(), + ..Default::default() + }; + let tx_res = cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse { + tx_response: Some(tx_response.clone()), + ..Default::default() + }; + + let mut client = MockBroadcastClient::new(); + client + .expect_get_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .return_once(|_| Ok(tx_res)); + + let sleep = Duration::from_secs(5); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, mut tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash).await.unwrap(); + assert_eq!( + tx_res_receiver.recv().await.unwrap(), + TxResponse { + status: TxStatus::Failure, + response: tx_response + } + ); + drop(tx_confirmer_sender); + assert!(handle.await.unwrap().is_ok()); + } + + #[test] + async fn should_retry_when_tx_is_not_found() { + let tx_hash = "tx_hash".to_string(); + + let mut client = MockBroadcastClient::new(); + client + .expect_get_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .times(3) + .returning(|_| Ok(cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse::default())); + + let sleep = Duration::from_millis(100); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, _tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash.clone()).await.unwrap(); + assert!(matches!( + handle.await.unwrap().unwrap_err().current_context(), + Error::Confirmation { tx_hash: actual } if *actual == tx_hash + )); + } + + #[test] + async fn should_retry_when_grpc_error() { + let tx_hash = "tx_hash".to_string(); + + let mut client = MockBroadcastClient::new(); + client + .expect_get_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .times(3) + .returning(|_| { + Err(tonic::Status::new( + tonic::Code::Internal, + "internal server error", + )) + }); + + let sleep = Duration::from_millis(100); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, _tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash.clone()).await.unwrap(); + assert!(matches!( + handle.await.unwrap().unwrap_err().current_context(), + Error::Grpc { tx_hash: actual, status } if *actual == tx_hash && status.code() == tonic::Code::Internal + )); + } +} diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index f0f848cda..34ec85284 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -1,7 +1,7 @@ +use std::cmp; use std::convert::TryInto; use std::ops::Mul; use std::time::Duration; -use std::{cmp, thread}; use async_trait::async_trait; use cosmrs::proto::cosmos::auth::v1beta1::{ @@ -9,14 +9,12 @@ use cosmrs::proto::cosmos::auth::v1beta1::{ }; use cosmrs::proto::cosmos::bank::v1beta1::QueryBalanceRequest; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmrs::proto::cosmos::tx::v1beta1::{ - BroadcastMode, BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, -}; +use cosmrs::proto::cosmos::tx::v1beta1::{BroadcastMode, BroadcastTxRequest, SimulateRequest}; use cosmrs::proto::traits::MessageExt; use cosmrs::tendermint::chain::Id; use cosmrs::tx::Fee; use cosmrs::{Amount, Coin, Denom, Gas}; -use error_stack::{ensure, report, FutureExt, Report, Result, ResultExt}; +use error_stack::{ensure, report, FutureExt, Result, ResultExt}; use futures::TryFutureExt; use k256::sha2::{Digest, Sha256}; use mockall::automock; @@ -26,20 +24,19 @@ use prost_types::Any; use serde::{Deserialize, Serialize}; use thiserror::Error; use tonic::{Code, Status}; -use tracing::debug; use tracing::info; use typed_builder::TypedBuilder; -use valuable::Valuable; use axelar_wasm_std::FnExt; use dec_coin::DecCoin; -use report::{LoggableError, ResultCompatExt}; +use report::ResultCompatExt; use tx::Tx; use crate::tofnd; use crate::tofnd::grpc::Multisig; use crate::types::{PublicKey, TMAddress}; +pub mod confirm_tx; mod cosmos; mod dec_coin; mod tx; @@ -54,10 +51,6 @@ pub enum Error { FeeEstimation, #[error("broadcast failed")] Broadcast, - #[error("failed to confirm inclusion in block for tx with hash '{tx_hash}'")] - TxConfirmation { tx_hash: String }, - #[error("failed to execute tx")] - Execution, #[error("failed to query balance for address '{address}' and denomination '{denom}'")] QueryBalance { address: TMAddress, denom: Denom }, #[error("failed to query account for address '{address}'")] @@ -104,6 +97,7 @@ impl Default for Config { #[automock] #[async_trait] pub trait Broadcaster { + fn sender_address(&self) -> TMAddress; async fn broadcast(&mut self, msgs: Vec) -> Result; async fn estimate_fee(&mut self, msgs: Vec) -> Result; } @@ -217,6 +211,10 @@ where S: Multisig + Send + Sync, Q: cosmos::AccountQueryClient + Send, { + fn sender_address(&self) -> TMAddress { + self.address.clone() + } + async fn broadcast(&mut self, msgs: Vec) -> Result { let (acc_number, acc_sequence) = self.acc_number_and_sequence().await?; let tx = Tx::builder() @@ -261,10 +259,6 @@ where info!(tx_hash, "broadcasted transaction"); - self.confirm_tx(tx_hash).await?; - - info!(tx_hash, "confirmed transaction"); - self.acc_sequence.replace( acc_sequence .checked_add(1) @@ -354,48 +348,6 @@ where }) .await } - - async fn confirm_tx(&mut self, tx_hash: &str) -> Result<(), Error> { - let mut result: Result<(), Status> = Ok(()); - - for i in 0..self.config.tx_fetch_max_retries.saturating_add(1) { - if i > 0 { - thread::sleep(self.config.tx_fetch_interval) - } - - let response = self - .client - .get_tx(GetTxRequest { - hash: tx_hash.to_string(), - }) - .await; - - match evaluate_tx_response(response) { - ConfirmationResult::Success => { - if let Err(report) = result { - debug!( - err = LoggableError::from(&report).as_value(), - "tx confirmed after {} retries", i - ) - } - - return Ok(()); - } - ConfirmationResult::Critical(err) => return Err(err), - ConfirmationResult::Retriable(err) => { - if let Err(result) = result.as_mut() { - result.extend_one(err); - } else { - result = Err(err); - } - } - }; - } - - result.change_context(Error::TxConfirmation { - tx_hash: tx_hash.to_string(), - }) - } } fn decode_base_account(account: Any) -> Result { @@ -406,27 +358,6 @@ fn decode_base_account(account: Any) -> Result { .attach_printable_lazy(|| format!("{{ value = {:?} }}", account.value)) } -fn evaluate_tx_response( - response: core::result::Result, -) -> ConfirmationResult { - match response { - Err(err) => ConfirmationResult::Retriable(report!(err)), - Ok(GetTxResponse { - tx_response: None, .. - }) => ConfirmationResult::Retriable(Report::new(Status::not_found("tx not found"))), - Ok(GetTxResponse { - tx_response: Some(response), - .. - }) => match response { - TxResponse { code: 0, .. } => ConfirmationResult::Success, - _ => ConfirmationResult::Critical( - report!(Error::Execution) - .attach_printable(format!("{{ response = {response:?} }}")), - ), - }, - } -} - fn remap_account_not_found_error( response: core::result::Result, ) -> core::result::Result { @@ -437,12 +368,6 @@ fn remap_account_not_found_error( } } -enum ConfirmationResult { - Success, - Retriable(Report), - Critical(Report), -} - #[cfg(test)] mod tests { use cosmrs::crypto::PublicKey; @@ -564,72 +489,6 @@ mod tests { )); } - #[test] - async fn tx_confirmation_failed() { - let mut client = MockBroadcastClient::new(); - client.expect_simulate().returning(|_| { - Ok(SimulateResponse { - gas_info: Some(GasInfo { - gas_wanted: 0, - gas_used: 0, - }), - result: None, - }) - }); - client - .expect_broadcast_tx() - .returning(|_| Ok(TxResponse::default())); - client - .expect_get_tx() - .times((Config::default().tx_fetch_max_retries + 1) as usize) - .returning(|_| Err(Status::deadline_exceeded("time out"))); - - let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; - let msgs = vec![dummy_msg()]; - - assert!(matches!( - broadcaster - .broadcast(msgs) - .await - .unwrap_err() - .current_context(), - Error::TxConfirmation { .. } - )); - } - - #[test] - async fn tx_execution_failed() { - let mut client = MockBroadcastClient::new(); - client.expect_simulate().returning(|_| { - Ok(SimulateResponse { - gas_info: Some(GasInfo { - gas_wanted: 0, - gas_used: 0, - }), - result: None, - }) - }); - client - .expect_broadcast_tx() - .returning(|_| Ok(TxResponse::default())); - client.expect_get_tx().times(1).returning(|_| { - Ok(GetTxResponse { - tx_response: Some(TxResponse { - code: 32, - ..TxResponse::default() - }), - ..GetTxResponse::default() - }) - }); - - let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; - let msgs = vec![dummy_msg()]; - - let report = broadcaster.broadcast(msgs).await.unwrap_err(); - - assert!(matches!(report.current_context(), Error::Execution)); - } - #[test] async fn broadcast_confirmed() { let mut broadcaster = init_validated_broadcaster(None, None, None).await; diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 6183ca619..4a64ea177 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -1,6 +1,7 @@ use std::time::Duration; use block_height_monitor::BlockHeightMonitor; +use broadcaster::confirm_tx::TxConfirmer; use cosmrs::proto::cosmos::{ auth::v1beta1::query_client::QueryClient as AuthQueryClient, bank::v1beta1::query_client::QueryClient as BankQueryClient, @@ -12,8 +13,10 @@ use evm::json_rpc::EthereumClient; use router_api::ChainName; use thiserror::Error; use tokio::signal::unix::{signal, SignalKind}; +use tokio::sync::mpsc; use tokio::time::interval; use tokio_util::sync::CancellationToken; +use tonic::transport::Channel; use tracing::info; use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; @@ -96,7 +99,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { .auth_query_client(auth_query_client) .bank_query_client(bank_query_client) .address_prefix(PREFIX.to_string()) - .client(service_client) + .client(service_client.clone()) .signer(multisig_client.clone()) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast.clone()) @@ -115,6 +118,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { App::new( tm_client, broadcaster, + service_client, multisig_client, broadcast, event_buffer_cap, @@ -149,6 +153,7 @@ where event_subscriber: event_sub::EventSubscriber, event_processor: TaskGroup, broadcaster: QueuedBroadcaster, + tx_confirmer: TxConfirmer>, multisig_client: MultisigClient, block_height_monitor: BlockHeightMonitor, health_check_server: health_check::Server, @@ -163,6 +168,7 @@ where fn new( tm_client: tendermint_rpc::HttpClient, broadcaster: T, + service_client: ServiceClient, multisig_client: MultisigClient, broadcast_cfg: broadcaster::Config, event_buffer_cap: usize, @@ -174,12 +180,24 @@ where let (event_publisher, event_subscriber) = event_sub::EventPublisher::new(tm_client, event_buffer_cap); + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); + let event_processor = TaskGroup::new(); let broadcaster = QueuedBroadcaster::new( broadcaster, broadcast_cfg.batch_gas_limit, broadcast_cfg.queue_cap, interval(broadcast_cfg.broadcast_interval), + tx_confirmer_sender, + tx_res_receiver, + ); + let tx_confirmer = TxConfirmer::new( + service_client, + broadcast_cfg.tx_fetch_interval, + broadcast_cfg.tx_fetch_max_retries.saturating_add(1), + tx_confirmer_receiver, + tx_res_sender, ); Self { @@ -187,6 +205,7 @@ where event_subscriber, event_processor, broadcaster, + tx_confirmer, multisig_client, block_height_monitor, health_check_server, @@ -344,6 +363,7 @@ where event_publisher, event_processor, broadcaster, + tx_confirmer, block_height_monitor, health_check_server, token, @@ -386,6 +406,9 @@ where .run(token) .change_context(Error::EventProcessor) })) + .add_task(CancellableTask::create(|_| { + tx_confirmer.run().change_context(Error::TxConfirmer) + })) .add_task(CancellableTask::create(|_| { broadcaster.run().change_context(Error::Broadcaster) })) @@ -402,6 +425,8 @@ pub enum Error { EventProcessor, #[error("broadcaster failed")] Broadcaster, + #[error("tx confirmer failed")] + TxConfirmer, #[error("tofnd failed")] Tofnd, #[error("connection failed")] diff --git a/ampd/src/queue/mod.rs b/ampd/src/queue/mod.rs index 2a6ce0415..d7568b662 100644 --- a/ampd/src/queue/mod.rs +++ b/ampd/src/queue/mod.rs @@ -1,2 +1,3 @@ mod msg_queue; +mod proto; pub mod queued_broadcaster; diff --git a/ampd/src/queue/proto.rs b/ampd/src/queue/proto.rs new file mode 100644 index 000000000..322f2ab62 --- /dev/null +++ b/ampd/src/queue/proto.rs @@ -0,0 +1,42 @@ +use cosmrs::proto::traits::TypeUrl; + +pub mod axelar { + pub mod auxiliary { + pub mod v1beta1 { + tonic::include_proto!("axelar.auxiliary.v1beta1"); + } + } +} + +mod cosmos { + pub mod base { + pub mod abci { + pub mod v1beta1 { + tonic::include_proto!("cosmos.base.abci.v1beta1"); + } + } + } +} + +mod tendermint { + #[allow(clippy::large_enum_variant)] + pub mod abci { + tonic::include_proto!("tendermint.abci"); + } + + pub mod crypto { + tonic::include_proto!("tendermint.crypto"); + } + + pub mod types { + tonic::include_proto!("tendermint.types"); + } + + pub mod version { + tonic::include_proto!("tendermint.version"); + } +} + +impl TypeUrl for axelar::auxiliary::v1beta1::BatchRequest { + const TYPE_URL: &'static str = "/axelar.auxiliary.v1beta1.BatchRequest"; +} diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index ef1b549fc..af35f9325 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -1,4 +1,5 @@ use async_trait::async_trait; +use cosmrs::tx::MessageExt; use cosmrs::{Any, Gas}; use error_stack::{self, Report, ResultExt}; use mockall::automock; @@ -10,6 +11,8 @@ use tracing::info; use tracing::warn; use super::msg_queue::MsgQueue; +use super::proto; +use crate::broadcaster::confirm_tx::{TxResponse, TxStatus}; use crate::broadcaster::Broadcaster; type Result = error_stack::Result; @@ -25,6 +28,10 @@ pub enum Error { Client, #[error("failed to queue message")] Queue, + #[error("failed to confirm transaction")] + TxConfirmation, + #[error("failed to decode tx response")] + DecodeTxResponse(#[from] prost::DecodeError), } #[automock] @@ -59,6 +66,8 @@ where batch_gas_limit: Gas, channel: Option<(mpsc::Sender, mpsc::Receiver)>, broadcast_interval: Interval, + tx_confirmer_sender: mpsc::Sender, + tx_confirmer_receiver: mpsc::Receiver, } impl QueuedBroadcaster @@ -70,6 +79,8 @@ where batch_gas_limit: Gas, capacity: usize, broadcast_interval: Interval, + tx_confirmer_sender: mpsc::Sender, + tx_res_receiver: mpsc::Receiver, ) -> Self { Self { broadcaster, @@ -77,6 +88,8 @@ where batch_gas_limit, channel: Some(mpsc::channel(capacity)), broadcast_interval, + tx_confirmer_sender, + tx_confirmer_receiver: tx_res_receiver, } } @@ -96,10 +109,18 @@ where self.broadcast_all().await?; self.broadcast_interval.reset(); }, + Some(tx_res) = self.tx_confirmer_receiver.recv() => self.handle_tx_res(tx_res).await?, } } + self.clean_up().await + } + + async fn clean_up(mut self) -> Result { self.broadcast_all().await?; + while let Some(tx_res) = self.tx_confirmer_receiver.recv().await { + self.handle_tx_res(tx_res).await?; + } Ok(()) } @@ -115,6 +136,30 @@ where } } + async fn handle_tx_res(&self, tx_res: TxResponse) -> Result { + let tx_hash = tx_res.response.txhash; + + match tx_res.status { + TxStatus::Success => { + tx_res.response.logs.iter().for_each(|log| { + let msg_index = log.msg_index; + + log.events + .iter() + .enumerate() + .for_each(|(event_index, event)| { + info!(tx_hash, msg_index, event_index, "tx event {:?}", event); + }); + }); + } + TxStatus::Failure => { + warn!(tx_hash, "tx failed"); + } + } + + Ok(()) + } + async fn broadcast_all(&mut self) -> Result { let msgs = self.queue.pop_all(); @@ -123,11 +168,25 @@ where n => { info!(message_count = n, "ready to broadcast messages"); - self.broadcaster - .broadcast(msgs) + let batch_req = proto::axelar::auxiliary::v1beta1::BatchRequest { + sender: self.broadcaster.sender_address().as_ref().to_bytes(), + messages: msgs, + } + .to_any() + .expect("failed to serialize proto message for batch request"); + + let tx_hash = self + .broadcaster + .broadcast(vec![batch_req]) + .await + .change_context(Error::Broadcast)? + .txhash; + self.tx_confirmer_sender + .send(tx_hash) .await - .map(|_| ()) - .change_context(Error::Broadcast) + .change_context(Error::TxConfirmation)?; + + Ok(()) } } } @@ -173,17 +232,21 @@ where #[cfg(test)] mod test { use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; - use cosmrs::tx::Fee; + use cosmrs::tx::{Fee, MessageExt}; use cosmrs::Any; use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use error_stack::Report; + use futures::StreamExt; use tokio::sync::mpsc; use tokio::test; use tokio::time::{interval, timeout, Duration, Instant}; + use tokio_stream::wrappers::ReceiverStream; use super::{Error, QueuedBroadcaster}; use crate::broadcaster::{self, MockBroadcaster}; + use crate::queue::proto; use crate::queue::queued_broadcaster::BroadcasterClient; + use crate::PREFIX; #[test] async fn should_ignore_msg_when_fee_estimation_fails() { @@ -192,8 +255,17 @@ mod test { .expect_estimate_fee() .return_once(|_| Err(Report::new(broadcaster::Error::FeeEstimation))); + let (tx_confirmer_sender, _tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let broadcast_interval = interval(Duration::from_secs(5)); - let queued_broadcaster = QueuedBroadcaster::new(broadcaster, 100, 10, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + 100, + 10, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); @@ -206,6 +278,7 @@ mod test { Error::EstimateFee )); drop(client); + drop(tx_res_sender); assert!(handle.await.unwrap().is_ok()); } @@ -231,24 +304,39 @@ mod test { payer: None, }) }); - + broadcaster + .expect_sender_address() + .once() + .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); broadcaster .expect_broadcast() - .times(1) + .once() .returning(move |msgs| { - assert_eq!(msgs.len(), tx_count); + assert_eq!(msgs.len(), 1); + let msg = msgs.first().unwrap(); + let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); + assert_eq!(msg.messages.len(), tx_count); + tx.try_send(()) .expect("Failed to send broadcast completion signal"); + Ok(TxResponse::default()) }); + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(interval_duration); broadcast_interval.tick().await; - - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + batch_gas_limit, + tx_count, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); - let _handle = tokio::spawn(queued_broadcaster.run()); + let handle = tokio::spawn(queued_broadcaster.run()); let start_time = Instant::now(); @@ -265,8 +353,14 @@ mod test { assert!(elapsed > interval_duration); assert!(elapsed < interval_duration * 2); } - Err(_) => panic!("Broadcast did not occur within the expected timeframe"), + Err(_) => panic!("broadcast did not occur within the expected timeframe"), } + + drop(client); + drop(tx_res_sender); + + assert!(handle.await.unwrap().is_ok()); + assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 1); } #[test(start_paused = true)] @@ -278,52 +372,73 @@ mod test { let interval_duration = Duration::from_secs(5); let mut broadcaster = MockBroadcaster::new(); - broadcaster.expect_estimate_fee().returning(move |_| { - Ok(Fee { - gas_limit, - amount: vec![], - granter: None, - payer: None, - }) - }); broadcaster - .expect_broadcast() - .once() - .returning(move |msgs| { - assert_eq!(msgs.len(), 9); - - Ok(TxResponse::default()) + .expect_estimate_fee() + .times(tx_count) + .returning(move |_| { + Ok(Fee { + gas_limit, + amount: vec![], + granter: None, + payer: None, + }) }); + broadcaster + .expect_sender_address() + .times(3) + .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); + let mut call_count = 0; broadcaster .expect_broadcast() - .once() + .times(3) .returning(move |msgs| { - assert_eq!(msgs.len(), 9); + call_count += 1; + + assert_eq!(msgs.len(), 1); + let msg = msgs.first().unwrap(); + let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); + + if call_count < 3 { + assert_eq!(msg.messages.len(), 9); + } else { + assert_eq!(msg.messages.len(), 2); + } Ok(TxResponse::default()) }); - + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(interval_duration); + // get rid of tick on startup broadcast_interval.tick().await; - - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, batch_size, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + batch_gas_limit, + batch_size, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); - let _handle = tokio::spawn(queued_broadcaster.run()); + let handle = tokio::spawn(queued_broadcaster.run()); let start_time = Instant::now(); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - // Advance time by a small amount to allow processing tokio::time::advance(Duration::from_millis(100)).await; let elapsed = start_time.elapsed(); - // Assert that broadcasts happened faster than the interval assert!(elapsed < interval_duration); + + drop(client); + drop(tx_res_sender); + + assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 3); + assert!(handle.await.unwrap().is_ok()); } #[test(start_paused = true)] @@ -345,35 +460,51 @@ mod test { }) }); broadcaster - .expect_broadcast() - .once() - .returning(move |msgs| { - assert_eq!(msgs.len(), tx_count - 1); - - Ok(TxResponse::default()) - }); + .expect_sender_address() + .times(2) + .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); + let mut broadcast_count = 0; broadcaster .expect_broadcast() - .once() + .times(2) .returning(move |msgs| { + broadcast_count += 1; + assert_eq!(msgs.len(), 1); + let msg = msgs.first().unwrap(); + let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); + + if broadcast_count == 1 { + assert_eq!(msg.messages.len(), tx_count - 1); + } else { + assert_eq!(msg.messages.len(), 1); + } + Ok(TxResponse::default()) }); + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(Duration::from_secs(5)); // get rid of tick on startup broadcast_interval.tick().await; - - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + batch_gas_limit, + tx_count, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - drop(client); + drop(tx_res_sender); + assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 2); assert!(handle.await.unwrap().is_ok()); } From 596b214004fbdcea84d600ee355d8077c25d70ad Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Thu, 18 Jul 2024 13:30:09 -0400 Subject: [PATCH 087/168] feat(minor-ampd): make handle sleep and max_attempts parameters configurable (#510) --- ampd/src/config.rs | 9 +- ampd/src/event_processor.rs | 85 +++++++++++++++---- ampd/src/lib.rs | 30 ++++--- ampd/src/tests/config_template.toml | 8 +- .../service-registry/src/contract/execute.rs | 2 +- 5 files changed, 97 insertions(+), 37 deletions(-) diff --git a/ampd/src/config.rs b/ampd/src/config.rs index e97311dad..ad1273a6e 100644 --- a/ampd/src/config.rs +++ b/ampd/src/config.rs @@ -1,10 +1,10 @@ use std::net::{Ipv4Addr, SocketAddrV4}; -use std::time::Duration; use serde::{Deserialize, Serialize}; use crate::broadcaster; use crate::commands::ServiceRegistryConfig; +use crate::event_processor; use crate::handlers::{self, config::deserialize_handler_configs}; use crate::tofnd::Config as TofndConfig; use crate::url::Url; @@ -15,9 +15,7 @@ pub struct Config { pub health_check_bind_addr: SocketAddrV4, pub tm_jsonrpc: Url, pub tm_grpc: Url, - pub event_buffer_cap: usize, - #[serde(with = "humantime_serde")] - pub event_stream_timeout: Duration, + pub event_processor: event_processor::Config, pub broadcast: broadcaster::Config, #[serde(deserialize_with = "deserialize_handler_configs")] pub handlers: Vec, @@ -33,8 +31,7 @@ impl Default for Config { broadcast: broadcaster::Config::default(), handlers: vec![], tofnd_config: TofndConfig::default(), - event_buffer_cap: 100000, - event_stream_timeout: Duration::from_secs(15), + event_processor: event_processor::Config::default(), service_registry: ServiceRegistryConfig::default(), health_check_bind_addr: SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 3000), } diff --git a/ampd/src/event_processor.rs b/ampd/src/event_processor.rs index 889fc7457..901041276 100644 --- a/ampd/src/event_processor.rs +++ b/ampd/src/event_processor.rs @@ -7,6 +7,7 @@ use error_stack::{Context, Result, ResultExt}; use events::Event; use futures::StreamExt; use report::LoggableError; +use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio::time::timeout; use tokio_stream::Stream; @@ -36,6 +37,27 @@ pub enum Error { Tasks(#[from] TaskError), } +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] +pub struct Config { + #[serde(with = "humantime_serde")] + pub retry_delay: Duration, + pub retry_max_attempts: u64, + #[serde(with = "humantime_serde")] + pub stream_timeout: Duration, + pub stream_buffer_size: usize, +} + +impl Default for Config { + fn default() -> Self { + Self { + retry_delay: Duration::from_secs(1), + retry_max_attempts: 3, + stream_timeout: Duration::from_secs(15), + stream_buffer_size: 100000, + } + } +} + /// Let the `handler` consume events from the `event_stream`. The token is checked for cancellation /// at the end of each consumed block or when the `event_stream` times out. If the token is cancelled or the /// `event_stream` is closed, the function returns @@ -44,7 +66,7 @@ pub async fn consume_events( handler: H, broadcaster: B, event_stream: S, - stream_timeout: Duration, + event_processor_config: Config, token: CancellationToken, ) -> Result<(), Error> where @@ -55,12 +77,20 @@ where { let mut event_stream = Box::pin(event_stream); loop { - let stream_status = retrieve_next_event(&mut event_stream, stream_timeout) - .await - .change_context(Error::EventStream)?; + let stream_status = + retrieve_next_event(&mut event_stream, event_processor_config.stream_timeout) + .await + .change_context(Error::EventStream)?; if let StreamStatus::Active(event) = &stream_status { - handle_event(&handler, &broadcaster, event).await?; + handle_event( + &handler, + &broadcaster, + event, + event_processor_config.retry_delay, + event_processor_config.retry_max_attempts, + ) + .await?; } if let StreamStatus::Active(Event::BlockEnd(height)) = &stream_status { @@ -77,7 +107,13 @@ where } } -async fn handle_event(handler: &H, broadcaster: &B, event: &Event) -> Result<(), Error> +async fn handle_event( + handler: &H, + broadcaster: &B, + event: &Event, + handle_sleep_duration: Duration, + handle_max_attempts: u64, +) -> Result<(), Error> where H: EventHandler, B: BroadcasterClient, @@ -85,10 +121,9 @@ where // if handlers run into errors we log them and then move on to the next event match future::with_retry( || handler.handle(event), - // TODO: make timeout and max_attempts configurable RetryPolicy::RepeatConstant { - sleep: Duration::from_secs(1), - max_attempts: 3, + sleep: handle_sleep_duration, + max_attempts: handle_max_attempts, }, ) .await @@ -162,10 +197,22 @@ mod tests { use crate::event_processor; use crate::{ - event_processor::{consume_events, Error, EventHandler}, + event_processor::{consume_events, Config, Error, EventHandler}, queue::queued_broadcaster::MockBroadcasterClient, }; + pub fn setup_event_config( + retry_delay_value: Duration, + stream_timeout_value: Duration, + ) -> Config { + Config { + retry_delay: retry_delay_value, + retry_max_attempts: 3, + stream_timeout: stream_timeout_value, + stream_buffer_size: 100000, + } + } + #[tokio::test] async fn stop_when_stream_closes() { let events: Vec> = vec![ @@ -181,6 +228,7 @@ mod tests { .returning(|_| Ok(vec![])); let broadcaster = MockBroadcasterClient::new(); + let event_config = setup_event_config(Duration::from_secs(1), Duration::from_secs(1000)); let result_with_timeout = timeout( Duration::from_secs(1), @@ -189,7 +237,7 @@ mod tests { handler, broadcaster, stream::iter(events), - Duration::from_secs(1000), + event_config, CancellationToken::new(), ), ) @@ -210,6 +258,7 @@ mod tests { handler.expect_handle().times(1).returning(|_| Ok(vec![])); let broadcaster = MockBroadcasterClient::new(); + let event_config = setup_event_config(Duration::from_secs(1), Duration::from_secs(1000)); let result_with_timeout = timeout( Duration::from_secs(1), @@ -218,7 +267,7 @@ mod tests { handler, broadcaster, stream::iter(events), - Duration::from_secs(1000), + event_config, CancellationToken::new(), ), ) @@ -240,6 +289,7 @@ mod tests { .returning(|_| Err(report!(EventHandlerError::Failed))); let broadcaster = MockBroadcasterClient::new(); + let event_config = setup_event_config(Duration::from_secs(1), Duration::from_secs(1000)); let result_with_timeout = timeout( Duration::from_secs(3), @@ -248,7 +298,7 @@ mod tests { handler, broadcaster, stream::iter(events), - Duration::from_secs(1000), + event_config, CancellationToken::new(), ), ) @@ -269,6 +319,7 @@ mod tests { .once() .returning(|_| Ok(vec![dummy_msg(), dummy_msg()])); + let event_config = setup_event_config(Duration::from_secs(1), Duration::from_secs(1000)); let mut broadcaster = MockBroadcasterClient::new(); broadcaster .expect_broadcast() @@ -282,7 +333,7 @@ mod tests { handler, broadcaster, stream::iter(events), - Duration::from_secs(1000), + event_config, CancellationToken::new(), ), ) @@ -306,6 +357,7 @@ mod tests { handler.expect_handle().times(4).returning(|_| Ok(vec![])); let broadcaster = MockBroadcasterClient::new(); + let event_config = setup_event_config(Duration::from_secs(1), Duration::from_secs(1000)); let token = CancellationToken::new(); token.cancel(); @@ -317,7 +369,7 @@ mod tests { handler, broadcaster, stream::iter(events), - Duration::from_secs(1000), + event_config, token, ), ) @@ -332,6 +384,7 @@ mod tests { let handler = MockEventHandler::new(); let broadcaster = MockBroadcasterClient::new(); + let event_config = setup_event_config(Duration::from_secs(1), Duration::from_secs(0)); let token = CancellationToken::new(); token.cancel(); @@ -343,7 +396,7 @@ mod tests { handler, broadcaster, stream::pending::>(), // never returns any items so it can time out - Duration::from_secs(0), + event_config, token, ), ) diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 4a64ea177..de2eebe11 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -65,8 +65,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { broadcast, handlers, tofnd_config, - event_buffer_cap, - event_stream_timeout, + event_processor, service_registry: _service_registry, health_check_bind_addr, } = cfg; @@ -121,11 +120,11 @@ async fn prepare_app(cfg: Config) -> Result, Error> { service_client, multisig_client, broadcast, - event_buffer_cap, + event_processor.stream_buffer_size, block_height_monitor, health_check_server, ) - .configure_handlers(verifier, handlers, event_stream_timeout) + .configure_handlers(verifier, handlers, event_processor) .await } @@ -217,7 +216,7 @@ where mut self, verifier: TMAddress, handler_configs: Vec, - stream_timeout: Duration, + event_processor_config: event_processor::Config, ) -> Result, Error> { for config in handler_configs { let task = match config { @@ -247,7 +246,7 @@ where rpc_client, self.block_height_monitor.latest_block_height(), ), - stream_timeout, + event_processor_config.clone(), ) } handlers::config::Config::EvmVerifierSetVerifier { @@ -276,7 +275,7 @@ where rpc_client, self.block_height_monitor.latest_block_height(), ), - stream_timeout, + event_processor_config.clone(), ) } handlers::config::Config::MultisigSigner { cosmwasm_contract } => self @@ -288,7 +287,7 @@ where self.multisig_client.clone(), self.block_height_monitor.latest_block_height(), ), - stream_timeout, + event_processor_config.clone(), ), handlers::config::Config::SuiMsgVerifier { cosmwasm_contract, @@ -309,7 +308,7 @@ where ), self.block_height_monitor.latest_block_height(), ), - stream_timeout, + event_processor_config.clone(), ), handlers::config::Config::SuiVerifierSetVerifier { cosmwasm_contract, @@ -330,7 +329,7 @@ where ), self.block_height_monitor.latest_block_height(), ), - stream_timeout, + event_processor_config.clone(), ), }; self.event_processor = self.event_processor.add_task(task); @@ -343,7 +342,7 @@ where &mut self, label: L, handler: H, - stream_timeout: Duration, + event_processor_config: event_processor::Config, ) -> CancellableTask> where L: AsRef, @@ -354,7 +353,14 @@ where let sub = self.event_subscriber.subscribe(); CancellableTask::create(move |token| { - event_processor::consume_events(label, handler, broadcaster, sub, stream_timeout, token) + event_processor::consume_events( + label, + handler, + broadcaster, + sub, + event_processor_config, + token, + ) }) } diff --git a/ampd/src/tests/config_template.toml b/ampd/src/tests/config_template.toml index df4cb492b..30865dbd9 100644 --- a/ampd/src/tests/config_template.toml +++ b/ampd/src/tests/config_template.toml @@ -1,8 +1,12 @@ health_check_bind_addr = '0.0.0.0:3000' tm_jsonrpc = 'http://localhost:26657/' tm_grpc = 'tcp://localhost:9090' -event_buffer_cap = 100000 -event_stream_timeout = '15s' + +[event_processor] +retry_delay = '1s' +retry_max_attempts = 3 +stream_timeout = '15s' +stream_buffer_size = 100000 [broadcast] chain_id = 'axelar-dojo-1' diff --git a/contracts/service-registry/src/contract/execute.rs b/contracts/service-registry/src/contract/execute.rs index 3b6068094..ab7ecb14f 100644 --- a/contracts/service-registry/src/contract/execute.rs +++ b/contracts/service-registry/src/contract/execute.rs @@ -219,6 +219,6 @@ pub fn claim_stake( denom: service.bond_denom, amount: released_bond, }] - .to_vec(), // TODO: isolate coins + .to_vec(), })) } From a7f3b99a41a72ac471386e105a33dee066084d32 Mon Sep 17 00:00:00 2001 From: Talal Ashraf Date: Fri, 19 Jul 2024 10:22:40 -0400 Subject: [PATCH 088/168] revert: chore: force cosmwasm-check install for build wasm release check (#519) (#522) --- .github/workflows/basic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index 2c8b3e572..66a76be10 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -83,7 +83,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: install - args: --version 1.5.5 --locked cosmwasm-check --force + args: --version 1.5.5 --locked cosmwasm-check - name: Check wasm contracts run: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm From deab56a75209a158c082cbf9b77caf500eb4ec7c Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Fri, 19 Jul 2024 10:25:24 -0400 Subject: [PATCH 089/168] chore(fmt): enforce unique import sorting in PR checks (#524) --- .github/workflows/basic.yaml | 14 ++++-- ampd/src/asyncutil/future.rs | 5 +- ampd/src/asyncutil/task.rs | 8 ++-- ampd/src/block_height_monitor.rs | 19 +++----- ampd/src/broadcaster/confirm_tx.rs | 9 ++-- ampd/src/broadcaster/cosmos.rs | 1 - ampd/src/broadcaster/dec_coin.rs | 6 ++- ampd/src/broadcaster/mod.rs | 13 ++--- ampd/src/broadcaster/tx.rs | 27 +++++------ ampd/src/commands/mod.rs | 14 ++---- ampd/src/commands/register_public_key.rs | 23 ++++----- ampd/src/commands/verifier_address.rs | 3 +- ampd/src/config.rs | 13 ++--- ampd/src/event_processor.rs | 12 ++--- ampd/src/event_sub.rs | 9 ++-- ampd/src/evm/finalizer.rs | 9 ++-- ampd/src/evm/json_rpc.rs | 6 +-- ampd/src/evm/verifier.rs | 30 +++++------- ampd/src/grpc/client.rs | 23 ++++----- ampd/src/grpc/server/ampd.rs | 20 ++++---- ampd/src/grpc/server/crypto.rs | 12 ++--- ampd/src/grpc/server/mod.rs | 10 ++-- ampd/src/handlers/config.rs | 5 +- ampd/src/handlers/evm_verify_msg.rs | 24 +++++----- ampd/src/handlers/evm_verify_verifier_set.rs | 48 +++++++++---------- ampd/src/handlers/multisig.rs | 34 ++++++------- ampd/src/handlers/sui_verify_msg.rs | 23 ++++----- ampd/src/handlers/sui_verify_verifier_set.rs | 31 ++++++------ ampd/src/health_check.rs | 14 ++++-- ampd/src/json_rpc.rs | 3 +- ampd/src/lib.rs | 21 ++++---- ampd/src/main.rs | 11 ++--- ampd/src/queue/msg_queue.rs | 5 +- ampd/src/queue/queued_broadcaster.rs | 9 ++-- ampd/src/sui/verifier.rs | 28 +++++------ ampd/src/tofnd/grpc.rs | 17 +++---- ampd/src/types.rs | 3 +- ampd/src/url.rs | 5 +- contracts/coordinator/src/bin/schema.rs | 3 +- contracts/coordinator/src/contract.rs | 14 +++--- contracts/coordinator/src/contract/execute.rs | 2 +- .../src/contract/migrations/v0_2_0.rs | 16 ++++--- contracts/coordinator/src/contract/query.rs | 3 +- contracts/coordinator/src/msg.rs | 3 +- contracts/coordinator/src/state.rs | 6 ++- contracts/gateway/src/bin/schema.rs | 3 +- contracts/gateway/src/contract.rs | 3 +- contracts/gateway/src/contract/query.rs | 5 +- contracts/gateway/tests/contract.rs | 7 ++- contracts/multisig-prover/src/bin/schema.rs | 1 - contracts/multisig-prover/src/contract.rs | 46 ++++++++---------- .../src/encoding/abi/execute_data.rs | 35 ++++++-------- .../multisig-prover/src/encoding/abi/mod.rs | 21 ++++---- contracts/multisig-prover/src/error.rs | 5 +- contracts/multisig-prover/src/events.rs | 3 +- contracts/multisig-prover/src/execute.rs | 38 +++++++-------- contracts/multisig-prover/src/msg.rs | 6 ++- contracts/multisig-prover/src/payload.rs | 14 +++--- contracts/multisig-prover/src/query.rs | 15 +++--- contracts/multisig-prover/src/reply.rs | 9 ++-- contracts/multisig-prover/src/state.rs | 10 ++-- .../multisig-prover/src/test/test_data.rs | 8 ++-- .../multisig-prover/src/test/test_utils.rs | 5 +- contracts/multisig/src/bin/schema.rs | 1 - contracts/multisig/src/contract.rs | 44 ++++++++--------- contracts/multisig/src/contract/execute.rs | 13 ++--- .../src/contract/migrations/v0_4_1.rs | 7 ++- contracts/multisig/src/contract/query.rs | 11 ++--- contracts/multisig/src/ed25519.rs | 3 +- contracts/multisig/src/events.rs | 6 +-- contracts/multisig/src/key.rs | 37 +++++++------- contracts/multisig/src/msg.rs | 8 ++-- contracts/multisig/src/multisig.rs | 22 ++++----- contracts/multisig/src/secp256k1.rs | 3 +- contracts/multisig/src/signing.rs | 21 ++++---- contracts/multisig/src/state.rs | 14 +++--- contracts/multisig/src/test/common.rs | 6 +-- contracts/multisig/src/types.rs | 3 +- contracts/multisig/src/verifier_set.rs | 4 +- contracts/nexus-gateway/src/bin/schema.rs | 1 - .../nexus-gateway/src/contract/execute.rs | 7 +-- contracts/nexus-gateway/src/error.rs | 3 +- contracts/nexus-gateway/src/nexus.rs | 3 +- contracts/rewards/src/bin/schema.rs | 1 - contracts/rewards/src/contract.rs | 11 ++--- contracts/rewards/src/contract/execute.rs | 25 ++++------ .../rewards/src/contract/migrations/v0_4_0.rs | 3 +- contracts/rewards/src/contract/query.rs | 18 +++---- contracts/rewards/src/state.rs | 15 ++++-- contracts/router/src/bin/schema.rs | 3 +- contracts/router/src/contract.rs | 26 +++++----- contracts/router/src/contract/execute.rs | 21 ++++---- .../router/src/contract/migrations/v0_3_3.rs | 9 ++-- contracts/router/src/contract/query.rs | 6 +-- contracts/service-registry/src/bin/schema.rs | 1 - contracts/service-registry/src/contract.rs | 10 ++-- .../service-registry/src/contract/execute.rs | 3 +- .../service-registry/src/contract/query.rs | 3 +- contracts/service-registry/src/helpers.rs | 3 +- .../service-registry/src/migrations/v_0_4.rs | 4 +- contracts/service-registry/src/state.rs | 15 +++--- contracts/voting-verifier/src/bin/schema.rs | 1 - contracts/voting-verifier/src/client.rs | 26 ++++------ contracts/voting-verifier/src/contract.rs | 34 ++++++------- contracts/voting-verifier/src/events.rs | 19 ++++---- contracts/voting-verifier/src/execute.rs | 40 +++++++--------- contracts/voting-verifier/src/msg.rs | 11 ++--- contracts/voting-verifier/src/query.rs | 33 +++++-------- contracts/voting-verifier/src/state.rs | 13 ++--- integration-tests/src/coordinator_contract.rs | 3 +- integration-tests/src/gateway_contract.rs | 3 +- integration-tests/src/multisig_contract.rs | 3 +- .../src/multisig_prover_contract.rs | 4 +- integration-tests/src/protocol.rs | 10 ++-- integration-tests/src/rewards_contract.rs | 3 +- integration-tests/src/router_contract.rs | 3 +- .../src/service_registry_contract.rs | 3 +- .../src/voting_verifier_contract.rs | 8 ++-- .../tests/chain_freeze_unfreeze.rs | 1 - integration-tests/tests/message_routing.rs | 1 - integration-tests/tests/test_utils/mod.rs | 32 +++++-------- integration-tests/tests/update_worker_set.rs | 4 +- packages/axelar-wasm-std/src/error.rs | 3 +- packages/axelar-wasm-std/src/flagset.rs | 4 +- packages/axelar-wasm-std/src/killswitch.rs | 3 +- packages/axelar-wasm-std/src/lib.rs | 12 ++--- .../src/msg_id/base_58_event_index.rs | 6 ++- .../src/msg_id/base_58_solana_event_index.rs | 3 +- packages/axelar-wasm-std/src/msg_id/mod.rs | 17 +++---- .../src/msg_id/tx_hash_event_index.rs | 6 ++- .../axelar-wasm-std/src/nonempty/timestamp.rs | 3 +- packages/axelar-wasm-std/src/nonempty/uint.rs | 3 +- packages/axelar-wasm-std/src/nonempty/vec.rs | 3 +- .../axelar-wasm-std/src/permission_control.rs | 11 +++-- packages/axelar-wasm-std/src/snapshot.rs | 6 +-- packages/axelar-wasm-std/src/voting.rs | 22 +++------ packages/client/src/lib.rs | 3 +- packages/events/src/event.rs | 3 +- packages/evm-gateway/src/lib.rs | 34 ++++++------- packages/msgs-derive/src/lib.rs | 6 +-- packages/msgs-derive/tests/macro.rs | 3 +- packages/report/src/loggable.rs | 6 ++- packages/router-api/src/msg.rs | 6 ++- packages/router-api/src/primitives.rs | 18 +++---- rustfmt.toml | 2 + 145 files changed, 769 insertions(+), 911 deletions(-) create mode 100644 rustfmt.toml diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index 66a76be10..e6b6d3d09 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -94,13 +94,13 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Install stable toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.78.0 + toolchain: nightly + components: rustfmt override: true - components: rustfmt, clippy - name: Install protoc uses: arduino/setup-protoc@v2 @@ -128,6 +128,14 @@ jobs: command: fmt args: --all -- --check + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.78.0 + components: clippy + override: true + - name: Run cargo sort uses: actions-rs/cargo@v1 with: diff --git a/ampd/src/asyncutil/future.rs b/ampd/src/asyncutil/future.rs index 5e0eb672a..a90b4c4b4 100644 --- a/ampd/src/asyncutil/future.rs +++ b/ampd/src/asyncutil/future.rs @@ -1,8 +1,8 @@ -use futures::{Future, FutureExt}; use std::pin::Pin; use std::task::{Context, Poll}; use std::time::Duration; +use futures::{Future, FutureExt}; use tokio::time; pub fn with_retry( @@ -101,7 +101,8 @@ where #[cfg(test)] mod tests { - use std::{future, sync::Mutex}; + use std::future; + use std::sync::Mutex; use tokio::time::Instant; diff --git a/ampd/src/asyncutil/task.rs b/ampd/src/asyncutil/task.rs index 1eae600d4..39d6f424a 100644 --- a/ampd/src/asyncutil/task.rs +++ b/ampd/src/asyncutil/task.rs @@ -1,7 +1,8 @@ -use axelar_wasm_std::error::extend_err; -use error_stack::{Context, Result, ResultExt}; use std::future::Future; use std::pin::Pin; + +use axelar_wasm_std::error::extend_err; +use error_stack::{Context, Result, ResultExt}; use thiserror::Error; use tokio::task::JoinSet; use tokio_util::sync::CancellationToken; @@ -109,10 +110,11 @@ pub struct TaskError; #[cfg(test)] mod test { - use crate::asyncutil::task::{CancellableTask, TaskError, TaskGroup}; use error_stack::report; use tokio_util::sync::CancellationToken; + use crate::asyncutil::task::{CancellableTask, TaskError, TaskGroup}; + #[tokio::test] async fn running_no_tasks_returns_no_error() { let tasks: TaskGroup = TaskGroup::new(); diff --git a/ampd/src/block_height_monitor.rs b/ampd/src/block_height_monitor.rs index bffbb72fa..4e9a3d8a9 100644 --- a/ampd/src/block_height_monitor.rs +++ b/ampd/src/block_height_monitor.rs @@ -1,11 +1,9 @@ -use error_stack::{Result, ResultExt}; use std::time::Duration; + +use error_stack::{Result, ResultExt}; use thiserror::Error; -use tokio::{ - select, - sync::watch::{self, Receiver, Sender}, - time, -}; +use tokio::sync::watch::{self, Receiver, Sender}; +use tokio::{select, time}; use tokio_util::sync::CancellationToken; use tracing::info; @@ -77,16 +75,13 @@ mod tests { use std::convert::TryInto; use std::time::Duration; + use async_trait::async_trait; use mockall::mock; use tendermint::block::Height; - use tokio::test; - use tokio::time; + use tokio::{test, time}; use tokio_util::sync::CancellationToken; - use crate::tm_client; - - use crate::BlockHeightMonitor; - use async_trait::async_trait; + use crate::{tm_client, BlockHeightMonitor}; #[test] #[allow(clippy::cast_possible_truncation)] diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs index 5de50051f..c9770ec97 100644 --- a/ampd/src/broadcaster/confirm_tx.rs +++ b/ampd/src/broadcaster/confirm_tx.rs @@ -5,10 +5,8 @@ use cosmrs::proto::cosmos::tx::v1beta1::{GetTxRequest, GetTxResponse}; use error_stack::{report, Report, Result}; use futures::{StreamExt, TryFutureExt}; use thiserror::Error; -use tokio::{ - sync::{mpsc, Mutex}, - time, -}; +use tokio::sync::{mpsc, Mutex}; +use tokio::time; use tokio_stream::wrappers::ReceiverStream; use tonic::Status; use tracing::error; @@ -179,7 +177,8 @@ mod test { use cosmrs::proto::cosmos::tx::v1beta1::GetTxRequest; use mockall::predicate; - use tokio::{sync::mpsc, test}; + use tokio::sync::mpsc; + use tokio::test; use super::{Error, TxConfirmer, TxResponse, TxStatus}; use crate::broadcaster::cosmos::MockBroadcastClient; diff --git a/ampd/src/broadcaster/cosmos.rs b/ampd/src/broadcaster/cosmos.rs index 9f4f8569e..f77134e4b 100644 --- a/ampd/src/broadcaster/cosmos.rs +++ b/ampd/src/broadcaster/cosmos.rs @@ -15,7 +15,6 @@ use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; use cosmrs::proto::cosmos::tx::v1beta1::{ BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, SimulateResponse, }; - use mockall::automock; use tonic::transport::Channel; use tonic::{Response, Status}; diff --git a/ampd/src/broadcaster/dec_coin.rs b/ampd/src/broadcaster/dec_coin.rs index ca2da4fff..a3d08a11d 100644 --- a/ampd/src/broadcaster/dec_coin.rs +++ b/ampd/src/broadcaster/dec_coin.rs @@ -186,10 +186,12 @@ impl Display for Denom { #[cfg(test)] mod tests { - use super::DecCoin; - use cosmrs::proto; use std::convert::TryFrom; + use cosmrs::proto; + + use super::DecCoin; + #[test] fn correct_parse() { assert!(DecCoin::new(1000.00, "uaxl").is_ok()) diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index 34ec85284..487c4e53f 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -4,6 +4,7 @@ use std::ops::Mul; use std::time::Duration; use async_trait::async_trait; +use axelar_wasm_std::FnExt; use cosmrs::proto::cosmos::auth::v1beta1::{ BaseAccount, QueryAccountRequest, QueryAccountResponse, }; @@ -14,6 +15,7 @@ use cosmrs::proto::traits::MessageExt; use cosmrs::tendermint::chain::Id; use cosmrs::tx::Fee; use cosmrs::{Amount, Coin, Denom, Gas}; +use dec_coin::DecCoin; use error_stack::{ensure, report, FutureExt, Result, ResultExt}; use futures::TryFutureExt; use k256::sha2::{Digest, Sha256}; @@ -21,16 +23,13 @@ use mockall::automock; use num_traits::{cast, Zero}; use prost::Message; use prost_types::Any; +use report::ResultCompatExt; use serde::{Deserialize, Serialize}; use thiserror::Error; use tonic::{Code, Status}; use tracing::info; -use typed_builder::TypedBuilder; - -use axelar_wasm_std::FnExt; -use dec_coin::DecCoin; -use report::ResultCompatExt; use tx::Tx; +use typed_builder::TypedBuilder; use crate::tofnd; use crate::tofnd::grpc::Multisig; @@ -370,6 +369,7 @@ fn remap_account_not_found_error( #[cfg(test)] mod tests { + use cosmrs::bank::MsgSend; use cosmrs::crypto::PublicKey; use cosmrs::proto::cosmos::auth::v1beta1::{BaseAccount, QueryAccountResponse}; use cosmrs::proto::cosmos::bank::v1beta1::QueryBalanceResponse; @@ -377,7 +377,8 @@ mod tests { use cosmrs::proto::cosmos::tx::v1beta1::{GetTxResponse, SimulateResponse}; use cosmrs::proto::traits::MessageExt; use cosmrs::proto::Any; - use cosmrs::{bank::MsgSend, tx::Msg, AccountId, Coin, Denom}; + use cosmrs::tx::Msg; + use cosmrs::{AccountId, Coin, Denom}; use ecdsa::SigningKey; use k256::Secp256k1; use rand::rngs::OsRng; diff --git a/ampd/src/broadcaster/tx.rs b/ampd/src/broadcaster/tx.rs index 48fee8f98..bcea228e8 100644 --- a/ampd/src/broadcaster/tx.rs +++ b/ampd/src/broadcaster/tx.rs @@ -1,12 +1,10 @@ use core::fmt::Debug; use std::future::Future; +use cosmrs::proto::cosmos::tx::v1beta1::TxRaw; use cosmrs::tendermint::chain::Id; -use cosmrs::{ - proto::cosmos::tx::v1beta1::TxRaw, - tx::{BodyBuilder, Fee, SignDoc, SignerInfo}, - Any, Coin, -}; +use cosmrs::tx::{BodyBuilder, Fee, SignDoc, SignerInfo}; +use cosmrs::{Any, Coin}; use error_stack::{Context, Result, ResultExt}; use report::ResultCompatExt; use thiserror::Error; @@ -98,24 +96,21 @@ where #[cfg(test)] mod tests { + use cosmrs::bank::MsgSend; + use cosmrs::bip32::secp256k1::elliptic_curve::rand_core::OsRng; + use cosmrs::crypto::secp256k1::SigningKey; + use cosmrs::proto::cosmos::tx::v1beta1::TxRaw; use cosmrs::proto::Any; - use cosmrs::{ - bank::MsgSend, - bip32::secp256k1::elliptic_curve::rand_core::OsRng, - crypto::secp256k1::SigningKey, - proto::cosmos::tx::v1beta1::TxRaw, - tendermint::chain::Id, - tx::{BodyBuilder, Fee, Msg, SignDoc, SignerInfo}, - AccountId, Coin, - }; + use cosmrs::tendermint::chain::Id; + use cosmrs::tx::{BodyBuilder, Fee, Msg, SignDoc, SignerInfo}; + use cosmrs::{AccountId, Coin}; use error_stack::Result; use k256::ecdsa; use k256::sha2::{Digest, Sha256}; use tokio::test; - use crate::types::PublicKey; - use super::{Error, Tx, DUMMY_CHAIN_ID}; + use crate::types::PublicKey; #[test] async fn sign_with_should_produce_the_correct_tx() { diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index c00e47911..5f4d091d2 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -1,14 +1,11 @@ use clap::Subcommand; +use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient as AuthQueryClient; +use cosmrs::proto::cosmos::bank::v1beta1::query_client::QueryClient as BankQueryClient; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmrs::proto::cosmos::{ - auth::v1beta1::query_client::QueryClient as AuthQueryClient, - bank::v1beta1::query_client::QueryClient as BankQueryClient, - tx::v1beta1::service_client::ServiceClient, -}; +use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; use cosmrs::proto::Any; use cosmrs::AccountId; -use error_stack::Result; -use error_stack::ResultExt; +use error_stack::{Result, ResultExt}; use serde::{Deserialize, Serialize}; use valuable::Valuable; @@ -16,8 +13,7 @@ use crate::broadcaster::Broadcaster; use crate::config::Config as AmpdConfig; use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::{PublicKey, TMAddress}; -use crate::{broadcaster, Error}; -use crate::{tofnd, PREFIX}; +use crate::{broadcaster, tofnd, Error, PREFIX}; pub mod bond_verifier; pub mod daemon; diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index 960d6885c..e0e8d0c7a 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -1,24 +1,21 @@ use std::convert::{TryFrom, TryInto}; -use cosmrs::{cosmwasm::MsgExecuteContract, tx::Msg}; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; use error_stack::{Result, ResultExt}; -use multisig::{key::PublicKey, msg::ExecuteMsg}; +use multisig::key::PublicKey; +use multisig::msg::ExecuteMsg; use report::ResultCompatExt; use sha3::{Digest, Keccak256}; use tracing::info; use valuable::Valuable; -use crate::{ - commands::{broadcast_tx, verifier_pub_key}, - config::Config, - handlers, - tofnd::{ - self, - grpc::{Multisig, MultisigClient}, - }, - types::TMAddress, - Error, PREFIX, -}; +use crate::commands::{broadcast_tx, verifier_pub_key}; +use crate::config::Config; +use crate::tofnd::grpc::{Multisig, MultisigClient}; +use crate::tofnd::{self}; +use crate::types::TMAddress; +use crate::{handlers, Error, PREFIX}; #[derive(clap::ValueEnum, Clone, Debug, Valuable, Copy)] enum KeyType { diff --git a/ampd/src/commands/verifier_address.rs b/ampd/src/commands/verifier_address.rs index a4afb66a3..d3b9f70f8 100644 --- a/ampd/src/commands/verifier_address.rs +++ b/ampd/src/commands/verifier_address.rs @@ -4,8 +4,7 @@ use report::ResultCompatExt; use crate::commands::verifier_pub_key; use crate::tofnd::Config as TofndConfig; -use crate::Error; -use crate::PREFIX; +use crate::{Error, PREFIX}; pub async fn run(config: TofndConfig) -> Result, Error> { verifier_pub_key(config) diff --git a/ampd/src/config.rs b/ampd/src/config.rs index ad1273a6e..dfca06d65 100644 --- a/ampd/src/config.rs +++ b/ampd/src/config.rs @@ -2,12 +2,12 @@ use std::net::{Ipv4Addr, SocketAddrV4}; use serde::{Deserialize, Serialize}; -use crate::broadcaster; use crate::commands::ServiceRegistryConfig; -use crate::event_processor; -use crate::handlers::{self, config::deserialize_handler_configs}; +use crate::handlers::config::deserialize_handler_configs; +use crate::handlers::{self}; use crate::tofnd::Config as TofndConfig; use crate::url::Url; +use crate::{broadcaster, event_processor}; #[derive(Deserialize, Serialize, Debug, PartialEq)] #[serde(default)] @@ -48,17 +48,14 @@ mod tests { use std::time::Duration; use cosmrs::AccountId; - use router_api::ChainName; + use super::Config; use crate::evm::finalizer::Finalization; - use crate::handlers::config::Chain; - use crate::handlers::config::Config as HandlerConfig; + use crate::handlers::config::{Chain, Config as HandlerConfig}; use crate::types::TMAddress; use crate::url::Url; - use super::Config; - const PREFIX: &str = "axelar"; #[test] diff --git a/ampd/src/event_processor.rs b/ampd/src/event_processor.rs index 901041276..204b0c64f 100644 --- a/ampd/src/event_processor.rs +++ b/ampd/src/event_processor.rs @@ -12,8 +12,7 @@ use thiserror::Error; use tokio::time::timeout; use tokio_stream::Stream; use tokio_util::sync::CancellationToken; -use tracing::info; -use tracing::warn; +use tracing::{info, warn}; use valuable::Valuable; use crate::asyncutil::future::{self, RetryPolicy}; @@ -183,6 +182,8 @@ enum StreamStatus { #[cfg(test)] mod tests { + use std::time::Duration; + use async_trait::async_trait; use cosmrs::bank::MsgSend; use cosmrs::tx::Msg; @@ -191,15 +192,12 @@ mod tests { use events::Event; use futures::stream; use mockall::mock; - use std::time::Duration; use tokio::time::timeout; use tokio_util::sync::CancellationToken; use crate::event_processor; - use crate::{ - event_processor::{consume_events, Config, Error, EventHandler}, - queue::queued_broadcaster::MockBroadcasterClient, - }; + use crate::event_processor::{consume_events, Config, Error, EventHandler}; + use crate::queue::queued_broadcaster::MockBroadcasterClient; pub fn setup_event_config( retry_delay_value: Duration, diff --git a/ampd/src/event_sub.rs b/ampd/src/event_sub.rs index 274e24e5b..d7393ab9e 100644 --- a/ampd/src/event_sub.rs +++ b/ampd/src/event_sub.rs @@ -1,23 +1,20 @@ use std::iter; use std::time::Duration; -use error_stack::ResultExt; -use error_stack::{FutureExt, Report, Result}; +use error_stack::{FutureExt, Report, Result, ResultExt}; +use events::Event; use futures::TryStreamExt; use mockall::automock; use tendermint::block; use thiserror::Error; -use tokio::select; use tokio::sync::broadcast::{self, Sender}; -use tokio::time; +use tokio::{select, time}; use tokio_stream::wrappers::errors::BroadcastStreamRecvError; use tokio_stream::wrappers::BroadcastStream; use tokio_stream::Stream; use tokio_util::sync::CancellationToken; use tracing::info; -use events::Event; - use crate::asyncutil::future::{self, RetryPolicy}; use crate::tm_client::TmClient; diff --git a/ampd/src/evm/finalizer.rs b/ampd/src/evm/finalizer.rs index b5dedda23..f47cdbf47 100644 --- a/ampd/src/evm/finalizer.rs +++ b/ampd/src/evm/finalizer.rs @@ -116,13 +116,12 @@ where #[cfg(test)] mod tests { + use ethers_core::abi::Hash; + use ethers_core::types::{Block, U64}; + use tokio::test; + use crate::evm::finalizer::{pick, ConfirmationHeightFinalizer, Finalization, Finalizer}; use crate::evm::json_rpc::MockEthereumClient; - use ethers_core::{ - abi::Hash, - types::{Block, U64}, - }; - use tokio::test; #[test] async fn latest_finalized_block_height_should_work() { diff --git a/ampd/src/evm/json_rpc.rs b/ampd/src/evm/json_rpc.rs index 3046d726d..983ef7eb0 100644 --- a/ampd/src/evm/json_rpc.rs +++ b/ampd/src/evm/json_rpc.rs @@ -1,8 +1,6 @@ use async_trait::async_trait; -use ethers_core::{ - types::{Block, BlockNumber, TransactionReceipt, H256, U64}, - utils::serialize, -}; +use ethers_core::types::{Block, BlockNumber, TransactionReceipt, H256, U64}; +use ethers_core::utils::serialize; use ethers_providers::{JsonRpcClient, ProviderError}; use mockall::automock; diff --git a/ampd/src/evm/verifier.rs b/ampd/src/evm/verifier.rs index e14722b7e..120d4313c 100644 --- a/ampd/src/evm/verifier.rs +++ b/ampd/src/evm/verifier.rs @@ -1,9 +1,8 @@ +use axelar_wasm_std::voting::Vote; use ethers_contract::EthLogDecode; use ethers_core::types::{Log, TransactionReceipt, H256}; -use num_traits::cast; - -use axelar_wasm_std::voting::Vote; use evm_gateway::{IAxelarAmplifierGatewayEvents, WeightedSigners}; +use num_traits::cast; use crate::handlers::evm_verify_msg::Message; use crate::handlers::evm_verify_verifier_set::VerifierSetConfirmation; @@ -121,24 +120,17 @@ mod tests { use axelar_wasm_std::voting::Vote; use cosmwasm_std::Uint128; use ethers_contract::EthEvent; - use ethers_core::{ - abi::{encode, Token}, - types::{Log, TransactionReceipt, H256}, - }; - use evm_gateway::{ - i_axelar_amplifier_gateway::{ContractCallFilter, SignersRotatedFilter}, - WeightedSigners, - }; - use multisig::{ - key::KeyType, - test::common::{build_verifier_set, ecdsa_test_data}, - }; + use ethers_core::abi::{encode, Token}; + use ethers_core::types::{Log, TransactionReceipt, H256}; + use evm_gateway::i_axelar_amplifier_gateway::{ContractCallFilter, SignersRotatedFilter}; + use evm_gateway::WeightedSigners; + use multisig::key::KeyType; + use multisig::test::common::{build_verifier_set, ecdsa_test_data}; use super::{verify_message, verify_verifier_set}; - use crate::{ - handlers::{evm_verify_msg::Message, evm_verify_verifier_set::VerifierSetConfirmation}, - types::{EVMAddress, Hash}, - }; + use crate::handlers::evm_verify_msg::Message; + use crate::handlers::evm_verify_verifier_set::VerifierSetConfirmation; + use crate::types::{EVMAddress, Hash}; #[test] fn should_not_verify_verifier_set_if_tx_id_does_not_match() { diff --git a/ampd/src/grpc/client.rs b/ampd/src/grpc/client.rs index 8cff0c2b3..4ea5b8f13 100644 --- a/ampd/src/grpc/client.rs +++ b/ampd/src/grpc/client.rs @@ -1,7 +1,8 @@ use error_stack::{Report, Result}; use tonic::{codegen, transport}; -use super::proto::{ampd_client::AmpdClient, crypto_client::CryptoClient}; +use super::proto::ampd_client::AmpdClient; +use super::proto::crypto_client::CryptoClient; pub struct Client { pub ampd: AmpdClient, @@ -29,8 +30,9 @@ where mod tests { use std::time::Duration; - use cosmrs::Any; - use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use cosmrs::bank::MsgSend; + use cosmrs::tx::Msg; + use cosmrs::{AccountId, Any}; use error_stack::Report; use events::Event; use futures::StreamExt; @@ -39,24 +41,23 @@ mod tests { use mockall::predicate; use rand::rngs::OsRng; use tokio::net::TcpListener; - use tokio::sync::mpsc; - use tokio::{sync::oneshot, test, time}; + use tokio::sync::{mpsc, oneshot}; + use tokio::{test, time}; use tokio_stream::wrappers::errors::BroadcastStreamRecvError; use tokio_stream::wrappers::{ReceiverStream, TcpListenerStream}; use tonic::Code; use url::Url; + use crate::event_sub::MockEventSub; + use crate::grpc; use crate::proto::{ Algorithm, BroadcastRequest, BroadcastResponse, GetKeyRequest, GetKeyResponse, SignRequest, SignResponse, SubscribeRequest, }; + use crate::queue::queued_broadcaster::MockBroadcasterClient; + use crate::tofnd::grpc::MockMultisig; + use crate::tofnd::{self}; use crate::types::PublicKey; - use crate::{ - event_sub::MockEventSub, - grpc, - queue::queued_broadcaster::MockBroadcasterClient, - tofnd::{self, grpc::MockMultisig}, - }; async fn start_server( event_sub: MockEventSub, diff --git a/ampd/src/grpc/server/ampd.rs b/ampd/src/grpc/server/ampd.rs index 966103019..5cbe6a6e3 100644 --- a/ampd/src/grpc/server/ampd.rs +++ b/ampd/src/grpc/server/ampd.rs @@ -1,4 +1,5 @@ -use std::{future, pin::Pin}; +use std::future; +use std::pin::Pin; use async_trait::async_trait; use events::Event; @@ -6,7 +7,8 @@ use futures::{Stream, StreamExt, TryStreamExt}; use tonic::{Request, Response, Status}; use super::proto; -use crate::{event_sub::EventSub, queue::queued_broadcaster::BroadcasterClient}; +use crate::event_sub::EventSub; +use crate::queue::queued_broadcaster::BroadcasterClient; impl From for proto::subscribe_response::Event { fn from(event: Event) -> Self { @@ -126,8 +128,9 @@ mod tests { use std::collections::HashMap; use std::time::Duration; - use cosmrs::Any; - use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use cosmrs::bank::MsgSend; + use cosmrs::tx::Msg; + use cosmrs::{AccountId, Any}; use error_stack::Report; use events::Event; use serde_json::Map; @@ -138,11 +141,12 @@ mod tests { use tokio_stream::StreamExt; use tonic::Code; - use crate::queue::queued_broadcaster; - use crate::{event_sub::MockEventSub, queue::queued_broadcaster::MockBroadcasterClient}; - - use super::proto::{self, ampd_server::Ampd}; + use super::proto::ampd_server::Ampd; + use super::proto::{self}; use super::Server; + use crate::event_sub::MockEventSub; + use crate::queue::queued_broadcaster; + use crate::queue::queued_broadcaster::MockBroadcasterClient; #[test] async fn subscribe_should_return_stream_of_error_when_event_subscriber_fails() { diff --git a/ampd/src/grpc/server/crypto.rs b/ampd/src/grpc/server/crypto.rs index a53ac3e63..690988c0e 100644 --- a/ampd/src/grpc/server/crypto.rs +++ b/ampd/src/grpc/server/crypto.rs @@ -2,10 +2,10 @@ use async_trait::async_trait; use k256::sha2::{Digest, Sha256}; use tonic::{Request, Response, Status}; -use crate::tofnd::{self, grpc::Multisig}; -use crate::types::PublicKey; - use super::proto; +use crate::tofnd::grpc::Multisig; +use crate::tofnd::{self}; +use crate::types::PublicKey; impl From for tofnd::Algorithm { fn from(algorithm: proto::Algorithm) -> Self { @@ -92,13 +92,13 @@ mod tests { use tokio::test; use tonic::Code; + use super::proto::crypto_server::Crypto; + use super::proto::{self}; + use super::Server; use crate::tofnd; use crate::tofnd::grpc::MockMultisig; use crate::types::PublicKey; - use super::proto::{self, crypto_server::Crypto}; - use super::Server; - #[test] async fn sign_should_return_correct_signature() { let key_id = "key_id"; diff --git a/ampd/src/grpc/server/mod.rs b/ampd/src/grpc/server/mod.rs index e5695026d..bb7483c8a 100644 --- a/ampd/src/grpc/server/mod.rs +++ b/ampd/src/grpc/server/mod.rs @@ -1,10 +1,10 @@ -use tonic::transport::{server::Router, Server}; - -use crate::{ - event_sub::EventSub, queue::queued_broadcaster::BroadcasterClient, tofnd::grpc::Multisig, -}; +use tonic::transport::server::Router; +use tonic::transport::Server; use super::proto; +use crate::event_sub::EventSub; +use crate::queue::queued_broadcaster::BroadcasterClient; +use crate::tofnd::grpc::Multisig; mod ampd; mod crypto; diff --git a/ampd/src/handlers/config.rs b/ampd/src/handlers/config.rs index 40bd94765..598a751a8 100644 --- a/ampd/src/handlers/config.rs +++ b/ampd/src/handlers/config.rs @@ -1,6 +1,7 @@ use std::time::Duration; use itertools::Itertools; +use router_api::ChainName; use serde::de::{self, Deserializer}; use serde::{Deserialize, Serialize}; use serde_with::with_prefix; @@ -8,7 +9,6 @@ use serde_with::with_prefix; use crate::evm::finalizer::Finalization; use crate::types::TMAddress; use crate::url::Url; -use router_api::ChainName; #[derive(Debug, Deserialize, Serialize, PartialEq)] pub struct Chain { @@ -160,7 +160,8 @@ where #[cfg(test)] mod tests { - use crate::{evm::finalizer::Finalization, handlers::config::Chain}; + use crate::evm::finalizer::Finalization; + use crate::handlers::config::Chain; #[test] fn finalizer_should_default_to_ethereum() { diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 6999583c4..9133e4c8a 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -2,21 +2,21 @@ use std::collections::{HashMap, HashSet}; use std::convert::TryInto; use async_trait::async_trait; +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; +use axelar_wasm_std::voting::{PollId, Vote}; use cosmrs::cosmwasm::MsgExecuteContract; -use cosmrs::{tx::Msg, Any}; +use cosmrs::tx::Msg; +use cosmrs::Any; use error_stack::ResultExt; use ethers_core::types::{TransactionReceipt, U64}; +use events::Error::EventTypeMismatch; +use events_derive::try_from; use futures::future::join_all; +use router_api::ChainName; use serde::Deserialize; use tokio::sync::watch::Receiver; use tracing::{info, info_span}; use valuable::Valuable; - -use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; -use axelar_wasm_std::voting::{PollId, Vote}; -use events::Error::EventTypeMismatch; -use events_derive::try_from; -use router_api::ChainName; use voting_verifier::msg::ExecuteMsg; use crate::event_processor::EventHandler; @@ -231,23 +231,21 @@ mod tests { use cosmwasm_std; use error_stack::{Report, Result}; use ethers_providers::ProviderError; - use tendermint::abci; - use tokio::sync::watch; - use tokio::test as async_test; - use events::Error::{DeserializationFailed, EventTypeMismatch}; use events::Event; use router_api::ChainName; + use tendermint::abci; + use tokio::sync::watch; + use tokio::test as async_test; use voting_verifier::events::{PollMetadata, PollStarted, TxEventConfirmation}; + use super::PollStartedEvent; use crate::event_processor::EventHandler; use crate::evm::finalizer::Finalization; use crate::evm::json_rpc::MockEthereumClient; use crate::types::{EVMAddress, Hash, TMAddress}; use crate::PREFIX; - use super::PollStartedEvent; - fn get_poll_started_event(participants: Vec, expires_at: u64) -> PollStarted { PollStarted::Messages { metadata: PollMetadata { diff --git a/ampd/src/handlers/evm_verify_verifier_set.rs b/ampd/src/handlers/evm_verify_verifier_set.rs index 6b85578ca..9e936f248 100644 --- a/ampd/src/handlers/evm_verify_verifier_set.rs +++ b/ampd/src/handlers/evm_verify_verifier_set.rs @@ -1,29 +1,28 @@ use std::convert::TryInto; use async_trait::async_trait; +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; +use axelar_wasm_std::voting::{PollId, Vote}; use cosmrs::cosmwasm::MsgExecuteContract; -use cosmrs::{tx::Msg, Any}; +use cosmrs::tx::Msg; +use cosmrs::Any; use error_stack::ResultExt; use ethers_core::types::{TransactionReceipt, U64}; +use events::Error::EventTypeMismatch; +use events_derive::try_from; use multisig::verifier_set::VerifierSet; +use router_api::ChainName; use serde::Deserialize; use tokio::sync::watch::Receiver; use tracing::{info, info_span}; use valuable::Valuable; - -use axelar_wasm_std::{ - msg_id::HexTxHashAndEventIndex, - voting::{PollId, Vote}, -}; -use events::Error::EventTypeMismatch; -use events_derive::try_from; -use router_api::ChainName; use voting_verifier::msg::ExecuteMsg; use crate::event_processor::EventHandler; +use crate::evm::finalizer; use crate::evm::finalizer::Finalization; +use crate::evm::json_rpc::EthereumClient; use crate::evm::verifier::verify_verifier_set; -use crate::evm::{finalizer, json_rpc::EthereumClient}; use crate::handlers::errors::Error; use crate::types::{EVMAddress, Hash, TMAddress}; @@ -199,31 +198,28 @@ where #[cfg(test)] mod tests { - use std::{convert::TryInto, str::FromStr}; + use std::convert::TryInto; + use std::str::FromStr; use base64::engine::general_purpose::STANDARD; use base64::Engine; use error_stack::{Report, Result}; use ethers_providers::ProviderError; - - use tendermint::abci; - use tokio::{sync::watch, test as async_test}; - use events::Event; - use multisig::{ - key::KeyType, - test::common::{build_verifier_set, ecdsa_test_data}, - }; + use multisig::key::KeyType; + use multisig::test::common::{build_verifier_set, ecdsa_test_data}; use router_api::ChainName; + use tendermint::abci; + use tokio::sync::watch; + use tokio::test as async_test; use voting_verifier::events::{PollMetadata, PollStarted, VerifierSetConfirmation}; - use crate::{ - event_processor::EventHandler, - evm::{finalizer::Finalization, json_rpc::MockEthereumClient}, - handlers::evm_verify_verifier_set::PollStartedEvent, - types::{Hash, TMAddress}, - PREFIX, - }; + use crate::event_processor::EventHandler; + use crate::evm::finalizer::Finalization; + use crate::evm::json_rpc::MockEthereumClient; + use crate::handlers::evm_verify_verifier_set::PollStartedEvent; + use crate::types::{Hash, TMAddress}; + use crate::PREFIX; #[test] fn should_deserialize_correct_event() { diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 00c013c0d..88a43d588 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -2,26 +2,25 @@ use std::collections::HashMap; use std::convert::TryInto; use async_trait::async_trait; -use cosmrs::{ - cosmwasm::MsgExecuteContract, - {tx::Msg, Any}, -}; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; +use cosmrs::Any; use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::VerifyingKey; use error_stack::{Report, ResultExt}; +use events::Error::EventTypeMismatch; +use events_derive::{self, try_from}; use hex::encode; -use serde::{de::Error as DeserializeError, Deserialize, Deserializer}; +use multisig::msg::ExecuteMsg; +use serde::de::Error as DeserializeError; +use serde::{Deserialize, Deserializer}; use tokio::sync::watch::Receiver; use tracing::info; -use events::Error::EventTypeMismatch; -use events_derive; -use events_derive::try_from; -use multisig::msg::ExecuteMsg; - use crate::event_processor::EventHandler; use crate::handlers::errors::Error::{self, DeserializeEvent}; -use crate::tofnd::{self, grpc::Multisig, MessageDigest}; +use crate::tofnd::grpc::Multisig; +use crate::tofnd::{self, MessageDigest}; use crate::types::{PublicKey, TMAddress}; #[derive(Debug, Deserialize)] @@ -194,6 +193,9 @@ mod test { use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::SigningKey; use error_stack::{Report, Result}; + use multisig::events::Event::SigningStarted; + use multisig::key::PublicKey; + use multisig::types::MsgToSign; use rand::distributions::Alphanumeric; use rand::rngs::OsRng; use rand::Rng; @@ -201,16 +203,10 @@ mod test { use tendermint::abci; use tokio::sync::watch; - use multisig::events::Event::SigningStarted; - use multisig::key::PublicKey; - use multisig::types::MsgToSign; - + use super::*; use crate::broadcaster::MockBroadcaster; - use crate::tofnd; use crate::tofnd::grpc::MockMultisig; - use crate::types; - - use super::*; + use crate::{tofnd, types}; const MULTISIG_ADDRESS: &str = "axelarvaloper1zh9wrak6ke4n6fclj5e8yk397czv430ygs5jz7"; diff --git a/ampd/src/handlers/sui_verify_msg.rs b/ampd/src/handlers/sui_verify_msg.rs index 86fd3838f..53dcbfdcf 100644 --- a/ampd/src/handlers/sui_verify_msg.rs +++ b/ampd/src/handlers/sui_verify_msg.rs @@ -2,22 +2,24 @@ use std::collections::HashSet; use std::convert::TryInto; use async_trait::async_trait; +use axelar_wasm_std::voting::{PollId, Vote}; use cosmrs::cosmwasm::MsgExecuteContract; -use cosmrs::{tx::Msg, Any}; +use cosmrs::tx::Msg; +use cosmrs::Any; use error_stack::ResultExt; +use events::Error::EventTypeMismatch; +use events::Event; +use events_derive::try_from; use serde::Deserialize; use sui_types::base_types::{SuiAddress, TransactionDigest}; use tokio::sync::watch::Receiver; use tracing::info; - -use axelar_wasm_std::voting::{PollId, Vote}; -use events::{Error::EventTypeMismatch, Event}; -use events_derive::try_from; use voting_verifier::msg::ExecuteMsg; use crate::event_processor::EventHandler; use crate::handlers::errors::Error; -use crate::sui::{json_rpc::SuiClient, verifier::verify_message}; +use crate::sui::json_rpc::SuiClient; +use crate::sui::verifier::verify_message; use crate::types::{Hash, TMAddress}; type Result = error_stack::Result; @@ -155,20 +157,19 @@ mod tests { use cosmwasm_std; use error_stack::{Report, Result}; use ethers_providers::ProviderError; + use events::Event; use sui_types::base_types::{SuiAddress, TransactionDigest}; use tokio::sync::watch; use tokio::test as async_test; - - use events::Event; use voting_verifier::events::{PollMetadata, PollStarted, TxEventConfirmation}; + use super::PollStartedEvent; use crate::event_processor::EventHandler; - use crate::handlers::{errors::Error, tests::get_event}; + use crate::handlers::errors::Error; + use crate::handlers::tests::get_event; use crate::sui::json_rpc::MockSuiClient; use crate::types::{EVMAddress, Hash, TMAddress}; - use super::PollStartedEvent; - const PREFIX: &str = "axelar"; #[test] diff --git a/ampd/src/handlers/sui_verify_verifier_set.rs b/ampd/src/handlers/sui_verify_verifier_set.rs index bc8cb6272..4632bc6ee 100644 --- a/ampd/src/handlers/sui_verify_verifier_set.rs +++ b/ampd/src/handlers/sui_verify_verifier_set.rs @@ -1,22 +1,22 @@ use std::convert::TryInto; use async_trait::async_trait; +use axelar_wasm_std::msg_id::Base58TxDigestAndEventIndex; +use axelar_wasm_std::voting::{PollId, Vote}; use cosmrs::cosmwasm::MsgExecuteContract; -use cosmrs::{tx::Msg, Any}; -use cosmwasm_std::HexBinary; -use cosmwasm_std::Uint128; +use cosmrs::tx::Msg; +use cosmrs::Any; +use cosmwasm_std::{HexBinary, Uint128}; use error_stack::ResultExt; +use events::Error::EventTypeMismatch; +use events::Event; +use events_derive::try_from; use multisig::verifier_set::VerifierSet; use serde::Deserialize; use sui_types::base_types::{SuiAddress, TransactionDigest}; use tokio::sync::watch::Receiver; use tracing::{info, info_span}; use valuable::Valuable; - -use axelar_wasm_std::msg_id::Base58TxDigestAndEventIndex; -use axelar_wasm_std::voting::{PollId, Vote}; -use events::{Error::EventTypeMismatch, Event}; -use events_derive::try_from; use voting_verifier::msg::ExecuteMsg; use crate::event_processor::EventHandler; @@ -165,23 +165,20 @@ mod tests { use error_stack::{Report, Result}; use ethers_providers::ProviderError; + use events::Event; + use multisig::key::KeyType; + use multisig::test::common::{build_verifier_set, ecdsa_test_data}; use sui_types::base_types::{SuiAddress, TransactionDigest}; use tokio::sync::watch; use tokio::test as async_test; - - use events::Event; - use multisig::{ - key::KeyType, - test::common::{build_verifier_set, ecdsa_test_data}, - }; use voting_verifier::events::{PollMetadata, PollStarted, VerifierSetConfirmation}; + use super::PollStartedEvent; use crate::event_processor::EventHandler; + use crate::handlers::tests::get_event; use crate::sui::json_rpc::MockSuiClient; + use crate::types::TMAddress; use crate::PREFIX; - use crate::{handlers::tests::get_event, types::TMAddress}; - - use super::PollStartedEvent; #[test] fn should_deserialize_verifier_set_poll_started_event() { diff --git a/ampd/src/health_check.rs b/ampd/src/health_check.rs index ffd366fc6..702de7598 100644 --- a/ampd/src/health_check.rs +++ b/ampd/src/health_check.rs @@ -1,11 +1,13 @@ -use error_stack::{Result, ResultExt}; use std::net::SocketAddrV4; -use thiserror::Error; -use tracing::info; -use axum::{http::StatusCode, routing::get, Json, Router}; +use axum::http::StatusCode; +use axum::routing::get; +use axum::{Json, Router}; +use error_stack::{Result, ResultExt}; use serde::{Deserialize, Serialize}; +use thiserror::Error; use tokio_util::sync::CancellationToken; +use tracing::info; #[derive(Error, Debug)] pub enum Error { @@ -55,11 +57,13 @@ struct Status { #[cfg(test)] mod tests { - use super::*; use std::net::{SocketAddr, TcpListener}; use std::time::Duration; + use tokio::test as async_test; + use super::*; + #[async_test] async fn server_lifecycle() { let bind_address = test_bind_addr(); diff --git a/ampd/src/json_rpc.rs b/ampd/src/json_rpc.rs index 20a76f69e..38df818db 100644 --- a/ampd/src/json_rpc.rs +++ b/ampd/src/json_rpc.rs @@ -2,7 +2,8 @@ use std::fmt::Debug; use error_stack::Report; use ethers_providers::{Http, JsonRpcClient, ProviderError}; -use serde::{de::DeserializeOwned, Serialize}; +use serde::de::DeserializeOwned; +use serde::Serialize; use crate::url::Url; diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index de2eebe11..a134c2fae 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -1,30 +1,27 @@ use std::time::Duration; +use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; use block_height_monitor::BlockHeightMonitor; use broadcaster::confirm_tx::TxConfirmer; -use cosmrs::proto::cosmos::{ - auth::v1beta1::query_client::QueryClient as AuthQueryClient, - bank::v1beta1::query_client::QueryClient as BankQueryClient, - tx::v1beta1::service_client::ServiceClient, -}; +use broadcaster::Broadcaster; +use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient as AuthQueryClient; +use cosmrs::proto::cosmos::bank::v1beta1::query_client::QueryClient as BankQueryClient; +use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; use error_stack::{FutureExt, Result, ResultExt}; +use event_processor::EventHandler; +use event_sub::EventSub; use evm::finalizer::{pick, Finalization}; use evm::json_rpc::EthereumClient; +use queue::queued_broadcaster::QueuedBroadcaster; use router_api::ChainName; use thiserror::Error; +use tofnd::grpc::{Multisig, MultisigClient}; use tokio::signal::unix::{signal, SignalKind}; use tokio::sync::mpsc; use tokio::time::interval; use tokio_util::sync::CancellationToken; use tonic::transport::Channel; use tracing::info; - -use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; -use broadcaster::Broadcaster; -use event_processor::EventHandler; -use event_sub::EventSub; -use queue::queued_broadcaster::QueuedBroadcaster; -use tofnd::grpc::{Multisig, MultisigClient}; use types::TMAddress; use crate::config::Config; diff --git a/ampd/src/main.rs b/ampd/src/main.rs index a15b409a1..d5881bfb5 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -4,12 +4,6 @@ use std::path::{Path, PathBuf}; use std::process::ExitCode; use ::config::{Config as cfg, Environment, File, FileFormat, FileSourceFile}; -use clap::{arg, command, Parser, ValueEnum}; -use config::ConfigError; -use error_stack::{Report, ResultExt}; -use tracing::{error, info}; -use valuable::Valuable; - use ampd::commands::{ bond_verifier, daemon, deregister_chain_support, register_chain_support, register_public_key, verifier_address, SubCommand, @@ -17,7 +11,12 @@ use ampd::commands::{ use ampd::config::Config; use ampd::Error; use axelar_wasm_std::FnExt; +use clap::{arg, command, Parser, ValueEnum}; +use config::ConfigError; +use error_stack::{Report, ResultExt}; use report::LoggableError; +use tracing::{error, info}; +use valuable::Valuable; #[derive(Debug, Parser, Valuable)] #[command(version)] diff --git a/ampd/src/queue/msg_queue.rs b/ampd/src/queue/msg_queue.rs index 5f4460da5..d12527e2e 100644 --- a/ampd/src/queue/msg_queue.rs +++ b/ampd/src/queue/msg_queue.rs @@ -44,8 +44,9 @@ impl MsgQueue { #[cfg(test)] mod test { - use cosmrs::Any; - use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use cosmrs::bank::MsgSend; + use cosmrs::tx::Msg; + use cosmrs::{AccountId, Any}; use super::MsgQueue; diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index af35f9325..836325acb 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -7,8 +7,7 @@ use thiserror::Error; use tokio::select; use tokio::sync::{mpsc, oneshot}; use tokio::time::Interval; -use tracing::info; -use tracing::warn; +use tracing::{info, warn}; use super::msg_queue::MsgQueue; use super::proto; @@ -231,10 +230,10 @@ where #[cfg(test)] mod test { + use cosmrs::bank::MsgSend; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; - use cosmrs::tx::{Fee, MessageExt}; - use cosmrs::Any; - use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; + use cosmrs::tx::{Fee, MessageExt, Msg}; + use cosmrs::{AccountId, Any}; use error_stack::Report; use futures::StreamExt; use tokio::sync::mpsc; diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index f44349dd8..7dcf603e0 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -1,9 +1,11 @@ use std::collections::HashMap; -use axelar_wasm_std::{self, voting::Vote}; +use axelar_wasm_std::voting::Vote; +use axelar_wasm_std::{self}; use cosmwasm_std::HexBinary; use move_core_types::language_storage::StructTag; -use serde::{de::Error, Deserialize, Deserializer}; +use serde::de::Error; +use serde::{Deserialize, Deserializer}; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockResponse}; use sui_types::base_types::SuiAddress; @@ -199,30 +201,28 @@ pub fn verify_verifier_set( #[cfg(test)] mod tests { + use axelar_wasm_std::voting::Vote; use cosmrs::crypto::PublicKey; use cosmwasm_std::{Addr, HexBinary, Uint128}; use ecdsa::SigningKey; use ethers_core::abi::AbiEncode; use move_core_types::language_storage::StructTag; + use multisig::key::KeyType; + use multisig::msg::Signer; + use multisig::verifier_set::VerifierSet; use rand::rngs::OsRng; use random_string::generate; + use router_api::ChainName; use serde_json::json; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockEvents, SuiTransactionBlockResponse}; - use sui_types::{ - base_types::{SuiAddress, TransactionDigest}, - event::EventID, - }; - - use axelar_wasm_std::voting::Vote; - use multisig::{key::KeyType, msg::Signer, verifier_set::VerifierSet}; - use router_api::ChainName; + use sui_types::base_types::{SuiAddress, TransactionDigest}; + use sui_types::event::EventID; + use crate::handlers::sui_verify_msg::Message; + use crate::handlers::sui_verify_verifier_set::VerifierSetConfirmation; use crate::sui::verifier::{verify_message, verify_verifier_set}; use crate::types::{EVMAddress, Hash}; - use crate::{ - handlers::{sui_verify_msg::Message, sui_verify_verifier_set::VerifierSetConfirmation}, - PREFIX, - }; + use crate::PREFIX; #[test] fn should_not_verify_msg_if_tx_id_does_not_match() { diff --git a/ampd/src/tofnd/grpc.rs b/ampd/src/tofnd/grpc.rs index 5d385f5a6..91a805bfa 100644 --- a/ampd/src/tofnd/grpc.rs +++ b/ampd/src/tofnd/grpc.rs @@ -6,15 +6,16 @@ use error_stack::{Report, ResultExt}; use k256::Secp256k1; use mockall::automock; use tokio::sync::Mutex; -use tonic::{transport::Channel, Status}; +use tonic::transport::Channel; +use tonic::Status; -use crate::{types::PublicKey, url::Url}; - -use super::proto::{ - keygen_response::KeygenResponse, multisig_client, sign_response::SignResponse, Algorithm, - KeygenRequest, SignRequest, -}; -use super::{error::Error, error::TofndError, MessageDigest, Signature}; +use super::error::{Error, TofndError}; +use super::proto::keygen_response::KeygenResponse; +use super::proto::sign_response::SignResponse; +use super::proto::{multisig_client, Algorithm, KeygenRequest, SignRequest}; +use super::{MessageDigest, Signature}; +use crate::types::PublicKey; +use crate::url::Url; type Result = error_stack::Result; diff --git a/ampd/src/types.rs b/ampd/src/types.rs index 4801b30ba..5d21e2312 100644 --- a/ampd/src/types.rs +++ b/ampd/src/types.rs @@ -1,8 +1,7 @@ use std::fmt; use std::hash::{Hash as StdHash, Hasher}; -use cosmrs::crypto; -use cosmrs::AccountId; +use cosmrs::{crypto, AccountId}; use ethers_core::types::{Address, H256}; use serde::{Deserialize, Serialize}; diff --git a/ampd/src/url.rs b/ampd/src/url.rs index 654c99062..90a1fdc10 100644 --- a/ampd/src/url.rs +++ b/ampd/src/url.rs @@ -1,8 +1,9 @@ +use std::fmt::{Display, Formatter}; +use std::str::FromStr; + use deref_derive::Deref; use serde::de::{Error, Visitor}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt::{Display, Formatter}; -use std::str::FromStr; use url::ParseError; #[derive(Debug, Deref, Hash, PartialEq, Eq, Clone)] diff --git a/contracts/coordinator/src/bin/schema.rs b/contracts/coordinator/src/bin/schema.rs index e026cca8c..c99447b20 100644 --- a/contracts/coordinator/src/bin/schema.rs +++ b/contracts/coordinator/src/bin/schema.rs @@ -1,6 +1,5 @@ -use cosmwasm_schema::write_api; - use coordinator::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; fn main() { write_api! { diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 9246c3d98..257cd07e1 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -2,10 +2,6 @@ mod execute; mod query; mod migrations; -use crate::contract::migrations::v0_2_0; -use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::is_prover_registered; use axelar_wasm_std::permission_control; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; @@ -14,6 +10,11 @@ use cosmwasm_std::{ }; use error_stack::report; +use crate::contract::migrations::v0_2_0; +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::is_prover_registered; + pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -98,8 +99,6 @@ mod tests { use std::collections::HashSet; - use super::*; - use crate::state::load_prover_by_chain; use axelar_wasm_std::permission_control::Permission; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, @@ -107,6 +106,9 @@ mod tests { use cosmwasm_std::{Addr, Empty, OwnedDeps}; use router_api::ChainName; + use super::*; + use crate::state::load_prover_by_chain; + struct TestSetup { deps: OwnedDeps, env: Env, diff --git a/contracts/coordinator/src/contract/execute.rs b/contracts/coordinator/src/contract/execute.rs index 22cbcd7c6..23aa67db3 100644 --- a/contracts/coordinator/src/contract/execute.rs +++ b/contracts/coordinator/src/contract/execute.rs @@ -1,6 +1,6 @@ -use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response}; use std::collections::HashSet; +use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response}; use router_api::ChainName; use crate::error::ContractError; diff --git a/contracts/coordinator/src/contract/migrations/v0_2_0.rs b/contracts/coordinator/src/contract/migrations/v0_2_0.rs index 825cbbd84..b6347d0ff 100644 --- a/contracts/coordinator/src/contract/migrations/v0_2_0.rs +++ b/contracts/coordinator/src/contract/migrations/v0_2_0.rs @@ -1,11 +1,13 @@ -use crate::error::ContractError; -use crate::{contract::CONTRACT_NAME, state::save_prover_for_chain}; use axelar_wasm_std::permission_control; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; use cw_storage_plus::{Item, Map}; use router_api::ChainName; +use crate::contract::CONTRACT_NAME; +use crate::error::ContractError; +use crate::state::save_prover_for_chain; + const BASE_VERSION: &str = "0.2.0"; pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { @@ -48,17 +50,17 @@ pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); #[cfg(test)] mod tests { + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; + use router_api::ChainName; + + use super::PROVER_PER_CHAIN; use crate::contract::migrations::v0_2_0; use crate::contract::migrations::v0_2_0::BASE_VERSION; use crate::contract::{execute, CONTRACT_NAME}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg}; use crate::state::{is_prover_registered, load_prover_by_chain}; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; - use router_api::ChainName; - - use super::PROVER_PER_CHAIN; #[test] fn migrate_checks_contract_version() { diff --git a/contracts/coordinator/src/contract/query.rs b/contracts/coordinator/src/contract/query.rs index fc277dcf4..275e5488e 100644 --- a/contracts/coordinator/src/contract/query.rs +++ b/contracts/coordinator/src/contract/query.rs @@ -1,6 +1,7 @@ -use crate::state::VERIFIER_PROVER_INDEXED_MAP; use cosmwasm_std::{Addr, Deps, Order, StdResult}; +use crate::state::VERIFIER_PROVER_INDEXED_MAP; + fn is_verifier_in_any_verifier_set(deps: Deps, verifier_address: &Addr) -> bool { VERIFIER_PROVER_INDEXED_MAP .idx diff --git a/contracts/coordinator/src/msg.rs b/contracts/coordinator/src/msg.rs index 50e3b61a0..b0e95f90f 100644 --- a/contracts/coordinator/src/msg.rs +++ b/contracts/coordinator/src/msg.rs @@ -1,8 +1,9 @@ +use std::collections::HashSet; + use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Addr; use msgs_derive::EnsurePermissions; use router_api::ChainName; -use std::collections::HashSet; #[cw_serde] pub struct InstantiateMsg { diff --git a/contracts/coordinator/src/state.rs b/contracts/coordinator/src/state.rs index a1b9510e8..8b953900b 100644 --- a/contracts/coordinator/src/state.rs +++ b/contracts/coordinator/src/state.rs @@ -1,9 +1,11 @@ -use crate::error::ContractError; +use std::collections::HashSet; + use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Order, Storage}; use cw_storage_plus::{index_list, IndexedMap, MultiIndex, UniqueIndex}; use router_api::ChainName; -use std::collections::HashSet; + +use crate::error::ContractError; type ProverAddress = Addr; type VerifierAddress = Addr; diff --git a/contracts/gateway/src/bin/schema.rs b/contracts/gateway/src/bin/schema.rs index afb8679ae..edf3475d3 100644 --- a/contracts/gateway/src/bin/schema.rs +++ b/contracts/gateway/src/bin/schema.rs @@ -1,7 +1,6 @@ use cosmwasm_schema::write_api; -use gateway_api::msg::{ExecuteMsg, QueryMsg}; - use gateway::msg::InstantiateMsg; +use gateway_api::msg::{ExecuteMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index b0096a2ce..8e886beee 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -1,9 +1,10 @@ +use std::fmt::Debug; + #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; use gateway_api::msg::{ExecuteMsg, QueryMsg}; use router_api::CrossChainId; -use std::fmt::Debug; use crate::msg::InstantiateMsg; diff --git a/contracts/gateway/src/contract/query.rs b/contracts/gateway/src/contract/query.rs index 13243d90d..468def5c7 100644 --- a/contracts/gateway/src/contract/query.rs +++ b/contracts/gateway/src/contract/query.rs @@ -1,9 +1,9 @@ -use crate::contract::Error; use axelar_wasm_std::error::extend_err; use cosmwasm_std::Storage; use error_stack::{report, Result, ResultExt}; use router_api::{CrossChainId, Message}; +use crate::contract::Error; use crate::state; pub fn get_outgoing_messages( @@ -39,10 +39,11 @@ fn accumulate_errs( #[cfg(test)] mod test { - use crate::state; use cosmwasm_std::testing::mock_dependencies; use router_api::{CrossChainId, Message}; + use crate::state; + #[test] fn get_outgoing_messages_all_messages_present_returns_all() { let mut deps = mock_dependencies(); diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index 3e0992d6b..30393c488 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -10,13 +10,12 @@ use cosmwasm_std::Response; use cosmwasm_std::{ from_json, to_json_binary, Addr, ContractResult, DepsMut, QuerierResult, WasmQuery, }; -use itertools::Itertools; -use router_api::{CrossChainId, Message}; -use serde::Serialize; - use gateway::contract::*; use gateway::msg::InstantiateMsg; use gateway_api::msg::{ExecuteMsg, QueryMsg}; +use itertools::Itertools; +use router_api::{CrossChainId, Message}; +use serde::Serialize; use voting_verifier::msg::MessageStatus; #[test] diff --git a/contracts/multisig-prover/src/bin/schema.rs b/contracts/multisig-prover/src/bin/schema.rs index 8a58b5f6e..0dc35b5f9 100644 --- a/contracts/multisig-prover/src/bin/schema.rs +++ b/contracts/multisig-prover/src/bin/schema.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::write_api; - use multisig_prover::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 5f1825867..787737180 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -5,13 +5,10 @@ use cosmwasm_std::{ }; use error_stack::ResultExt; -use crate::{ - error::ContractError, - execute, - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, - query, reply, - state::{Config, CONFIG}, -}; +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::{Config, CONFIG}; +use crate::{execute, query, reply}; pub const START_MULTISIG_REPLY_ID: u64 = 1; @@ -141,32 +138,27 @@ pub fn migrate( #[cfg(test)] mod tests { + use axelar_wasm_std::{MajorityThreshold, Threshold, VerificationStatus}; + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, + }; use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, - Addr, Empty, Fraction, OwnedDeps, SubMsgResponse, SubMsgResult, Uint128, Uint64, + from_json, Addr, Empty, Fraction, OwnedDeps, SubMsgResponse, SubMsgResult, Uint128, Uint64, }; - - use axelar_wasm_std::{MajorityThreshold, Threshold, VerificationStatus}; - use multisig::{msg::Signer, verifier_set::VerifierSet}; + use multisig::msg::Signer; + use multisig::verifier_set::VerifierSet; use prost::Message; use router_api::CrossChainId; - use crate::{ - contract::execute::should_update_verifier_set, - msg::VerifierSetResponse, - test::test_utils::{ - mock_querier_handler, ADMIN, COORDINATOR_ADDRESS, GATEWAY_ADDRESS, GOVERNANCE, - MULTISIG_ADDRESS, SERVICE_NAME, SERVICE_REGISTRY_ADDRESS, VOTING_VERIFIER_ADDRESS, - }, - }; - use crate::{ - encoding::Encoder, - msg::{GetProofResponse, ProofStatus}, - test::test_data::{self, TestOperator}, - }; - use super::*; + use crate::contract::execute::should_update_verifier_set; + use crate::encoding::Encoder; + use crate::msg::{GetProofResponse, ProofStatus, VerifierSetResponse}; + use crate::test::test_data::{self, TestOperator}; + use crate::test::test_utils::{ + mock_querier_handler, ADMIN, COORDINATOR_ADDRESS, GATEWAY_ADDRESS, GOVERNANCE, + MULTISIG_ADDRESS, SERVICE_NAME, SERVICE_REGISTRY_ADDRESS, VOTING_VERIFIER_ADDRESS, + }; const RELAYER: &str = "relayer"; const MULTISIG_SESSION_ID: Uint64 = Uint64::one(); diff --git a/contracts/multisig-prover/src/encoding/abi/execute_data.rs b/contracts/multisig-prover/src/encoding/abi/execute_data.rs index 1f3ed470d..dea1d443e 100644 --- a/contracts/multisig-prover/src/encoding/abi/execute_data.rs +++ b/contracts/multisig-prover/src/encoding/abi/execute_data.rs @@ -1,13 +1,15 @@ +use axelar_wasm_std::hash::Hash; use cosmwasm_std::HexBinary; use error_stack::ResultExt; use ethers_contract::contract::EthCall; use ethers_core::abi::{encode as abi_encode, Tokenize}; - -use axelar_wasm_std::hash::Hash; use evm_gateway::{ApproveMessagesCall, Message, Proof, RotateSignersCall, WeightedSigners}; -use multisig::{key::Signature, msg::SignerWithSig, verifier_set::VerifierSet}; +use multisig::key::Signature; +use multisig::msg::SignerWithSig; +use multisig::verifier_set::VerifierSet; -use crate::{error::ContractError, payload::Payload}; +use crate::error::ContractError; +use crate::payload::Payload; pub fn encode( verifier_set: &VerifierSet, @@ -78,31 +80,24 @@ pub fn add27(recovery_byte: k256::ecdsa::RecoveryId) -> u8 { mod tests { use std::str::FromStr; + use axelar_wasm_std::hash::Hash; use cosmwasm_std::HexBinary; use elliptic_curve::consts::U32; use ethers_core::types::Signature as EthersSignature; + use evm_gateway::evm_address; use generic_array::GenericArray; use hex::FromHex; use itertools::Itertools; use k256::ecdsa::Signature as K256Signature; + use multisig::key::{KeyType, KeyTyped, Signature}; + use multisig::msg::{Signer, SignerWithSig}; use sha3::{Digest, Keccak256}; - use axelar_wasm_std::hash::Hash; - use evm_gateway::evm_address; - use multisig::{ - key::{KeyType, KeyTyped, Signature}, - msg::{Signer, SignerWithSig}, - }; - - use crate::{ - encoding::abi::{ - execute_data::{add27, encode}, - payload_hash_to_sign, - }, - payload::Payload, - test::test_data::{ - curr_verifier_set, domain_separator, messages, verifier_set_from_pub_keys, - }, + use crate::encoding::abi::execute_data::{add27, encode}; + use crate::encoding::abi::payload_hash_to_sign; + use crate::payload::Payload; + use crate::test::test_data::{ + curr_verifier_set, domain_separator, messages, verifier_set_from_pub_keys, }; #[test] diff --git a/contracts/multisig-prover/src/encoding/abi/mod.rs b/contracts/multisig-prover/src/encoding/abi/mod.rs index c2135a065..6ed8a79b0 100644 --- a/contracts/multisig-prover/src/encoding/abi/mod.rs +++ b/contracts/multisig-prover/src/encoding/abi/mod.rs @@ -1,15 +1,15 @@ pub mod execute_data; +use axelar_wasm_std::hash::Hash; use error_stack::{Result, ResultExt}; use ethers_core::abi::{encode as abi_encode, Token, Tokenize}; -use itertools::Itertools; -use sha3::{Digest, Keccak256}; - -use axelar_wasm_std::hash::Hash; use evm_gateway::{CommandType, Message, WeightedSigners}; +use itertools::Itertools; use multisig::verifier_set::VerifierSet; +use sha3::{Digest, Keccak256}; -use crate::{error::ContractError, payload::Payload}; +use crate::error::ContractError; +use crate::payload::Payload; impl From<&Payload> for CommandType { fn from(payload: &Payload) -> Self { @@ -72,13 +72,10 @@ pub fn encode(payload: &Payload) -> Result, ContractError> { mod tests { use cosmwasm_std::HexBinary; - use crate::{ - encoding::abi::{payload_hash_to_sign, CommandType}, - payload::Payload, - test::test_data::{ - curr_verifier_set, domain_separator, messages, new_verifier_set, - verifier_set_from_pub_keys, - }, + use crate::encoding::abi::{payload_hash_to_sign, CommandType}; + use crate::payload::Payload; + use crate::test::test_data::{ + curr_verifier_set, domain_separator, messages, new_verifier_set, verifier_set_from_pub_keys, }; #[test] diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index 5d070a80b..7915392a6 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -1,8 +1,7 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - use axelar_wasm_std::nonempty; use axelar_wasm_std_derive::IntoContractError; +use cosmwasm_std::StdError; +use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] pub enum ContractError { diff --git a/contracts/multisig-prover/src/events.rs b/contracts/multisig-prover/src/events.rs index 63ce89efd..1a2348a6e 100644 --- a/contracts/multisig-prover/src/events.rs +++ b/contracts/multisig-prover/src/events.rs @@ -47,9 +47,10 @@ impl From for cosmwasm_std::Event { #[cfg(test)] mod tests { - use super::*; use serde_json::to_string; + use super::*; + #[test] fn proof_under_construction_is_serializable() { let msg_ids = vec![ diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index 25f4c528d..d4d8b2a70 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -1,24 +1,22 @@ use std::collections::{BTreeMap, HashSet}; +use axelar_wasm_std::snapshot::{Participant, Snapshot}; +use axelar_wasm_std::{FnExt, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ to_json_binary, wasm_execute, Addr, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, WasmQuery, }; use itertools::Itertools; - -use axelar_wasm_std::{ - snapshot::{Participant, Snapshot}, - FnExt, MajorityThreshold, VerificationStatus, -}; -use multisig::{msg::Signer, verifier_set::VerifierSet}; +use multisig::msg::Signer; +use multisig::verifier_set::VerifierSet; use router_api::{ChainName, CrossChainId, Message}; use service_registry::state::{Service, WeightedVerifier}; -use crate::{ - contract::START_MULTISIG_REPLY_ID, - error::ContractError, - payload::Payload, - state::{Config, CONFIG, CURRENT_VERIFIER_SET, NEXT_VERIFIER_SET, PAYLOAD, REPLY_TRACKER}, +use crate::contract::START_MULTISIG_REPLY_ID; +use crate::error::ContractError; +use crate::payload::Payload; +use crate::state::{ + Config, CONFIG, CURRENT_VERIFIER_SET, NEXT_VERIFIER_SET, PAYLOAD, REPLY_TRACKER, }; pub fn require_admin(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { @@ -427,21 +425,17 @@ pub fn update_admin(deps: DepsMut, new_admin_address: String) -> Result for PayloadId { mod test { use router_api::CrossChainId; - use crate::{payload::PayloadId, test::test_data}; + use crate::payload::PayloadId; + use crate::test::test_data; #[test] fn test_payload_id() { diff --git a/contracts/multisig-prover/src/query.rs b/contracts/multisig-prover/src/query.rs index d6b2cfc4f..82f620f47 100644 --- a/contracts/multisig-prover/src/query.rs +++ b/contracts/multisig-prover/src/query.rs @@ -1,12 +1,12 @@ use cosmwasm_std::{to_json_binary, Deps, QueryRequest, StdResult, Uint64, WasmQuery}; use error_stack::Result; +use multisig::multisig::Multisig; +use multisig::types::MultisigState; -use multisig::{multisig::Multisig, types::MultisigState}; - -use crate::{ - error::ContractError, - msg::{GetProofResponse, ProofStatus, VerifierSetResponse}, - state::{CONFIG, CURRENT_VERIFIER_SET, MULTISIG_SESSION_PAYLOAD, NEXT_VERIFIER_SET, PAYLOAD}, +use crate::error::ContractError; +use crate::msg::{GetProofResponse, ProofStatus, VerifierSetResponse}; +use crate::state::{ + CONFIG, CURRENT_VERIFIER_SET, MULTISIG_SESSION_PAYLOAD, NEXT_VERIFIER_SET, PAYLOAD, }; pub fn get_proof( @@ -73,7 +73,8 @@ pub fn next_verifier_set(deps: Deps) -> StdResult> { mod test { use cosmwasm_std::testing::mock_dependencies; - use crate::{state, test::test_data::new_verifier_set}; + use crate::state; + use crate::test::test_data::new_verifier_set; #[test] fn next_verifier_set() { diff --git a/contracts/multisig-prover/src/reply.rs b/contracts/multisig-prover/src/reply.rs index ddb6951f2..d3fc7253b 100644 --- a/contracts/multisig-prover/src/reply.rs +++ b/contracts/multisig-prover/src/reply.rs @@ -1,12 +1,9 @@ use cosmwasm_std::{from_json, DepsMut, Reply, Response, Uint64}; use cw_utils::{parse_reply_execute_data, MsgExecuteContractResponse}; -use crate::state::{CONFIG, PAYLOAD}; -use crate::{ - error::ContractError, - events::Event, - state::{MULTISIG_SESSION_PAYLOAD, REPLY_TRACKER}, -}; +use crate::error::ContractError; +use crate::events::Event; +use crate::state::{CONFIG, MULTISIG_SESSION_PAYLOAD, PAYLOAD, REPLY_TRACKER}; pub fn start_multisig_reply(deps: DepsMut, reply: Reply) -> Result { let config = CONFIG.load(deps.storage)?; diff --git a/contracts/multisig-prover/src/state.rs b/contracts/multisig-prover/src/state.rs index 98dd34fe4..6891febeb 100644 --- a/contracts/multisig-prover/src/state.rs +++ b/contracts/multisig-prover/src/state.rs @@ -1,16 +1,14 @@ +use axelar_wasm_std::hash::Hash; +use axelar_wasm_std::MajorityThreshold; use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; use cw_storage_plus::{Item, Map}; - -use axelar_wasm_std::{hash::Hash, MajorityThreshold}; use multisig::key::KeyType; use multisig::verifier_set::VerifierSet; use router_api::ChainName; -use crate::{ - encoding::Encoder, - payload::{Payload, PayloadId}, -}; +use crate::encoding::Encoder; +use crate::payload::{Payload, PayloadId}; #[cw_serde] pub struct Config { diff --git a/contracts/multisig-prover/src/test/test_data.rs b/contracts/multisig-prover/src/test/test_data.rs index f817fe1ea..74a4f5f99 100644 --- a/contracts/multisig-prover/src/test/test_data.rs +++ b/contracts/multisig-prover/src/test/test_data.rs @@ -3,11 +3,9 @@ use std::collections::BTreeMap; use axelar_wasm_std::{nonempty, MajorityThreshold, Participant, Threshold}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Uint128, Uint64}; -use multisig::{ - key::{KeyType, PublicKey, Signature}, - msg::Signer, - verifier_set::VerifierSet, -}; +use multisig::key::{KeyType, PublicKey, Signature}; +use multisig::msg::Signer; +use multisig::verifier_set::VerifierSet; use router_api::{CrossChainId, Message}; pub fn new_verifier_set() -> VerifierSet { diff --git a/contracts/multisig-prover/src/test/test_utils.rs b/contracts/multisig-prover/src/test/test_utils.rs index 9e3dec6ed..5db7060f8 100644 --- a/contracts/multisig-prover/src/test/test_utils.rs +++ b/contracts/multisig-prover/src/test/test_utils.rs @@ -1,6 +1,9 @@ use axelar_wasm_std::VerificationStatus; use cosmwasm_std::{from_json, to_json_binary, Addr, QuerierResult, Uint128, WasmQuery}; -use multisig::{msg::Signer, multisig::Multisig, types::MultisigState, verifier_set::VerifierSet}; +use multisig::msg::Signer; +use multisig::multisig::Multisig; +use multisig::types::MultisigState; +use multisig::verifier_set::VerifierSet; use service_registry::state::{ AuthorizationState, BondingState, Verifier, WeightedVerifier, VERIFIER_WEIGHT, }; diff --git a/contracts/multisig/src/bin/schema.rs b/contracts/multisig/src/bin/schema.rs index 923fac67b..6b8f5bdfd 100644 --- a/contracts/multisig/src/bin/schema.rs +++ b/contracts/multisig/src/bin/schema.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::write_api; - use multisig::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index c3d55300f..93d568b25 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1,13 +1,3 @@ -use crate::msg::MigrationMsg; -use crate::{ - events::Event, - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, - state::{ - get_verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, - }, - types::{MsgToSign, MultisigState}, - ContractError, -}; use axelar_wasm_std::{killswitch, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; @@ -18,6 +8,14 @@ use cosmwasm_std::{ use error_stack::{report, ResultExt}; use itertools::Itertools; +use crate::events::Event; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrationMsg, QueryMsg}; +use crate::state::{ + get_verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, +}; +use crate::types::{MsgToSign, MultisigState}; +use crate::ContractError; + mod execute; mod migrations; mod query; @@ -194,28 +192,24 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { #[cfg(feature = "test")] #[cfg(test)] mod tests { - use std::{collections::HashMap, vec}; + use std::collections::HashMap; + use std::vec; - use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, - Addr, Empty, OwnedDeps, WasmMsg, + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; + use cosmwasm_std::{from_json, Addr, Empty, OwnedDeps, WasmMsg}; use permission_control::Permission; use router_api::ChainName; use serde_json::from_str; - use crate::{ - key::{KeyType, PublicKey, Signature}, - multisig::Multisig, - state::load_session_signatures, - test::common::{build_verifier_set, TestSigner}, - test::common::{ecdsa_test_data, ed25519_test_data}, - types::MultisigState, - verifier_set::VerifierSet, - }; - use super::*; + use crate::key::{KeyType, PublicKey, Signature}; + use crate::multisig::Multisig; + use crate::state::load_session_signatures; + use crate::test::common::{build_verifier_set, ecdsa_test_data, ed25519_test_data, TestSigner}; + use crate::types::MultisigState; + use crate::verifier_set::VerifierSet; const INSTANTIATOR: &str = "inst"; const PROVER: &str = "prover"; diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index e3617e0f6..c7ed84e23 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -5,16 +5,11 @@ use router_api::ChainName; use sha3::{Digest, Keccak256}; use signature_verifier_api::client::SignatureVerifier; -use crate::signing::validate_session_signature; -use crate::state::{load_session_signatures, save_pub_key, save_signature}; -use crate::verifier_set::VerifierSet; -use crate::{ - key::{KeyTyped, PublicKey, Signature}, - signing::SigningSession, - state::AUTHORIZED_CALLERS, -}; - use super::*; +use crate::key::{KeyTyped, PublicKey, Signature}; +use crate::signing::{validate_session_signature, SigningSession}; +use crate::state::{load_session_signatures, save_pub_key, save_signature, AUTHORIZED_CALLERS}; +use crate::verifier_set::VerifierSet; pub fn start_signing_session( deps: DepsMut, diff --git a/contracts/multisig/src/contract/migrations/v0_4_1.rs b/contracts/multisig/src/contract/migrations/v0_4_1.rs index 1501a6366..caa3e85a8 100644 --- a/contracts/multisig/src/contract/migrations/v0_4_1.rs +++ b/contracts/multisig/src/contract/migrations/v0_4_1.rs @@ -1,5 +1,7 @@ #![allow(deprecated)] +use axelar_wasm_std::killswitch::State; +use axelar_wasm_std::{killswitch, nonempty, permission_control}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdError, Storage}; use cw2::VersionError; @@ -9,8 +11,6 @@ use router_api::ChainName; use crate::contract::CONTRACT_NAME; use crate::state::AUTHORIZED_CALLERS; -use axelar_wasm_std::killswitch::State; -use axelar_wasm_std::{killswitch, nonempty, permission_control}; const BASE_VERSION: &str = "0.4.1"; @@ -88,11 +88,10 @@ const CONFIG: Item = Item::new("config"); #[cfg(test)] mod tests { + use axelar_wasm_std::nonempty; use cosmwasm_schema::cw_serde; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{Addr, DepsMut, Env, HexBinary, MessageInfo, Response, Uint64}; - - use axelar_wasm_std::nonempty; use router_api::ChainName; use crate::contract::migrations::v0_4_1; diff --git a/contracts/multisig/src/contract/query.rs b/contracts/multisig/src/contract/query.rs index e032e9c8c..6d34cc0e6 100644 --- a/contracts/multisig/src/contract/query.rs +++ b/contracts/multisig/src/contract/query.rs @@ -1,13 +1,10 @@ use router_api::ChainName; -use crate::{ - key::{KeyType, PublicKey}, - multisig::Multisig, - state::{load_pub_key, load_session_signatures, AUTHORIZED_CALLERS}, - verifier_set::VerifierSet, -}; - use super::*; +use crate::key::{KeyType, PublicKey}; +use crate::multisig::Multisig; +use crate::state::{load_pub_key, load_session_signatures, AUTHORIZED_CALLERS}; +use crate::verifier_set::VerifierSet; pub fn get_multisig(deps: Deps, session_id: Uint64) -> StdResult { let session = SIGNING_SESSIONS.load(deps.storage, session_id.into())?; diff --git a/contracts/multisig/src/ed25519.rs b/contracts/multisig/src/ed25519.rs index 29c2159a7..550e3ace7 100644 --- a/contracts/multisig/src/ed25519.rs +++ b/contracts/multisig/src/ed25519.rs @@ -14,9 +14,8 @@ pub fn ed25519_verify(msg_hash: &[u8], sig: &[u8], pub_key: &[u8]) -> Result Result, verifier_set: &Verifi #[cfg(test)] mod tests { - use cosmwasm_std::{testing::MockQuerier, to_json_binary, Addr, HexBinary, QuerierWrapper}; - - use crate::{ - key::KeyType, - test::common::build_verifier_set, - test::common::{ecdsa_test_data, ed25519_test_data}, - }; + use cosmwasm_std::testing::MockQuerier; + use cosmwasm_std::{to_json_binary, Addr, HexBinary, QuerierWrapper}; use super::*; + use crate::key::KeyType; + use crate::test::common::{build_verifier_set, ecdsa_test_data, ed25519_test_data}; pub struct TestConfig { pub verifier_set: VerifierSet, diff --git a/contracts/multisig/src/state.rs b/contracts/multisig/src/state.rs index a8a8e2d72..0ead03953 100644 --- a/contracts/multisig/src/state.rs +++ b/contracts/multisig/src/state.rs @@ -1,17 +1,16 @@ use std::collections::HashMap; -use crate::{ - key::{KeyType, KeyTyped, PublicKey, Signature}, - signing::SigningSession, - verifier_set::VerifierSet, - ContractError, -}; use axelar_wasm_std::nonempty; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Order, StdResult, Storage, Uint64}; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; use router_api::ChainName; +use crate::key::{KeyType, KeyTyped, PublicKey, Signature}; +use crate::signing::SigningSession; +use crate::verifier_set::VerifierSet; +use crate::ContractError; + #[cw_serde] pub struct Config { pub rewards_contract: Addr, @@ -118,9 +117,8 @@ mod tests { use cosmwasm_std::testing::mock_dependencies; - use crate::test::common::ecdsa_test_data; - use super::*; + use crate::test::common::ecdsa_test_data; #[test] fn should_fail_if_duplicate_public_key() { diff --git a/contracts/multisig/src/test/common.rs b/contracts/multisig/src/test/common.rs index ff32de0c6..9b0ad9335 100644 --- a/contracts/multisig/src/test/common.rs +++ b/contracts/multisig/src/test/common.rs @@ -1,10 +1,8 @@ use axelar_wasm_std::Participant; use cosmwasm_std::{Addr, HexBinary, Uint128}; -use crate::{ - key::{KeyType, PublicKey}, - verifier_set::VerifierSet, -}; +use crate::key::{KeyType, PublicKey}; +use crate::verifier_set::VerifierSet; #[derive(Clone)] pub struct TestSigner { diff --git a/contracts/multisig/src/types.rs b/contracts/multisig/src/types.rs index f20a77904..c36c996f0 100644 --- a/contracts/multisig/src/types.rs +++ b/contracts/multisig/src/types.rs @@ -50,9 +50,8 @@ impl TryFrom for MsgToSign { #[cfg(test)] mod tests { - use crate::test::common::ecdsa_test_data; - use super::*; + use crate::test::common::ecdsa_test_data; #[test] fn test_try_from_hexbinary_to_message() { diff --git a/contracts/multisig/src/verifier_set.rs b/contracts/multisig/src/verifier_set.rs index f2e9f76ae..634a63dde 100644 --- a/contracts/multisig/src/verifier_set.rs +++ b/contracts/multisig/src/verifier_set.rs @@ -1,12 +1,14 @@ use std::collections::{BTreeMap, HashMap}; -use crate::{key::PublicKey, msg::Signer}; use axelar_wasm_std::hash::Hash; use axelar_wasm_std::Participant; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Uint128}; use sha3::{Digest, Keccak256}; +use crate::key::PublicKey; +use crate::msg::Signer; + #[cw_serde] pub struct VerifierSet { // An ordered map with the signer's axelar address as the key, and the signer as the value. diff --git a/contracts/nexus-gateway/src/bin/schema.rs b/contracts/nexus-gateway/src/bin/schema.rs index cb8b8c93c..a3a20bcbe 100644 --- a/contracts/nexus-gateway/src/bin/schema.rs +++ b/contracts/nexus-gateway/src/bin/schema.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::write_api; - use nexus_gateway::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index dad9b9c69..945759169 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -1,12 +1,11 @@ use cosmwasm_std::{to_json_binary, Addr, Response, WasmMsg}; use error_stack::report; +use super::Contract; use crate::error::ContractError; use crate::nexus; use crate::state::Store; -use super::Contract; - type Result = error_stack::Result; impl Contract @@ -70,12 +69,10 @@ mod test { use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use cosmwasm_std::{from_json, CosmosMsg}; use hex::decode; - use router_api::CrossChainId; - use crate::state::{Config, MockStore}; - use super::*; + use crate::state::{Config, MockStore}; #[test] fn route_to_router_unauthorized() { diff --git a/contracts/nexus-gateway/src/error.rs b/contracts/nexus-gateway/src/error.rs index 385d2d5b4..964decca1 100644 --- a/contracts/nexus-gateway/src/error.rs +++ b/contracts/nexus-gateway/src/error.rs @@ -1,8 +1,7 @@ +use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::HexBinary; use thiserror::Error; -use axelar_wasm_std_derive::IntoContractError; - #[derive(Error, Debug, PartialEq, IntoContractError)] pub enum ContractError { #[error("caller is not authorized")] diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 55ad071d1..2f192b6bd 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -1,6 +1,7 @@ use std::str::FromStr; -use axelar_wasm_std::{msg_id::HexTxHashAndEventIndex, nonempty}; +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; +use axelar_wasm_std::nonempty; use cosmwasm_std::{CosmosMsg, CustomMsg}; use error_stack::{Report, Result, ResultExt}; use router_api::{Address, ChainName, CrossChainId}; diff --git a/contracts/rewards/src/bin/schema.rs b/contracts/rewards/src/bin/schema.rs index e0a5ec117..c7b7ba02e 100644 --- a/contracts/rewards/src/bin/schema.rs +++ b/contracts/rewards/src/bin/schema.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::write_api; - use rewards::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index 8b5993e7d..deea2c917 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -8,11 +8,9 @@ use error_stack::ResultExt; use itertools::Itertools; use crate::contract::migrations::v0_4_0; -use crate::{ - error::ContractError, - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, - state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG, PARAMS}, -}; +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG, PARAMS}; mod execute; mod migrations; @@ -177,11 +175,10 @@ mod tests { use cw_multi_test::{App, ContractWrapper, Executor}; use router_api::ChainName; + use super::*; use crate::msg::{ExecuteMsg, InstantiateMsg, Params, QueryMsg, RewardsPool}; use crate::state::PoolId; - use super::*; - #[test] fn migrate_sets_contract_version() { let mut deps = mock_dependencies(); diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index a67d97d11..383fb026f 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -4,11 +4,9 @@ use axelar_wasm_std::{nonempty, FnExt}; use cosmwasm_std::{Addr, OverflowError, OverflowOperation, Storage, Uint128}; use error_stack::{Report, Result}; -use crate::{ - error::ContractError, - msg::Params, - state::{self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, StorageState}, -}; +use crate::error::ContractError; +use crate::msg::Params; +use crate::state::{self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, StorageState}; const DEFAULT_EPOCHS_TO_PROCESS: u64 = 10; const EPOCH_PAYOUT_DELAY: u64 = 2; @@ -205,22 +203,17 @@ fn merge_rewards( #[cfg(test)] mod test { - use super::*; - use std::collections::HashMap; use axelar_wasm_std::nonempty; - use cosmwasm_std::{ - testing::{mock_dependencies, MockApi, MockQuerier, MockStorage}, - Addr, OwnedDeps, Uint128, Uint64, - }; + use cosmwasm_std::testing::{mock_dependencies, MockApi, MockQuerier, MockStorage}; + use cosmwasm_std::{Addr, OwnedDeps, Uint128, Uint64}; use router_api::ChainName; - use crate::{ - error::ContractError, - msg::Params, - state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG}, - }; + use super::*; + use crate::error::ContractError; + use crate::msg::Params; + use crate::state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG}; /// Tests that the current epoch is computed correctly when the expected epoch is the same as the stored epoch #[test] diff --git a/contracts/rewards/src/contract/migrations/v0_4_0.rs b/contracts/rewards/src/contract/migrations/v0_4_0.rs index ff536c0c0..9e76fb97d 100644 --- a/contracts/rewards/src/contract/migrations/v0_4_0.rs +++ b/contracts/rewards/src/contract/migrations/v0_4_0.rs @@ -1,10 +1,9 @@ #![allow(deprecated)] +use axelar_wasm_std::{permission_control, ContractError}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; use cw_storage_plus::Item; - -use axelar_wasm_std::{permission_control, ContractError}; use router_api::error::Error; use crate::contract::CONTRACT_NAME; diff --git a/contracts/rewards/src/contract/query.rs b/contracts/rewards/src/contract/query.rs index 0bfbdafcc..9da88e320 100644 --- a/contracts/rewards/src/contract/query.rs +++ b/contracts/rewards/src/contract/query.rs @@ -1,11 +1,9 @@ use cosmwasm_std::{Storage, Uint64}; use error_stack::Result; -use crate::{ - error::ContractError, - msg, - state::{self, Epoch, PoolId}, -}; +use crate::error::ContractError; +use crate::msg; +use crate::state::{self, Epoch, PoolId}; pub fn rewards_pool( storage: &dyn Storage, @@ -65,15 +63,13 @@ pub fn participation( #[cfg(test)] mod tests { - use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128, Uint64}; + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{Addr, Uint128, Uint64}; use msg::Participation; - use crate::{ - msg::Params, - state::{EpochTally, ParamsSnapshot, RewardsPool}, - }; - use super::*; + use crate::msg::Params; + use crate::state::{EpochTally, ParamsSnapshot, RewardsPool}; fn setup(storage: &mut dyn Storage, initial_balance: Uint128) -> (ParamsSnapshot, PoolId) { let pool_id = PoolId { diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index 1b043112a..937885e38 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -8,7 +8,8 @@ use cw_storage_plus::{Item, Key, KeyDeserialize, Map, Prefixer, PrimaryKey}; use error_stack::{Result, ResultExt}; use router_api::ChainName; -use crate::{error::ContractError, msg::Params}; +use crate::error::ContractError; +use crate::msg::Params; #[cw_serde] pub struct Config { @@ -399,12 +400,16 @@ impl Deref for StorageState { #[cfg(test)] mod test { + use std::collections::HashMap; + + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{Addr, Uint128, Uint64}; + use router_api::ChainName; + use super::*; use crate::error::ContractError; - use crate::{msg::Params, state::ParamsSnapshot}; - use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128, Uint64}; - use router_api::ChainName; - use std::collections::HashMap; + use crate::msg::Params; + use crate::state::ParamsSnapshot; /// Test that the rewards are /// - distributed evenly to all verifiers that reach quorum diff --git a/contracts/router/src/bin/schema.rs b/contracts/router/src/bin/schema.rs index ae74ba830..6a15ff65f 100644 --- a/contracts/router/src/bin/schema.rs +++ b/contracts/router/src/bin/schema.rs @@ -1,7 +1,6 @@ use cosmwasm_schema::write_api; -use router_api::msg::{ExecuteMsg, QueryMsg}; - use router::msg::InstantiateMsg; +use router_api::msg::{ExecuteMsg, QueryMsg}; fn main() { write_api! { diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 68be100fb..f353f630f 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -1,18 +1,17 @@ -use axelar_wasm_std::killswitch; +use axelar_wasm_std::{killswitch, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, }; +use router_api::error::Error; +use router_api::msg::{ExecuteMsg, QueryMsg}; use crate::contract::migrations::v0_3_3; use crate::events::RouterInstantiated; use crate::msg::InstantiateMsg; use crate::state; use crate::state::{load_chain_by_gateway, load_config, Config}; -use axelar_wasm_std::{permission_control, FnExt}; -use router_api::error::Error; -use router_api::msg::{ExecuteMsg, QueryMsg}; mod execute; mod migrations; @@ -142,23 +141,24 @@ pub fn query( #[cfg(test)] mod test { - use std::{collections::HashMap, str::FromStr}; + use std::collections::HashMap; + use std::str::FromStr; - use super::*; - use crate::events; use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::ContractError; - use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, - Addr, CosmosMsg, Empty, OwnedDeps, WasmMsg, + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; + use cosmwasm_std::{from_json, Addr, CosmosMsg, Empty, OwnedDeps, WasmMsg}; use permission_control::Permission; + use router_api::error::Error; use router_api::{ - error::Error, ChainEndpoint, ChainName, CrossChainId, GatewayDirection, Message, - CHAIN_NAME_DELIMITER, + ChainEndpoint, ChainName, CrossChainId, GatewayDirection, Message, CHAIN_NAME_DELIMITER, }; + use super::*; + use crate::events; + const ADMIN_ADDRESS: &str = "admin"; const GOVERNANCE_ADDRESS: &str = "governance"; const NEXUS_GATEWAY_ADDRESS: &str = "nexus_gateway"; diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index 69f649d36..c13f9a76a 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -1,13 +1,12 @@ use std::collections::HashMap; use std::vec; +use axelar_wasm_std::flagset::FlagSet; use axelar_wasm_std::killswitch; +use axelar_wasm_std::msg_id::{self, MessageIdFormat}; use cosmwasm_std::{to_json_binary, Addr, Event, Response, StdResult, Storage, WasmMsg}; use error_stack::{ensure, report, ResultExt}; use itertools::Itertools; - -use axelar_wasm_std::flagset::FlagSet; -use axelar_wasm_std::msg_id::{self, MessageIdFormat}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection, Message}; @@ -240,12 +239,8 @@ pub fn route_messages( #[cfg(test)] mod test { - use super::{freeze_chains, unfreeze_chains}; - use crate::contract::execute::route_messages; - use crate::contract::instantiate; - use crate::events::{ChainFrozen, ChainUnfrozen}; - use crate::msg::InstantiateMsg; - use crate::state::chain_endpoints; + use std::collections::HashMap; + use axelar_wasm_std::flagset::FlagSet; use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; @@ -253,7 +248,13 @@ mod test { use rand::{random, RngCore}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, CrossChainId, Gateway, GatewayDirection, Message}; - use std::collections::HashMap; + + use super::{freeze_chains, unfreeze_chains}; + use crate::contract::execute::route_messages; + use crate::contract::instantiate; + use crate::events::{ChainFrozen, ChainUnfrozen}; + use crate::msg::InstantiateMsg; + use crate::state::chain_endpoints; fn rand_message(source_chain: ChainName, destination_chain: ChainName) -> Message { let mut bytes = [0; 32]; diff --git a/contracts/router/src/contract/migrations/v0_3_3.rs b/contracts/router/src/contract/migrations/v0_3_3.rs index 5b3d5d655..2302c6691 100644 --- a/contracts/router/src/contract/migrations/v0_3_3.rs +++ b/contracts/router/src/contract/migrations/v0_3_3.rs @@ -1,13 +1,13 @@ #![allow(deprecated)] +use axelar_wasm_std::{killswitch, permission_control, ContractError}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdResult, Storage}; use cw_storage_plus::Item; +use router_api::error::Error; use crate::contract::CONTRACT_NAME; use crate::state; -use axelar_wasm_std::{killswitch, permission_control, ContractError}; -use router_api::error::Error; const BASE_VERSION: &str = "0.3.3"; @@ -51,11 +51,10 @@ const CONFIG: Item = Item::new("config"); mod test { use std::collections::HashMap; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; - use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::{killswitch, ContractError}; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; use router_api::msg::ExecuteMsg; use crate::contract::migrations::v0_3_3; diff --git a/contracts/router/src/contract/query.rs b/contracts/router/src/contract/query.rs index 054003a09..8c2833d45 100644 --- a/contracts/router/src/contract/query.rs +++ b/contracts/router/src/contract/query.rs @@ -1,6 +1,5 @@ use cosmwasm_std::{Deps, Order, Storage}; use cw_storage_plus::Bound; - use error_stack::{Result, ResultExt}; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName}; @@ -37,13 +36,14 @@ pub fn chains( #[cfg(test)] mod test { - use crate::state::chain_endpoints; use axelar_wasm_std::flagset::FlagSet; - use cosmwasm_std::{testing::mock_dependencies, Addr}; + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::Addr; use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection}; use super::get_chain_info; + use crate::state::chain_endpoints; #[test] fn should_get_chain_info() { diff --git a/contracts/service-registry/src/bin/schema.rs b/contracts/service-registry/src/bin/schema.rs index 8e54a70e3..85da9dcac 100644 --- a/contracts/service-registry/src/bin/schema.rs +++ b/contracts/service-registry/src/bin/schema.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::write_api; - use service_registry::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 33d086c22..2ef660b87 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -172,16 +172,14 @@ pub fn migrate( mod test { use std::str::FromStr; - use cosmwasm_std::{ - coins, from_json, - testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, - CosmosMsg, Empty, OwnedDeps, StdResult, + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; + use cosmwasm_std::{coins, from_json, CosmosMsg, Empty, OwnedDeps, StdResult}; use router_api::ChainName; - use crate::state::{WeightedVerifier, VERIFIER_WEIGHT}; - use super::*; + use crate::state::{WeightedVerifier, VERIFIER_WEIGHT}; const GOVERNANCE_ADDRESS: &str = "governance"; const UNAUTHORIZED_ADDRESS: &str = "unauthorized"; diff --git a/contracts/service-registry/src/contract/execute.rs b/contracts/service-registry/src/contract/execute.rs index ab7ecb14f..9ed49df12 100644 --- a/contracts/service-registry/src/contract/execute.rs +++ b/contracts/service-registry/src/contract/execute.rs @@ -1,8 +1,7 @@ -use crate::state::{self, Verifier}; -use crate::state::{AuthorizationState, VERIFIERS}; use router_api::ChainName; use super::*; +use crate::state::{self, AuthorizationState, Verifier, VERIFIERS}; pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { let config = CONFIG.load(deps.storage)?; diff --git a/contracts/service-registry/src/contract/query.rs b/contracts/service-registry/src/contract/query.rs index 051f6615b..7748cb027 100644 --- a/contracts/service-registry/src/contract/query.rs +++ b/contracts/service-registry/src/contract/query.rs @@ -1,8 +1,7 @@ use router_api::ChainName; -use crate::state::{WeightedVerifier, VERIFIERS, VERIFIERS_PER_CHAIN, VERIFIER_WEIGHT}; - use super::*; +use crate::state::{WeightedVerifier, VERIFIERS, VERIFIERS_PER_CHAIN, VERIFIER_WEIGHT}; pub fn get_active_verifiers( deps: Deps, diff --git a/contracts/service-registry/src/helpers.rs b/contracts/service-registry/src/helpers.rs index 7247c3fdf..8ba4bfa8f 100644 --- a/contracts/service-registry/src/helpers.rs +++ b/contracts/service-registry/src/helpers.rs @@ -1,8 +1,7 @@ +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg}; - use crate::msg::ExecuteMsg; /// ServiceRegistry is a wrapper around Addr that provides a lot of helpers diff --git a/contracts/service-registry/src/migrations/v_0_4.rs b/contracts/service-registry/src/migrations/v_0_4.rs index ebce0cf46..31682752d 100644 --- a/contracts/service-registry/src/migrations/v_0_4.rs +++ b/contracts/service-registry/src/migrations/v_0_4.rs @@ -53,8 +53,10 @@ pub fn migrate_services_coordinator_contract( #[cfg(test)] mod test { + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{Addr, Uint128}; + use super::*; - use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128}; #[test] fn successfully_migrate_services() { diff --git a/contracts/service-registry/src/state.rs b/contracts/service-registry/src/state.rs index 5dafe177b..fdf54123f 100644 --- a/contracts/service-registry/src/state.rs +++ b/contracts/service-registry/src/state.rs @@ -1,11 +1,10 @@ use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Storage, Timestamp, Uint128}; +use cw_storage_plus::{Item, Map}; use router_api::ChainName; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, Storage, Timestamp, Uint128}; -use cw_storage_plus::{Item, Map}; - #[cw_serde] pub struct Config { pub governance: Addr, @@ -13,7 +12,8 @@ pub struct Config { pub const CONFIG: Item = Item::new("config"); -use axelar_wasm_std::{nonempty, snapshot::Participant}; +use axelar_wasm_std::nonempty; +use axelar_wasm_std::snapshot::Participant; use crate::ContractError; @@ -189,9 +189,12 @@ pub fn deregister_chains_support( #[cfg(test)] mod tests { - use super::*; + use std::str::FromStr; + use std::vec; + use cosmwasm_std::testing::mock_dependencies; - use std::{str::FromStr, vec}; + + use super::*; #[test] fn register_single_verifier_chain_single_call_success() { diff --git a/contracts/voting-verifier/src/bin/schema.rs b/contracts/voting-verifier/src/bin/schema.rs index 6f6a8eb3f..d6bf17803 100644 --- a/contracts/voting-verifier/src/bin/schema.rs +++ b/contracts/voting-verifier/src/bin/schema.rs @@ -1,5 +1,4 @@ use cosmwasm_schema::write_api; - use voting_verifier::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index 84503a1a3..b6d211a31 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -1,11 +1,7 @@ +use axelar_wasm_std::voting::{PollId, Vote}; +use axelar_wasm_std::{nonempty, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{Addr, WasmMsg}; use error_stack::ResultExt; - -use axelar_wasm_std::{ - nonempty, - voting::{PollId, Vote}, - MajorityThreshold, VerificationStatus, -}; use multisig::verifier_set::VerifierSet; use router_api::Message; @@ -104,20 +100,16 @@ fn ignore_empty(msgs: Vec) -> Option> { mod test { use std::collections::BTreeMap; - use axelar_wasm_std::{msg_id::HexTxHashAndEventIndex, Threshold, VerificationStatus}; - use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info, MockQuerier}, - Addr, DepsMut, QuerierWrapper, Uint128, Uint64, WasmQuery, - }; + use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; + use axelar_wasm_std::{Threshold, VerificationStatus}; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier}; + use cosmwasm_std::{from_json, Addr, DepsMut, QuerierWrapper, Uint128, Uint64, WasmQuery}; use multisig::verifier_set::VerifierSet; use router_api::{CrossChainId, Message}; - use crate::{ - contract::{instantiate, query}, - msg::{InstantiateMsg, MessageStatus, QueryMsg}, - Client, - }; + use crate::contract::{instantiate, query}; + use crate::msg::{InstantiateMsg, MessageStatus, QueryMsg}; + use crate::Client; #[test] fn query_messages_status() { diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 12177df30..47cb98426 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -96,34 +96,28 @@ pub fn migrate( #[cfg(test)] mod test { - use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, - Addr, Empty, Fraction, OwnedDeps, Uint128, Uint64, WasmQuery, + use axelar_wasm_std::msg_id::{ + Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, + MessageIdFormat, }; - use sha3::{Digest, Keccak256, Keccak512}; - - use axelar_wasm_std::{ - msg_id::{ - Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, - HexTxHashAndEventIndex, MessageIdFormat, - }, - nonempty, - voting::Vote, - MajorityThreshold, Threshold, VerificationStatus, - }; - use multisig::{ - key::KeyType, - test::common::{build_verifier_set, ecdsa_test_data}, + use axelar_wasm_std::voting::Vote; + use axelar_wasm_std::{nonempty, MajorityThreshold, Threshold, VerificationStatus}; + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; + use cosmwasm_std::{from_json, Addr, Empty, Fraction, OwnedDeps, Uint128, Uint64, WasmQuery}; + use multisig::key::KeyType; + use multisig::test::common::{build_verifier_set, ecdsa_test_data}; use router_api::{ChainName, CrossChainId, Message}; use service_registry::state::{ AuthorizationState, BondingState, Verifier, WeightedVerifier, VERIFIER_WEIGHT, }; - - use crate::{error::ContractError, events::TxEventConfirmation, msg::MessageStatus}; + use sha3::{Digest, Keccak256, Keccak512}; use super::*; + use crate::error::ContractError; + use crate::events::TxEventConfirmation; + use crate::msg::MessageStatus; const SENDER: &str = "sender"; const SERVICE_REGISTRY_ADDRESS: &str = "service_registry_address"; diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 427c868f5..764a62103 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -1,15 +1,14 @@ use std::str::FromStr; use std::vec::Vec; -use axelar_wasm_std::msg_id::Base58SolanaTxSignatureAndEventIndex; -use axelar_wasm_std::msg_id::Base58TxDigestAndEventIndex; -use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; -use axelar_wasm_std::msg_id::MessageIdFormat; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Attribute, Event}; - +use axelar_wasm_std::msg_id::{ + Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, + MessageIdFormat, +}; use axelar_wasm_std::voting::{PollId, Vote}; use axelar_wasm_std::{nonempty, VerificationStatus}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Attribute, Event}; use multisig::verifier_set::VerifierSet; use router_api::{Address, ChainName, Message}; @@ -265,10 +264,10 @@ where mod test { use std::collections::BTreeMap; - use axelar_wasm_std::{ - msg_id::{Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat}, - nonempty, + use axelar_wasm_std::msg_id::{ + Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat, }; + use axelar_wasm_std::nonempty; use cosmwasm_std::Uint128; use multisig::verifier_set::VerifierSet; use router_api::{CrossChainId, Message}; diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 82a44ce88..0987d1226 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -1,32 +1,26 @@ use std::collections::HashMap; +use axelar_wasm_std::voting::{PollId, PollResults, Vote, WeightedPoll}; +use axelar_wasm_std::{nonempty, snapshot, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ to_json_binary, Addr, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, }; - -use axelar_wasm_std::{ - nonempty, snapshot, - voting::{PollId, PollResults, Vote, WeightedPoll}, - MajorityThreshold, VerificationStatus, -}; - +use itertools::Itertools; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; -use service_registry::{msg::QueryMsg, state::WeightedVerifier}; - -use crate::state::{self, Poll, PollContent, VOTES}; -use crate::state::{CONFIG, POLLS, POLL_ID}; -use crate::{error::ContractError, query::message_status}; -use crate::{events::QuorumReached, query::verifier_set_status, state::poll_verifier_sets}; -use crate::{ - events::{ - PollEnded, PollMetadata, PollStarted, TxEventConfirmation, VerifierSetConfirmation, Voted, - }, - state::poll_messages, -}; +use service_registry::msg::QueryMsg; +use service_registry::state::WeightedVerifier; -use itertools::Itertools; +use crate::error::ContractError; +use crate::events::{ + PollEnded, PollMetadata, PollStarted, QuorumReached, TxEventConfirmation, + VerifierSetConfirmation, Voted, +}; +use crate::query::{message_status, verifier_set_status}; +use crate::state::{ + self, poll_messages, poll_verifier_sets, Poll, PollContent, CONFIG, POLLS, POLL_ID, VOTES, +}; // TODO: this type of function exists in many contracts. Would be better to implement this // in one place, and then just include it @@ -386,11 +380,11 @@ fn calculate_expiration(block_height: u64, block_expiry: u64) -> Result Config { Config { diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index 3bb142b93..55d287664 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -1,12 +1,7 @@ +use axelar_wasm_std::msg_id::MessageIdFormat; +use axelar_wasm_std::voting::{PollId, PollStatus, Vote, WeightedPoll}; +use axelar_wasm_std::{nonempty, MajorityThreshold, VerificationStatus}; use cosmwasm_schema::{cw_serde, QueryResponses}; - -use axelar_wasm_std::voting::PollStatus; -use axelar_wasm_std::{ - msg_id::MessageIdFormat, - nonempty, - voting::{PollId, Vote, WeightedPoll}, - MajorityThreshold, VerificationStatus, -}; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index 5337fcf35..91096a98a 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -1,19 +1,12 @@ -use axelar_wasm_std::{ - voting::{PollId, PollStatus, Vote}, - MajorityThreshold, VerificationStatus, -}; +use axelar_wasm_std::voting::{PollId, PollStatus, Vote}; +use axelar_wasm_std::{MajorityThreshold, VerificationStatus}; use cosmwasm_std::Deps; use multisig::verifier_set::VerifierSet; use router_api::Message; -use crate::{ - error::ContractError, - state::{poll_messages, poll_verifier_sets, CONFIG}, -}; -use crate::{ - msg::{MessageStatus, PollData, PollResponse}, - state::{self, Poll, PollContent, POLLS}, -}; +use crate::error::ContractError; +use crate::msg::{MessageStatus, PollData, PollResponse}; +use crate::state::{self, poll_messages, poll_verifier_sets, Poll, PollContent, CONFIG, POLLS}; pub fn voting_threshold(deps: Deps) -> Result { Ok(CONFIG.load(deps.storage)?.voting_threshold) @@ -152,20 +145,16 @@ fn voting_completed(poll: &state::Poll, cur_block_height: u64) -> bool { #[cfg(test)] mod tests { - use axelar_wasm_std::{ - msg_id::HexTxHashAndEventIndex, - nonempty, - voting::{PollId, Tallies, Vote, WeightedPoll}, - Participant, Snapshot, Threshold, - }; - use cosmwasm_std::testing::mock_env; - use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128, Uint64}; + use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; + use axelar_wasm_std::voting::{PollId, Tallies, Vote, WeightedPoll}; + use axelar_wasm_std::{nonempty, Participant, Snapshot, Threshold}; + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + use cosmwasm_std::{Addr, Uint128, Uint64}; use itertools::Itertools; use router_api::CrossChainId; - use crate::state::PollContent; - use super::*; + use crate::state::PollContent; #[test] fn verification_status_in_progress() { diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index 7d5f438d6..567ea197a 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -1,15 +1,10 @@ +use axelar_wasm_std::hash::Hash; +use axelar_wasm_std::msg_id::MessageIdFormat; +use axelar_wasm_std::voting::{PollId, Vote, WeightedPoll}; +use axelar_wasm_std::{counter, nonempty, MajorityThreshold}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Order, StdResult, Storage}; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex}; - -use axelar_wasm_std::{ - counter, - hash::Hash, - msg_id::MessageIdFormat, - nonempty, - voting::{PollId, Vote, WeightedPoll}, - MajorityThreshold, -}; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; diff --git a/integration-tests/src/coordinator_contract.rs b/integration-tests/src/coordinator_contract.rs index 7b178253f..c742492c1 100644 --- a/integration-tests/src/coordinator_contract.rs +++ b/integration-tests/src/coordinator_contract.rs @@ -1,8 +1,9 @@ -use crate::contract::Contract; use coordinator::contract::{execute, instantiate, query}; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; +use crate::contract::Contract; + #[derive(Clone)] pub struct CoordinatorContract { pub contract_addr: Addr, diff --git a/integration-tests/src/gateway_contract.rs b/integration-tests/src/gateway_contract.rs index 7ed4b8585..73ec11b32 100644 --- a/integration-tests/src/gateway_contract.rs +++ b/integration-tests/src/gateway_contract.rs @@ -1,7 +1,8 @@ -use crate::contract::Contract; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; +use crate::contract::Contract; + #[derive(Clone)] pub struct GatewayContract { pub contract_addr: Addr, diff --git a/integration-tests/src/multisig_contract.rs b/integration-tests/src/multisig_contract.rs index 52a35ebdc..ef7bbefc4 100644 --- a/integration-tests/src/multisig_contract.rs +++ b/integration-tests/src/multisig_contract.rs @@ -1,8 +1,9 @@ -use crate::contract::Contract; use axelar_wasm_std::nonempty; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; +use crate::contract::Contract; + #[derive(Clone)] pub struct MultisigContract { pub contract_addr: Addr, diff --git a/integration-tests/src/multisig_prover_contract.rs b/integration-tests/src/multisig_prover_contract.rs index a86ba7f20..75256fb28 100644 --- a/integration-tests/src/multisig_prover_contract.rs +++ b/integration-tests/src/multisig_prover_contract.rs @@ -1,10 +1,12 @@ -use crate::{contract::Contract, protocol::Protocol}; use axelar_wasm_std::Threshold; use cosmwasm_std::Addr; use cw_multi_test::{ContractWrapper, Executor}; use multisig::key::KeyType; use multisig_prover::encoding::Encoder; +use crate::contract::Contract; +use crate::protocol::Protocol; + #[derive(Clone)] pub struct MultisigProverContract { pub contract_addr: Addr, diff --git a/integration-tests/src/protocol.rs b/integration-tests/src/protocol.rs index dd7ae0506..962ad2dff 100644 --- a/integration-tests/src/protocol.rs +++ b/integration-tests/src/protocol.rs @@ -2,11 +2,11 @@ use axelar_wasm_std::nonempty; use cosmwasm_std::Addr; use cw_multi_test::App; -use crate::{ - coordinator_contract::CoordinatorContract, multisig_contract::MultisigContract, - rewards_contract::RewardsContract, router_contract::RouterContract, - service_registry_contract::ServiceRegistryContract, -}; +use crate::coordinator_contract::CoordinatorContract; +use crate::multisig_contract::MultisigContract; +use crate::rewards_contract::RewardsContract; +use crate::router_contract::RouterContract; +use crate::service_registry_contract::ServiceRegistryContract; pub struct Protocol { pub genesis_address: Addr, // holds u128::max coins, can use to send coins to other addresses diff --git a/integration-tests/src/rewards_contract.rs b/integration-tests/src/rewards_contract.rs index 14809ed54..0e0118739 100644 --- a/integration-tests/src/rewards_contract.rs +++ b/integration-tests/src/rewards_contract.rs @@ -1,7 +1,8 @@ -use crate::contract::Contract; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; +use crate::contract::Contract; + #[derive(Clone)] pub struct RewardsContract { pub contract_addr: Addr, diff --git a/integration-tests/src/router_contract.rs b/integration-tests/src/router_contract.rs index 1ade90804..45ca7e33f 100644 --- a/integration-tests/src/router_contract.rs +++ b/integration-tests/src/router_contract.rs @@ -1,7 +1,8 @@ -use crate::contract::Contract; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; +use crate::contract::Contract; + #[derive(Clone)] pub struct RouterContract { pub contract_addr: Addr, diff --git a/integration-tests/src/service_registry_contract.rs b/integration-tests/src/service_registry_contract.rs index 34d79c477..59afd08da 100644 --- a/integration-tests/src/service_registry_contract.rs +++ b/integration-tests/src/service_registry_contract.rs @@ -1,8 +1,9 @@ -use crate::contract::Contract; use cosmwasm_std::Addr; use cw_multi_test::{App, ContractWrapper, Executor}; use service_registry::contract::{execute, instantiate, query}; +use crate::contract::Contract; + #[derive(Clone)] pub struct ServiceRegistryContract { pub contract_addr: Addr, diff --git a/integration-tests/src/voting_verifier_contract.rs b/integration-tests/src/voting_verifier_contract.rs index 5f992770b..f4936e90d 100644 --- a/integration-tests/src/voting_verifier_contract.rs +++ b/integration-tests/src/voting_verifier_contract.rs @@ -1,11 +1,11 @@ -use crate::contract::Contract; -use crate::protocol::Protocol; -use axelar_wasm_std::nonempty; -use axelar_wasm_std::MajorityThreshold; +use axelar_wasm_std::{nonempty, MajorityThreshold}; use cosmwasm_std::Addr; use cw_multi_test::{ContractWrapper, Executor}; use router_api::ChainName; +use crate::contract::Contract; +use crate::protocol::Protocol; + #[derive(Clone)] pub struct VotingVerifierContract { pub contract_addr: Addr, diff --git a/integration-tests/tests/chain_freeze_unfreeze.rs b/integration-tests/tests/chain_freeze_unfreeze.rs index 084d6eab7..a2edb2988 100644 --- a/integration-tests/tests/chain_freeze_unfreeze.rs +++ b/integration-tests/tests/chain_freeze_unfreeze.rs @@ -1,5 +1,4 @@ use cosmwasm_std::{Addr, HexBinary}; - use integration_tests::contract::Contract; use router_api::{CrossChainId, Message}; diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index 3faf8da08..74d64fd63 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -1,5 +1,4 @@ use cosmwasm_std::{Addr, HexBinary, Uint128}; - use integration_tests::contract::Contract; use router_api::{CrossChainId, Message}; diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 6b2c7d94e..15bfd23d2 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -1,37 +1,31 @@ -use axelar_wasm_std::{ - msg_id::HexTxHashAndEventIndex, - nonempty, - voting::{PollId, Vote}, - Participant, Threshold, -}; +use std::collections::{HashMap, HashSet}; + +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; +use axelar_wasm_std::voting::{PollId, Vote}; +use axelar_wasm_std::{nonempty, Participant, Threshold}; +use coordinator::msg::ExecuteMsg as CoordinatorExecuteMsg; use cosmwasm_std::{ coins, Addr, Attribute, BlockInfo, Event, HexBinary, StdError, Uint128, Uint64, }; use cw_multi_test::{App, AppResponse, Executor}; -use multisig_prover::msg::VerifierSetResponse; -use router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; -use std::collections::{HashMap, HashSet}; - use integration_tests::contract::Contract; use integration_tests::coordinator_contract::CoordinatorContract; use integration_tests::gateway_contract::GatewayContract; use integration_tests::multisig_contract::MultisigContract; use integration_tests::multisig_prover_contract::MultisigProverContract; +use integration_tests::protocol::Protocol; use integration_tests::rewards_contract::RewardsContract; +use integration_tests::router_contract::RouterContract; use integration_tests::service_registry_contract::ServiceRegistryContract; use integration_tests::voting_verifier_contract::VotingVerifierContract; -use integration_tests::{protocol::Protocol, router_contract::RouterContract}; - use k256::ecdsa; -use sha3::{Digest, Keccak256}; - -use coordinator::msg::ExecuteMsg as CoordinatorExecuteMsg; -use multisig::{ - key::{KeyType, PublicKey}, - verifier_set::VerifierSet, -}; +use multisig::key::{KeyType, PublicKey}; +use multisig::verifier_set::VerifierSet; +use multisig_prover::msg::VerifierSetResponse; use rewards::state::PoolId; +use router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; use service_registry::msg::ExecuteMsg; +use sha3::{Digest, Keccak256}; use tofn::ecdsa::KeyPair; pub const AXL_DENOMINATION: &str = "uaxl"; diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index 33495385f..7746d571a 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -1,9 +1,9 @@ use cosmwasm_std::Addr; use cw_multi_test::Executor; - use integration_tests::contract::Contract; use multisig_prover::msg::ExecuteMsg; -use service_registry::{msg::QueryMsg as ServiceRegistryQueryMsg, state::WeightedVerifier}; +use service_registry::msg::QueryMsg as ServiceRegistryQueryMsg; +use service_registry::state::WeightedVerifier; use test_utils::{ create_new_verifiers_vec, get_multisig_session_id, register_in_service_registry, register_verifiers, rotate_active_verifier_set, Verifier, diff --git a/packages/axelar-wasm-std/src/error.rs b/packages/axelar-wasm-std/src/error.rs index 8e8f7410c..18301abac 100644 --- a/packages/axelar-wasm-std/src/error.rs +++ b/packages/axelar-wasm-std/src/error.rs @@ -1,9 +1,10 @@ -use crate::permission_control; use cosmwasm_std::StdError; use error_stack::{Context, Report}; use report::LoggableError; use thiserror::Error; +use crate::permission_control; + /// This error is supposed to be the top-level error type our contracts return to the cosmwasm module. /// Ideally, we would like to return an error-stack [Report] directly, /// but it won't show all necessary information (namely attachments) in the error message, and many places also return an [StdError]. diff --git a/packages/axelar-wasm-std/src/flagset.rs b/packages/axelar-wasm-std/src/flagset.rs index 8402862f0..78280ef89 100644 --- a/packages/axelar-wasm-std/src/flagset.rs +++ b/packages/axelar-wasm-std/src/flagset.rs @@ -1,6 +1,8 @@ use std::ops::{Deref, DerefMut}; -use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; +use schemars::gen::SchemaGenerator; +use schemars::schema::Schema; +use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize}; #[derive(Serialize, Clone, Debug, PartialEq, Eq)] diff --git a/packages/axelar-wasm-std/src/killswitch.rs b/packages/axelar-wasm-std/src/killswitch.rs index 597a79bb1..dffb53a6d 100644 --- a/packages/axelar-wasm-std/src/killswitch.rs +++ b/packages/axelar-wasm-std/src/killswitch.rs @@ -78,7 +78,8 @@ const STATE: Item = Item::new("state"); #[cfg(test)] mod tests { - use cosmwasm_std::{testing::mock_dependencies, Event}; + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::Event; use crate::killswitch::{disengage, engage, init, is_contract_active, State, STATE}; diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 5b986b59c..60e3c9313 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -1,10 +1,8 @@ -pub use crate::{ - error::ContractError, - fn_ext::FnExt, - snapshot::{Participant, Snapshot}, - threshold::{MajorityThreshold, Threshold}, - verification::VerificationStatus, -}; +pub use crate::error::ContractError; +pub use crate::fn_ext::FnExt; +pub use crate::snapshot::{Participant, Snapshot}; +pub use crate::threshold::{MajorityThreshold, Threshold}; +pub use crate::verification::VerificationStatus; pub mod counter; pub mod error; diff --git a/packages/axelar-wasm-std/src/msg_id/base_58_event_index.rs b/packages/axelar-wasm-std/src/msg_id/base_58_event_index.rs index ea6debb0d..1c75542b2 100644 --- a/packages/axelar-wasm-std/src/msg_id/base_58_event_index.rs +++ b/packages/axelar-wasm-std/src/msg_id/base_58_event_index.rs @@ -1,12 +1,14 @@ use core::fmt; -use std::{fmt::Display, str::FromStr}; +use std::fmt::Display; +use std::str::FromStr; use error_stack::{Report, ResultExt}; use lazy_static::lazy_static; use regex::Regex; use super::Error; -use crate::{hash::Hash, nonempty}; +use crate::hash::Hash; +use crate::nonempty; pub struct Base58TxDigestAndEventIndex { pub tx_digest: Hash, diff --git a/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs b/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs index 4c7fd150b..1a625f910 100644 --- a/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs +++ b/packages/axelar-wasm-std/src/msg_id/base_58_solana_event_index.rs @@ -1,5 +1,6 @@ use core::fmt; -use std::{fmt::Display, str::FromStr}; +use std::fmt::Display; +use std::str::FromStr; use error_stack::{Report, ResultExt}; use lazy_static::lazy_static; diff --git a/packages/axelar-wasm-std/src/msg_id/mod.rs b/packages/axelar-wasm-std/src/msg_id/mod.rs index b900d1c92..26c33de5b 100644 --- a/packages/axelar-wasm-std/src/msg_id/mod.rs +++ b/packages/axelar-wasm-std/src/msg_id/mod.rs @@ -1,13 +1,12 @@ -use std::{fmt::Display, str::FromStr}; +use std::fmt::Display; +use std::str::FromStr; use cosmwasm_schema::cw_serde; use error_stack::Report; -pub use self::{ - base_58_event_index::Base58TxDigestAndEventIndex, - base_58_solana_event_index::Base58SolanaTxSignatureAndEventIndex, - tx_hash_event_index::HexTxHashAndEventIndex, -}; +pub use self::base_58_event_index::Base58TxDigestAndEventIndex; +pub use self::base_58_solana_event_index::Base58SolanaTxSignatureAndEventIndex; +pub use self::tx_hash_event_index::HexTxHashAndEventIndex; mod base_58_event_index; mod base_58_solana_event_index; @@ -62,11 +61,9 @@ pub fn verify_msg_id(message_id: &str, format: &MessageIdFormat) -> Result<(), R #[cfg(test)] mod test { - use crate::msg_id::{ - base_58_event_index::Base58TxDigestAndEventIndex, verify_msg_id, MessageIdFormat, - }; - use super::tx_hash_event_index::HexTxHashAndEventIndex; + use crate::msg_id::base_58_event_index::Base58TxDigestAndEventIndex; + use crate::msg_id::{verify_msg_id, MessageIdFormat}; #[test] fn should_verify_hex_tx_hash_event_index_msg_id() { diff --git a/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs b/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs index 42c764f7d..63be431d6 100644 --- a/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs +++ b/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs @@ -1,5 +1,6 @@ use core::fmt; -use std::{fmt::Display, str::FromStr}; +use std::fmt::Display; +use std::str::FromStr; use cosmwasm_std::HexBinary; use error_stack::{Report, ResultExt}; @@ -7,7 +8,8 @@ use lazy_static::lazy_static; use regex::Regex; use super::Error; -use crate::{hash::Hash, nonempty}; +use crate::hash::Hash; +use crate::nonempty; pub struct HexTxHashAndEventIndex { pub tx_hash: Hash, diff --git a/packages/axelar-wasm-std/src/nonempty/timestamp.rs b/packages/axelar-wasm-std/src/nonempty/timestamp.rs index 2501f8c36..2b1ec1ce4 100644 --- a/packages/axelar-wasm-std/src/nonempty/timestamp.rs +++ b/packages/axelar-wasm-std/src/nonempty/timestamp.rs @@ -1,6 +1,7 @@ -use crate::nonempty::Error; use cosmwasm_schema::cw_serde; +use crate::nonempty::Error; + #[cw_serde] pub struct Timestamp(cosmwasm_std::Timestamp); diff --git a/packages/axelar-wasm-std/src/nonempty/uint.rs b/packages/axelar-wasm-std/src/nonempty/uint.rs index 1627d78d7..de9eba31a 100644 --- a/packages/axelar-wasm-std/src/nonempty/uint.rs +++ b/packages/axelar-wasm-std/src/nonempty/uint.rs @@ -1,8 +1,9 @@ use std::fmt; -use crate::nonempty::Error; use cosmwasm_schema::cw_serde; +use crate::nonempty::Error; + #[cw_serde] #[serde(try_from = "cosmwasm_std::Uint64")] #[serde(into = "cosmwasm_std::Uint64")] diff --git a/packages/axelar-wasm-std/src/nonempty/vec.rs b/packages/axelar-wasm-std/src/nonempty/vec.rs index 874033ab0..eb9c68918 100644 --- a/packages/axelar-wasm-std/src/nonempty/vec.rs +++ b/packages/axelar-wasm-std/src/nonempty/vec.rs @@ -1,7 +1,8 @@ -use crate::nonempty::Error; use cosmwasm_schema::cw_serde; use cosmwasm_std::HexBinary; +use crate::nonempty::Error; + #[cw_serde] #[serde(try_from = "std::vec::Vec")] pub struct Vec(std::vec::Vec); diff --git a/packages/axelar-wasm-std/src/permission_control.rs b/packages/axelar-wasm-std/src/permission_control.rs index 047be9469..6320149ec 100644 --- a/packages/axelar-wasm-std/src/permission_control.rs +++ b/packages/axelar-wasm-std/src/permission_control.rs @@ -1,11 +1,13 @@ -use crate::flagset::FlagSet; -use crate::FnExt; +use std::fmt::{Debug, Display, Formatter}; + use cosmwasm_std::{Addr, StdResult}; use cw_storage_plus::Item; use flagset::{flags, Flags}; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use std::fmt::{Debug, Display, Formatter}; + +use crate::flagset::FlagSet; +use crate::FnExt; flags! { #[repr(u8)] @@ -94,9 +96,10 @@ pub fn sender_role( #[cfg(test)] mod tests { - use super::*; use cosmwasm_std::testing::MockStorage; + use super::*; + #[test] fn display_permissions() { assert_eq!(format!("{}", FlagSet::from(Permission::Admin)), "Admin"); diff --git a/packages/axelar-wasm-std/src/snapshot.rs b/packages/axelar-wasm-std/src/snapshot.rs index ec7956d03..1487a42d6 100644 --- a/packages/axelar-wasm-std/src/snapshot.rs +++ b/packages/axelar-wasm-std/src/snapshot.rs @@ -3,7 +3,8 @@ use std::collections::HashMap; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Uint128}; -use crate::{nonempty, threshold::MajorityThreshold}; +use crate::nonempty; +use crate::threshold::MajorityThreshold; #[cw_serde] pub struct Participant { @@ -61,9 +62,8 @@ impl Snapshot { mod tests { use cosmwasm_std::{from_json, to_json_binary, Uint64}; - use crate::Threshold; - use super::*; + use crate::Threshold; fn mock_participant(address: &str, weight: nonempty::Uint128) -> Participant { Participant { diff --git a/packages/axelar-wasm-std/src/voting.rs b/packages/axelar-wasm-std/src/voting.rs index b815fb0d6..3c38feffc 100644 --- a/packages/axelar-wasm-std/src/voting.rs +++ b/packages/axelar-wasm-std/src/voting.rs @@ -14,27 +14,20 @@ on whether the transaction was successfully verified. */ use std::array::TryFromSliceError; -use std::collections::BTreeMap; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::fmt; -use std::ops::Add; -use std::ops::Mul; +use std::ops::{Add, Mul}; use std::str::FromStr; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdError, StdResult, Uint128, Uint64}; -use cw_storage_plus::Prefixer; -use cw_storage_plus::{IntKey, Key, KeyDeserialize, PrimaryKey}; -use num_traits::CheckedAdd; -use num_traits::One; -use strum::EnumIter; -use strum::EnumString; -use strum::IntoEnumIterator; +use cw_storage_plus::{IntKey, Key, KeyDeserialize, Prefixer, PrimaryKey}; +use num_traits::{CheckedAdd, One}; +use strum::{EnumIter, EnumString, IntoEnumIterator}; use thiserror::Error; use valuable::Valuable; -use crate::nonempty; -use crate::Snapshot; +use crate::{nonempty, Snapshot}; #[derive(Error, Debug, PartialEq, Eq)] pub enum Error { @@ -420,9 +413,8 @@ mod tests { use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; - use crate::{nonempty, Participant, Threshold}; - use super::*; + use crate::{nonempty, Participant, Threshold}; #[test] fn cast_vote() { diff --git a/packages/client/src/lib.rs b/packages/client/src/lib.rs index 87e1df2d4..49864d1b8 100644 --- a/packages/client/src/lib.rs +++ b/packages/client/src/lib.rs @@ -4,7 +4,8 @@ use cosmwasm_std::{ to_json_binary, Addr, QuerierWrapper, QueryRequest, StdError, WasmMsg, WasmQuery, }; use error_stack::{Report, Result}; -use serde::{de::DeserializeOwned, Serialize}; +use serde::de::DeserializeOwned; +use serde::Serialize; #[derive(thiserror::Error, Debug)] pub enum Error { diff --git a/packages/events/src/event.rs b/packages/events/src/event.rs index d39ce5925..17e179519 100644 --- a/packages/events/src/event.rs +++ b/packages/events/src/event.rs @@ -3,6 +3,7 @@ use std::fmt::Display; use axelar_wasm_std::FnExt; use base64::engine::general_purpose::STANDARD; use base64::Engine; +use cosmrs::AccountId; use error_stack::{Report, Result, ResultExt}; use serde_json::Value; use tendermint::abci::EventAttribute; @@ -11,8 +12,6 @@ use tendermint::{abci, block}; use crate::errors::DecodingError; use crate::Error; -use cosmrs::AccountId; - #[derive(Clone, Debug, PartialEq, Eq)] pub enum Event { BlockBegin(block::Height), diff --git a/packages/evm-gateway/src/lib.rs b/packages/evm-gateway/src/lib.rs index 8383ed2f2..689f7e7b8 100644 --- a/packages/evm-gateway/src/lib.rs +++ b/packages/evm-gateway/src/lib.rs @@ -2,28 +2,21 @@ pub mod error; use std::str::FromStr; +use axelar_wasm_std::hash::Hash; +use axelar_wasm_std::FnExt; use cosmwasm_std::Uint256; use error_stack::{Report, ResultExt}; use ethers_contract::abigen; -use ethers_core::{ - abi::{ - encode, - Token::{self, Tuple, Uint}, - Tokenize, - }, - types::{Address, Bytes, U256}, - utils::public_key_to_address, -}; +use ethers_core::abi::Token::{self, Tuple, Uint}; +use ethers_core::abi::{encode, Tokenize}; +use ethers_core::types::{Address, Bytes, U256}; +use ethers_core::utils::public_key_to_address; use k256::ecdsa::VerifyingKey; -use sha3::{Digest, Keccak256}; - -use axelar_wasm_std::{hash::Hash, FnExt}; -use multisig::{ - key::PublicKey, - msg::{Signer, SignerWithSig}, - verifier_set::VerifierSet, -}; +use multisig::key::PublicKey; +use multisig::msg::{Signer, SignerWithSig}; +use multisig::verifier_set::VerifierSet; use router_api::Message as RouterMessage; +use sha3::{Digest, Keccak256}; use crate::error::Error; @@ -152,10 +145,11 @@ pub fn evm_address(pub_key: &PublicKey) -> Result> { mod test { use std::str::FromStr; + use axelar_wasm_std::nonempty; + use axelar_wasm_std::snapshot::Participant; use cosmwasm_std::{Addr, HexBinary, Uint128}; - - use axelar_wasm_std::{nonempty, snapshot::Participant}; - use multisig::{key::PublicKey, verifier_set::VerifierSet}; + use multisig::key::PublicKey; + use multisig::verifier_set::VerifierSet; use router_api::{CrossChainId, Message as RouterMessage}; use crate::{Message, WeightedSigners}; diff --git a/packages/msgs-derive/src/lib.rs b/packages/msgs-derive/src/lib.rs index dd7a0ee95..c2e3ce947 100644 --- a/packages/msgs-derive/src/lib.rs +++ b/packages/msgs-derive/src/lib.rs @@ -10,10 +10,10 @@ use syn::{Data, DataEnum, DeriveInput, Expr, ExprCall, Ident, Path, Token, Varia /// has the required permissions to execute the variant. The permissions are defined using the /// `#[permission]` attribute. The attribute can be used in two ways: /// - `#[permission(Permission1, Permission2, ...)]` requires the sender to have at least one of -/// the specified permissions. These permissions are defined in the [axelar_wasm_std::permission_control::Permission] enum. +/// the specified permissions. These permissions are defined in the [axelar_wasm_std::permission_control::Permission] enum. /// - `#[permission(Specific(Addr1, Addr2, ...))]` requires the sender to be one of the specified -/// addresses. The macro will generate a function signature that takes closures as arguments to determine -/// the whitelisted addresses. +/// addresses. The macro will generate a function signature that takes closures as arguments to determine +/// the whitelisted addresses. /// /// Both attributes can be used together, in which case the sender must have at least one of the /// specified permissions or be one of the specified addresses. diff --git a/packages/msgs-derive/tests/macro.rs b/packages/msgs-derive/tests/macro.rs index c3db0ac58..4d4da6c44 100644 --- a/packages/msgs-derive/tests/macro.rs +++ b/packages/msgs-derive/tests/macro.rs @@ -1,8 +1,9 @@ +use std::fmt::Display; + use axelar_wasm_std::permission_control; use cosmwasm_std::testing::MockStorage; use cosmwasm_std::{Addr, Storage}; use error_stack::{report, Report}; -use std::fmt::Display; #[derive(msgs_derive::EnsurePermissions, Clone, Debug)] #[allow(dead_code)] // the msg fields are only defined to make sure the derive attribute can handle fields correctly diff --git a/packages/report/src/loggable.rs b/packages/report/src/loggable.rs index 35578938d..ab851a93e 100644 --- a/packages/report/src/loggable.rs +++ b/packages/report/src/loggable.rs @@ -150,11 +150,13 @@ impl<'a> From<&'a Frame> for FrameType<'a> { #[cfg(test)] mod tests { - use crate::LoggableError; - use error_stack::Report; use std::env; + + use error_stack::Report; use thiserror::Error; + use crate::LoggableError; + #[derive(Error, Debug)] enum Error { #[error("{0}")] diff --git a/packages/router-api/src/msg.rs b/packages/router-api/src/msg.rs index a7b2de172..57c43f7af 100644 --- a/packages/router-api/src/msg.rs +++ b/packages/router-api/src/msg.rs @@ -1,8 +1,10 @@ -use crate::primitives::*; +use std::collections::HashMap; + use axelar_wasm_std::msg_id::MessageIdFormat; use cosmwasm_schema::{cw_serde, QueryResponses}; use msgs_derive::EnsurePermissions; -use std::collections::HashMap; + +use crate::primitives::*; #[cw_serde] #[derive(EnsurePermissions)] diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index c0d515411..ccf104f67 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -1,14 +1,16 @@ -use std::{any::type_name, fmt, ops::Deref, str::FromStr}; +use std::any::type_name; +use std::fmt; +use std::ops::Deref; +use std::str::FromStr; use axelar_wasm_std::flagset::FlagSet; +use axelar_wasm_std::hash::Hash; use axelar_wasm_std::msg_id::MessageIdFormat; -use axelar_wasm_std::{hash::Hash, nonempty, FnExt}; +use axelar_wasm_std::{nonempty, FnExt}; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Attribute, HexBinary}; -use cosmwasm_std::{StdError, StdResult}; +use cosmwasm_std::{Addr, Attribute, HexBinary, StdError, StdResult}; use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; -use error_stack::Report; -use error_stack::ResultExt; +use error_stack::{Report, ResultExt}; use flagset::flags; use schemars::gen::SchemaGenerator; use schemars::schema::Schema; @@ -291,13 +293,13 @@ impl ChainEndpoint { #[cfg(test)] mod tests { - use super::*; - use cosmwasm_std::to_json_vec; use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; use sha3::{Digest, Sha3_256}; + use super::*; + #[test] // Any modifications to the Message struct fields or their types // will cause this test to fail, indicating that a migration is needed. diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 000000000..1dc74ed1d --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,2 @@ +imports_granularity = "Module" +group_imports = "StdExternalCrate" \ No newline at end of file From ac966f168f81702fa1913e2b98c6fc926e3a258d Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Mon, 22 Jul 2024 14:39:30 -0400 Subject: [PATCH 090/168] docs: add bullet points to all chapters of SUMMARY.md (#529) --- doc/src/SUMMARY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/SUMMARY.md b/doc/src/SUMMARY.md index 1f3cfc509..e9229e3e2 100644 --- a/doc/src/SUMMARY.md +++ b/doc/src/SUMMARY.md @@ -15,8 +15,8 @@ ## Message Access Requirements -[Amplifier Access Control](message_access.md) +- [Amplifier Access Control](message_access.md) # Contributing -[Documentation](contributing/documentation.md) \ No newline at end of file +- [Documentation](contributing/documentation.md) \ No newline at end of file From 546b5e1abbfae3f2cfed180adaac5a29534c59c0 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 22 Jul 2024 19:04:19 -0400 Subject: [PATCH 091/168] feat(multisig-prover): add permission control to multisig-prover (#526) --- Cargo.lock | 1 + contracts/multisig-prover/Cargo.toml | 1 + contracts/multisig-prover/src/contract.rs | 126 +++++----- .../src/{ => contract}/execute.rs | 38 +-- .../src/contract/migrations/mod.rs | 1 + .../src/contract/migrations/v0_6_0.rs | 218 ++++++++++++++++++ .../src/{ => contract}/query.rs | 0 .../src/{ => contract}/reply.rs | 0 contracts/multisig-prover/src/error.rs | 3 - contracts/multisig-prover/src/lib.rs | 3 - contracts/multisig-prover/src/msg.rs | 17 +- contracts/multisig-prover/src/state.rs | 2 - 12 files changed, 311 insertions(+), 99 deletions(-) rename contracts/multisig-prover/src/{ => contract}/execute.rs (94%) create mode 100644 contracts/multisig-prover/src/contract/migrations/mod.rs create mode 100644 contracts/multisig-prover/src/contract/migrations/v0_6_0.rs rename contracts/multisig-prover/src/{ => contract}/query.rs (100%) rename contracts/multisig-prover/src/{ => contract}/reply.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 7f01dedf7..4100bbd92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4657,6 +4657,7 @@ dependencies = [ "hex", "itertools 0.11.0", "k256", + "msgs-derive", "multisig", "prost 0.12.6", "report", diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 3f4d92f08..5d10e1833 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -51,6 +51,7 @@ gateway-api = { workspace = true } hex = { version = "0.4.3", default-features = false, features = [] } itertools = "0.11.0" k256 = { version = "0.13.1", features = ["ecdsa"] } +msgs-derive = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } router-api = { workspace = true } diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 787737180..223c529ac 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::permission_control; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -8,7 +9,10 @@ use error_stack::ResultExt; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{Config, CONFIG}; -use crate::{execute, query, reply}; +mod execute; +mod migrations; +mod query; +mod reply; pub const START_MULTISIG_REPLY_ID: u64 = 1; @@ -24,43 +28,29 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let config = make_config(&deps, msg)?; - CONFIG.save(deps.storage, &config)?; - - Ok(Response::default()) -} - -fn make_config( - deps: &DepsMut, - msg: InstantiateMsg, -) -> Result { - let admin = deps.api.addr_validate(&msg.admin_address)?; - let governance = deps.api.addr_validate(&msg.governance_address)?; - let gateway = deps.api.addr_validate(&msg.gateway_address)?; - let multisig = deps.api.addr_validate(&msg.multisig_address)?; - let coordinator = deps.api.addr_validate(&msg.coordinator_address)?; - let service_registry = deps.api.addr_validate(&msg.service_registry_address)?; - let voting_verifier = deps.api.addr_validate(&msg.voting_verifier_address)?; - - Ok(Config { - admin, - governance, - gateway, - multisig, - coordinator, - service_registry, - voting_verifier, + let config = Config { + gateway: deps.api.addr_validate(&msg.gateway_address)?, + multisig: deps.api.addr_validate(&msg.multisig_address)?, + coordinator: deps.api.addr_validate(&msg.coordinator_address)?, + service_registry: deps.api.addr_validate(&msg.service_registry_address)?, + voting_verifier: deps.api.addr_validate(&msg.voting_verifier_address)?, signing_threshold: msg.signing_threshold, service_name: msg.service_name, - chain_name: msg - .chain_name - .parse() - .map_err(|_| ContractError::InvalidChainName)?, + chain_name: msg.chain_name.parse()?, verifier_set_diff_threshold: msg.verifier_set_diff_threshold, encoder: msg.encoder, key_type: msg.key_type, domain_separator: msg.domain_separator, - }) + }; + CONFIG.save(deps.storage, &config)?; + + permission_control::set_admin(deps.storage, &deps.api.addr_validate(&msg.admin_address)?)?; + permission_control::set_governance( + deps.storage, + &deps.api.addr_validate(&msg.governance_address)?, + )?; + + Ok(Response::default()) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -70,29 +60,22 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { - ExecuteMsg::ConstructProof { message_ids } => execute::construct_proof(deps, message_ids), - ExecuteMsg::UpdateVerifierSet {} => { - execute::require_admin(&deps, info.clone()) - .or_else(|_| execute::require_governance(&deps, info))?; - execute::update_verifier_set(deps, env) + match msg.ensure_permissions(deps.storage, &info.sender)? { + ExecuteMsg::ConstructProof { message_ids } => { + Ok(execute::construct_proof(deps, message_ids)?) } + ExecuteMsg::UpdateVerifierSet {} => Ok(execute::update_verifier_set(deps, env)?), ExecuteMsg::ConfirmVerifierSet {} => Ok(execute::confirm_verifier_set(deps, info.sender)?), ExecuteMsg::UpdateSigningThreshold { new_signing_threshold, - } => { - execute::require_governance(&deps, info)?; - Ok(execute::update_signing_threshold( - deps, - new_signing_threshold, - )?) - } + } => Ok(execute::update_signing_threshold( + deps, + new_signing_threshold, + )?), ExecuteMsg::UpdateAdmin { new_admin_address } => { - execute::require_governance(&deps, info)?; Ok(execute::update_admin(deps, new_admin_address)?) } } - .map_err(axelar_wasm_std::ContractError::from) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -131,19 +114,22 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + migrations::v0_6_0::migrate(deps.storage)?; + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(Response::default()) } #[cfg(test)] mod tests { - use axelar_wasm_std::{MajorityThreshold, Threshold, VerificationStatus}; + use axelar_wasm_std::permission_control::Permission; + use axelar_wasm_std::{permission_control, MajorityThreshold, Threshold, VerificationStatus}; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; use cosmwasm_std::{ - from_json, Addr, Empty, Fraction, OwnedDeps, SubMsgResponse, SubMsgResult, Uint128, Uint64, + from_json, Addr, Api, Empty, Fraction, OwnedDeps, SubMsgResponse, SubMsgResult, Uint128, + Uint64, }; use multisig::msg::Signer; use multisig::verifier_set::VerifierSet; @@ -345,13 +331,30 @@ mod tests { assert_eq!(res.messages.len(), 0); let config = CONFIG.load(deps.as_ref().storage).unwrap(); - assert_eq!(config.admin, admin); assert_eq!(config.gateway, gateway_address); assert_eq!(config.multisig, multisig_address); assert_eq!(config.service_registry, service_registry_address); assert_eq!(config.signing_threshold, signing_threshold); assert_eq!(config.service_name, service_name); - assert_eq!(config.encoder, encoding) + assert_eq!(config.encoder, encoding); + + assert_eq!( + permission_control::sender_role( + deps.as_ref().storage, + &deps.api.addr_validate(admin).unwrap() + ) + .unwrap(), + Permission::Admin.into() + ); + + assert_eq!( + permission_control::sender_role( + deps.as_ref().storage, + &deps.api.addr_validate(governance).unwrap() + ) + .unwrap(), + Permission::Governance.into() + ); } } @@ -413,7 +416,11 @@ mod tests { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::Unauthorized).to_string() + axelar_wasm_std::ContractError::from(permission_control::Error::PermissionDenied { + expected: Permission::Elevated.into(), + actual: Permission::NoPrivilege.into() + }) + .to_string() ); } @@ -864,7 +871,16 @@ mod tests { let res = execute_update_admin(deps.as_mut(), GOVERNANCE, new_admin.to_string()); assert!(res.is_ok(), "{:?}", res); - let config = CONFIG.load(deps.as_ref().storage).unwrap(); - assert_eq!(config.admin, Addr::unchecked(new_admin)); + assert_eq!( + permission_control::sender_role(deps.as_ref().storage, &Addr::unchecked(new_admin)) + .unwrap(), + Permission::Admin.into() + ); + + assert_eq!( + permission_control::sender_role(deps.as_ref().storage, &Addr::unchecked(ADMIN)) + .unwrap(), + Permission::NoPrivilege.into() + ); } } diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/contract/execute.rs similarity index 94% rename from contracts/multisig-prover/src/execute.rs rename to contracts/multisig-prover/src/contract/execute.rs index d4d8b2a70..677ec8d55 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -1,10 +1,11 @@ use std::collections::{BTreeMap, HashSet}; +use axelar_wasm_std::permission_control::Permission; use axelar_wasm_std::snapshot::{Participant, Snapshot}; -use axelar_wasm_std::{FnExt, MajorityThreshold, VerificationStatus}; +use axelar_wasm_std::{permission_control, FnExt, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ - to_json_binary, wasm_execute, Addr, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, - Response, Storage, SubMsg, WasmQuery, + to_json_binary, wasm_execute, Addr, DepsMut, Env, QuerierWrapper, QueryRequest, Response, + Storage, SubMsg, WasmQuery, }; use itertools::Itertools; use multisig::msg::Signer; @@ -19,20 +20,6 @@ use crate::state::{ Config, CONFIG, CURRENT_VERIFIER_SET, NEXT_VERIFIER_SET, PAYLOAD, REPLY_TRACKER, }; -pub fn require_admin(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { - match CONFIG.load(deps.storage)?.admin { - admin if admin == info.sender => Ok(()), - _ => Err(ContractError::Unauthorized), - } -} - -pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { - match CONFIG.load(deps.storage)?.governance { - governance if governance == info.sender => Ok(()), - _ => Err(ContractError::Unauthorized), - } -} - pub fn construct_proof( deps: DepsMut, message_ids: Vec, @@ -322,7 +309,8 @@ pub fn confirm_verifier_set(deps: DepsMut, sender: Addr) -> Result Result { - CONFIG.update( - deps.storage, - |mut config| -> Result { - config.admin = deps.api.addr_validate(&new_admin_address)?; - Ok(config) - }, - )?; + let new_admin = deps.api.addr_validate(&new_admin_address)?; + permission_control::set_admin(deps.storage, &new_admin)?; Ok(Response::new()) } @@ -432,8 +415,7 @@ mod tests { use cosmwasm_std::Addr; use router_api::ChainName; - use super::{different_set_in_progress, get_next_verifier_set}; - use crate::execute::should_update_verifier_set; + use super::{different_set_in_progress, get_next_verifier_set, should_update_verifier_set}; use crate::state::{Config, NEXT_VERIFIER_SET}; use crate::test::test_data; @@ -554,8 +536,6 @@ mod tests { fn mock_config() -> Config { Config { - admin: Addr::unchecked("doesn't matter"), - governance: Addr::unchecked("doesn't matter"), gateway: Addr::unchecked("doesn't matter"), multisig: Addr::unchecked("doesn't matter"), coordinator: Addr::unchecked("doesn't matter"), diff --git a/contracts/multisig-prover/src/contract/migrations/mod.rs b/contracts/multisig-prover/src/contract/migrations/mod.rs new file mode 100644 index 000000000..b29376b44 --- /dev/null +++ b/contracts/multisig-prover/src/contract/migrations/mod.rs @@ -0,0 +1 @@ +pub(crate) mod v0_6_0; diff --git a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs new file mode 100644 index 000000000..b1786db5e --- /dev/null +++ b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs @@ -0,0 +1,218 @@ +#![allow(deprecated)] + +use axelar_wasm_std::hash::Hash; +use axelar_wasm_std::{permission_control, ContractError, MajorityThreshold}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Storage}; +use cw_storage_plus::Item; +use multisig::key::KeyType; +use router_api::ChainName; + +use crate::contract::CONTRACT_NAME; +use crate::encoding::Encoder; +use crate::state; + +const BASE_VERSION: &str = "0.6.0"; + +pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + let config = CONFIG.load(storage)?; + + migrate_permission_control(storage, &config)?; + + migrate_config(storage, config)?; + Ok(()) +} + +fn migrate_permission_control( + storage: &mut dyn Storage, + config: &Config, +) -> Result<(), ContractError> { + permission_control::set_governance(storage, &config.governance)?; + permission_control::set_admin(storage, &config.admin)?; + Ok(()) +} + +fn migrate_config(storage: &mut dyn Storage, config: Config) -> Result<(), ContractError> { + CONFIG.remove(storage); + + let config = state::Config { + gateway: config.gateway, + multisig: config.multisig, + coordinator: config.coordinator, + service_registry: config.service_registry, + voting_verifier: config.voting_verifier, + signing_threshold: config.signing_threshold, + service_name: config.service_name, + chain_name: config.chain_name, + verifier_set_diff_threshold: config.verifier_set_diff_threshold, + encoder: config.encoder, + key_type: config.key_type, + domain_separator: config.domain_separator, + }; + state::CONFIG.save(storage, &config)?; + Ok(()) +} + +#[cw_serde] +#[deprecated(since = "0.6.0", note = "only used during migration")] +pub struct Config { + pub admin: Addr, + pub governance: Addr, + pub gateway: Addr, + pub multisig: Addr, + pub coordinator: Addr, + pub service_registry: Addr, + pub voting_verifier: Addr, + pub signing_threshold: MajorityThreshold, + pub service_name: String, + pub chain_name: ChainName, + pub verifier_set_diff_threshold: u32, + pub encoder: Encoder, + pub key_type: KeyType, + pub domain_separator: Hash, +} +#[deprecated(since = "0.6.0", note = "only used during migration")] +pub const CONFIG: Item = Item::new("config"); + +#[cfg(test)] +mod tests { + use axelar_wasm_std::permission_control::Permission; + use axelar_wasm_std::{permission_control, MajorityThreshold, Threshold}; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; + use multisig::key::KeyType; + + use crate::contract::migrations::v0_6_0; + use crate::contract::CONTRACT_NAME; + use crate::encoding::Encoder; + use crate::error::ContractError; + use crate::msg::InstantiateMsg; + use crate::state; + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_6_0::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_6_0::BASE_VERSION) + .unwrap(); + + assert!(v0_6_0::migrate(deps.as_mut().storage).is_ok()); + } + + #[test] + fn migrate_permission_control() { + let mut deps = mock_dependencies(); + + instantiate_contract(deps.as_mut()); + + assert!(v0_6_0::migrate(deps.as_mut().storage).is_ok()); + + assert_eq!( + permission_control::sender_role(deps.as_ref().storage, &Addr::unchecked("admin")) + .unwrap(), + Permission::Admin.into() + ); + + assert_eq!( + permission_control::sender_role(deps.as_ref().storage, &Addr::unchecked("governance")) + .unwrap(), + Permission::Governance.into() + ); + } + + #[test] + fn migrate_config() { + let mut deps = mock_dependencies(); + + instantiate_contract(deps.as_mut()); + + assert!(v0_6_0::CONFIG.load(deps.as_ref().storage).is_ok()); + assert!(state::CONFIG.load(deps.as_ref().storage).is_err()); + + assert!(v0_6_0::migrate(deps.as_mut().storage).is_ok()); + + assert!(v0_6_0::CONFIG.load(deps.as_ref().storage).is_err()); + assert!(state::CONFIG.load(deps.as_ref().storage).is_ok()); + } + + fn instantiate_contract(deps: DepsMut) { + instantiate( + deps, + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + admin_address: "admin".to_string(), + governance_address: "governance".to_string(), + gateway_address: "gateway".to_string(), + multisig_address: "multisig".to_string(), + coordinator_address: "coordinator".to_string(), + service_registry_address: "service_registry".to_string(), + voting_verifier_address: "voting_verifier".to_string(), + signing_threshold: Threshold::try_from((2u64, 3u64)) + .and_then(MajorityThreshold::try_from) + .unwrap(), + service_name: "service".to_string(), + chain_name: "chain".to_string(), + verifier_set_diff_threshold: 1, + encoder: Encoder::Abi, + key_type: KeyType::Ecdsa, + domain_separator: [0; 32], + }, + ) + .unwrap(); + } + + #[deprecated(since = "0.6.0", note = "only used to test the migration")] + pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_6_0::BASE_VERSION)?; + + let config = make_config(&deps, msg)?; + v0_6_0::CONFIG.save(deps.storage, &config)?; + + Ok(Response::default()) + } + + fn make_config( + deps: &DepsMut, + msg: InstantiateMsg, + ) -> Result { + let admin = deps.api.addr_validate(&msg.admin_address)?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + let gateway = deps.api.addr_validate(&msg.gateway_address)?; + let multisig = deps.api.addr_validate(&msg.multisig_address)?; + let coordinator = deps.api.addr_validate(&msg.coordinator_address)?; + let service_registry = deps.api.addr_validate(&msg.service_registry_address)?; + let voting_verifier = deps.api.addr_validate(&msg.voting_verifier_address)?; + + Ok(v0_6_0::Config { + admin, + governance, + gateway, + multisig, + coordinator, + service_registry, + voting_verifier, + signing_threshold: msg.signing_threshold, + service_name: msg.service_name, + chain_name: msg + .chain_name + .parse() + .map_err(|_| ContractError::InvalidChainName)?, + verifier_set_diff_threshold: msg.verifier_set_diff_threshold, + encoder: msg.encoder, + key_type: msg.key_type, + domain_separator: msg.domain_separator, + }) + } +} diff --git a/contracts/multisig-prover/src/query.rs b/contracts/multisig-prover/src/contract/query.rs similarity index 100% rename from contracts/multisig-prover/src/query.rs rename to contracts/multisig-prover/src/contract/query.rs diff --git a/contracts/multisig-prover/src/reply.rs b/contracts/multisig-prover/src/contract/reply.rs similarity index 100% rename from contracts/multisig-prover/src/reply.rs rename to contracts/multisig-prover/src/contract/reply.rs diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index 7915392a6..0e7c90113 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -8,9 +8,6 @@ pub enum ContractError { #[error(transparent)] Std(#[from] StdError), - #[error("caller is not authorized")] - Unauthorized, - #[error("message is invalid")] InvalidMessage, diff --git a/contracts/multisig-prover/src/lib.rs b/contracts/multisig-prover/src/lib.rs index aa670ca61..b59c7551a 100644 --- a/contracts/multisig-prover/src/lib.rs +++ b/contracts/multisig-prover/src/lib.rs @@ -2,11 +2,8 @@ pub mod contract; pub mod encoding; pub mod error; pub mod events; -mod execute; pub mod msg; pub mod payload; -mod query; -mod reply; pub mod state; #[cfg(test)] diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index 2505cd1ef..5a7f7001a 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -2,6 +2,7 @@ use axelar_wasm_std::hash::Hash; use axelar_wasm_std::MajorityThreshold; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{HexBinary, Uint64}; +use msgs_derive::EnsurePermissions; use multisig::key::KeyType; use router_api::CrossChainId; @@ -57,23 +58,25 @@ pub struct InstantiateMsg { } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { // Start building a proof that includes specified messages // Queries the gateway for actual message contents - ConstructProof { - message_ids: Vec, - }, + #[permission(Any)] + ConstructProof { message_ids: Vec }, + #[permission(Elevated)] UpdateVerifierSet, + + #[permission(Any)] ConfirmVerifierSet, // Updates the signing threshold. The threshold currently in use does not change. // The verifier set must be updated and confirmed for the change to take effect. - // Callable only by governance. + #[permission(Governance)] UpdateSigningThreshold { new_signing_threshold: MajorityThreshold, }, - UpdateAdmin { - new_admin_address: String, - }, + #[permission(Governance)] + UpdateAdmin { new_admin_address: String }, } #[cw_serde] diff --git a/contracts/multisig-prover/src/state.rs b/contracts/multisig-prover/src/state.rs index 6891febeb..babfc35f5 100644 --- a/contracts/multisig-prover/src/state.rs +++ b/contracts/multisig-prover/src/state.rs @@ -12,8 +12,6 @@ use crate::payload::{Payload, PayloadId}; #[cw_serde] pub struct Config { - pub admin: Addr, - pub governance: Addr, pub gateway: Addr, pub multisig: Addr, pub coordinator: Addr, From 638454c0cc369cb996136be4693b6fb16dbdf526 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 22 Jul 2024 19:18:27 -0400 Subject: [PATCH 092/168] feat: return structured errors from contracts (#527) --- contracts/coordinator/src/contract.rs | 10 ++-- contracts/multisig/src/contract.rs | 45 +++++++++-------- contracts/multisig/src/contract/execute.rs | 2 +- contracts/rewards/src/contract.rs | 6 +-- contracts/router/src/contract.rs | 4 +- contracts/service-registry/src/contract.rs | 5 +- contracts/voting-verifier/src/contract.rs | 5 +- packages/axelar-wasm-std-derive/src/lib.rs | 7 +-- packages/axelar-wasm-std/src/error.rs | 57 +++++++++++++++++----- packages/report/src/loggable.rs | 5 +- 10 files changed, 91 insertions(+), 55 deletions(-) diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 257cd07e1..94a11842a 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -2,7 +2,7 @@ mod execute; mod query; mod migrations; -use axelar_wasm_std::permission_control; +use axelar_wasm_std::{permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -67,8 +67,8 @@ pub fn execute( ExecuteMsg::SetActiveVerifiers { verifiers } => { execute::set_active_verifier_set(deps, info, verifiers) } - } - .map_err(axelar_wasm_std::ContractError::from) + }? + .then(Ok) } fn find_prover_address( @@ -89,9 +89,9 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result to_json_binary( &query::check_verifier_ready_to_unbond(deps, worker_address)?, - ) - .map_err(|err| err.into()), + )?, } + .then(Ok) } #[cfg(test)] diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 93d568b25..2c00e4b58 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1,12 +1,15 @@ -use axelar_wasm_std::{killswitch, permission_control}; +use std::collections::HashMap; + +use axelar_wasm_std::{killswitch, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, - Storage, Uint64, + to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdError, + StdResult, Storage, Uint64, }; use error_stack::{report, ResultExt}; use itertools::Itertools; +use router_api::ChainName; use crate::events::Event; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrationMsg, QueryMsg}; @@ -121,31 +124,31 @@ pub fn execute( signed_sender_address, } => execute::register_pub_key(deps, info, public_key, signed_sender_address), ExecuteMsg::AuthorizeCallers { contracts } => { - let contracts = contracts - .into_iter() - .map(|(contract_address, chain_name)| { - deps.api - .addr_validate(&contract_address) - .map(|addr| (addr, chain_name)) - }) - .try_collect()?; + let contracts = validate_contract_addresses(&deps, contracts)?; execute::authorize_callers(deps, contracts) } ExecuteMsg::UnauthorizeCallers { contracts } => { - let contracts = contracts - .into_iter() - .map(|(contract_address, chain_name)| { - deps.api - .addr_validate(&contract_address) - .map(|addr| (addr, chain_name)) - }) - .try_collect()?; + let contracts = validate_contract_addresses(&deps, contracts)?; execute::unauthorize_callers(deps, contracts) } ExecuteMsg::DisableSigning => execute::disable_signing(deps), ExecuteMsg::EnableSigning => execute::enable_signing(deps), - } - .map_err(axelar_wasm_std::ContractError::from) + }? + .then(Ok) +} + +fn validate_contract_addresses( + deps: &DepsMut, + contracts: HashMap, +) -> Result, StdError> { + contracts + .into_iter() + .map(|(contract_address, chain_name)| { + deps.api + .addr_validate(&contract_address) + .map(|addr| (addr, chain_name)) + }) + .try_collect() } fn can_start_signing_session( diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index c7ed84e23..81cea039c 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -215,7 +215,7 @@ pub fn authorize_callers( pub fn unauthorize_callers( deps: DepsMut, - contracts: Vec<(Addr, ChainName)>, + contracts: HashMap, ) -> Result { contracts.iter().for_each(|(contract_address, _)| { AUTHORIZED_CALLERS.remove(deps.storage, contract_address) diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index deea2c917..b1f6a409b 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -91,8 +91,7 @@ pub fn execute( verifier_address, pool_id, env.block.height, - ) - .map_err(axelar_wasm_std::ContractError::from)?; + )?; Ok(Response::new()) } @@ -122,8 +121,7 @@ pub fn execute( deps.api.addr_validate(pool_id.contract.as_str())?; let rewards = - execute::distribute_rewards(deps.storage, pool_id, env.block.height, epoch_count) - .map_err(axelar_wasm_std::ContractError::from)?; + execute::distribute_rewards(deps.storage, pool_id, env.block.height, epoch_count)?; let msgs = rewards .into_iter() diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index f353f630f..c17339bc6 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -101,8 +101,8 @@ pub fn execute( } ExecuteMsg::DisableRouting => execute::disable_routing(deps.storage), ExecuteMsg::EnableRouting => execute::enable_routing(deps.storage), - } - .map_err(axelar_wasm_std::ContractError::from) + }? + .then(Ok) } fn find_gateway_address( diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 2ef660b87..d8301addf 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::FnExt; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -130,8 +131,8 @@ pub fn execute( ExecuteMsg::ClaimStake { service_name } => { execute::claim_stake(deps, env, info, service_name) } - } - .map_err(axelar_wasm_std::ContractError::from) + }? + .then(Ok) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 47cb98426..921a21bbd 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::FnExt; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -60,8 +61,8 @@ pub fn execute( execute::require_governance(&deps, info.sender)?; execute::update_voting_threshold(deps, new_voting_threshold) } - } - .map_err(axelar_wasm_std::ContractError::from) + }? + .then(Ok) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/packages/axelar-wasm-std-derive/src/lib.rs b/packages/axelar-wasm-std-derive/src/lib.rs index d1fb6f92a..86b24b629 100644 --- a/packages/axelar-wasm-std-derive/src/lib.rs +++ b/packages/axelar-wasm-std-derive/src/lib.rs @@ -9,14 +9,11 @@ pub fn into_contract_error_derive(input: TokenStream) -> TokenStream { let name = &ast.ident; let gen = quote! { - use axelar_wasm_std::ContractError as _ContractError; - - impl From<#name> for _ContractError { + impl From<#name> for axelar_wasm_std::ContractError { fn from(error: #name) -> Self { - use report::LoggableError; use error_stack::report; - LoggableError::from(&report!(error)).into() + report!(error).into() } } }; diff --git a/packages/axelar-wasm-std/src/error.rs b/packages/axelar-wasm-std/src/error.rs index 18301abac..a8ea9bc13 100644 --- a/packages/axelar-wasm-std/src/error.rs +++ b/packages/axelar-wasm-std/src/error.rs @@ -1,5 +1,7 @@ +use std::fmt::{Display, Formatter}; + use cosmwasm_std::StdError; -use error_stack::{Context, Report}; +use error_stack::{report, Context, Report}; use report::LoggableError; use thiserror::Error; @@ -10,16 +12,39 @@ use crate::permission_control; /// but it won't show all necessary information (namely attachments) in the error message, and many places also return an [StdError]. /// To this end, reports get converted into [LoggableError] and this [ContractError] type unifies [LoggableError] and [StdError], /// so we can return both to cosmwasm. -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error(transparent)] - Std(#[from] StdError), - #[error(transparent)] - Structured(#[from] LoggableError), - #[error(transparent)] - Unauthorized(#[from] permission_control::Error), - #[error(transparent)] - WrongVersion(#[from] cw2::VersionError), +#[derive(Error, Debug)] +pub struct ContractError { + pub report: Report, +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("")] + Report, +} + +impl From for ContractError { + fn from(err: StdError) -> Self { + ContractError { + report: report!(err).change_context(Error::Report), + } + } +} + +impl From for ContractError { + fn from(err: cw2::VersionError) -> Self { + ContractError { + report: report!(err).change_context(Error::Report), + } + } +} + +impl From for ContractError { + fn from(err: permission_control::Error) -> Self { + ContractError { + report: report!(err).change_context(Error::Report), + } + } } impl From> for ContractError @@ -27,7 +52,15 @@ where T: Context, { fn from(report: Report) -> Self { - ContractError::Structured(LoggableError::from(&report)) + ContractError { + report: report.change_context(Error::Report), + } + } +} + +impl Display for ContractError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + LoggableError::from(&self.report).fmt(f) } } diff --git a/packages/report/src/loggable.rs b/packages/report/src/loggable.rs index ab851a93e..070bbd4fa 100644 --- a/packages/report/src/loggable.rs +++ b/packages/report/src/loggable.rs @@ -81,7 +81,10 @@ impl From<&Report> for LoggableError { // because of the stack order of attachments we need to reverse them to get the historical order attachments.reverse(); error.attachments = attachments; - errors.push(error) + + if !error.msg.is_empty() || !error.attachments.is_empty() { + errors.push(error) + } } chain_causes(errors).expect("a report must have at least one error") From 7a7f9bf969d6d09c021b11a9da2770dd9e388bef Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 23 Jul 2024 12:27:43 -0400 Subject: [PATCH 093/168] feat(minor): add legacy (uppercase) chain name support (#523) --- ampd/src/handlers/multisig.rs | 3 +- contracts/coordinator/src/contract.rs | 2 +- contracts/gateway/src/contract/execute.rs | 2 +- contracts/gateway/src/contract/query.rs | 27 +- contracts/gateway/src/state.rs | 31 +- contracts/gateway/tests/contract.rs | 5 +- contracts/multisig-prover/src/contract.rs | 9 +- contracts/multisig-prover/src/events.rs | 10 +- contracts/multisig-prover/src/payload.rs | 5 +- .../multisig-prover/src/test/test_data.rs | 11 +- .../nexus-gateway/src/contract/execute.rs | 20 +- contracts/nexus-gateway/src/nexus.rs | 53 +-- contracts/nexus-gateway/src/state.rs | 6 +- contracts/router/src/contract.rs | 74 +++- contracts/router/src/contract/execute.rs | 31 +- contracts/voting-verifier/src/client.rs | 24 +- contracts/voting-verifier/src/contract.rs | 28 +- contracts/voting-verifier/src/events.rs | 31 +- contracts/voting-verifier/src/execute.rs | 10 +- contracts/voting-verifier/src/query.rs | 12 +- .../tests/chain_freeze_unfreeze.rs | 12 +- integration-tests/tests/message_routing.rs | 24 +- packages/axelar-wasm-std/src/error.rs | 10 + packages/evm-gateway/src/lib.rs | 9 +- packages/router-api/src/primitives.rs | 342 +++++++++++++----- rustfmt.toml | 2 +- 26 files changed, 483 insertions(+), 310 deletions(-) diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 88a43d588..c05936889 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -9,7 +9,8 @@ use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::VerifyingKey; use error_stack::{Report, ResultExt}; use events::Error::EventTypeMismatch; -use events_derive::{self, try_from}; +use events_derive; +use events_derive::try_from; use hex::encode; use multisig::msg::ExecuteMsg; use serde::de::Error as DeserializeError; diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 94a11842a..e67e4bd88 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -129,7 +129,7 @@ mod tests { assert!(res.is_ok()); let eth_prover = Addr::unchecked("eth_prover"); - let eth: ChainName = "Ethereum".to_string().try_into().unwrap(); + let eth: ChainName = "Ethereum".parse().unwrap(); TestSetup { deps, diff --git a/contracts/gateway/src/contract/execute.rs b/contracts/gateway/src/contract/execute.rs index efd1721cd..78586a14e 100644 --- a/contracts/gateway/src/contract/execute.rs +++ b/contracts/gateway/src/contract/execute.rs @@ -37,7 +37,7 @@ pub(crate) fn route_outgoing_messages( let msgs = check_for_duplicates(verified)?; for msg in msgs.iter() { - state::save_outgoing_msg(store, msg.cc_id.clone(), msg) + state::save_outgoing_msg(store, &msg.cc_id, msg) .change_context(Error::InvalidStoreAccess)?; } diff --git a/contracts/gateway/src/contract/query.rs b/contracts/gateway/src/contract/query.rs index 468def5c7..c6b1a632d 100644 --- a/contracts/gateway/src/contract/query.rs +++ b/contracts/gateway/src/contract/query.rs @@ -17,7 +17,7 @@ pub fn get_outgoing_messages( } fn try_load_msg(storage: &dyn Storage, id: CrossChainId) -> Result { - state::may_load_outgoing_msg(storage, id.clone()) + state::may_load_outgoing_msg(storage, &id) .change_context(Error::InvalidStoreAccess) .transpose() .unwrap_or(Err(report!(Error::MessageNotFound(id)))) @@ -51,8 +51,7 @@ mod test { let messages = generate_messages(); for message in messages.iter() { - state::save_outgoing_msg(deps.as_mut().storage, message.cc_id.clone(), message) - .unwrap(); + state::save_outgoing_msg(deps.as_mut().storage, &message.cc_id, message).unwrap(); } let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); @@ -80,12 +79,7 @@ mod test { let messages = generate_messages(); - state::save_outgoing_msg( - deps.as_mut().storage, - messages[1].cc_id.clone(), - &messages[1], - ) - .unwrap(); + state::save_outgoing_msg(deps.as_mut().storage, &messages[1].cc_id, &messages[1]).unwrap(); let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); @@ -98,30 +92,21 @@ mod test { fn generate_messages() -> Vec { vec![ Message { - cc_id: CrossChainId { - chain: "chain1".parse().unwrap(), - id: "id1".parse().unwrap(), - }, + cc_id: CrossChainId::new("chain1", "id1").unwrap(), destination_address: "addr1".parse().unwrap(), destination_chain: "chain2".parse().unwrap(), source_address: "addr2".parse().unwrap(), payload_hash: [0; 32], }, Message { - cc_id: CrossChainId { - chain: "chain2".parse().unwrap(), - id: "id2".parse().unwrap(), - }, + cc_id: CrossChainId::new("chain2", "id2").unwrap(), destination_address: "addr3".parse().unwrap(), destination_chain: "chain3".parse().unwrap(), source_address: "addr4".parse().unwrap(), payload_hash: [1; 32], }, Message { - cc_id: CrossChainId { - chain: "chain3".parse().unwrap(), - id: "id3".parse().unwrap(), - }, + cc_id: CrossChainId::new("chain3", "id3").unwrap(), destination_address: "addr5".parse().unwrap(), destination_chain: "chain4".parse().unwrap(), source_address: "addr6".parse().unwrap(), diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index c36a2fc33..1c1af0cb7 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -23,7 +23,7 @@ pub(crate) fn load_config(storage: &dyn Storage) -> Result { pub(crate) fn save_outgoing_msg( storage: &mut dyn Storage, - key: CrossChainId, + key: &CrossChainId, value: &Message, ) -> Result<(), Error> { OUTGOING_MESSAGES @@ -32,10 +32,10 @@ pub(crate) fn save_outgoing_msg( } pub(crate) fn may_load_outgoing_msg( storage: &dyn Storage, - id: CrossChainId, + id: &CrossChainId, ) -> Result, Error> { OUTGOING_MESSAGES - .may_load(storage, id.clone()) + .may_load(storage, id) .change_context(Error::Parse(OUTGOING_MESSAGES_NAME)) .attach_printable(id.to_string()) } @@ -53,7 +53,7 @@ pub(crate) enum Error { const CONFIG_NAME: &str = "config"; const CONFIG: Item = Item::new(CONFIG_NAME); const OUTGOING_MESSAGES_NAME: &str = "outgoing_messages"; -const OUTGOING_MESSAGES: Map = Map::new(OUTGOING_MESSAGES_NAME); +const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new(OUTGOING_MESSAGES_NAME); #[cfg(test)] mod test { @@ -83,39 +83,30 @@ mod test { let mut deps = mock_dependencies(); let message = Message { - cc_id: CrossChainId { - chain: "chain".parse().unwrap(), - id: "id".parse().unwrap(), - }, + cc_id: CrossChainId::new("chain", "id").unwrap(), source_address: "source_address".parse().unwrap(), destination_chain: "destination".parse().unwrap(), destination_address: "destination_address".parse().unwrap(), payload_hash: [1; 32], }; - assert!(save_outgoing_msg(deps.as_mut().storage, message.cc_id.clone(), &message).is_ok()); + assert!(save_outgoing_msg(deps.as_mut().storage, &message.cc_id, &message).is_ok()); assert_eq!( - may_load_outgoing_msg(&deps.storage, message.cc_id.clone()).unwrap(), + may_load_outgoing_msg(&deps.storage, &message.cc_id).unwrap(), Some(message) ); - let unknown_chain_id = CrossChainId { - chain: "unknown".parse().unwrap(), - id: "id".parse().unwrap(), - }; + let unknown_chain_id = CrossChainId::new("unknown", "id").unwrap(); assert_eq!( - may_load_outgoing_msg(&deps.storage, unknown_chain_id).unwrap(), + may_load_outgoing_msg(&deps.storage, &unknown_chain_id).unwrap(), None ); - let unknown_id = CrossChainId { - chain: "chain".parse().unwrap(), - id: "unknown".parse().unwrap(), - }; + let unknown_id = CrossChainId::new("chain", "unkown").unwrap(); assert_eq!( - may_load_outgoing_msg(&deps.storage, unknown_id).unwrap(), + may_load_outgoing_msg(&deps.storage, &unknown_id).unwrap(), None ); } diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index 30393c488..03c44bd9c 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -344,10 +344,7 @@ fn generate_msgs_with_all_statuses( fn generate_msgs(namespace: impl Debug, count: u8) -> Vec { (0..count) .map(|i| Message { - cc_id: CrossChainId { - chain: "mock-chain".parse().unwrap(), - id: format!("{:?}{}", namespace, i).parse().unwrap(), - }, + cc_id: CrossChainId::new("mock-chain", format!("{:?}{}", namespace, i)).unwrap(), destination_address: "idc".parse().unwrap(), destination_chain: "mock-chain-2".parse().unwrap(), source_address: "idc".parse().unwrap(), diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 223c529ac..7b9cab357 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -222,13 +222,12 @@ mod tests { deps: DepsMut, message_ids: Option>, ) -> Result { - let message_ids = match message_ids { - Some(ids) => ids, - None => test_data::messages() + let message_ids = message_ids.unwrap_or_else(|| { + test_data::messages() .into_iter() .map(|msg| msg.cc_id) - .collect::>(), - }; + .collect::>() + }); let msg = ExecuteMsg::ConstructProof { message_ids }; execute(deps, mock_env(), mock_info(RELAYER, &[]), msg) diff --git a/contracts/multisig-prover/src/events.rs b/contracts/multisig-prover/src/events.rs index 1a2348a6e..ec7687536 100644 --- a/contracts/multisig-prover/src/events.rs +++ b/contracts/multisig-prover/src/events.rs @@ -54,14 +54,8 @@ mod tests { #[test] fn proof_under_construction_is_serializable() { let msg_ids = vec![ - CrossChainId { - chain: "ethereum".parse().unwrap(), - id: "some_id".try_into().unwrap(), - }, - CrossChainId { - chain: "fantom".parse().unwrap(), - id: "some_other_id".try_into().unwrap(), - }, + CrossChainId::new("ethereum", "some_id").unwrap(), + CrossChainId::new("fantom", "some_other_id").unwrap(), ]; let event = Event::ProofUnderConstruction { diff --git a/contracts/multisig-prover/src/payload.rs b/contracts/multisig-prover/src/payload.rs index bf9fc3789..94521f8e5 100644 --- a/contracts/multisig-prover/src/payload.rs +++ b/contracts/multisig-prover/src/payload.rs @@ -24,10 +24,7 @@ impl Payload { pub fn id(&self) -> PayloadId { match self { Payload::Messages(msgs) => { - let message_ids = msgs - .iter() - .map(|msg| msg.cc_id.clone()) - .collect::>(); + let message_ids: Vec<_> = msgs.iter().map(|msg| msg.cc_id.clone()).collect(); message_ids.as_slice().into() } diff --git a/contracts/multisig-prover/src/test/test_data.rs b/contracts/multisig-prover/src/test/test_data.rs index 74a4f5f99..d8dc6351d 100644 --- a/contracts/multisig-prover/src/test/test_data.rs +++ b/contracts/multisig-prover/src/test/test_data.rs @@ -76,12 +76,11 @@ pub fn new_verifier_set() -> VerifierSet { pub fn messages() -> Vec { vec![Message { - cc_id: CrossChainId { - chain: "ganache-1".parse().unwrap(), - id: "0xff822c88807859ff226b58e24f24974a70f04b9442501ae38fd665b3c68f3834-0" - .parse() - .unwrap(), - }, + cc_id: CrossChainId::new( + "ganache-1", + "0xff822c88807859ff226b58e24f24974a70f04b9442501ae38fd665b3c68f3834-0", + ) + .unwrap(), source_address: "0x52444f1835Adc02086c37Cb226561605e2E1699b" .parse() .unwrap(), diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index 945759169..8e61ab9a3 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -244,10 +244,7 @@ mod test { let msgs = vec![ router_api::Message { - cc_id: CrossChainId { - chain: "sourceChain".parse().unwrap(), - id: "0x2fe4:0".parse().unwrap(), - }, + cc_id: CrossChainId::new("sourceChain", "0x2fe4:0").unwrap(), source_address: "0xb860".parse().unwrap(), destination_address: "0xD419".parse().unwrap(), destination_chain: "destinationChain".parse().unwrap(), @@ -259,10 +256,7 @@ mod test { .unwrap(), }, router_api::Message { - cc_id: CrossChainId { - chain: "sourceChain".parse().unwrap(), - id: "0x6b33:10".parse().unwrap(), - }, + cc_id: CrossChainId::new("sourceChain", "0x6b33:10").unwrap(), source_address: "0x0725".parse().unwrap(), destination_address: "0x7FAD".parse().unwrap(), destination_chain: "destinationChain".parse().unwrap(), @@ -305,10 +299,7 @@ mod test { let msgs = vec![ router_api::Message { - cc_id: CrossChainId { - chain: "sourceChain".parse().unwrap(), - id: "0x2fe4:0".parse().unwrap(), - }, + cc_id: CrossChainId::new("sourceChain", "0x2fe4:0").unwrap(), source_address: "0xb860".parse().unwrap(), destination_address: "0xD419".parse().unwrap(), destination_chain: "destinationChain".parse().unwrap(), @@ -320,10 +311,7 @@ mod test { .unwrap(), }, router_api::Message { - cc_id: CrossChainId { - chain: "sourceChain".parse().unwrap(), - id: "0x6b33:10".parse().unwrap(), - }, + cc_id: CrossChainId::new("sourceChain", "0x6b33:10").unwrap(), source_address: "0x70725".parse().unwrap(), destination_address: "0x7FAD".parse().unwrap(), destination_chain: "destinationChain".parse().unwrap(), diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 2f192b6bd..6f6fb7c1b 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -4,7 +4,7 @@ use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::nonempty; use cosmwasm_std::{CosmosMsg, CustomMsg}; use error_stack::{Report, Result, ResultExt}; -use router_api::{Address, ChainName, CrossChainId}; +use router_api::{Address, ChainName, ChainNameRaw, CrossChainId}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -14,7 +14,7 @@ use crate::error::ContractError; // this matches the message type defined in the nexus module // https://github.com/axelarnetwork/axelar-core/blob/6c887df3797ba660093061662aff04e325b9c429/x/nexus/exported/types.pb.go#L405 pub struct Message { - pub source_chain: ChainName, + pub source_chain: ChainNameRaw, pub source_address: Address, pub destination_chain: ChainName, pub destination_address: Address, @@ -44,14 +44,14 @@ impl From for Message { parse_message_id(&msg.cc_id.id).unwrap_or((vec![0; 32].try_into().unwrap(), 0)); Self { - source_chain: msg.cc_id.chain.clone(), + source_chain: msg.cc_id.chain, source_address: msg.source_address, destination_chain: msg.destination_chain, destination_address: msg.destination_address, payload_hash: msg.payload_hash, source_tx_id, source_tx_index, - id: msg.cc_id.id.to_string(), + id: msg.cc_id.id.into(), } } } @@ -63,8 +63,8 @@ impl TryFrom for router_api::Message { Ok(Self { cc_id: CrossChainId { chain: msg.source_chain, - id: nonempty::String::try_from(msg.id.clone()) - .change_context(ContractError::InvalidMessageId(msg.id.to_string()))?, + id: nonempty::String::try_from(msg.id.as_str()) + .change_context(ContractError::InvalidMessageId(msg.id))?, }, source_address: msg.source_address, destination_chain: msg.destination_chain, @@ -109,23 +109,24 @@ mod test { let router_msg = router_api::Message::try_from(msg.clone()); assert!(router_msg.is_ok()); let router_msg = router_msg.unwrap(); - assert_eq!(router_msg.cc_id.chain, msg.source_chain); - assert_eq!(router_msg.cc_id.id.to_string(), msg.id); + let router_msg_cc_id = router_msg.cc_id; + assert_eq!(router_msg_cc_id.chain, msg.source_chain); + assert_eq!(router_msg_cc_id.id.to_string(), msg.id); } #[test] fn should_convert_router_message_to_nexus_message() { let msg = router_api::Message { - cc_id: CrossChainId { - chain: "ethereum".parse().unwrap(), - id: HexTxHashAndEventIndex { + cc_id: CrossChainId::new( + "ethereum", + HexTxHashAndEventIndex { tx_hash: [2; 32], event_index: 1, } .to_string() - .try_into() - .unwrap(), - }, + .as_str(), + ) + .unwrap(), source_address: "something".parse().unwrap(), destination_chain: "polygon".parse().unwrap(), destination_address: "something else".parse().unwrap(), @@ -134,11 +135,13 @@ mod test { let nexus_msg = Message::from(msg.clone()); - assert_eq!(nexus_msg.id, msg.cc_id.id.to_string()); + let router_msg_cc_id = msg.cc_id; + + assert_eq!(nexus_msg.id, *router_msg_cc_id.id); assert_eq!(nexus_msg.destination_address, msg.destination_address); assert_eq!(nexus_msg.destination_chain, msg.destination_chain); assert_eq!(nexus_msg.source_address, msg.source_address); - assert_eq!(nexus_msg.source_chain, msg.cc_id.chain); + assert_eq!(nexus_msg.source_chain, router_msg_cc_id.chain.clone()); assert_eq!(nexus_msg.source_tx_id, vec![2; 32].try_into().unwrap()); assert_eq!(nexus_msg.source_tx_index, 1); } @@ -146,16 +149,16 @@ mod test { #[test] fn should_convert_router_message_with_non_hex_msg_id_to_nexus_message() { let msg = router_api::Message { - cc_id: CrossChainId { - chain: "ethereum".parse().unwrap(), - id: Base58TxDigestAndEventIndex { + cc_id: CrossChainId::new( + "ethereum", + Base58TxDigestAndEventIndex { tx_digest: [2; 32], event_index: 1, } .to_string() - .try_into() - .unwrap(), - }, + .as_str(), + ) + .unwrap(), source_address: "something".parse().unwrap(), destination_chain: "polygon".parse().unwrap(), destination_address: "something else".parse().unwrap(), @@ -164,13 +167,15 @@ mod test { let nexus_msg = Message::from(msg.clone()); - assert_eq!(nexus_msg.id, msg.cc_id.id.to_string()); + let router_msg_cc_id = msg.cc_id; + + assert_eq!(nexus_msg.id, *router_msg_cc_id.id); assert_eq!(nexus_msg.source_tx_id, vec![0; 32].try_into().unwrap()); assert_eq!(nexus_msg.source_tx_index, 0); assert_eq!(nexus_msg.destination_address, msg.destination_address); assert_eq!(nexus_msg.destination_chain, msg.destination_chain); assert_eq!(nexus_msg.source_address, msg.source_address); - assert_eq!(nexus_msg.source_chain, msg.cc_id.chain); + assert_eq!(nexus_msg.source_chain, router_msg_cc_id.chain.clone()); } } diff --git a/contracts/nexus-gateway/src/state.rs b/contracts/nexus-gateway/src/state.rs index 1936b770d..8dba6d550 100644 --- a/contracts/nexus-gateway/src/state.rs +++ b/contracts/nexus-gateway/src/state.rs @@ -8,7 +8,7 @@ use router_api::CrossChainId; use crate::error::ContractError; const CONFIG: Item = Item::new("config"); -const ROUTED_MESSAGE_IDS: Map = Map::new("routed_message_ids"); +const ROUTED_MESSAGE_IDS: Map<&CrossChainId, ()> = Map::new("routed_message_ids"); type Result = error_stack::Result; @@ -45,13 +45,13 @@ impl Store for GatewayStore<'_> { fn set_message_routed(&mut self, id: &CrossChainId) -> Result<()> { ROUTED_MESSAGE_IDS - .save(self.storage, id.clone(), &()) + .save(self.storage, id, &()) .change_context(ContractError::StoreFailure) } fn is_message_routed(&self, id: &CrossChainId) -> Result { ROUTED_MESSAGE_IDS - .may_load(self.storage, id.clone()) + .may_load(self.storage, id) .map(|result| result.is_some()) .change_context(ContractError::StoreFailure) } diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index c17339bc6..1484e87d5 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -145,7 +145,7 @@ mod test { use std::str::FromStr; use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; - use axelar_wasm_std::ContractError; + use axelar_wasm_std::{err_contains, ContractError}; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; @@ -224,10 +224,7 @@ mod test { } .to_string(); msgs.push(Message { - cc_id: CrossChainId { - id: id.parse().unwrap(), - chain: src_chain.chain_name.clone(), - }, + cc_id: CrossChainId::new(src_chain.chain_name.clone(), id).unwrap(), destination_address: "idc".parse().unwrap(), destination_chain: dest_chain.chain_name.clone(), source_address: "idc".parse().unwrap(), @@ -250,10 +247,10 @@ mod test { pub fn assert_messages_in_cosmos_msg( contract_addr: String, messages: Vec, - cosmos_msg: CosmosMsg, + cosmos_msg: &CosmosMsg, ) { assert_eq!( - CosmosMsg::Wasm(WasmMsg::Execute { + &CosmosMsg::Wasm(WasmMsg::Execute { contract_addr, msg: to_json_binary(&gateway_api::msg::ExecuteMsg::RouteMessages(messages,)) .unwrap(), @@ -287,7 +284,7 @@ mod test { assert_messages_in_cosmos_msg( polygon.gateway.to_string(), messages.clone(), - res.messages[0].msg.clone(), + &res.messages[0].msg, ); // try to route twice @@ -323,6 +320,57 @@ mod test { assert_contract_err_string_contains(err, Error::WrongSourceChain); } + #[test] + fn amplifier_messages_must_have_lower_case() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let mut messages = generate_messages(ð, &polygon, &mut 0, 1); + messages + .iter_mut() + .for_each(|msg| msg.cc_id.chain = "Ethereum".parse().unwrap()); + + let result = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages), + ) + .unwrap_err(); + assert!(err_contains!(result.report, Error, Error::WrongSourceChain)); + } + + #[test] + fn nexus_messages_can_have_upper_case() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), &polygon); + + let mut messages = generate_messages(ð, &polygon, &mut 0, 1); + messages + .iter_mut() + .for_each(|msg| msg.cc_id.chain = "Ethereum".parse().unwrap()); + + let result = execute( + deps.as_mut(), + mock_env(), + mock_info(NEXUS_GATEWAY_ADDRESS, &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ); + assert!(result.is_ok()); + assert_messages_in_cosmos_msg( + polygon.gateway.to_string(), + messages, + &result.unwrap().messages[0].msg, + ); + } + #[test] fn multi_chain_route() { let mut deps = setup(); @@ -381,7 +429,7 @@ mod test { .into_iter() .filter(|m| m.cc_id.chain == s.chain_name) .collect::>(), - res.messages[i].msg.clone(), + &res.messages[i].msg, ); } } @@ -617,7 +665,7 @@ mod test { assert_messages_in_cosmos_msg( new_gateway.to_string(), messages.clone(), - res.messages[0].msg.clone(), + &res.messages[0].msg, ); } @@ -664,7 +712,7 @@ mod test { assert_messages_in_cosmos_msg( eth.gateway.to_string(), messages.clone(), - res.messages[0].msg.clone(), + &res.messages[0].msg, ); } @@ -837,7 +885,7 @@ mod test { assert_messages_in_cosmos_msg( polygon.gateway.to_string(), messages.clone(), - res.messages[0].msg.clone(), + &res.messages[0].msg, ); let res = execute( @@ -917,7 +965,7 @@ mod test { assert_messages_in_cosmos_msg( polygon.gateway.to_string(), messages.clone(), - res.messages[0].msg.clone(), + &res.messages[0].msg, ); } diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index c13f9a76a..4ca2b9bbf 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -278,10 +278,7 @@ mod test { rand::thread_rng().fill_bytes(&mut payload_hash); Message { - cc_id: CrossChainId { - chain: source_chain, - id: id.parse().unwrap(), - }, + cc_id: CrossChainId::new(source_chain, id).unwrap(), source_address, destination_chain, destination_address, @@ -486,8 +483,8 @@ mod test { ) .unwrap(); - let mut msg = rand_message(source_chain, destination_chain.clone()); - msg.cc_id.id = "foobar".try_into().unwrap(); + let mut msg = rand_message(source_chain.clone(), destination_chain.clone()); + msg.cc_id = CrossChainId::new(source_chain, "foobar").unwrap(); assert!(route_messages(deps.as_mut().storage, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } @@ -511,8 +508,8 @@ mod test { ) .unwrap(); - let mut msg = rand_message(source_chain, destination_chain.clone()); - msg.cc_id.id = "foobar".try_into().unwrap(); + let mut msg = rand_message(source_chain.clone(), destination_chain.clone()); + msg.cc_id = CrossChainId::new(source_chain, "foobar").unwrap(); assert!(route_messages(deps.as_mut().storage, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } @@ -552,14 +549,18 @@ mod test { ) .unwrap(); - let mut msg = rand_message(source_chain, destination_chain.clone()); - msg.cc_id.id = HexTxHashAndEventIndex { - tx_hash: [0; 32], - event_index: 0, - } - .to_string() - .try_into() + let mut msg = rand_message(source_chain.clone(), destination_chain.clone()); + msg.cc_id = CrossChainId::new( + source_chain, + HexTxHashAndEventIndex { + tx_hash: [0; 32], + event_index: 0, + } + .to_string() + .as_str(), + ) .unwrap(); + assert!(route_messages(deps.as_mut().storage, sender, vec![msg]) .is_err_and(move |err| { matches!(err.current_context(), Error::InvalidMessageId) })); } diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index b6d211a31..a36b3cc67 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -117,32 +117,32 @@ mod test { let client: Client = client::Client::new(QuerierWrapper::new(&querier), addr).into(); let msg_1 = Message { - cc_id: CrossChainId { - chain: "eth".parse().unwrap(), - id: HexTxHashAndEventIndex { + cc_id: CrossChainId::new( + "eth", + HexTxHashAndEventIndex { tx_hash: [0; 32], event_index: 0, } .to_string() - .parse() - .unwrap(), - }, + .as_str(), + ) + .unwrap(), source_address: "0x1234".parse().unwrap(), destination_address: "0x5678".parse().unwrap(), destination_chain: "eth".parse().unwrap(), payload_hash: [0; 32], }; let msg_2 = Message { - cc_id: CrossChainId { - chain: "eth".parse().unwrap(), - id: HexTxHashAndEventIndex { + cc_id: CrossChainId::new( + "eth", + HexTxHashAndEventIndex { tx_hash: [1; 32], event_index: 0, } .to_string() - .parse() - .unwrap(), - }, + .as_str(), + ) + .unwrap(), source_address: "0x4321".parse().unwrap(), destination_address: "0x8765".parse().unwrap(), destination_chain: "eth".parse().unwrap(), diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 921a21bbd..6d8457a94 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -54,7 +54,7 @@ pub fn execute( ExecuteMsg::VerifyVerifierSet { message_id, new_verifier_set, - } => execute::verify_verifier_set(deps, env, message_id, new_verifier_set), + } => execute::verify_verifier_set(deps, env, &message_id, new_verifier_set), ExecuteMsg::UpdateVotingThreshold { new_voting_threshold, } => { @@ -233,10 +233,8 @@ mod test { fn messages(len: u32, msg_id_format: &MessageIdFormat) -> Vec { (0..len) .map(|i| Message { - cc_id: CrossChainId { - chain: source_chain(), - id: message_id("id", i, msg_id_format), - }, + cc_id: CrossChainId::new(source_chain(), message_id("id", i, msg_id_format)) + .unwrap(), source_address: format!("source_address{i}").parse().unwrap(), destination_chain: format!("destination-chain{i}").parse().unwrap(), destination_address: format!("destination_address{i}").parse().unwrap(), @@ -281,20 +279,16 @@ mod test { let msg = ExecuteMsg::VerifyMessages { messages: vec![ Message { - cc_id: CrossChainId { - chain: source_chain(), - id: message_id("id", 1, &msg_id_format), - }, + cc_id: CrossChainId::new(source_chain(), message_id("id", 1, &msg_id_format)) + .unwrap(), source_address: "source_address1".parse().unwrap(), destination_chain: "destination-chain1".parse().unwrap(), destination_address: "destination_address1".parse().unwrap(), payload_hash: [0; 32], }, Message { - cc_id: CrossChainId { - chain: "other-chain".parse().unwrap(), - id: message_id("id", 2, &msg_id_format), - }, + cc_id: CrossChainId::new("other-chain", message_id("id", 2, &msg_id_format)) + .unwrap(), source_address: "source_address2".parse().unwrap(), destination_chain: "destination-chain2".parse().unwrap(), destination_address: "destination_address2".parse().unwrap(), @@ -313,13 +307,15 @@ mod test { let mut deps = setup(verifiers.clone(), &msg_id_format); let mut messages = messages(1, &MessageIdFormat::HexTxHashAndEventIndex); - let msg_id = "foobar"; - messages[0].cc_id.id = msg_id.parse().unwrap(); + messages[0].cc_id = CrossChainId::new(source_chain(), "foobar").unwrap(); let msg = ExecuteMsg::VerifyMessages { messages }; let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::InvalidMessageID(msg_id.to_string())); + assert_contract_err_strings_equal( + err, + ContractError::InvalidMessageID("foobar".to_string()), + ); } #[test] diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 764a62103..956eaeb83 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -122,24 +122,24 @@ pub struct VerifierSetConfirmation { /// If parsing is successful, returns (tx_id, event_index). Otherwise returns ContractError::InvalidMessageID fn parse_message_id( - message_id: nonempty::String, + message_id: &str, msg_id_format: &MessageIdFormat, ) -> Result<(nonempty::String, u32), ContractError> { match msg_id_format { MessageIdFormat::Base58TxDigestAndEventIndex => { - let id = Base58TxDigestAndEventIndex::from_str(&message_id) - .map_err(|_| ContractError::InvalidMessageID(message_id.into()))?; + let id = Base58TxDigestAndEventIndex::from_str(message_id) + .map_err(|_| ContractError::InvalidMessageID(message_id.to_string()))?; Ok((id.tx_digest_as_base58(), id.event_index)) } MessageIdFormat::HexTxHashAndEventIndex => { - let id = HexTxHashAndEventIndex::from_str(&message_id) - .map_err(|_| ContractError::InvalidMessageID(message_id.into()))?; + let id = HexTxHashAndEventIndex::from_str(message_id) + .map_err(|_| ContractError::InvalidMessageID(message_id.to_string()))?; Ok((id.tx_hash_as_hex(), id.event_index)) } MessageIdFormat::Base58SolanaTxSignatureAndEventIndex => { - let id = Base58SolanaTxSignatureAndEventIndex::from_str(&message_id) - .map_err(|_| ContractError::InvalidMessageID(message_id.into()))?; + let id = Base58SolanaTxSignatureAndEventIndex::from_str(message_id) + .map_err(|_| ContractError::InvalidMessageID(message_id.to_string()))?; Ok((id.signature_as_base58(), id.event_index)) } @@ -148,7 +148,7 @@ fn parse_message_id( impl VerifierSetConfirmation { pub fn new( - message_id: nonempty::String, + message_id: &str, msg_id_format: MessageIdFormat, verifier_set: VerifierSet, ) -> Result { @@ -179,7 +179,7 @@ pub struct TxEventConfirmation { impl TryFrom<(Message, &MessageIdFormat)> for TxEventConfirmation { type Error = ContractError; fn try_from((msg, msg_id_format): (Message, &MessageIdFormat)) -> Result { - let (tx_id, event_index) = parse_message_id(msg.cc_id.id, msg_id_format)?; + let (tx_id, event_index) = parse_message_id(&msg.cc_id.id, msg_id_format)?; Ok(TxEventConfirmation { tx_id, @@ -284,10 +284,7 @@ mod test { fn generate_msg(msg_id: nonempty::String) -> Message { Message { - cc_id: CrossChainId { - chain: "source-chain".parse().unwrap(), - id: msg_id, - }, + cc_id: CrossChainId::new("source-chain", msg_id).unwrap(), source_address: "source_address".parse().unwrap(), destination_chain: "destination-chain".parse().unwrap(), destination_address: "destination-address".parse().unwrap(), @@ -373,7 +370,7 @@ mod test { created_at: 1, }; let event = VerifierSetConfirmation::new( - msg_id.to_string().parse().unwrap(), + &msg_id.to_string(), MessageIdFormat::HexTxHashAndEventIndex, verifier_set.clone(), ) @@ -396,7 +393,7 @@ mod test { created_at: 1, }; let event = VerifierSetConfirmation::new( - msg_id.to_string().parse().unwrap(), + &msg_id.to_string(), MessageIdFormat::Base58TxDigestAndEventIndex, verifier_set.clone(), ) @@ -417,7 +414,7 @@ mod test { }; let event = VerifierSetConfirmation::new( - msg_id.to_string().parse().unwrap(), + msg_id, MessageIdFormat::Base58TxDigestAndEventIndex, verifier_set, ); @@ -437,7 +434,7 @@ mod test { }; let event = VerifierSetConfirmation::new( - msg_id.to_string().parse().unwrap(), + &msg_id.to_string(), MessageIdFormat::Base58TxDigestAndEventIndex, verifier_set, ); diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index 0987d1226..a8d50ce33 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use axelar_wasm_std::voting::{PollId, PollResults, Vote, WeightedPoll}; -use axelar_wasm_std::{nonempty, snapshot, MajorityThreshold, VerificationStatus}; +use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ to_json_binary, Addr, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, @@ -46,7 +46,7 @@ pub fn update_voting_threshold( pub fn verify_verifier_set( deps: DepsMut, env: Env, - message_id: nonempty::String, + message_id: &str, new_verifier_set: VerifierSet, ) -> Result { let status = verifier_set_status(deps.as_ref(), &new_verifier_set, env.block.height)?; @@ -100,9 +100,9 @@ pub fn verify_messages( if messages .iter() - .any(|message| message.cc_id.chain.ne(&source_chain)) + .any(|message| message.cc_id.chain != source_chain) { - Err(ContractError::SourceChainMismatch(source_chain))?; + Err(ContractError::SourceChainMismatch(source_chain.clone()))?; } let config = CONFIG.load(deps.storage)?; @@ -131,7 +131,7 @@ pub fn verify_messages( return Ok(Response::new()); } - let snapshot = take_snapshot(deps.as_ref(), &msgs_to_verify[0].cc_id.chain)?; + let snapshot = take_snapshot(deps.as_ref(), &source_chain)?; let participants = snapshot.get_participants(); let expires_at = calculate_expiration(env.block.height, config.block_expiry)?; diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index 91096a98a..6bf2f7d66 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -309,16 +309,16 @@ mod tests { fn message(id: u32) -> Message { Message { - cc_id: CrossChainId { - chain: "source-chain".parse().unwrap(), - id: HexTxHashAndEventIndex { + cc_id: CrossChainId::new( + "source-chain", + HexTxHashAndEventIndex { tx_hash: [0; 32], event_index: id, } .to_string() - .try_into() - .unwrap(), - }, + .as_str(), + ) + .unwrap(), source_address: format!("source_address{id}").parse().unwrap(), destination_chain: format!("destination-chain{id}").parse().unwrap(), destination_address: format!("destination_address{id}").parse().unwrap(), diff --git a/integration-tests/tests/chain_freeze_unfreeze.rs b/integration-tests/tests/chain_freeze_unfreeze.rs index a2edb2988..91fb5cc77 100644 --- a/integration-tests/tests/chain_freeze_unfreeze.rs +++ b/integration-tests/tests/chain_freeze_unfreeze.rs @@ -16,13 +16,11 @@ fn chain_can_be_freezed_unfreezed() { } = test_utils::setup_test_case(); let msgs = vec![Message { - cc_id: CrossChainId { - chain: chain1.chain_name.clone(), - id: "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3" - .to_string() - .try_into() - .unwrap(), - }, + cc_id: CrossChainId::new( + chain1.chain_name.clone(), + "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3", + ) + .unwrap(), source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" .to_string() .try_into() diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index 74d64fd63..98447c62c 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -19,13 +19,11 @@ fn single_message_can_be_verified_and_routed_and_proven_and_rewards_are_distribu } = test_utils::setup_test_case(); let msgs = vec![Message { - cc_id: CrossChainId { - chain: chain1.chain_name.clone(), - id: "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3" - .to_string() - .try_into() - .unwrap(), - }, + cc_id: CrossChainId::new( + chain1.chain_name.clone(), + "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3", + ) + .unwrap(), source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" .to_string() .try_into() @@ -126,13 +124,11 @@ fn routing_to_incorrect_gateway_interface() { } = test_utils::setup_test_case(); let msgs = [Message { - cc_id: CrossChainId { - chain: chain1.chain_name.clone(), - id: "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3" - .to_string() - .try_into() - .unwrap(), - }, + cc_id: CrossChainId::new( + chain1.chain_name.clone(), + "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3", + ) + .unwrap(), source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" .to_string() .try_into() diff --git a/packages/axelar-wasm-std/src/error.rs b/packages/axelar-wasm-std/src/error.rs index a8ea9bc13..8af69ee3c 100644 --- a/packages/axelar-wasm-std/src/error.rs +++ b/packages/axelar-wasm-std/src/error.rs @@ -76,3 +76,13 @@ pub fn extend_err( Err(added_error) } } + +#[macro_export] +macro_rules! err_contains { + ($expression:expr, $error_type:ty, $pattern:pat $(if $guard:expr)? $(,)?) => { + match $expression.downcast_ref::<$error_type>() { + Some($pattern) $(if $guard)? => true, + _ => false, + } + }; +} diff --git a/packages/evm-gateway/src/lib.rs b/packages/evm-gateway/src/lib.rs index 689f7e7b8..b022e9f72 100644 --- a/packages/evm-gateway/src/lib.rs +++ b/packages/evm-gateway/src/lib.rs @@ -1,5 +1,3 @@ -pub mod error; - use std::str::FromStr; use axelar_wasm_std::hash::Hash; @@ -20,6 +18,8 @@ use sha3::{Digest, Keccak256}; use crate::error::Error; +pub mod error; + // Generates the bindings for the Axelar Amplifier Gateway contract. // This includes the defined structs: Messages, WeightedSigners, WeightedSigner, and Proofs. abigen!( @@ -182,10 +182,7 @@ mod test { for destination_address in destination_addresses { let router_messages = RouterMessage { - cc_id: CrossChainId { - chain: source_chain.parse().unwrap(), - id: message_id.parse().unwrap(), - }, + cc_id: CrossChainId::new(source_chain, message_id).unwrap(), source_address: source_address.parse().unwrap(), destination_address: destination_address.parse().unwrap(), destination_chain: destination_chain.parse().unwrap(), diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index ccf104f67..a8894b6ee 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -1,5 +1,6 @@ use std::any::type_name; use std::fmt; +use std::fmt::Display; use std::ops::Deref; use std::str::FromStr; @@ -10,7 +11,7 @@ use axelar_wasm_std::{nonempty, FnExt}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Attribute, HexBinary, StdError, StdResult}; use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; -use error_stack::{Report, ResultExt}; +use error_stack::{Context, Report, ResultExt}; use flagset::flags; use schemars::gen::SchemaGenerator; use schemars::schema::Schema; @@ -101,43 +102,31 @@ impl TryFrom for Address { #[cw_serde] #[derive(Eq, Hash)] pub struct CrossChainId { - pub chain: ChainName, + pub chain: ChainNameRaw, pub id: nonempty::String, } -/// todo: remove this when state::NewMessage is used -impl FromStr for CrossChainId { - type Err = Error; - - fn from_str(s: &str) -> Result { - let parts = s.split_once(CHAIN_NAME_DELIMITER); - let (chain, id) = parts - .map(|(chain, id)| { - ( - chain.parse::(), - id.parse::() - .map_err(|_| Error::InvalidMessageId), - ) - }) - .ok_or(Error::InvalidMessageId)?; +impl CrossChainId { + pub fn new( + chain: impl TryInto, + id: impl TryInto, + ) -> error_stack::Result + where + S: Context, + T: Context, + { Ok(CrossChainId { - chain: chain?, - id: id?, + chain: chain.try_into().change_context(Error::InvalidChainName)?, + id: id.try_into().change_context(Error::InvalidMessageId)?, }) } } -impl fmt::Display for CrossChainId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}{}{}", self.chain, CHAIN_NAME_DELIMITER, *self.id) - } -} - impl PrimaryKey<'_> for CrossChainId { - type Prefix = ChainName; + type Prefix = ChainNameRaw; type SubPrefix = (); type Suffix = String; - type SuperSuffix = (ChainName, String); + type SuperSuffix = (ChainNameRaw, String); fn key(&self) -> Vec { let mut keys = self.chain.key(); @@ -150,7 +139,7 @@ impl KeyDeserialize for CrossChainId { type Output = Self; fn from_vec(value: Vec) -> StdResult { - let (chain, id) = <(ChainName, String)>::from_vec(value)?; + let (chain, id) = <(ChainNameRaw, String)>::from_vec(value)?; Ok(CrossChainId { chain, id: id @@ -159,6 +148,11 @@ impl KeyDeserialize for CrossChainId { }) } } +impl Display for CrossChainId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}{}{}", self.chain, CHAIN_NAME_DELIMITER, *self.id) + } +} #[cw_serde] #[serde(try_from = "String")] @@ -169,11 +163,9 @@ impl FromStr for ChainName { type Err = Error; fn from_str(s: &str) -> Result { - if s.contains(CHAIN_NAME_DELIMITER) || s.is_empty() { - return Err(Error::InvalidChainName); - } + let chain_name: ChainNameRaw = s.parse()?; - Ok(ChainName(s.to_lowercase())) + Ok(ChainName(chain_name.0.to_lowercase())) } } @@ -191,15 +183,35 @@ impl TryFrom for ChainName { } } -impl fmt::Display for ChainName { +impl TryFrom<&str> for ChainName { + type Error = Error; + + fn try_from(value: &str) -> Result { + value.parse() + } +} + +impl Display for ChainName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } +impl PartialEq for ChainName { + fn eq(&self, other: &ChainNameRaw) -> bool { + self == &other.as_ref() + } +} + impl PartialEq for ChainName { fn eq(&self, other: &String) -> bool { - self.0 == other.to_lowercase() + self == &other.as_str() + } +} + +impl PartialEq<&str> for ChainName { + fn eq(&self, other: &&str) -> bool { + self.0 == *other } } @@ -247,6 +259,119 @@ impl AsRef for ChainName { } } +#[cw_serde] +#[serde(try_from = "String")] +#[derive(Eq, Hash)] +pub struct ChainNameRaw(String); + +impl From for ChainNameRaw { + fn from(other: ChainName) -> Self { + ChainNameRaw(other.0) + } +} + +impl FromStr for ChainNameRaw { + type Err = Error; + + fn from_str(s: &str) -> Result { + if s.contains(CHAIN_NAME_DELIMITER) || s.is_empty() { + return Err(Error::InvalidChainName); + } + + Ok(ChainNameRaw(s.to_owned())) + } +} + +impl From for String { + fn from(d: ChainNameRaw) -> Self { + d.0 + } +} + +impl TryFrom for ChainNameRaw { + type Error = Error; + + fn try_from(value: String) -> Result { + value.parse() + } +} + +impl TryFrom<&str> for ChainNameRaw { + type Error = Error; + + fn try_from(value: &str) -> Result { + value.parse() + } +} + +impl Display for ChainNameRaw { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl AsRef for ChainNameRaw { + fn as_ref(&self) -> &str { + self.0.as_str() + } +} + +impl PartialEq for ChainNameRaw { + fn eq(&self, other: &ChainName) -> bool { + self == &other.as_ref() + } +} + +impl PartialEq for ChainNameRaw { + fn eq(&self, other: &String) -> bool { + self == &other.as_str() + } +} + +impl PartialEq<&str> for ChainNameRaw { + fn eq(&self, other: &&str) -> bool { + self.0 == *other + } +} + +impl<'a> PrimaryKey<'a> for ChainNameRaw { + type Prefix = (); + type SubPrefix = (); + type Suffix = Self; + type SuperSuffix = Self; + + fn key(&self) -> Vec { + vec![Key::Ref(self.0.as_bytes())] + } +} + +impl<'a> Prefixer<'a> for ChainNameRaw { + fn prefix(&self) -> Vec { + vec![Key::Ref(self.0.as_bytes())] + } +} + +impl KeyDeserialize for ChainNameRaw { + type Output = Self; + + #[inline(always)] + fn from_vec(value: Vec) -> StdResult { + String::from_utf8(value) + .map_err(StdError::invalid_utf8)? + .then(ChainNameRaw::try_from) + .map_err(StdError::invalid_utf8) + } +} + +impl KeyDeserialize for &ChainNameRaw { + type Output = ChainNameRaw; + + #[inline(always)] + fn from_vec(value: Vec) -> StdResult { + ChainNameRaw::from_vec(value) + } +} + flags! { #[repr(u8)] #[derive(Deserialize, Serialize, Hash)] @@ -326,43 +451,6 @@ mod tests { assert_eq!(hex::encode(msg.hash()), expected_message_hash); } - #[test] - fn should_fail_to_parse_invalid_chain_name() { - // empty - assert_eq!( - "".parse::().unwrap_err(), - Error::InvalidChainName - ); - - // name contains id separator - assert_eq!( - format!("chain {CHAIN_NAME_DELIMITER}") - .parse::() - .unwrap_err(), - Error::InvalidChainName - ); - } - - #[test] - fn should_parse_to_case_insensitive_chain_name() { - let rand_str: String = thread_rng() - .sample_iter(&Alphanumeric) - .take(10) - .map(char::from) - .collect(); - - let chain_name: ChainName = rand_str.parse().unwrap(); - - assert_eq!( - chain_name, - rand_str.to_lowercase().parse::().unwrap() - ); - assert_eq!( - chain_name, - rand_str.to_uppercase().parse::().unwrap() - ); - } - #[test] fn should_not_deserialize_invalid_chain_name() { assert_eq!( @@ -381,15 +469,96 @@ mod tests { } #[test] - fn chain_name_case_insensitive_comparison() { - let chain_name = ChainName::from_str("ethereum").unwrap(); - - assert!(chain_name.eq(&"Ethereum".to_string())); - assert!(chain_name.eq(&"ETHEREUM".to_string())); - assert!(chain_name.eq(&"ethereum".to_string())); - assert!(chain_name.eq(&"ethEReum".to_string())); - - assert!(!chain_name.eq(&"Ethereum-1".to_string())); + fn ensure_chain_name_parsing_respect_restrictions() { + struct TestCase<'a> { + input: &'a str, + can_parse: bool, + is_normalized: bool, + } + let random_lower = random_chain_name().to_lowercase(); + let random_upper = random_chain_name().to_uppercase(); + + let test_cases = [ + TestCase { + input: "", + can_parse: false, + is_normalized: false, + }, + TestCase { + input: "chain_with_prohibited_symbols", + can_parse: false, + is_normalized: false, + }, + TestCase { + input: "!@#$%^&*()+=-1234567890", + can_parse: true, + is_normalized: true, + }, + TestCase { + input: "ethereum", + can_parse: true, + is_normalized: true, + }, + TestCase { + input: "ETHEREUM", + can_parse: true, + is_normalized: false, + }, + TestCase { + input: "ethereum-1", + can_parse: true, + is_normalized: true, + }, + TestCase { + input: "ETHEREUM-1", + can_parse: true, + is_normalized: false, + }, + TestCase { + input: random_lower.as_str(), + can_parse: true, + is_normalized: true, + }, + TestCase { + input: random_upper.as_str(), + can_parse: true, + is_normalized: false, + }, + ]; + + let conversions = [ + |input: &str| ChainName::from_str(input), + |input: &str| ChainName::try_from(input), + |input: &str| ChainName::try_from(input.to_string()), + ]; + + let raw_conversions = [ + |input: &str| ChainNameRaw::from_str(input), + |input: &str| ChainNameRaw::try_from(input), + |input: &str| ChainNameRaw::try_from(input.to_string()), + ]; + + for case in test_cases.into_iter() { + for conversion in conversions.into_iter() { + let result = conversion(case.input); + assert_eq!(result.is_ok(), case.can_parse, "input: {}", case.input); + if case.can_parse { + if case.is_normalized { + assert_eq!(result.unwrap(), case.input); + } else { + assert_ne!(result.unwrap(), case.input); + } + } + } + + for conversion in raw_conversions.into_iter() { + let result = conversion(case.input); + assert_eq!(result.is_ok(), case.can_parse, "input: {}", case.input); + if case.can_parse { + assert_eq!(result.unwrap(), case.input); + } + } + } } #[test] @@ -404,14 +573,19 @@ mod tests { fn dummy_message() -> Message { Message { - cc_id: CrossChainId { - id: "hash-index".parse().unwrap(), - chain: "chain".parse().unwrap(), - }, + cc_id: CrossChainId::new("chain", "hash-index").unwrap(), source_address: "source_address".parse().unwrap(), destination_chain: "destination-chain".parse().unwrap(), destination_address: "destination_address".parse().unwrap(), payload_hash: [1; 32], } } + + fn random_chain_name() -> String { + thread_rng() + .sample_iter(&Alphanumeric) + .take(10) + .map(char::from) + .collect() + } } diff --git a/rustfmt.toml b/rustfmt.toml index 1dc74ed1d..3a3f3f1dd 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,2 +1,2 @@ imports_granularity = "Module" -group_imports = "StdExternalCrate" \ No newline at end of file +group_imports = "StdExternalCrate" From 8ee688fac54f50b307b1d21669a20bcf3d3d66d4 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 23 Jul 2024 13:33:58 -0400 Subject: [PATCH 094/168] feat(nexus-gateway): add permission control to nexus-gateway (#530) --- Cargo.lock | 1 + contracts/coordinator/src/contract.rs | 24 +- .../src/contract/migrations/v0_2_0.rs | 2 +- contracts/gateway/src/contract.rs | 8 +- contracts/gateway/tests/contract.rs | 3 +- contracts/multisig-prover/src/contract.rs | 51 +-- .../src/contract/migrations/v0_6_0.rs | 7 +- contracts/multisig/src/contract.rs | 37 +- contracts/nexus-gateway/Cargo.toml | 1 + contracts/nexus-gateway/src/contract.rs | 289 ++++++++++++-- .../nexus-gateway/src/contract/execute.rs | 361 ++---------------- contracts/nexus-gateway/src/error.rs | 3 - contracts/nexus-gateway/src/msg.rs | 4 + contracts/nexus-gateway/src/state.rs | 55 +-- contracts/rewards/src/contract.rs | 12 +- .../rewards/src/contract/migrations/v0_4_0.rs | 5 +- contracts/router/src/contract.rs | 17 +- .../router/src/contract/migrations/v0_3_3.rs | 6 +- contracts/service-registry/src/contract.rs | 14 +- .../service-registry/src/migrations/v_0_4.rs | 2 +- contracts/voting-verifier/src/contract.rs | 10 +- integration-tests/src/contract.rs | 6 +- integration-tests/tests/test_utils/mod.rs | 4 +- packages/axelar-wasm-std-derive/src/lib.rs | 2 +- .../axelar-wasm-std-derive/tests/derive.rs | 2 +- packages/axelar-wasm-std/src/lib.rs | 1 - packages/msgs-derive/src/lib.rs | 8 +- 27 files changed, 434 insertions(+), 501 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4100bbd92..65399cbe3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4802,6 +4802,7 @@ dependencies = [ "error-stack", "hex", "mockall 0.11.4", + "msgs-derive", "report", "router-api", "schemars", diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index e67e4bd88..c1670e0c7 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -23,7 +23,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { v0_2_0::migrate(deps.storage)?; // this needs to be the last thing to do during migration, @@ -39,7 +39,7 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let governance = deps.api.addr_validate(&msg.governance_address)?; @@ -54,7 +54,7 @@ pub fn execute( _env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg.ensure_permissions( deps.storage, &info.sender, @@ -208,10 +208,12 @@ mod tests { ); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(permission_control::Error::PermissionDenied { - expected: Permission::Governance.into(), - actual: Permission::NoPrivilege.into() - }) + axelar_wasm_std::error::ContractError::from( + permission_control::Error::PermissionDenied { + expected: Permission::Governance.into(), + actual: Permission::NoPrivilege.into() + } + ) .to_string() ); } @@ -257,9 +259,11 @@ mod tests { }, ); assert!(res.unwrap_err().to_string().contains( - &axelar_wasm_std::ContractError::from(permission_control::Error::WhitelistNotFound { - sender: test_setup.prover - }) + &axelar_wasm_std::error::ContractError::from( + permission_control::Error::WhitelistNotFound { + sender: test_setup.prover + } + ) .to_string() )); } diff --git a/contracts/coordinator/src/contract/migrations/v0_2_0.rs b/contracts/coordinator/src/contract/migrations/v0_2_0.rs index b6347d0ff..ae6db4fa0 100644 --- a/contracts/coordinator/src/contract/migrations/v0_2_0.rs +++ b/contracts/coordinator/src/contract/migrations/v0_2_0.rs @@ -141,7 +141,7 @@ mod tests { fn instantiate_0_2_0_contract( deps: DepsMut, - ) -> Result { + ) -> Result { let governance = "governance"; let msg = InstantiateMsg { diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 8e886beee..91b5fe956 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -19,7 +19,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { // any version checks should be done before here cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -33,7 +33,7 @@ pub fn instantiate( env: Env, info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(internal::instantiate(deps, env, info, msg)?) @@ -45,7 +45,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { let msg = msg.ensure_permissions(deps.storage, &info.sender)?; Ok(internal::execute(deps, env, info, msg)?) } @@ -55,7 +55,7 @@ pub fn query( deps: Deps, env: Env, msg: QueryMsg, -) -> Result { +) -> Result { Ok(internal::query(deps, env, msg)?) } diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index 03c44bd9c..541e8eb63 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -3,7 +3,8 @@ use std::fmt::Debug; use std::fs::File; use std::iter; -use axelar_wasm_std::{ContractError, VerificationStatus}; +use axelar_wasm_std::error::ContractError; +use axelar_wasm_std::VerificationStatus; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier}; #[cfg(not(feature = "generate_golden_files"))] use cosmwasm_std::Response; diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 7b9cab357..1a01ce10e 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -25,7 +25,7 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let config = Config { @@ -59,7 +59,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::ConstructProof { message_ids } => { Ok(execute::construct_proof(deps, message_ids)?) @@ -83,12 +83,12 @@ pub fn reply( deps: DepsMut, _env: Env, reply: Reply, -) -> Result { +) -> Result { match reply.id { START_MULTISIG_REPLY_ID => reply::start_multisig_reply(deps, reply), _ => unreachable!("unknown reply ID"), } - .map_err(axelar_wasm_std::ContractError::from) + .map_err(axelar_wasm_std::error::ContractError::from) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -96,7 +96,7 @@ pub fn query( deps: Deps, _env: Env, msg: QueryMsg, -) -> Result { +) -> Result { match msg { QueryMsg::GetProof { multisig_session_id, @@ -105,7 +105,7 @@ pub fn query( QueryMsg::NextVerifierSet {} => to_json_binary(&query::next_verifier_set(deps)?), } .change_context(ContractError::SerializeResponse) - .map_err(axelar_wasm_std::ContractError::from) + .map_err(axelar_wasm_std::error::ContractError::from) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -113,7 +113,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { migrations::v0_6_0::migrate(deps.storage)?; cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -185,7 +185,7 @@ mod tests { fn execute_update_verifier_set( deps: DepsMut, - ) -> Result { + ) -> Result { let msg = ExecuteMsg::UpdateVerifierSet {}; execute(deps, mock_env(), mock_info(ADMIN, &[]), msg) } @@ -193,7 +193,7 @@ mod tests { fn confirm_verifier_set( deps: DepsMut, sender: Addr, - ) -> Result { + ) -> Result { let msg = ExecuteMsg::ConfirmVerifierSet {}; execute(deps, mock_env(), mock_info(sender.as_str(), &[]), msg) } @@ -202,7 +202,7 @@ mod tests { deps: DepsMut, sender: Addr, new_signing_threshold: MajorityThreshold, - ) -> Result { + ) -> Result { let msg = ExecuteMsg::UpdateSigningThreshold { new_signing_threshold, }; @@ -213,7 +213,7 @@ mod tests { deps: DepsMut, sender: &str, new_admin_address: String, - ) -> Result { + ) -> Result { let msg = ExecuteMsg::UpdateAdmin { new_admin_address }; execute(deps, mock_env(), mock_info(sender, &[]), msg) } @@ -221,7 +221,7 @@ mod tests { fn execute_construct_proof( deps: DepsMut, message_ids: Option>, - ) -> Result { + ) -> Result { let message_ids = message_ids.unwrap_or_else(|| { test_data::messages() .into_iter() @@ -233,7 +233,9 @@ mod tests { execute(deps, mock_env(), mock_info(RELAYER, &[]), msg) } - fn reply_construct_proof(deps: DepsMut) -> Result { + fn reply_construct_proof( + deps: DepsMut, + ) -> Result { let session_id = to_json_binary(&MULTISIG_SESSION_ID).unwrap(); let response = SubMsgResponse { @@ -259,7 +261,7 @@ mod tests { fn query_get_proof( deps: Deps, multisig_session_id: Option, - ) -> Result { + ) -> Result { let multisig_session_id = match multisig_session_id { Some(id) => id, None => MULTISIG_SESSION_ID, @@ -277,7 +279,7 @@ mod tests { fn query_get_verifier_set( deps: Deps, - ) -> Result, axelar_wasm_std::ContractError> { + ) -> Result, axelar_wasm_std::error::ContractError> { query(deps, mock_env(), QueryMsg::CurrentVerifierSet {}).map(|res| from_json(res).unwrap()) } @@ -415,10 +417,12 @@ mod tests { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(permission_control::Error::PermissionDenied { - expected: Permission::Elevated.into(), - actual: Permission::NoPrivilege.into() - }) + axelar_wasm_std::error::ContractError::from( + permission_control::Error::PermissionDenied { + expected: Permission::Elevated.into(), + actual: Permission::NoPrivilege.into() + } + ) .to_string() ); } @@ -557,7 +561,8 @@ mod tests { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::VerifierSetUnchanged).to_string() + axelar_wasm_std::error::ContractError::from(ContractError::VerifierSetUnchanged) + .to_string() ); } @@ -582,7 +587,7 @@ mod tests { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::VerifierSetNotConfirmed) + axelar_wasm_std::error::ContractError::from(ContractError::VerifierSetNotConfirmed) .to_string() ); } @@ -612,7 +617,7 @@ mod tests { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::VerifierSetNotConfirmed) + axelar_wasm_std::error::ContractError::from(ContractError::VerifierSetNotConfirmed) .to_string() ); } @@ -669,7 +674,7 @@ mod tests { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::NoVerifierSet).to_string() + axelar_wasm_std::error::ContractError::from(ContractError::NoVerifierSet).to_string() ); } diff --git a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs index b1786db5e..b872d0aa1 100644 --- a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs +++ b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs @@ -1,7 +1,8 @@ #![allow(deprecated)] +use axelar_wasm_std::error::ContractError; use axelar_wasm_std::hash::Hash; -use axelar_wasm_std::{permission_control, ContractError, MajorityThreshold}; +use axelar_wasm_std::{permission_control, MajorityThreshold}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; use cw_storage_plus::Item; @@ -174,7 +175,7 @@ mod tests { _env: Env, _info: MessageInfo, msg: InstantiateMsg, - ) -> Result { + ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_6_0::BASE_VERSION)?; let config = make_config(&deps, msg)?; @@ -186,7 +187,7 @@ mod tests { fn make_config( deps: &DepsMut, msg: InstantiateMsg, - ) -> Result { + ) -> Result { let admin = deps.api.addr_validate(&msg.admin_address)?; let governance = deps.api.addr_validate(&msg.governance_address)?; let gateway = deps.api.addr_validate(&msg.gateway_address)?; diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 2c00e4b58..4f0ea8120 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -31,7 +31,7 @@ pub fn migrate( deps: DepsMut, _env: Env, msg: MigrationMsg, -) -> Result { +) -> Result { let admin = deps.api.addr_validate(&msg.admin_address)?; let authorized_callers = msg .authorized_callers @@ -59,7 +59,7 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let admin = deps.api.addr_validate(&msg.admin_address)?; @@ -87,7 +87,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg.ensure_permissions( deps.storage, &info.sender, @@ -107,7 +107,7 @@ pub fn execute( env, verifier_set_id, msg.try_into() - .map_err(axelar_wasm_std::ContractError::from)?, + .map_err(axelar_wasm_std::error::ContractError::from)?, chain_name, sig_verifier, ) @@ -222,7 +222,7 @@ mod tests { const SIGNATURE_BLOCK_EXPIRY: u64 = 100; - fn do_instantiate(deps: DepsMut) -> Result { + fn do_instantiate(deps: DepsMut) -> Result { let info = mock_info(INSTANTIATOR, &[]); let env = mock_env(); @@ -239,7 +239,7 @@ mod tests { fn generate_verifier_set( key_type: KeyType, deps: DepsMut, - ) -> Result<(Response, VerifierSet), axelar_wasm_std::ContractError> { + ) -> Result<(Response, VerifierSet), axelar_wasm_std::error::ContractError> { let info = mock_info(PROVER, &[]); let env = mock_env(); @@ -272,7 +272,7 @@ mod tests { sender: &str, verifier_set_id: &str, chain_name: ChainName, - ) -> Result { + ) -> Result { let info = mock_info(sender, &[]); let env = mock_env(); @@ -291,7 +291,7 @@ mod tests { env: Env, session_id: Uint64, signer: &TestSigner, - ) -> Result { + ) -> Result { let msg = ExecuteMsg::SubmitSignature { session_id, signature: signer.signature.clone(), @@ -304,7 +304,7 @@ mod tests { verifier: Addr, public_key: PublicKey, signed_sender_address: HexBinary, - ) -> Result { + ) -> Result { let msg = ExecuteMsg::RegisterPublicKey { public_key, signed_sender_address, @@ -315,7 +315,7 @@ mod tests { fn do_authorize_callers( deps: DepsMut, contracts: Vec<(Addr, ChainName)>, - ) -> Result { + ) -> Result { let info = mock_info(GOVERNANCE, &[]); let env = mock_env(); @@ -331,7 +331,7 @@ mod tests { fn do_unauthorize_caller( deps: DepsMut, contracts: Vec<(Addr, ChainName)>, - ) -> Result { + ) -> Result { let info = mock_info(GOVERNANCE, &[]); let env = mock_env(); @@ -347,7 +347,7 @@ mod tests { fn do_disable_signing( deps: DepsMut, sender: &str, - ) -> Result { + ) -> Result { let info = mock_info(sender, &[]); let env = mock_env(); @@ -358,7 +358,7 @@ mod tests { fn do_enable_signing( deps: DepsMut, sender: &str, - ) -> Result { + ) -> Result { let info = mock_info(sender, &[]); let env = mock_env(); @@ -786,7 +786,7 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::SigningSessionClosed { + axelar_wasm_std::error::ContractError::from(ContractError::SigningSessionClosed { session_id }) .to_string() @@ -811,7 +811,7 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::SigningSessionNotFound { + axelar_wasm_std::error::ContractError::from(ContractError::SigningSessionNotFound { session_id: invalid_session_id }) .to_string() @@ -1038,7 +1038,7 @@ mod tests { ); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from( + axelar_wasm_std::error::ContractError::from( ContractError::InvalidPublicKeyRegistrationSignature ) .to_string() @@ -1057,7 +1057,7 @@ mod tests { ); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from( + axelar_wasm_std::error::ContractError::from( ContractError::InvalidPublicKeyRegistrationSignature ) .to_string() @@ -1091,7 +1091,8 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::DuplicatePublicKey).to_string() + axelar_wasm_std::error::ContractError::from(ContractError::DuplicatePublicKey) + .to_string() ); } diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index 17f30bbc9..fcf181460 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -22,6 +22,7 @@ cw2 = { workspace = true } error-stack = { workspace = true } hex = "0.4.3" mockall = "0.11.4" +msgs-derive = { workspace = true } report = { workspace = true } router-api = { workspace = true } schemars = "0.8.15" diff --git a/contracts/nexus-gateway/src/contract.rs b/contracts/nexus-gateway/src/contract.rs index 71983bf06..2da129fc4 100644 --- a/contracts/nexus-gateway/src/contract.rs +++ b/contracts/nexus-gateway/src/contract.rs @@ -1,12 +1,13 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{DepsMut, Empty, Env, MessageInfo, Response}; -use error_stack::ResultExt; +use cosmwasm_std::{Addr, DepsMut, Empty, Env, MessageInfo, Response, Storage}; +use error_stack::{Report, ResultExt}; +use crate::contract::execute::{route_to_nexus, route_to_router}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg}; -use crate::nexus; -use crate::state::{Config, GatewayStore, Store}; +use crate::state::Config; +use crate::{nexus, state}; mod execute; @@ -18,7 +19,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { // any version checks should be done before here cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -32,15 +33,13 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let nexus = deps.api.addr_validate(&msg.nexus)?; let router = deps.api.addr_validate(&msg.router)?; - GatewayStore::new(deps.storage) - .save_config(Config { nexus, router }) - .expect("config must be saved"); + state::save_config(deps.storage, Config { nexus, router }).expect("config must be saved"); Ok(Response::default()) } @@ -51,47 +50,41 @@ pub fn execute( _env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result, axelar_wasm_std::ContractError> { - let contract = Contract::new(GatewayStore::new(deps.storage)); - - let res = match msg { - ExecuteMsg::RouteMessages(msgs) => contract - .route_to_nexus(info.sender, msgs) - .change_context(ContractError::RouteToNexus)?, - ExecuteMsg::RouteMessagesFromNexus(msgs) => contract - .route_to_router(info.sender, msgs) - .change_context(ContractError::RouteToRouter)?, +) -> Result, axelar_wasm_std::error::ContractError> { + let res = match msg.ensure_permissions(deps.storage, &info.sender, match_router, match_nexus)? { + ExecuteMsg::RouteMessages(msgs) => { + route_to_nexus(deps.storage, msgs).change_context(ContractError::RouteToNexus)? + } + ExecuteMsg::RouteMessagesFromNexus(msgs) => { + route_to_router(deps.storage, msgs).change_context(ContractError::RouteToRouter)? + } }; Ok(res) } -struct Contract -where - S: Store, -{ - store: S, - config: Config, +fn match_router(storage: &dyn Storage, _: &ExecuteMsg) -> Result> { + Ok(state::load_config(storage)?.router) } -impl Contract -where - S: Store, -{ - pub fn new(store: S) -> Self { - let config = store.load_config().expect("config must be loaded"); - - Self { store, config } - } +fn match_nexus(storage: &dyn Storage, _: &ExecuteMsg) -> Result> { + Ok(state::load_config(storage)?.nexus) } #[cfg(test)] mod tests { - - use cosmwasm_std::testing::{mock_dependencies, mock_env}; + use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; + use axelar_wasm_std::{err_contains, permission_control}; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{from_json, Addr, CosmosMsg, WasmMsg}; + use hex::decode; + use router_api::CrossChainId; use super::*; + const NEXUS: &str = "nexus"; + const ROUTER: &str = "router"; + #[test] fn migrate_sets_contract_version() { let mut deps = mock_dependencies(); @@ -102,4 +95,228 @@ mod tests { assert_eq!(contract_version.contract, "nexus-gateway"); assert_eq!(contract_version.version, CONTRACT_VERSION); } + + #[test] + fn route_to_router_unauthorized() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info("unauthorized", &[]), + ExecuteMsg::RouteMessagesFromNexus(vec![]), + ); + + assert!(res.is_err_and(|err| err_contains!( + err.report, + permission_control::Error, + permission_control::Error::AddressNotWhitelisted { .. } + ))); + } + + #[test] + fn route_to_router_with_no_msg() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(NEXUS, &[]), + ExecuteMsg::RouteMessagesFromNexus(vec![]), + ); + + assert!(res.is_ok_and(|res| res.messages.is_empty())); + } + + #[test] + fn route_to_router_with_msgs() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(NEXUS, &[]), + ExecuteMsg::RouteMessagesFromNexus(nexus_messages()), + ); + + assert!(res.is_ok_and(|res| { + if res.messages.len() != 1 { + return false; + } + + match &res.messages[0].msg { + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr, + msg, + funds, + }) => { + if let Ok(router_api::msg::ExecuteMsg::RouteMessages(msgs)) = from_json(msg) { + return *contract_addr == Addr::unchecked(ROUTER) + && msgs.len() == 2 + && funds.is_empty(); + } + + false + } + _ => false, + } + })); + } + + #[test] + fn route_to_nexus_unauthorized() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info("unauthorized", &[]), + ExecuteMsg::RouteMessages(vec![]), + ); + + assert!(res.is_err_and(|err| err_contains!( + err.report, + permission_control::Error, + permission_control::Error::AddressNotWhitelisted { .. } + ))); + } + + #[test] + fn route_to_nexus_with_no_msg() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ROUTER, &[]), + ExecuteMsg::RouteMessages(vec![]), + ); + + assert!(res.is_ok_and(|res| res.messages.is_empty())); + } + + #[test] + fn route_to_nexus_with_msgs_only_route_once() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let msgs = router_messages(); + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ROUTER, &[]), + ExecuteMsg::RouteMessages(msgs.clone()), + ); + + assert!(res.is_ok_and(|res| res.messages.len() == 2)); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ROUTER, &[]), + ExecuteMsg::RouteMessages(msgs.clone()), + ); + + assert!(res.is_ok_and(|res| res.messages.is_empty())); + } + + fn nexus_messages() -> Vec { + let msg_ids = [ + HexTxHashAndEventIndex { + tx_hash: vec![0x2f; 32].try_into().unwrap(), + event_index: 100, + }, + HexTxHashAndEventIndex { + tx_hash: vec![0x23; 32].try_into().unwrap(), + event_index: 1000, + }, + ]; + let msgs = vec![ + nexus::Message { + source_chain: "sourceChain".parse().unwrap(), + source_address: "0xb860".parse().unwrap(), + destination_address: "0xD419".parse().unwrap(), + destination_chain: "destinationChain".parse().unwrap(), + payload_hash: decode( + "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", + ) + .unwrap() + .try_into() + .unwrap(), + source_tx_id: msg_ids[0].tx_hash.to_vec().try_into().unwrap(), + source_tx_index: msg_ids[0].event_index as u64, + id: msg_ids[0].to_string(), + }, + nexus::Message { + source_chain: "sourceChain".parse().unwrap(), + source_address: "0xc860".parse().unwrap(), + destination_address: "0xA419".parse().unwrap(), + destination_chain: "destinationChain".parse().unwrap(), + payload_hash: decode( + "cb9b5566c2f4876853333e481f4698350154259ffe6226e283b16ce18a64bcf1", + ) + .unwrap() + .try_into() + .unwrap(), + source_tx_id: msg_ids[1].tx_hash.to_vec().try_into().unwrap(), + source_tx_index: msg_ids[1].event_index as u64, + id: msg_ids[1].to_string(), + }, + ]; + msgs + } + + fn router_messages() -> Vec { + let msgs = vec![ + router_api::Message { + cc_id: CrossChainId { + chain: "sourceChain".parse().unwrap(), + id: "0x2fe4:0".parse().unwrap(), + }, + source_address: "0xb860".parse().unwrap(), + destination_address: "0xD419".parse().unwrap(), + destination_chain: "destinationChain".parse().unwrap(), + payload_hash: decode( + "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", + ) + .unwrap() + .try_into() + .unwrap(), + }, + router_api::Message { + cc_id: CrossChainId { + chain: "sourceChain".parse().unwrap(), + id: "0x6b33:10".parse().unwrap(), + }, + source_address: "0x70725".parse().unwrap(), + destination_address: "0x7FAD".parse().unwrap(), + destination_chain: "destinationChain".parse().unwrap(), + payload_hash: decode( + "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", + ) + .unwrap() + .try_into() + .unwrap(), + }, + ]; + msgs + } + + fn instantiate_contract(deps: DepsMut) { + instantiate( + deps, + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + nexus: NEXUS.to_string(), + router: ROUTER.to_string(), + }, + ) + .unwrap(); + } } diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index 8e61ab9a3..523b830f1 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -1,330 +1,47 @@ -use cosmwasm_std::{to_json_binary, Addr, Response, WasmMsg}; -use error_stack::report; +use cosmwasm_std::{to_json_binary, Response, Storage, WasmMsg}; -use super::Contract; use crate::error::ContractError; -use crate::nexus; -use crate::state::Store; +use crate::{nexus, state}; type Result = error_stack::Result; -impl Contract -where - S: Store, -{ - pub fn route_to_router( - self, - sender: Addr, - msgs: Vec, - ) -> Result> { - if sender != self.config.nexus { - return Err(report!(ContractError::Unauthorized)); - } - - let msgs: Vec<_> = msgs - .into_iter() - .map(router_api::Message::try_from) - .collect::>>()?; - if msgs.is_empty() { - return Ok(Response::default()); - } - - Ok(Response::new().add_message(WasmMsg::Execute { - contract_addr: self.config.router.to_string(), - msg: to_json_binary(&router_api::msg::ExecuteMsg::RouteMessages(msgs)) - .expect("must serialize route-messages message"), - funds: vec![], - })) - } - - pub fn route_to_nexus( - mut self, - sender: Addr, - msgs: Vec, - ) -> Result> { - if sender != self.config.router { - return Err(report!(ContractError::Unauthorized)); - } - - let msgs = msgs - .into_iter() - .filter_map(|msg| match self.store.is_message_routed(&msg.cc_id) { - Ok(true) => None, - Ok(false) => Some(Ok(msg)), - Err(err) => Some(Err(err)), - }) - .collect::>>()?; - - msgs.iter() - .try_for_each(|msg| self.store.set_message_routed(&msg.cc_id))?; - - let msgs: Vec = msgs.into_iter().map(Into::into).collect(); - - Ok(Response::new().add_messages(msgs)) - } +pub fn route_to_router( + storage: &dyn Storage, + msgs: Vec, +) -> Result> { + let msgs: Vec<_> = msgs + .into_iter() + .map(router_api::Message::try_from) + .collect::>>()?; + if msgs.is_empty() { + return Ok(Response::default()); + } + + Ok(Response::new().add_message(WasmMsg::Execute { + contract_addr: state::load_config(storage)?.router.to_string(), + msg: to_json_binary(&router_api::msg::ExecuteMsg::RouteMessages(msgs)) + .expect("must serialize route-messages message"), + funds: vec![], + })) } -#[cfg(test)] -mod test { - use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; - use cosmwasm_std::{from_json, CosmosMsg}; - use hex::decode; - use router_api::CrossChainId; - - use super::*; - use crate::state::{Config, MockStore}; - - #[test] - fn route_to_router_unauthorized() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - let contract = Contract::new(store); - - let res = contract.route_to_router(Addr::unchecked("unauthorized"), vec![]); - - assert!(res.is_err_and(|err| matches!(err.current_context(), ContractError::Unauthorized))); - } - - #[test] - fn route_to_router_with_no_msg() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - let contract = Contract::new(store); - - let res = contract.route_to_router(Addr::unchecked("nexus"), vec![]); - - assert!(res.is_ok_and(|res| res.messages.is_empty())); - } - - #[test] - fn route_to_router_with_msgs() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - let contract = Contract::new(store); - - let msg_ids = [ - HexTxHashAndEventIndex { - tx_hash: vec![0x2f; 32].try_into().unwrap(), - event_index: 100, - }, - HexTxHashAndEventIndex { - tx_hash: vec![0x23; 32].try_into().unwrap(), - event_index: 1000, - }, - ]; - let msgs = vec![ - nexus::Message { - source_chain: "sourceChain".parse().unwrap(), - source_address: "0xb860".parse().unwrap(), - destination_address: "0xD419".parse().unwrap(), - destination_chain: "destinationChain".parse().unwrap(), - payload_hash: decode( - "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", - ) - .unwrap() - .try_into() - .unwrap(), - source_tx_id: msg_ids[0].tx_hash.to_vec().try_into().unwrap(), - source_tx_index: msg_ids[0].event_index as u64, - id: msg_ids[0].to_string(), - }, - nexus::Message { - source_chain: "sourceChain".parse().unwrap(), - source_address: "0xc860".parse().unwrap(), - destination_address: "0xA419".parse().unwrap(), - destination_chain: "destinationChain".parse().unwrap(), - payload_hash: decode( - "cb9b5566c2f4876853333e481f4698350154259ffe6226e283b16ce18a64bcf1", - ) - .unwrap() - .try_into() - .unwrap(), - source_tx_id: msg_ids[1].tx_hash.to_vec().try_into().unwrap(), - source_tx_index: msg_ids[1].event_index as u64, - id: msg_ids[1].to_string(), - }, - ]; - let res = contract.route_to_router(Addr::unchecked("nexus"), msgs); - - assert!(res.is_ok_and(|res| { - if res.messages.len() != 1 { - return false; - } - - match &res.messages[0].msg { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) => { - if let Ok(router_api::msg::ExecuteMsg::RouteMessages(msgs)) = from_json(msg) { - return *contract_addr == Addr::unchecked("router") - && msgs.len() == 2 - && funds.is_empty(); - } - - false - } - _ => false, - } - })); - } - - #[test] - fn route_to_nexus_unauthorized() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - let contract = Contract::new(store); - - let res = contract.route_to_nexus(Addr::unchecked("unauthorized"), vec![]); - - assert!(res.is_err_and(|err| matches!(err.current_context(), ContractError::Unauthorized))); - } - - #[test] - fn route_to_nexus_with_no_msg() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - let contract = Contract::new(store); - - let res = contract.route_to_nexus(Addr::unchecked("router"), vec![]); - - assert!(res.is_ok_and(|res| res.messages.is_empty())); - } - - #[test] - fn route_to_nexus_with_msgs_that_have_not_been_routed() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - store - .expect_is_message_routed() - .times(2) - .returning(|_| Ok(false)); - store - .expect_set_message_routed() - .times(2) - .returning(|_| Ok(())); - let contract = Contract::new(store); - - let msgs = vec![ - router_api::Message { - cc_id: CrossChainId::new("sourceChain", "0x2fe4:0").unwrap(), - source_address: "0xb860".parse().unwrap(), - destination_address: "0xD419".parse().unwrap(), - destination_chain: "destinationChain".parse().unwrap(), - payload_hash: decode( - "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", - ) - .unwrap() - .try_into() - .unwrap(), - }, - router_api::Message { - cc_id: CrossChainId::new("sourceChain", "0x6b33:10").unwrap(), - source_address: "0x0725".parse().unwrap(), - destination_address: "0x7FAD".parse().unwrap(), - destination_chain: "destinationChain".parse().unwrap(), - payload_hash: decode( - "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", - ) - .unwrap() - .try_into() - .unwrap(), - }, - ]; - let res = contract.route_to_nexus(Addr::unchecked("router"), msgs); - - assert!(res.is_ok_and(|res| res.messages.len() == 2)); - } - - #[test] - fn route_to_nexus_with_msgs_that_have_been_routed() { - let mut store = MockStore::new(); - let config = Config { - nexus: Addr::unchecked("nexus"), - router: Addr::unchecked("router"), - }; - store - .expect_load_config() - .returning(move || Ok(config.clone())); - store - .expect_is_message_routed() - .once() - .returning(|_| Ok(false)); - store - .expect_is_message_routed() - .once() - .returning(|_| Ok(true)); - store - .expect_set_message_routed() - .once() - .returning(|_| Ok(())); - let contract = Contract::new(store); - - let msgs = vec![ - router_api::Message { - cc_id: CrossChainId::new("sourceChain", "0x2fe4:0").unwrap(), - source_address: "0xb860".parse().unwrap(), - destination_address: "0xD419".parse().unwrap(), - destination_chain: "destinationChain".parse().unwrap(), - payload_hash: decode( - "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", - ) - .unwrap() - .try_into() - .unwrap(), - }, - router_api::Message { - cc_id: CrossChainId::new("sourceChain", "0x6b33:10").unwrap(), - source_address: "0x70725".parse().unwrap(), - destination_address: "0x7FAD".parse().unwrap(), - destination_chain: "destinationChain".parse().unwrap(), - payload_hash: decode( - "bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1", - ) - .unwrap() - .try_into() - .unwrap(), - }, - ]; - let res = contract.route_to_nexus(Addr::unchecked("router"), msgs); - - assert!(res.is_ok_and(|res| res.messages.len() == 1)); - } +pub fn route_to_nexus( + storage: &mut dyn Storage, + msgs: Vec, +) -> Result> { + let msgs = msgs + .into_iter() + .filter_map(|msg| match state::is_message_routed(storage, &msg.cc_id) { + Ok(true) => None, + Ok(false) => Some(Ok(msg)), + Err(err) => Some(Err(err)), + }) + .collect::>>()?; + + msgs.iter() + .try_for_each(|msg| state::set_message_routed(storage, &msg.cc_id))?; + + let msgs: Vec = msgs.into_iter().map(Into::into).collect(); + + Ok(Response::new().add_messages(msgs)) } diff --git a/contracts/nexus-gateway/src/error.rs b/contracts/nexus-gateway/src/error.rs index 964decca1..68f36e127 100644 --- a/contracts/nexus-gateway/src/error.rs +++ b/contracts/nexus-gateway/src/error.rs @@ -4,9 +4,6 @@ use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] pub enum ContractError { - #[error("caller is not authorized")] - Unauthorized, - #[error("store failed saving/loading data")] StoreFailure, diff --git a/contracts/nexus-gateway/src/msg.rs b/contracts/nexus-gateway/src/msg.rs index 058fb4291..a95cc7f46 100644 --- a/contracts/nexus-gateway/src/msg.rs +++ b/contracts/nexus-gateway/src/msg.rs @@ -1,4 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use msgs_derive::EnsurePermissions; use crate::nexus; @@ -9,8 +10,11 @@ pub struct InstantiateMsg { } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { + #[permission(Specific(router))] RouteMessages(Vec), + #[permission(Specific(nexus))] RouteMessagesFromNexus(Vec), } diff --git a/contracts/nexus-gateway/src/state.rs b/contracts/nexus-gateway/src/state.rs index 8dba6d550..77d5daf63 100644 --- a/contracts/nexus-gateway/src/state.rs +++ b/contracts/nexus-gateway/src/state.rs @@ -2,7 +2,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; use cw_storage_plus::{Item, Map}; use error_stack::{self, ResultExt}; -use mockall::automock; use router_api::CrossChainId; use crate::error::ContractError; @@ -12,49 +11,29 @@ const ROUTED_MESSAGE_IDS: Map<&CrossChainId, ()> = Map::new("routed_message_ids" type Result = error_stack::Result; -#[automock] -pub trait Store { - fn save_config(&mut self, config: Config) -> Result<()>; - fn load_config(&self) -> Result; - fn set_message_routed(&mut self, id: &CrossChainId) -> Result<()>; - fn is_message_routed(&self, id: &CrossChainId) -> Result; +pub(crate) fn save_config(storage: &mut dyn Storage, config: Config) -> Result<()> { + CONFIG + .save(storage, &config) + .change_context(ContractError::StoreFailure) } -pub struct GatewayStore<'a> { - storage: &'a mut dyn Storage, +pub(crate) fn load_config(storage: &dyn Storage) -> Result { + CONFIG + .load(storage) + .change_context(ContractError::StoreFailure) } -impl<'a> GatewayStore<'a> { - pub fn new(storage: &'a mut dyn Storage) -> Self { - Self { storage } - } +pub(crate) fn set_message_routed(storage: &mut dyn Storage, id: &CrossChainId) -> Result<()> { + ROUTED_MESSAGE_IDS + .save(storage, id, &()) + .change_context(ContractError::StoreFailure) } -impl Store for GatewayStore<'_> { - fn save_config(&mut self, config: Config) -> Result<()> { - CONFIG - .save(self.storage, &config) - .change_context(ContractError::StoreFailure) - } - - fn load_config(&self) -> Result { - CONFIG - .load(self.storage) - .change_context(ContractError::StoreFailure) - } - - fn set_message_routed(&mut self, id: &CrossChainId) -> Result<()> { - ROUTED_MESSAGE_IDS - .save(self.storage, id, &()) - .change_context(ContractError::StoreFailure) - } - - fn is_message_routed(&self, id: &CrossChainId) -> Result { - ROUTED_MESSAGE_IDS - .may_load(self.storage, id) - .map(|result| result.is_some()) - .change_context(ContractError::StoreFailure) - } +pub(crate) fn is_message_routed(storage: &dyn Storage, id: &CrossChainId) -> Result { + ROUTED_MESSAGE_IDS + .may_load(storage, id) + .map(|result| result.is_some()) + .change_context(ContractError::StoreFailure) } #[cw_serde] diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index b1f6a409b..90c4d0919 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -24,7 +24,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { v0_4_0::migrate(deps.storage)?; // any version checks should be done before here @@ -40,7 +40,7 @@ pub fn instantiate( env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let governance = deps.api.addr_validate(&msg.governance_address)?; @@ -73,7 +73,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::RecordParticipation { chain_name, @@ -149,19 +149,19 @@ pub fn query( deps: Deps, env: Env, msg: QueryMsg, -) -> Result { +) -> Result { match msg { QueryMsg::RewardsPool { pool_id } => { let pool = query::rewards_pool(deps.storage, pool_id, env.block.height)?; to_json_binary(&pool) .change_context(ContractError::SerializeResponse) - .map_err(axelar_wasm_std::ContractError::from) + .map_err(axelar_wasm_std::error::ContractError::from) } QueryMsg::VerifierParticipation { pool_id, epoch_num } => { let tally = query::participation(deps.storage, pool_id, epoch_num, env.block.height)?; to_json_binary(&tally) .change_context(ContractError::SerializeResponse) - .map_err(axelar_wasm_std::ContractError::from) + .map_err(axelar_wasm_std::error::ContractError::from) } } } diff --git a/contracts/rewards/src/contract/migrations/v0_4_0.rs b/contracts/rewards/src/contract/migrations/v0_4_0.rs index 9e76fb97d..115da34ae 100644 --- a/contracts/rewards/src/contract/migrations/v0_4_0.rs +++ b/contracts/rewards/src/contract/migrations/v0_4_0.rs @@ -1,6 +1,7 @@ #![allow(deprecated)] -use axelar_wasm_std::{permission_control, ContractError}; +use axelar_wasm_std::error::ContractError; +use axelar_wasm_std::permission_control; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage}; use cw_storage_plus::Item; @@ -57,7 +58,7 @@ pub mod tests { env: Env, _info: MessageInfo, msg: InstantiateMsg, - ) -> Result { + ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_4_0::BASE_VERSION)?; let governance = deps.api.addr_validate(&msg.governance_address)?; diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 1484e87d5..205bcee8e 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -24,7 +24,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { v0_3_3::migrate(deps.storage)?; // this needs to be the last thing to do during migration, @@ -40,7 +40,7 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let admin = deps.api.addr_validate(&msg.admin_address)?; @@ -73,7 +73,7 @@ pub fn execute( _env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg.ensure_permissions( deps.storage, &info.sender, @@ -126,7 +126,7 @@ pub fn query( deps: Deps, _env: Env, msg: QueryMsg, -) -> Result { +) -> Result { match msg { QueryMsg::GetChainInfo(chain) => { to_json_binary(&query::get_chain_info(deps.storage, chain)?) @@ -136,7 +136,7 @@ pub fn query( } QueryMsg::IsEnabled => to_json_binary(&killswitch::is_contract_active(deps.storage)), } - .map_err(axelar_wasm_std::ContractError::from) + .map_err(axelar_wasm_std::error::ContractError::from) } #[cfg(test)] @@ -144,8 +144,9 @@ mod test { use std::collections::HashMap; use std::str::FromStr; + use axelar_wasm_std::err_contains; + use axelar_wasm_std::error::ContractError; use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; - use axelar_wasm_std::{err_contains, ContractError}; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; @@ -235,8 +236,8 @@ mod test { } pub fn assert_contract_err_string_contains( - actual: impl Into, - expected: impl Into, + actual: impl Into, + expected: impl Into, ) { assert!(actual .into() diff --git a/contracts/router/src/contract/migrations/v0_3_3.rs b/contracts/router/src/contract/migrations/v0_3_3.rs index 2302c6691..86c849b26 100644 --- a/contracts/router/src/contract/migrations/v0_3_3.rs +++ b/contracts/router/src/contract/migrations/v0_3_3.rs @@ -1,6 +1,7 @@ #![allow(deprecated)] -use axelar_wasm_std::{killswitch, permission_control, ContractError}; +use axelar_wasm_std::error::ContractError; +use axelar_wasm_std::{killswitch, permission_control}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdResult, Storage}; use cw_storage_plus::Item; @@ -51,8 +52,9 @@ const CONFIG: Item = Item::new("config"); mod test { use std::collections::HashMap; + use axelar_wasm_std::error::ContractError; + use axelar_wasm_std::killswitch; use axelar_wasm_std::msg_id::MessageIdFormat; - use axelar_wasm_std::{killswitch, ContractError}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; use router_api::msg::ExecuteMsg; diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index d8301addf..dd02fc8c1 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -23,7 +23,7 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; CONFIG.save( @@ -41,7 +41,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg { ExecuteMsg::RegisterService { service_name, @@ -163,10 +163,10 @@ pub fn migrate( deps: DepsMut, _env: Env, msg: MigrateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; migrations::v_0_4::migrate_services_coordinator_contract(deps.storage, msg.coordinator_contract) - .map_err(axelar_wasm_std::ContractError::from) + .map_err(axelar_wasm_std::error::ContractError::from) } #[cfg(test)] @@ -212,8 +212,8 @@ mod test { } pub fn assert_contract_err_strings_equal( - actual: impl Into, - expected: impl Into, + actual: impl Into, + expected: impl Into, ) { assert_eq!(actual.into().to_string(), expected.into().to_string()); } @@ -1739,7 +1739,7 @@ mod test { assert!(res.is_err()); assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::ContractError::from(ContractError::InvalidBondingState( + axelar_wasm_std::error::ContractError::from(ContractError::InvalidBondingState( BondingState::Unbonding { unbonded_at: unbond_request_env.block.time, amount: min_verifier_bond, diff --git a/contracts/service-registry/src/migrations/v_0_4.rs b/contracts/service-registry/src/migrations/v_0_4.rs index 31682752d..7b4295ea1 100644 --- a/contracts/service-registry/src/migrations/v_0_4.rs +++ b/contracts/service-registry/src/migrations/v_0_4.rs @@ -28,7 +28,7 @@ mod v0_3_state { pub fn migrate_services_coordinator_contract( store: &mut dyn Storage, coordinator_contract: Addr, -) -> Result { +) -> Result { v0_3_state::SERVICES .range(store, None, None, Order::Ascending) .collect::, _>>()? diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 6d8457a94..19450d871 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -19,7 +19,7 @@ pub fn instantiate( _env: Env, _info: MessageInfo, msg: InstantiateMsg, -) -> Result { +) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let config = Config { @@ -46,7 +46,7 @@ pub fn execute( env: Env, info: MessageInfo, msg: ExecuteMsg, -) -> Result { +) -> Result { match msg { ExecuteMsg::VerifyMessages { messages } => execute::verify_messages(deps, env, messages), ExecuteMsg::Vote { poll_id, votes } => execute::vote(deps, env, info, poll_id, votes), @@ -87,7 +87,7 @@ pub fn migrate( deps: DepsMut, _env: Env, _msg: Empty, -) -> Result { +) -> Result { // any version checks should be done before here cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; @@ -140,8 +140,8 @@ mod test { } fn assert_contract_err_strings_equal( - actual: impl Into, - expected: impl Into, + actual: impl Into, + expected: impl Into, ) { assert_eq!(actual.into().to_string(), expected.into().to_string()); } diff --git a/integration-tests/src/contract.rs b/integration-tests/src/contract.rs index 4d2cea980..487ca9ca2 100644 --- a/integration-tests/src/contract.rs +++ b/integration-tests/src/contract.rs @@ -22,7 +22,7 @@ pub trait Contract { app: &mut App, caller: Addr, execute_message: &Self::ExMsg, - ) -> Result + ) -> Result where Self::ExMsg: Serialize, Self::ExMsg: std::fmt::Debug, @@ -36,7 +36,7 @@ pub trait Contract { caller: Addr, execute_message: &Self::ExMsg, funds: &[Coin], - ) -> Result + ) -> Result where Self::ExMsg: Serialize, Self::ExMsg: std::fmt::Debug, @@ -49,7 +49,7 @@ pub trait Contract { ) .map_err(|err| { report!(err - .downcast::() + .downcast::() .unwrap_or_else(|err| err.downcast::().unwrap().into())) }) } diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 15bfd23d2..c8c1729fe 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -855,8 +855,8 @@ pub fn setup_test_case() -> TestCase { } pub fn assert_contract_err_strings_equal( - actual: impl Into, - expected: impl Into, + actual: impl Into, + expected: impl Into, ) { assert_eq!(actual.into().to_string(), expected.into().to_string()); } diff --git a/packages/axelar-wasm-std-derive/src/lib.rs b/packages/axelar-wasm-std-derive/src/lib.rs index 86b24b629..4ebac5c0f 100644 --- a/packages/axelar-wasm-std-derive/src/lib.rs +++ b/packages/axelar-wasm-std-derive/src/lib.rs @@ -9,7 +9,7 @@ pub fn into_contract_error_derive(input: TokenStream) -> TokenStream { let name = &ast.ident; let gen = quote! { - impl From<#name> for axelar_wasm_std::ContractError { + impl From<#name> for axelar_wasm_std::error::ContractError { fn from(error: #name) -> Self { use error_stack::report; diff --git a/packages/axelar-wasm-std-derive/tests/derive.rs b/packages/axelar-wasm-std-derive/tests/derive.rs index 5c04d3827..300d4403f 100644 --- a/packages/axelar-wasm-std-derive/tests/derive.rs +++ b/packages/axelar-wasm-std-derive/tests/derive.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::ContractError; +use axelar_wasm_std::error::ContractError; use axelar_wasm_std_derive::IntoContractError; use thiserror::Error; diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 60e3c9313..5ddcb9a68 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -1,4 +1,3 @@ -pub use crate::error::ContractError; pub use crate::fn_ext::FnExt; pub use crate::snapshot::{Participant, Snapshot}; pub use crate::threshold::{MajorityThreshold, Threshold}; diff --git a/packages/msgs-derive/src/lib.rs b/packages/msgs-derive/src/lib.rs index c2e3ce947..10b488f02 100644 --- a/packages/msgs-derive/src/lib.rs +++ b/packages/msgs-derive/src/lib.rs @@ -245,24 +245,26 @@ fn build_general_permissions_check( if general_permissions.is_empty() && !permission.specific.is_empty() { // getting to this point means the specific check has failed, so we return an error quote! { - return Err(axelar_wasm_std::permission_control::Error::AddressNotWhitelisted { + Err(axelar_wasm_std::permission_control::Error::AddressNotWhitelisted { expected: whitelisted.clone(), actual: sender.clone(), }.into()) } } else { // specific permissions have either failed or there were none, so check general permissions - quote! {(#(axelar_wasm_std::permission_control::Permission::#general_permissions )|*).into()} + quote! {Ok((#(axelar_wasm_std::permission_control::Permission::#general_permissions )|*).into())} } }); // map enum variants to general permission checks. Exclude checks for the 'Any' case, // because it allows any address, compare permissions to the sender's role otherwise. quote! { - let permission : axelar_wasm_std::flagset::FlagSet<_> = match self { + let permission : Result, axelar_wasm_std::permission_control::Error > = match self { #(#enum_type::#variants {..}=> {#general_permissions_quote})* }; + let permission = permission?; + if permission.contains(axelar_wasm_std::permission_control::Permission::Any) { return Ok(self); } From c5e8bef54a3f7ce29bd16e385b3f14ec7d3a5c6d Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Tue, 23 Jul 2024 13:44:18 -0400 Subject: [PATCH 095/168] refactor: remove unnecessary allow dead_code flags (#531) --- ampd/src/block_height_monitor.rs | 1 - ampd/src/handlers/sui_verify_verifier_set.rs | 8 -------- contracts/coordinator/src/contract.rs | 1 - 3 files changed, 10 deletions(-) diff --git a/ampd/src/block_height_monitor.rs b/ampd/src/block_height_monitor.rs index 4e9a3d8a9..5a80cf670 100644 --- a/ampd/src/block_height_monitor.rs +++ b/ampd/src/block_height_monitor.rs @@ -64,7 +64,6 @@ impl BlockHeightMonitor { } } - #[allow(dead_code)] pub fn latest_block_height(&self) -> Receiver { self.latest_height_rx.clone() } diff --git a/ampd/src/handlers/sui_verify_verifier_set.rs b/ampd/src/handlers/sui_verify_verifier_set.rs index 4632bc6ee..8b12a701b 100644 --- a/ampd/src/handlers/sui_verify_verifier_set.rs +++ b/ampd/src/handlers/sui_verify_verifier_set.rs @@ -6,7 +6,6 @@ use axelar_wasm_std::voting::{PollId, Vote}; use cosmrs::cosmwasm::MsgExecuteContract; use cosmrs::tx::Msg; use cosmrs::Any; -use cosmwasm_std::{HexBinary, Uint128}; use error_stack::ResultExt; use events::Error::EventTypeMismatch; use events::Event; @@ -25,13 +24,6 @@ use crate::sui::json_rpc::SuiClient; use crate::sui::verifier::verify_verifier_set; use crate::types::TMAddress; -#[allow(dead_code)] -#[derive(Deserialize, Debug)] -pub struct Operators { - pub weights_by_addresses: Vec<(HexBinary, Uint128)>, - pub threshold: Uint128, -} - #[derive(Deserialize, Debug)] pub struct VerifierSetConfirmation { pub tx_id: TransactionDigest, diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index c1670e0c7..2199452ee 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -84,7 +84,6 @@ fn find_prover_address( } #[cfg_attr(not(feature = "library"), entry_point)] -#[allow(dead_code)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::ReadyToUnbond { worker_address } => to_json_binary( From b4cf22ff5d683745e3b119b86254f03ab4e415e7 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 24 Jul 2024 10:49:31 -0400 Subject: [PATCH 096/168] feat(minor-voting-verifier): add permission control to the voting-verifier (#536) --- Cargo.lock | 1 + .../src/contract/migrations/v0_4_1.rs | 4 +- contracts/rewards/src/contract.rs | 4 +- contracts/rewards/src/contract/execute.rs | 2 +- contracts/router/src/contract/query.rs | 4 +- contracts/voting-verifier/Cargo.toml | 1 + contracts/voting-verifier/src/client.rs | 4 +- contracts/voting-verifier/src/contract.rs | 71 +++-- .../src/{ => contract}/execute.rs | 67 +---- .../src/contract/migrations/mod.rs | 1 + .../src/contract/migrations/v0_5_0.rs | 242 ++++++++++++++++++ .../src/{ => contract}/query.rs | 0 contracts/voting-verifier/src/events.rs | 34 ++- contracts/voting-verifier/src/lib.rs | 3 - .../voting-verifier/src/migrations/mod.rs | 1 - contracts/voting-verifier/src/msg.rs | 24 +- contracts/voting-verifier/src/state.rs | 3 +- .../src/voting_verifier_contract.rs | 9 +- integration-tests/tests/bond_unbond.rs | 24 +- integration-tests/tests/test_utils/mod.rs | 8 +- integration-tests/tests/update_worker_set.rs | 14 +- 21 files changed, 356 insertions(+), 165 deletions(-) rename contracts/voting-verifier/src/{ => contract}/execute.rs (83%) create mode 100644 contracts/voting-verifier/src/contract/migrations/mod.rs create mode 100644 contracts/voting-verifier/src/contract/migrations/v0_5_0.rs rename contracts/voting-verifier/src/{ => contract}/query.rs (100%) delete mode 100644 contracts/voting-verifier/src/migrations/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 65399cbe3..d9076e38d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8548,6 +8548,7 @@ dependencies = [ "error-stack", "integration-tests", "itertools 0.11.0", + "msgs-derive", "multisig", "rand", "report", diff --git a/contracts/multisig/src/contract/migrations/v0_4_1.rs b/contracts/multisig/src/contract/migrations/v0_4_1.rs index caa3e85a8..087697151 100644 --- a/contracts/multisig/src/contract/migrations/v0_4_1.rs +++ b/contracts/multisig/src/contract/migrations/v0_4_1.rs @@ -247,7 +247,7 @@ mod tests { assert!(query::caller_authorized(deps.as_ref(), prover, chain_name).unwrap()); } - #[deprecated(since = "0.4.1", note = "only used to test migration")] + #[deprecated(since = "0.4.1", note = "only used to test the migration")] fn instantiate( deps: DepsMut, _env: Env, @@ -270,7 +270,7 @@ mod tests { } #[cw_serde] - #[deprecated(since = "0.4.1", note = "only used to test migration")] + #[deprecated(since = "0.4.1", note = "only used to test the migration")] struct InstantiateMsg { // the governance address is allowed to modify the authorized caller list for this contract pub governance_address: String, diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index 90c4d0919..142cf5d1a 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -266,7 +266,7 @@ mod tests { contract_address.clone(), &ExecuteMsg::RecordParticipation { chain_name: chain_name.clone(), - event_id: "some event".to_string().try_into().unwrap(), + event_id: "some event".try_into().unwrap(), verifier_address: verifier.to_string(), }, &[], @@ -278,7 +278,7 @@ mod tests { contract_address.clone(), &ExecuteMsg::RecordParticipation { chain_name: chain_name.clone(), - event_id: "some other event".to_string().try_into().unwrap(), + event_id: "some other event".try_into().unwrap(), verifier_address: verifier.to_string(), }, &[], diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index 383fb026f..dcffd963f 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -372,7 +372,7 @@ mod test { for (i, verifiers) in verifiers.iter().enumerate() { record_participation( mock_deps.as_mut().storage, - "some event".to_string().try_into().unwrap(), + "some event".try_into().unwrap(), verifiers.clone(), pool_id.clone(), height_at_epoch_end + i as u64, diff --git a/contracts/router/src/contract/query.rs b/contracts/router/src/contract/query.rs index 8c2833d45..28a3f70aa 100644 --- a/contracts/router/src/contract/query.rs +++ b/contracts/router/src/contract/query.rs @@ -48,7 +48,7 @@ mod test { #[test] fn should_get_chain_info() { let mut deps = mock_dependencies(); - let chain_name: ChainName = "Ethereum".to_string().try_into().unwrap(); + let chain_name: ChainName = "Ethereum".try_into().unwrap(); let chain_info = ChainEndpoint { name: chain_name.clone(), gateway: Gateway { @@ -69,7 +69,7 @@ mod test { #[test] fn get_non_existent_chain_info() { let deps = mock_dependencies(); - let chain_name: ChainName = "Ethereum".to_string().try_into().unwrap(); + let chain_name: ChainName = "Ethereum".try_into().unwrap(); let result = get_chain_info(deps.as_ref().storage, chain_name); assert!(result.is_err()); assert_eq!(result.unwrap_err().current_context(), &Error::ChainNotFound); diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index 882c2e1c6..d4f031a56 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -42,6 +42,7 @@ cw-storage-plus = { workspace = true } cw2 = { workspace = true } error-stack = { workspace = true } itertools = { workspace = true } +msgs-derive = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } rewards = { workspace = true, features = ["library"] } diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index a36b3cc67..e2a9c3538 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -219,10 +219,10 @@ mod test { .unwrap() .try_into() .unwrap(), - block_expiry: 100, + block_expiry: 100.try_into().unwrap(), confirmation_height: 10, source_chain: "source-chain".parse().unwrap(), - rewards_address: "rewards".to_string(), + rewards_address: "rewards".try_into().unwrap(), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }; diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 19450d871..135a79854 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::FnExt; +use axelar_wasm_std::{permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -6,9 +6,13 @@ use cosmwasm_std::{ StdResult, }; +use crate::contract::migrations::v0_5_0; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{Config, CONFIG}; -use crate::{execute, query}; + +mod execute; +mod migrations; +mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -22,8 +26,10 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + permission_control::set_governance(deps.storage, &governance)?; + let config = Config { - governance: deps.api.addr_validate(&msg.governance_address)?, service_name: msg.service_name, service_registry_contract: deps.api.addr_validate(&msg.service_registry_address)?, source_gateway_address: msg.source_gateway_address, @@ -47,7 +53,7 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { + match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::VerifyMessages { messages } => execute::verify_messages(deps, env, messages), ExecuteMsg::Vote { poll_id, votes } => execute::vote(deps, env, info, poll_id, votes), ExecuteMsg::EndPoll { poll_id } => execute::end_poll(deps, env, poll_id), @@ -57,10 +63,7 @@ pub fn execute( } => execute::verify_verifier_set(deps, env, &message_id, new_verifier_set), ExecuteMsg::UpdateVotingThreshold { new_voting_threshold, - } => { - execute::require_governance(&deps, info.sender)?; - execute::update_voting_threshold(deps, new_voting_threshold) - } + } => execute::update_voting_threshold(deps, new_voting_threshold), }? .then(Ok) } @@ -88,9 +91,7 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - // any version checks should be done before here - - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + v0_5_0::migrate(deps.storage)?; Ok(Response::default()) } @@ -131,10 +132,6 @@ mod test { "source-chain".parse().unwrap() } - fn governance() -> Addr { - Addr::unchecked(GOVERNANCE) - } - fn initial_voting_threshold() -> MajorityThreshold { Threshold::try_from((2, 3)).unwrap().try_into().unwrap() } @@ -167,19 +164,24 @@ mod test { ) -> OwnedDeps { let mut deps = mock_dependencies(); - let config = Config { - governance: governance(), - service_name: SERVICE_NAME.parse().unwrap(), - service_registry_contract: Addr::unchecked(SERVICE_REGISTRY_ADDRESS), - source_gateway_address: "source_gateway_address".parse().unwrap(), - voting_threshold: initial_voting_threshold(), - block_expiry: POLL_BLOCK_EXPIRY, - confirmation_height: 100, - source_chain: source_chain(), - rewards_contract: Addr::unchecked(REWARDS_ADDRESS), - msg_id_format: msg_id_format.clone(), - }; - CONFIG.save(deps.as_mut().storage, &config).unwrap(); + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: GOVERNANCE.parse().unwrap(), + service_registry_address: SERVICE_REGISTRY_ADDRESS.parse().unwrap(), + service_name: SERVICE_NAME.parse().unwrap(), + source_gateway_address: "source_gateway_address".parse().unwrap(), + voting_threshold: initial_voting_threshold(), + block_expiry: POLL_BLOCK_EXPIRY.try_into().unwrap(), + confirmation_height: 100, + source_chain: source_chain(), + rewards_address: REWARDS_ADDRESS.parse().unwrap(), + msg_id_format: msg_id_format.clone(), + }, + ) + .unwrap(); deps.querier.update_wasm(move |wq| match wq { WasmQuery::Smart { contract_addr, .. } if contract_addr == SERVICE_REGISTRY_ADDRESS => { @@ -257,19 +259,6 @@ mod test { .collect() } - #[test] - fn migrate_sets_contract_version() { - let msg_id_format = MessageIdFormat::HexTxHashAndEventIndex; - let verifiers = verifiers(2); - let mut deps = setup(verifiers.clone(), &msg_id_format); - - migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); - - let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, "voting-verifier"); - assert_eq!(contract_version.version, CONTRACT_VERSION); - } - #[test] fn should_fail_if_messages_are_not_from_same_source() { let msg_id_format = MessageIdFormat::HexTxHashAndEventIndex; diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/contract/execute.rs similarity index 83% rename from contracts/voting-verifier/src/execute.rs rename to contracts/voting-verifier/src/contract/execute.rs index a8d50ce33..e5a6cc991 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use axelar_wasm_std::voting::{PollId, PollResults, Vote, WeightedPoll}; use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ - to_json_binary, Addr, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, + to_json_binary, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, }; use itertools::Itertools; @@ -12,26 +12,16 @@ use router_api::{ChainName, Message}; use service_registry::msg::QueryMsg; use service_registry::state::WeightedVerifier; +use crate::contract::query::{message_status, verifier_set_status}; use crate::error::ContractError; use crate::events::{ PollEnded, PollMetadata, PollStarted, QuorumReached, TxEventConfirmation, VerifierSetConfirmation, Voted, }; -use crate::query::{message_status, verifier_set_status}; use crate::state::{ self, poll_messages, poll_verifier_sets, Poll, PollContent, CONFIG, POLLS, POLL_ID, VOTES, }; -// TODO: this type of function exists in many contracts. Would be better to implement this -// in one place, and then just include it -pub fn require_governance(deps: &DepsMut, sender: Addr) -> Result<(), ContractError> { - let config = CONFIG.load(deps.storage)?; - if config.governance != sender { - return Err(ContractError::Unauthorized); - } - Ok(()) -} - pub fn update_voting_threshold( deps: DepsMut, new_voting_threshold: MajorityThreshold, @@ -57,7 +47,7 @@ pub fn verify_verifier_set( let config = CONFIG.load(deps.storage)?; let snapshot = take_snapshot(deps.as_ref(), &config.source_chain)?; let participants = snapshot.get_participants(); - let expires_at = calculate_expiration(env.block.height, config.block_expiry)?; + let expires_at = calculate_expiration(env.block.height, config.block_expiry.into())?; let poll_id = create_verifier_set_poll(deps.storage, expires_at, snapshot)?; @@ -133,7 +123,7 @@ pub fn verify_messages( let snapshot = take_snapshot(deps.as_ref(), &source_chain)?; let participants = snapshot.get_participants(); - let expires_at = calculate_expiration(env.block.height, config.block_expiry)?; + let expires_at = calculate_expiration(env.block.height, config.block_expiry.into())?; let id = create_messages_poll(deps.storage, expires_at, snapshot, msgs_to_verify.len())?; @@ -376,52 +366,3 @@ fn calculate_expiration(block_height: u64, block_expiry: u64) -> Result Config { - Config { - governance, - service_registry_contract: Addr::unchecked("doesn't matter"), - service_name: "validators".to_string().try_into().unwrap(), - source_gateway_address: "0x89e51fA8CA5D66cd220bAed62ED01e8951aa7c40" - .to_string() - .try_into() - .unwrap(), - voting_threshold, - source_chain: "ethereum".to_string().try_into().unwrap(), - block_expiry: 10, - confirmation_height: 2, - rewards_contract: Addr::unchecked("rewards"), - msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, - } - } - - #[test] - fn require_governance_should_reject_non_governance() { - let mut deps = mock_dependencies(); - let governance = Addr::unchecked("governance"); - CONFIG - .save( - deps.as_mut().storage, - &mock_config( - governance.clone(), - Threshold::try_from((2, 3)).unwrap().try_into().unwrap(), - ), - ) - .unwrap(); - - let res = require_governance(&deps.as_mut(), Addr::unchecked("random")); - assert!(res.is_err()); - - let res = require_governance(&deps.as_mut(), governance); - assert!(res.is_ok()); - } -} diff --git a/contracts/voting-verifier/src/contract/migrations/mod.rs b/contracts/voting-verifier/src/contract/migrations/mod.rs new file mode 100644 index 000000000..504cbdb5c --- /dev/null +++ b/contracts/voting-verifier/src/contract/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v0_5_0; diff --git a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs new file mode 100644 index 000000000..1cee2ac84 --- /dev/null +++ b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs @@ -0,0 +1,242 @@ +#![allow(deprecated)] + +use axelar_wasm_std::error::ContractError; +use axelar_wasm_std::msg_id::MessageIdFormat; +use axelar_wasm_std::{nonempty, permission_control, MajorityThreshold}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Attribute, StdResult, Storage}; +use cw_storage_plus::Item; +use router_api::ChainName; + +use crate::contract::{CONTRACT_NAME, CONTRACT_VERSION}; +use crate::state; + +const BASE_VERSION: &str = "0.5.0"; + +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + let config = CONFIG.load(storage)?; + migrate_permission_control(storage, &config.governance)?; + migrate_config(storage, config)?; + + cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(()) +} + +fn migrate_config(storage: &mut dyn Storage, config: Config) -> StdResult<()> { + CONFIG.remove(storage); + + let config = state::Config { + service_registry_contract: config.service_registry_contract, + service_name: config.service_name, + source_chain: config.source_chain, + rewards_contract: config.rewards_contract, + block_expiry: config + .block_expiry + .try_into() + .unwrap_or(1.try_into().expect("1 is not zero")), + confirmation_height: config.confirmation_height, + msg_id_format: config.msg_id_format, + source_gateway_address: config.source_gateway_address, + voting_threshold: config.voting_threshold, + }; + + state::CONFIG.save(storage, &config) +} + +fn migrate_permission_control(storage: &mut dyn Storage, governance: &Addr) -> StdResult<()> { + permission_control::set_governance(storage, governance) +} + +#[cw_serde] +#[deprecated(since = "0.5.0", note = "only used during migration")] +pub struct Config { + pub governance: Addr, + pub service_registry_contract: Addr, + pub service_name: nonempty::String, + pub source_gateway_address: nonempty::String, + pub voting_threshold: MajorityThreshold, + pub block_expiry: u64, // number of blocks after which a poll expires + pub confirmation_height: u64, + pub source_chain: ChainName, + pub rewards_contract: Addr, + pub msg_id_format: MessageIdFormat, +} +impl From for Vec { + fn from(other: Config) -> Self { + vec![ + ("service_name", other.service_name.to_string()), + ( + "service_registry_contract", + other.service_registry_contract.to_string(), + ), + ( + "source_gateway_address", + other.source_gateway_address.to_string(), + ), + ( + "voting_threshold", + serde_json::to_string(&other.voting_threshold) + .expect("failed to serialize voting_threshold"), + ), + ("block_expiry", other.block_expiry.to_string()), + ("confirmation_height", other.confirmation_height.to_string()), + ] + .into_iter() + .map(Attribute::from) + .collect() + } +} +#[deprecated(since = "0.5.0", note = "only used during migration")] +pub const CONFIG: Item = Item::new("config"); + +#[cfg(test)] +mod tests { + use axelar_wasm_std::msg_id::MessageIdFormat; + use axelar_wasm_std::permission_control::Permission; + use axelar_wasm_std::{nonempty, permission_control, MajorityThreshold, Threshold}; + use cosmwasm_schema::cw_serde; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, Attribute, DepsMut, Empty, Env, Event, MessageInfo, Response}; + use router_api::ChainName; + + use crate::contract::migrations::v0_5_0; + use crate::contract::{migrate, CONTRACT_NAME, CONTRACT_VERSION}; + use crate::state; + + const GOVERNANCE: &str = "governance"; + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_5_0::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_5_0::BASE_VERSION) + .unwrap(); + + assert!(v0_5_0::migrate(deps.as_mut().storage).is_ok()); + } + + #[test] + fn migrate_sets_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); + + let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); + assert_eq!(contract_version.contract, CONTRACT_NAME); + assert_eq!(contract_version.version, CONTRACT_VERSION); + } + + #[test] + fn config_gets_migrated() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + assert!(v0_5_0::CONFIG.load(deps.as_mut().storage).is_ok()); + assert!(state::CONFIG.load(deps.as_mut().storage).is_err()); + + assert!(v0_5_0::migrate(deps.as_mut().storage).is_ok()); + + assert!(v0_5_0::CONFIG.load(deps.as_mut().storage).is_err()); + assert!(state::CONFIG.load(deps.as_mut().storage).is_ok()); + } + + #[test] + fn permission_control_gets_migrated() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + assert!(v0_5_0::migrate(deps.as_mut().storage).is_ok()); + + assert!(permission_control::sender_role( + deps.as_mut().storage, + &Addr::unchecked(GOVERNANCE) + ) + .unwrap() + .contains(Permission::Governance)); + } + + fn instantiate_contract(deps: DepsMut) { + instantiate( + deps, + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: GOVERNANCE.parse().unwrap(), + service_registry_address: "service_registry".parse().unwrap(), + service_name: "service".parse().unwrap(), + source_gateway_address: "source_gateway".parse().unwrap(), + voting_threshold: Threshold::try_from((2u64, 3u64)) + .and_then(MajorityThreshold::try_from) + .unwrap(), + block_expiry: 1, + confirmation_height: 1, + source_chain: "source-chain".parse().unwrap(), + rewards_address: "rewards".to_string(), + msg_id_format: MessageIdFormat::HexTxHashAndEventIndex, + }, + ) + .unwrap(); + } + + #[deprecated(since = "0.5.0", note = "only used to test the migration")] + fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_5_0::BASE_VERSION)?; + + let config = v0_5_0::Config { + governance: deps.api.addr_validate(&msg.governance_address)?, + service_name: msg.service_name, + service_registry_contract: deps.api.addr_validate(&msg.service_registry_address)?, + source_gateway_address: msg.source_gateway_address, + voting_threshold: msg.voting_threshold, + block_expiry: msg.block_expiry, + confirmation_height: msg.confirmation_height, + source_chain: msg.source_chain, + rewards_contract: deps.api.addr_validate(&msg.rewards_address)?, + msg_id_format: msg.msg_id_format, + }; + v0_5_0::CONFIG.save(deps.storage, &config)?; + + Ok(Response::new() + .add_event(Event::new("instantiated").add_attributes(>::from(config)))) + } + + #[cw_serde] + #[deprecated(since = "0.5.0", note = "only used to test the migration")] + pub struct InstantiateMsg { + /// Address that can call all messages of unrestricted governance permission level, like UpdateVotingThreshold. + /// It can execute messages that bypasses verification checks to rescue the contract if it got into an otherwise unrecoverable state due to external forces. + /// On mainnet it should match the address of the Cosmos governance module. + pub governance_address: nonempty::String, + /// Service registry contract address on axelar. + pub service_registry_address: nonempty::String, + /// Name of service in the service registry for which verifiers are registered. + pub service_name: nonempty::String, + /// Axelar's gateway contract address on the source chain + pub source_gateway_address: nonempty::String, + /// Threshold of weighted votes required for voting to be considered complete for a particular message + pub voting_threshold: MajorityThreshold, + /// The number of blocks after which a poll expires + pub block_expiry: u64, + /// The number of blocks to wait for on the source chain before considering a transaction final + pub confirmation_height: u64, + /// Name of the source chain + pub source_chain: ChainName, + /// Rewards contract address on axelar. + pub rewards_address: String, + /// Format that incoming messages should use for the id field of CrossChainId + pub msg_id_format: MessageIdFormat, + } +} diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/contract/query.rs similarity index 100% rename from contracts/voting-verifier/src/query.rs rename to contracts/voting-verifier/src/contract/query.rs diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 956eaeb83..7755b2c51 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -17,23 +17,39 @@ use crate::state::Config; impl From for Vec { fn from(other: Config) -> Self { + // destructuring the Config struct so changes to the fields don't go unnoticed + let Config { + service_name, + service_registry_contract, + source_gateway_address, + voting_threshold, + block_expiry, + confirmation_height, + source_chain, + rewards_contract, + msg_id_format, + } = other; + vec![ - ("service_name", other.service_name.to_string()), + ("service_name", service_name.to_string()), ( "service_registry_contract", - other.service_registry_contract.to_string(), - ), - ( - "source_gateway_address", - other.source_gateway_address.to_string(), + service_registry_contract.to_string(), ), + ("source_gateway_address", source_gateway_address.to_string()), ( "voting_threshold", - serde_json::to_string(&other.voting_threshold) + serde_json::to_string(&voting_threshold) .expect("failed to serialize voting_threshold"), ), - ("block_expiry", other.block_expiry.to_string()), - ("confirmation_height", other.confirmation_height.to_string()), + ("block_expiry", block_expiry.to_string()), + ("confirmation_height", confirmation_height.to_string()), + ("source_chain", source_chain.to_string()), + ("rewards_contract", rewards_contract.to_string()), + ( + "msg_id_format", + serde_json::to_string(&msg_id_format).expect("failed to serialize msg_id_format"), + ), ] .into_iter() .map(Attribute::from) diff --git a/contracts/voting-verifier/src/lib.rs b/contracts/voting-verifier/src/lib.rs index 20ce222dd..f2ab17a66 100644 --- a/contracts/voting-verifier/src/lib.rs +++ b/contracts/voting-verifier/src/lib.rs @@ -4,8 +4,5 @@ pub use client::Client; pub mod contract; pub mod error; pub mod events; -pub mod execute; -mod migrations; pub mod msg; -pub mod query; pub mod state; diff --git a/contracts/voting-verifier/src/migrations/mod.rs b/contracts/voting-verifier/src/migrations/mod.rs deleted file mode 100644 index 8b1378917..000000000 --- a/contracts/voting-verifier/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index 55d287664..8aa480e37 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -2,6 +2,7 @@ use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::voting::{PollId, PollStatus, Vote, WeightedPoll}; use axelar_wasm_std::{nonempty, MajorityThreshold, VerificationStatus}; use cosmwasm_schema::{cw_serde, QueryResponses}; +use msgs_derive::EnsurePermissions; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; @@ -20,44 +21,43 @@ pub struct InstantiateMsg { /// Threshold of weighted votes required for voting to be considered complete for a particular message pub voting_threshold: MajorityThreshold, /// The number of blocks after which a poll expires - pub block_expiry: u64, + pub block_expiry: nonempty::Uint64, /// The number of blocks to wait for on the source chain before considering a transaction final pub confirmation_height: u64, /// Name of the source chain pub source_chain: ChainName, /// Rewards contract address on axelar. - pub rewards_address: String, + pub rewards_address: nonempty::String, /// Format that incoming messages should use for the id field of CrossChainId pub msg_id_format: MessageIdFormat, } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { // Computes the results of a poll // For all verified messages, calls MessagesVerified on the verifier - EndPoll { - poll_id: PollId, - }, + #[permission(Any)] + EndPoll { poll_id: PollId }, // Casts votes for specified poll - Vote { - poll_id: PollId, - votes: Vec, - }, + #[permission(Any)] + Vote { poll_id: PollId, votes: Vec }, // returns a vector of true/false values, indicating current verification status for each message // starts a poll for any not yet verified messages - VerifyMessages { - messages: Vec, - }, + #[permission(Any)] + VerifyMessages { messages: Vec }, // Starts a poll to confirm a verifier set update on the external gateway + #[permission(Any)] VerifyVerifierSet { message_id: nonempty::String, new_verifier_set: VerifierSet, }, // Update the threshold used for new polls. Callable only by governance + #[permission(Governance)] UpdateVotingThreshold { new_voting_threshold: MajorityThreshold, }, diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index 567ea197a..1d687d5ee 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -12,12 +12,11 @@ use crate::error::ContractError; #[cw_serde] pub struct Config { - pub governance: Addr, pub service_registry_contract: Addr, pub service_name: nonempty::String, pub source_gateway_address: nonempty::String, pub voting_threshold: MajorityThreshold, - pub block_expiry: u64, // number of blocks after which a poll expires + pub block_expiry: nonempty::Uint64, // number of blocks after which a poll expires pub confirmation_height: u64, pub source_chain: ChainName, pub rewards_contract: Addr, diff --git a/integration-tests/src/voting_verifier_contract.rs b/integration-tests/src/voting_verifier_contract.rs index f4936e90d..b3342355d 100644 --- a/integration-tests/src/voting_verifier_contract.rs +++ b/integration-tests/src/voting_verifier_contract.rs @@ -41,10 +41,15 @@ impl VotingVerifierContract { service_name: protocol.service_name.clone(), source_gateway_address, voting_threshold, - block_expiry: 10, + block_expiry: 10.try_into().unwrap(), confirmation_height: 5, source_chain, - rewards_address: protocol.rewards.contract_addr.to_string(), + rewards_address: protocol + .rewards + .contract_addr + .to_string() + .try_into() + .unwrap(), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, }, &[], diff --git a/integration-tests/tests/bond_unbond.rs b/integration-tests/tests/bond_unbond.rs index 4ee8da440..b3f27638d 100644 --- a/integration-tests/tests/bond_unbond.rs +++ b/integration-tests/tests/bond_unbond.rs @@ -7,8 +7,8 @@ pub mod test_utils; #[test] fn claim_stake_after_rotation_success() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { @@ -78,8 +78,8 @@ fn claim_stake_after_rotation_success() { #[test] fn claim_stake_when_in_all_active_verifier_sets_fails() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { @@ -118,8 +118,8 @@ fn claim_stake_when_in_all_active_verifier_sets_fails() { #[test] fn claim_stake_when_in_some_active_verifier_sets_fails() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { @@ -162,8 +162,8 @@ fn claim_stake_when_in_some_active_verifier_sets_fails() { #[test] fn claim_stake_after_deregistering_before_rotation_fails() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { @@ -212,8 +212,8 @@ fn claim_stake_after_deregistering_before_rotation_fails() { #[test] fn claim_stake_when_jailed_fails() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { @@ -267,8 +267,8 @@ fn claim_stake_when_jailed_fails() { #[test] fn claim_stake_when_in_next_verifier_sets_fails() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index c8c1729fe..fee9f9194 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -648,7 +648,7 @@ pub fn setup_chain( ) -> Chain { let voting_verifier = VotingVerifierContract::instantiate_contract( protocol, - "doesn't matter".to_string().try_into().unwrap(), + "doesn't matter".try_into().unwrap(), Threshold::try_from((3, 4)).unwrap().try_into().unwrap(), chain_name.clone(), ); @@ -827,10 +827,10 @@ pub struct TestCase { // Creates an instance of Axelar Amplifier with an initial verifier set registered, and returns a TestCase instance. pub fn setup_test_case() -> TestCase { - let mut protocol = setup_protocol("validators".to_string().try_into().unwrap()); + let mut protocol = setup_protocol("validators".try_into().unwrap()); let chains = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let verifiers = create_new_verifiers_vec( chains.clone(), diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index 7746d571a..190f71981 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -14,8 +14,8 @@ pub mod test_utils; #[test] fn verifier_set_can_be_initialized_and_then_manually_updated() { let chains: Vec = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { @@ -111,8 +111,8 @@ fn verifier_set_can_be_initialized_and_then_manually_updated() { #[test] fn verifier_set_cannot_be_updated_again_while_pending_verifier_is_not_yet_confirmed() { let chains = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { mut protocol, @@ -231,8 +231,8 @@ fn verifier_set_cannot_be_updated_again_while_pending_verifier_is_not_yet_confir #[test] fn verifier_set_update_can_be_resigned() { let chains = vec![ - "Ethereum".to_string().try_into().unwrap(), - "Polygon".to_string().try_into().unwrap(), + "Ethereum".try_into().unwrap(), + "Polygon".try_into().unwrap(), ]; let test_utils::TestCase { mut protocol, @@ -325,7 +325,7 @@ fn verifier_set_update_can_be_resigned() { #[test] fn governance_should_confirm_new_verifier_set_without_verification() { - let chains: Vec = vec!["Ethereum".to_string().try_into().unwrap()]; + let chains: Vec = vec!["Ethereum".try_into().unwrap()]; let test_utils::TestCase { mut protocol, chain1: ethereum, From b93c3db85b2a2ef6fa8be3e7df3b37fbb5308219 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 24 Jul 2024 12:02:10 -0400 Subject: [PATCH 097/168] feat(service-registry): add permission control to the service-registry (#535) --- Cargo.lock | 1 + contracts/service-registry/Cargo.toml | 1 + contracts/service-registry/src/contract.rs | 127 +++++++++++------- .../service-registry/src/contract/execute.rs | 16 --- .../src/contract/migrations/mod.rs | 1 + .../src/contract/migrations/v0_4_1.rs | 117 ++++++++++++++++ contracts/service-registry/src/lib.rs | 2 - .../service-registry/src/migrations/mod.rs | 1 - .../service-registry/src/migrations/v_0_4.rs | 116 ---------------- contracts/service-registry/src/msg.rs | 41 +++--- packages/axelar-wasm-std/src/error.rs | 2 + 11 files changed, 225 insertions(+), 200 deletions(-) create mode 100644 contracts/service-registry/src/contract/migrations/mod.rs create mode 100644 contracts/service-registry/src/contract/migrations/v0_4_1.rs delete mode 100644 contracts/service-registry/src/migrations/mod.rs delete mode 100644 contracts/service-registry/src/migrations/v_0_4.rs diff --git a/Cargo.lock b/Cargo.lock index d9076e38d..d320b4719 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6877,6 +6877,7 @@ dependencies = [ "cw2 1.1.2", "error-stack", "integration-tests", + "msgs-derive", "report", "router-api", "schemars", diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index 91e6ccfdd..2437847de 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -41,6 +41,7 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } error-stack = { workspace = true } +msgs-derive = { workspace = true } report = { workspace = true } router-api = { workspace = true } schemars = "0.8.10" diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index dd02fc8c1..98f4bf970 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,17 +1,18 @@ -use axelar_wasm_std::FnExt; +use axelar_wasm_std::{permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Order, - QueryRequest, Response, Uint128, WasmQuery, + to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, Order, + QueryRequest, Response, Storage, Uint128, WasmQuery, }; +use error_stack::{bail, Report, ResultExt}; use crate::error::ContractError; -use crate::migrations; -use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use crate::state::{AuthorizationState, BondingState, Config, Service, Verifier, CONFIG, SERVICES}; +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::{AuthorizationState, BondingState, Service, Verifier, SERVICES, VERIFIERS}; mod execute; +mod migrations; mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); @@ -26,12 +27,9 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - CONFIG.save( - deps.storage, - &Config { - governance: deps.api.addr_validate(&msg.governance_account)?, - }, - )?; + let governance = deps.api.addr_validate(&msg.governance_account)?; + permission_control::set_governance(deps.storage, &governance)?; + Ok(Response::default()) } @@ -42,7 +40,7 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - match msg { + match msg.ensure_permissions(deps.storage, &info.sender, match_verifier(&info.sender))? { ExecuteMsg::RegisterService { service_name, coordinator_contract, @@ -52,25 +50,21 @@ pub fn execute( bond_denom, unbonding_period_days, description, - } => { - execute::require_governance(&deps, info)?; - execute::register_service( - deps, - service_name, - coordinator_contract, - min_num_verifiers, - max_num_verifiers, - min_verifier_bond, - bond_denom, - unbonding_period_days, - description, - ) - } + } => execute::register_service( + deps, + service_name, + coordinator_contract, + min_num_verifiers, + max_num_verifiers, + min_verifier_bond, + bond_denom, + unbonding_period_days, + description, + ), ExecuteMsg::AuthorizeVerifiers { verifiers, service_name, } => { - execute::require_governance(&deps, info)?; let verifiers = verifiers .into_iter() .map(|veriier| deps.api.addr_validate(&veriier)) @@ -86,7 +80,6 @@ pub fn execute( verifiers, service_name, } => { - execute::require_governance(&deps, info)?; let verifiers = verifiers .into_iter() .map(|verifier| deps.api.addr_validate(&verifier)) @@ -102,7 +95,6 @@ pub fn execute( verifiers, service_name, } => { - execute::require_governance(&deps, info)?; let verifiers = verifiers .into_iter() .map(|verifier| deps.api.addr_validate(&verifier)) @@ -135,6 +127,23 @@ pub fn execute( .then(Ok) } +fn match_verifier( + sender: &Addr, +) -> impl FnOnce(&dyn Storage, &ExecuteMsg) -> Result> + '_ +{ + |storage: &dyn Storage, msg: &ExecuteMsg| { + let service_name = match msg { + ExecuteMsg::RegisterChainSupport { service_name, .. } + | ExecuteMsg::DeregisterChainSupport { service_name, .. } => service_name, + _ => bail!(permission_control::Error::WrongVariant), + }; + VERIFIERS + .load(storage, (service_name, sender)) + .map(|verifier| verifier.address) + .change_context(permission_control::Error::Unauthorized) + } +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { @@ -162,17 +171,20 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result Result { + migrations::v0_4_1::migrate(deps.storage)?; + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - migrations::v_0_4::migrate_services_coordinator_contract(deps.storage, msg.coordinator_contract) - .map_err(axelar_wasm_std::error::ContractError::from) + + Ok(Response::default()) } #[cfg(test)] mod test { use std::str::FromStr; + use axelar_wasm_std::error::err_contains; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; @@ -211,13 +223,6 @@ mod test { deps } - pub fn assert_contract_err_strings_equal( - actual: impl Into, - expected: impl Into, - ) { - assert_eq!(actual.into().to_string(), expected.into().to_string()); - } - #[test] fn register_service() { let mut deps = setup(); @@ -255,7 +260,11 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::Unauthorized); + assert!(err_contains!( + err.report, + permission_control::Error, + permission_control::Error::PermissionDenied { .. } + )); } #[test] @@ -301,7 +310,11 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::Unauthorized); + assert!(err_contains!( + err.report, + permission_control::Error, + permission_control::Error::PermissionDenied { .. } + )); } #[test] @@ -1160,7 +1173,11 @@ mod test { ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::VerifierNotFound); + assert!(err_contains!( + err.report, + permission_control::Error, + permission_control::Error::WhitelistNotFound { .. } + )); let verifiers: Vec = from_json( query( @@ -1196,7 +1213,11 @@ mod test { ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::ServiceNotFound); + assert!(err_contains!( + err.report, + permission_control::Error, + permission_control::Error::WhitelistNotFound { .. } + )); } #[test] @@ -1319,7 +1340,11 @@ mod test { ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::WrongDenom); + assert!(err_contains!( + err.report, + ContractError, + ContractError::WrongDenom + )); } #[test] @@ -1948,7 +1973,11 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::VerifierJailed); + assert!(err_contains!( + err.report, + ContractError, + ContractError::VerifierJailed + )); // given a verifier passed unbonding period let verifier2 = Addr::unchecked("verifier-2"); @@ -2030,6 +2059,10 @@ mod test { }, ) .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::VerifierJailed); + assert!(err_contains!( + err.report, + ContractError, + ContractError::VerifierJailed + )); } } diff --git a/contracts/service-registry/src/contract/execute.rs b/contracts/service-registry/src/contract/execute.rs index 9ed49df12..65ee8b542 100644 --- a/contracts/service-registry/src/contract/execute.rs +++ b/contracts/service-registry/src/contract/execute.rs @@ -3,14 +3,6 @@ use router_api::ChainName; use super::*; use crate::state::{self, AuthorizationState, Verifier, VERIFIERS}; -pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { - let config = CONFIG.load(deps.storage)?; - if config.governance != info.sender { - return Err(ContractError::Unauthorized); - } - Ok(()) -} - #[allow(clippy::too_many_arguments)] pub fn register_service( deps: DepsMut, @@ -131,10 +123,6 @@ pub fn register_chains_support( .may_load(deps.storage, &service_name)? .ok_or(ContractError::ServiceNotFound)?; - VERIFIERS - .may_load(deps.storage, (&service_name, &info.sender))? - .ok_or(ContractError::VerifierNotFound)?; - state::register_chains_support( deps.storage, service_name.clone(), @@ -155,10 +143,6 @@ pub fn deregister_chains_support( .may_load(deps.storage, &service_name)? .ok_or(ContractError::ServiceNotFound)?; - VERIFIERS - .may_load(deps.storage, (&service_name, &info.sender))? - .ok_or(ContractError::VerifierNotFound)?; - state::deregister_chains_support(deps.storage, service_name.clone(), chains, info.sender)?; Ok(Response::new()) diff --git a/contracts/service-registry/src/contract/migrations/mod.rs b/contracts/service-registry/src/contract/migrations/mod.rs new file mode 100644 index 000000000..080e953e7 --- /dev/null +++ b/contracts/service-registry/src/contract/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v0_4_1; diff --git a/contracts/service-registry/src/contract/migrations/v0_4_1.rs b/contracts/service-registry/src/contract/migrations/v0_4_1.rs new file mode 100644 index 000000000..b06e781c8 --- /dev/null +++ b/contracts/service-registry/src/contract/migrations/v0_4_1.rs @@ -0,0 +1,117 @@ +#![allow(deprecated)] +use axelar_wasm_std::error::ContractError; +use axelar_wasm_std::permission_control; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, StdResult, Storage}; +use cw_storage_plus::Item; + +use crate::contract::CONTRACT_NAME; + +const BASE_VERSION: &str = "0.4.1"; +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + let config = CONFIG.load(storage)?; + delete_config(storage); + migrate_permission_control(storage, config)?; + + Ok(()) +} + +fn migrate_permission_control(storage: &mut dyn Storage, config: Config) -> StdResult<()> { + permission_control::set_governance(storage, &config.governance) +} + +fn delete_config(storage: &mut dyn Storage) { + CONFIG.remove(storage) +} + +#[cw_serde] +#[deprecated(since = "0.4.1", note = "Only used during migrations")] +pub struct Config { + pub governance: Addr, +} + +#[deprecated(since = "0.4.1", note = "Only used during migrations")] +pub const CONFIG: Item = Item::new("config"); + +#[cfg(test)] +mod tests { + use axelar_wasm_std::permission_control; + use axelar_wasm_std::permission_control::Permission; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; + + use crate::contract::migrations::v0_4_1; + use crate::contract::CONTRACT_NAME; + use crate::msg::InstantiateMsg; + + const GOVERNANCE: &str = "governance"; + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_4_1::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_4_1::BASE_VERSION) + .unwrap(); + + assert!(v0_4_1::migrate(deps.as_mut().storage).is_ok()); + } + #[test] + fn migrate_to_permission_control() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + assert!(v0_4_1::migrate(deps.as_mut().storage).is_ok()); + + assert!( + permission_control::sender_role(&deps.storage, &Addr::unchecked(GOVERNANCE)) + .unwrap() + .contains(Permission::Governance) + ); + } + + #[test] + fn migrate_deletes_config() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + assert!(v0_4_1::migrate(deps.as_mut().storage).is_ok()); + + assert!(v0_4_1::CONFIG.load(&deps.storage).is_err()) + } + + fn instantiate_contract(deps: DepsMut) { + instantiate( + deps, + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_account: GOVERNANCE.to_string(), + }, + ) + .unwrap(); + } + #[deprecated(since = "0.4.1", note = "Only used to test the migration")] + fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_4_1::BASE_VERSION)?; + + v0_4_1::CONFIG.save( + deps.storage, + &v0_4_1::Config { + governance: deps.api.addr_validate(&msg.governance_account)?, + }, + )?; + Ok(Response::default()) + } +} diff --git a/contracts/service-registry/src/lib.rs b/contracts/service-registry/src/lib.rs index fad5e4ff9..98208b782 100644 --- a/contracts/service-registry/src/lib.rs +++ b/contracts/service-registry/src/lib.rs @@ -4,6 +4,4 @@ pub mod helpers; pub mod msg; pub mod state; -mod migrations; - pub use crate::error::ContractError; diff --git a/contracts/service-registry/src/migrations/mod.rs b/contracts/service-registry/src/migrations/mod.rs deleted file mode 100644 index 683e59145..000000000 --- a/contracts/service-registry/src/migrations/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v_0_4; diff --git a/contracts/service-registry/src/migrations/v_0_4.rs b/contracts/service-registry/src/migrations/v_0_4.rs deleted file mode 100644 index 7b4295ea1..000000000 --- a/contracts/service-registry/src/migrations/v_0_4.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! Migrate the `Service` struct and rename `service_contract` field to `coordinator_contract`. - -use cosmwasm_std::{Addr, Order, Response, Storage}; - -use crate::state::{Service, SERVICES}; - -mod v0_3_state { - use cosmwasm_schema::cw_serde; - use cosmwasm_std::{Addr, Uint128}; - use cw_storage_plus::Map; - - #[cw_serde] - pub struct Service { - pub name: String, - pub service_contract: Addr, - pub min_num_verifiers: u16, - pub max_num_verifiers: Option, - pub min_verifier_bond: Uint128, - pub bond_denom: String, - pub unbonding_period_days: u16, - pub description: String, - } - - type ServiceName = str; - pub const SERVICES: Map<&ServiceName, Service> = Map::new("services"); -} - -pub fn migrate_services_coordinator_contract( - store: &mut dyn Storage, - coordinator_contract: Addr, -) -> Result { - v0_3_state::SERVICES - .range(store, None, None, Order::Ascending) - .collect::, _>>()? - .into_iter() - .map(|(service_name, service)| { - let service = Service { - name: service.name, - coordinator_contract: coordinator_contract.clone(), - min_num_verifiers: service.min_num_verifiers, - max_num_verifiers: service.max_num_verifiers, - min_verifier_bond: service.min_verifier_bond, - bond_denom: service.bond_denom, - unbonding_period_days: service.unbonding_period_days, - description: service.description, - }; - SERVICES.save(store, &service_name, &service) - }) - .collect::, _>>()?; - - Ok(Response::default()) -} - -#[cfg(test)] -mod test { - use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::{Addr, Uint128}; - - use super::*; - - #[test] - fn successfully_migrate_services() { - let mut deps = mock_dependencies(); - - let initial_services = vec![ - v0_3_state::Service { - name: "service1".to_string(), - service_contract: Addr::unchecked("service_contract1"), - min_num_verifiers: 5, - max_num_verifiers: Some(10), - min_verifier_bond: Uint128::from(1000u128), - bond_denom: "denom1".to_string(), - unbonding_period_days: 7, - description: "description1".to_string(), - }, - v0_3_state::Service { - name: "service2".to_string(), - service_contract: Addr::unchecked("service_contract2"), - min_num_verifiers: 3, - max_num_verifiers: None, - min_verifier_bond: Uint128::from(2000u128), - bond_denom: "denom2".to_string(), - unbonding_period_days: 14, - description: "description2".to_string(), - }, - ]; - - for service in &initial_services { - v0_3_state::SERVICES - .save(&mut deps.storage, service.name.as_str(), service) - .unwrap(); - } - - let coordinator_contract = Addr::unchecked("coordinator"); - migrate_services_coordinator_contract(&mut deps.storage, coordinator_contract.clone()) - .unwrap(); - - for service in &initial_services { - let migrated_service: Service = - SERVICES.load(&deps.storage, service.name.as_str()).unwrap(); - - let expected_service = Service { - name: service.name.clone(), - coordinator_contract: coordinator_contract.clone(), - min_num_verifiers: service.min_num_verifiers, - max_num_verifiers: service.max_num_verifiers, - min_verifier_bond: service.min_verifier_bond, - bond_denom: service.bond_denom.clone(), - unbonding_period_days: service.unbonding_period_days, - description: service.description.clone(), - }; - - assert_eq!(migrated_service, expected_service); - } - } -} diff --git a/contracts/service-registry/src/msg.rs b/contracts/service-registry/src/msg.rs index 34b3718bd..ca30c421a 100644 --- a/contracts/service-registry/src/msg.rs +++ b/contracts/service-registry/src/msg.rs @@ -1,5 +1,6 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, Uint128}; +use msgs_derive::EnsurePermissions; use router_api::ChainName; #[cw_serde] @@ -8,8 +9,10 @@ pub struct InstantiateMsg { } #[cw_serde] +#[derive(EnsurePermissions)] pub enum ExecuteMsg { - // Can only be called by governance account + /// Can only be called by governance account + #[permission(Governance)] RegisterService { service_name: String, coordinator_contract: Addr, @@ -20,45 +23,47 @@ pub enum ExecuteMsg { unbonding_period_days: u16, // number of days to wait after starting unbonding before allowed to claim stake description: String, }, - // Authorizes verifiers to join a service. Can only be called by governance account. Verifiers must still bond sufficient stake to participate. + /// Authorizes verifiers to join a service. Can only be called by governance account. Verifiers must still bond sufficient stake to participate. + #[permission(Governance)] AuthorizeVerifiers { verifiers: Vec, service_name: String, }, - // Revoke authorization for specified verifiers. Can only be called by governance account. Verifiers bond remains unchanged + /// Revoke authorization for specified verifiers. Can only be called by governance account. Verifiers bond remains unchanged + #[permission(Governance)] UnauthorizeVerifiers { verifiers: Vec, service_name: String, }, - // Jail verifiers. Can only be called by governance account. Jailed verifiers are not allowed to unbond or claim stake. + /// Jail verifiers. Can only be called by governance account. Jailed verifiers are not allowed to unbond or claim stake. + #[permission(Governance)] JailVerifiers { verifiers: Vec, service_name: String, }, - // Register support for the specified chains. Called by the verifier. + /// Register support for the specified chains. Called by the verifier. + #[permission(Specific(verifier))] RegisterChainSupport { service_name: String, chains: Vec, }, - // Deregister support for the specified chains. Called by the verifier. + /// Deregister support for the specified chains. Called by the verifier. + #[permission(Specific(verifier))] DeregisterChainSupport { service_name: String, chains: Vec, }, - // Locks up any funds sent with the message as stake. Called by the verifier. - BondVerifier { - service_name: String, - }, - // Initiates unbonding of staked funds. Called by the verifier. - UnbondVerifier { - service_name: String, - }, - // Claim previously staked funds that have finished unbonding. Called by the verifier. - ClaimStake { - service_name: String, - }, + /// Locks up any funds sent with the message as stake. Marks the sender as a potential verifier that can be authorized. + #[permission(Any)] + BondVerifier { service_name: String }, + /// Initiates unbonding of staked funds for the sender. + #[permission(Any)] + UnbondVerifier { service_name: String }, + /// Claim previously staked funds that have finished unbonding for the sender. + #[permission(Any)] + ClaimStake { service_name: String }, } #[cw_serde] diff --git a/packages/axelar-wasm-std/src/error.rs b/packages/axelar-wasm-std/src/error.rs index 8af69ee3c..0e994e51a 100644 --- a/packages/axelar-wasm-std/src/error.rs +++ b/packages/axelar-wasm-std/src/error.rs @@ -86,3 +86,5 @@ macro_rules! err_contains { } }; } + +pub use err_contains; From febb75b391992154d58f986c96b89e6cdda2d869 Mon Sep 17 00:00:00 2001 From: Sammy Date: Wed, 24 Jul 2024 12:07:57 -0400 Subject: [PATCH 098/168] revert(ampd): revert "integrate ampd queued broadcaster with the axelar batch request (#474)" (#540) --- ampd/build.rs | 8 - ampd/proto/axelar/README.md | 11 - .../axelar/auxiliary/v1beta1/events.proto | 12 - .../axelar/auxiliary/v1beta1/genesis.proto | 11 - .../axelar/auxiliary/v1beta1/service.proto | 20 - ampd/proto/axelar/auxiliary/v1beta1/tx.proto | 30 -- .../axelar/axelarnet/v1beta1/events.proto | 131 ------ .../axelar/axelarnet/v1beta1/genesis.proto | 27 -- .../axelar/axelarnet/v1beta1/params.proto | 33 -- .../axelar/axelarnet/v1beta1/proposal.proto | 29 -- .../axelar/axelarnet/v1beta1/query.proto | 39 -- .../axelar/axelarnet/v1beta1/service.proto | 118 ----- ampd/proto/axelar/axelarnet/v1beta1/tx.proto | 188 -------- .../axelar/axelarnet/v1beta1/types.proto | 62 --- ampd/proto/axelar/evm/v1beta1/events.proto | 340 -------------- ampd/proto/axelar/evm/v1beta1/genesis.proto | 39 -- ampd/proto/axelar/evm/v1beta1/params.proto | 37 -- ampd/proto/axelar/evm/v1beta1/query.proto | 243 ----------- ampd/proto/axelar/evm/v1beta1/service.proto | 208 --------- ampd/proto/axelar/evm/v1beta1/tx.proto | 259 ----------- ampd/proto/axelar/evm/v1beta1/types.proto | 375 ---------------- .../multisig/exported/v1beta1/types.proto | 28 -- .../axelar/multisig/v1beta1/events.proto | 127 ------ .../axelar/multisig/v1beta1/genesis.proto | 20 - .../axelar/multisig/v1beta1/params.proto | 21 - .../proto/axelar/multisig/v1beta1/query.proto | 114 ----- .../axelar/multisig/v1beta1/service.proto | 92 ---- ampd/proto/axelar/multisig/v1beta1/tx.proto | 86 ---- .../proto/axelar/multisig/v1beta1/types.proto | 84 ---- .../axelar/nexus/exported/v1beta1/types.proto | 129 ------ ampd/proto/axelar/nexus/v1beta1/events.proto | 66 --- ampd/proto/axelar/nexus/v1beta1/genesis.proto | 32 -- ampd/proto/axelar/nexus/v1beta1/params.proto | 22 - ampd/proto/axelar/nexus/v1beta1/query.proto | 175 -------- ampd/proto/axelar/nexus/v1beta1/service.proto | 150 ------- ampd/proto/axelar/nexus/v1beta1/tx.proto | 87 ---- ampd/proto/axelar/nexus/v1beta1/types.proto | 65 --- .../permission/exported/v1beta1/types.proto | 24 - .../axelar/permission/v1beta1/genesis.proto | 19 - .../axelar/permission/v1beta1/params.proto | 10 - .../axelar/permission/v1beta1/query.proto | 27 -- .../axelar/permission/v1beta1/service.proto | 54 --- ampd/proto/axelar/permission/v1beta1/tx.proto | 41 -- .../axelar/permission/v1beta1/types.proto | 15 - .../proto/axelar/reward/v1beta1/genesis.proto | 17 - ampd/proto/axelar/reward/v1beta1/params.proto | 20 - ampd/proto/axelar/reward/v1beta1/query.proto | 28 -- .../proto/axelar/reward/v1beta1/service.proto | 42 -- ampd/proto/axelar/reward/v1beta1/tx.proto | 24 - ampd/proto/axelar/reward/v1beta1/types.proto | 33 -- .../snapshot/exported/v1beta1/types.proto | 39 -- .../axelar/snapshot/v1beta1/genesis.proto | 18 - .../axelar/snapshot/v1beta1/params.proto | 11 - .../proto/axelar/snapshot/v1beta1/query.proto | 35 -- .../axelar/snapshot/v1beta1/service.proto | 41 -- ampd/proto/axelar/snapshot/v1beta1/tx.proto | 28 -- .../proto/axelar/snapshot/v1beta1/types.proto | 17 - .../axelar/tss/exported/v1beta1/types.proto | 68 --- .../axelar/tss/tofnd/v1beta1/common.proto | 28 -- .../axelar/tss/tofnd/v1beta1/multisig.proto | 40 -- .../axelar/tss/tofnd/v1beta1/tofnd.proto | 129 ------ ampd/proto/axelar/tss/v1beta1/genesis.proto | 12 - ampd/proto/axelar/tss/v1beta1/params.proto | 32 -- ampd/proto/axelar/tss/v1beta1/query.proto | 14 - ampd/proto/axelar/tss/v1beta1/service.proto | 32 -- ampd/proto/axelar/tss/v1beta1/tx.proto | 147 ------- ampd/proto/axelar/tss/v1beta1/types.proto | 63 --- ampd/proto/axelar/utils/v1beta1/bitmap.proto | 16 - ampd/proto/axelar/utils/v1beta1/queuer.proto | 19 - .../axelar/utils/v1beta1/threshold.proto | 16 - .../axelar/vote/exported/v1beta1/types.proto | 73 ---- ampd/proto/axelar/vote/v1beta1/events.proto | 16 - ampd/proto/axelar/vote/v1beta1/genesis.proto | 17 - ampd/proto/axelar/vote/v1beta1/params.proto | 16 - ampd/proto/axelar/vote/v1beta1/query.proto | 14 - ampd/proto/axelar/vote/v1beta1/service.proto | 30 -- ampd/proto/axelar/vote/v1beta1/tx.proto | 31 -- ampd/proto/axelar/vote/v1beta1/types.proto | 33 -- ampd/proto/third_party/buf.yaml | 20 - .../cosmos/auth/v1beta1/auth.proto | 50 --- .../cosmos/auth/v1beta1/genesis.proto | 17 - .../cosmos/auth/v1beta1/query.proto | 89 ---- .../cosmos/authz/v1beta1/authz.proto | 39 -- .../cosmos/authz/v1beta1/event.proto | 25 -- .../cosmos/authz/v1beta1/genesis.proto | 13 - .../cosmos/authz/v1beta1/query.proto | 81 ---- .../third_party/cosmos/authz/v1beta1/tx.proto | 70 --- .../cosmos/bank/v1beta1/authz.proto | 19 - .../cosmos/bank/v1beta1/bank.proto | 96 ---- .../cosmos/bank/v1beta1/genesis.proto | 39 -- .../cosmos/bank/v1beta1/query.proto | 193 -------- .../third_party/cosmos/bank/v1beta1/tx.proto | 42 -- .../cosmos/base/abci/v1beta1/abci.proto | 144 ------ .../cosmos/base/kv/v1beta1/kv.proto | 17 - .../cosmos/base/node/v1beta1/query.proto | 22 - .../base/query/v1beta1/pagination.proto | 55 --- .../base/reflection/v1beta1/reflection.proto | 44 -- .../base/reflection/v2alpha1/reflection.proto | 218 --------- .../base/snapshots/v1beta1/snapshot.proto | 57 --- .../base/store/v1beta1/commit_info.proto | 29 -- .../cosmos/base/store/v1beta1/listening.proto | 34 -- .../base/tendermint/v1beta1/query.proto | 138 ------ .../cosmos/base/v1beta1/coin.proto | 40 -- .../capability/v1beta1/capability.proto | 30 -- .../cosmos/capability/v1beta1/genesis.proto | 26 -- .../cosmos/crisis/v1beta1/genesis.proto | 15 - .../cosmos/crisis/v1beta1/tx.proto | 25 -- .../cosmos/crypto/ed25519/keys.proto | 23 - .../cosmos/crypto/multisig/keys.proto | 18 - .../crypto/multisig/v1beta1/multisig.proto | 25 -- .../cosmos/crypto/secp256k1/keys.proto | 22 - .../cosmos/crypto/secp256r1/keys.proto | 23 - .../distribution/v1beta1/distribution.proto | 157 ------- .../cosmos/distribution/v1beta1/genesis.proto | 155 ------- .../cosmos/distribution/v1beta1/query.proto | 218 --------- .../cosmos/distribution/v1beta1/tx.proto | 79 ---- .../cosmos/evidence/v1beta1/evidence.proto | 21 - .../cosmos/evidence/v1beta1/genesis.proto | 12 - .../cosmos/evidence/v1beta1/query.proto | 51 --- .../cosmos/evidence/v1beta1/tx.proto | 32 -- .../cosmos/feegrant/v1beta1/feegrant.proto | 78 ---- .../cosmos/feegrant/v1beta1/genesis.proto | 13 - .../cosmos/feegrant/v1beta1/query.proto | 78 ---- .../cosmos/feegrant/v1beta1/tx.proto | 49 --- .../cosmos/genutil/v1beta1/genesis.proto | 16 - .../cosmos/gov/v1beta1/genesis.proto | 26 -- .../third_party/cosmos/gov/v1beta1/gov.proto | 200 --------- .../cosmos/gov/v1beta1/query.proto | 190 -------- .../third_party/cosmos/gov/v1beta1/tx.proto | 99 ----- .../cosmos/mint/v1beta1/genesis.proto | 16 - .../cosmos/mint/v1beta1/mint.proto | 53 --- .../cosmos/mint/v1beta1/query.proto | 57 --- .../cosmos/params/v1beta1/params.proto | 27 -- .../cosmos/params/v1beta1/query.proto | 32 -- .../cosmos/slashing/v1beta1/genesis.proto | 50 --- .../cosmos/slashing/v1beta1/query.proto | 63 --- .../cosmos/slashing/v1beta1/slashing.proto | 58 --- .../cosmos/slashing/v1beta1/tx.proto | 26 -- .../cosmos/staking/v1beta1/authz.proto | 47 -- .../cosmos/staking/v1beta1/genesis.proto | 53 --- .../cosmos/staking/v1beta1/query.proto | 348 --------------- .../cosmos/staking/v1beta1/staking.proto | 334 -------------- .../cosmos/staking/v1beta1/tx.proto | 123 ------ .../cosmos/tx/signing/v1beta1/signing.proto | 91 ---- .../cosmos/tx/v1beta1/service.proto | 165 ------- .../third_party/cosmos/tx/v1beta1/tx.proto | 183 -------- .../cosmos/upgrade/v1beta1/query.proto | 104 ----- .../cosmos/upgrade/v1beta1/upgrade.proto | 78 ---- .../cosmos/vesting/v1beta1/tx.proto | 31 -- .../cosmos/vesting/v1beta1/vesting.proto | 85 ---- .../third_party/cosmos_proto/cosmos.proto | 16 - .../third_party/cosmwasm/wasm/v1/authz.proto | 118 ----- .../cosmwasm/wasm/v1/genesis.proto | 46 -- .../third_party/cosmwasm/wasm/v1/ibc.proto | 37 -- .../cosmwasm/wasm/v1/proposal.proto | 272 ------------ .../third_party/cosmwasm/wasm/v1/query.proto | 263 ----------- .../third_party/cosmwasm/wasm/v1/tx.proto | 192 -------- .../third_party/cosmwasm/wasm/v1/types.proto | 145 ------ ampd/proto/third_party/gogoproto/gogo.proto | 145 ------ .../third_party/google/api/annotations.proto | 31 -- ampd/proto/third_party/google/api/http.proto | 379 ---------------- .../applications/transfer/v1/genesis.proto | 19 - .../ibc/applications/transfer/v1/query.proto | 105 ----- .../applications/transfer/v1/transfer.proto | 30 -- .../ibc/applications/transfer/v1/tx.proto | 49 --- .../ibc/applications/transfer/v2/packet.proto | 21 - .../ibc/core/channel/v1/channel.proto | 162 ------- .../ibc/core/channel/v1/genesis.proto | 32 -- .../ibc/core/channel/v1/query.proto | 376 ---------------- .../third_party/ibc/core/channel/v1/tx.proto | 245 ----------- .../ibc/core/client/v1/client.proto | 103 ----- .../ibc/core/client/v1/genesis.proto | 48 -- .../ibc/core/client/v1/query.proto | 207 --------- .../third_party/ibc/core/client/v1/tx.proto | 99 ----- .../ibc/core/commitment/v1/commitment.proto | 41 -- .../ibc/core/connection/v1/connection.proto | 114 ----- .../ibc/core/connection/v1/genesis.proto | 18 - .../ibc/core/connection/v1/query.proto | 138 ------ .../ibc/core/connection/v1/tx.proto | 118 ----- .../ibc/core/types/v1/genesis.proto | 23 - .../lightclients/localhost/v1/localhost.proto | 18 - .../solomachine/v1/solomachine.proto | 189 -------- .../solomachine/v2/solomachine.proto | 189 -------- .../tendermint/v1/tendermint.proto | 114 ----- ampd/proto/third_party/proofs.proto | 234 ---------- .../third_party/tendermint/abci/types.proto | 413 ------------------ .../third_party/tendermint/crypto/keys.proto | 17 - .../third_party/tendermint/crypto/proof.proto | 41 -- .../tendermint/libs/bits/types.proto | 9 - .../third_party/tendermint/p2p/types.proto | 34 -- .../third_party/tendermint/types/block.proto | 15 - .../tendermint/types/evidence.proto | 38 -- .../third_party/tendermint/types/params.proto | 80 ---- .../third_party/tendermint/types/types.proto | 157 ------- .../tendermint/types/validator.proto | 25 -- .../tendermint/version/types.proto | 24 - ampd/src/broadcaster/confirm_tx.rs | 352 --------------- ampd/src/broadcaster/mod.rs | 162 ++++++- ampd/src/lib.rs | 27 +- ampd/src/queue/mod.rs | 1 - ampd/src/queue/proto.rs | 42 -- ampd/src/queue/queued_broadcaster.rs | 229 +++------- 202 files changed, 201 insertions(+), 16004 deletions(-) delete mode 100644 ampd/proto/axelar/README.md delete mode 100644 ampd/proto/axelar/auxiliary/v1beta1/events.proto delete mode 100644 ampd/proto/axelar/auxiliary/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/auxiliary/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/auxiliary/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/events.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/proposal.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/axelarnet/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/events.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/evm/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/multisig/exported/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/events.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/multisig/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/nexus/exported/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/events.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/nexus/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/permission/exported/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/permission/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/permission/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/permission/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/permission/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/permission/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/permission/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/reward/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/reward/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/reward/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/reward/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/reward/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/reward/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/snapshot/exported/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/snapshot/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/snapshot/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/snapshot/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/snapshot/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/snapshot/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/snapshot/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/tss/exported/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/common.proto delete mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto delete mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto delete mode 100644 ampd/proto/axelar/tss/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/tss/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/tss/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/tss/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/tss/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/tss/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/utils/v1beta1/bitmap.proto delete mode 100644 ampd/proto/axelar/utils/v1beta1/queuer.proto delete mode 100644 ampd/proto/axelar/utils/v1beta1/threshold.proto delete mode 100644 ampd/proto/axelar/vote/exported/v1beta1/types.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/events.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/genesis.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/params.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/query.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/service.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/tx.proto delete mode 100644 ampd/proto/axelar/vote/v1beta1/types.proto delete mode 100644 ampd/proto/third_party/buf.yaml delete mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto delete mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto delete mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/event.proto delete mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto delete mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto delete mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto delete mode 100644 ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto delete mode 100644 ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto delete mode 100644 ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto delete mode 100644 ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto delete mode 100644 ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto delete mode 100644 ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto delete mode 100644 ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto delete mode 100644 ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/base/v1beta1/coin.proto delete mode 100644 ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto delete mode 100644 ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto delete mode 100644 ampd/proto/third_party/cosmos/crypto/multisig/keys.proto delete mode 100644 ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto delete mode 100644 ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto delete mode 100644 ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto delete mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto delete mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto delete mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto delete mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto delete mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto delete mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/params/v1beta1/params.proto delete mode 100644 ampd/proto/third_party/cosmos/params/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto delete mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto delete mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto delete mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto delete mode 100644 ampd/proto/third_party/cosmos/tx/v1beta1/service.proto delete mode 100644 ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto delete mode 100644 ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto delete mode 100644 ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto delete mode 100644 ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto delete mode 100644 ampd/proto/third_party/cosmos_proto/cosmos.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/query.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto delete mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/types.proto delete mode 100644 ampd/proto/third_party/gogoproto/gogo.proto delete mode 100644 ampd/proto/third_party/google/api/annotations.proto delete mode 100644 ampd/proto/third_party/google/api/http.proto delete mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto delete mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/query.proto delete mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto delete mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto delete mode 100644 ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto delete mode 100644 ampd/proto/third_party/ibc/core/channel/v1/channel.proto delete mode 100644 ampd/proto/third_party/ibc/core/channel/v1/genesis.proto delete mode 100644 ampd/proto/third_party/ibc/core/channel/v1/query.proto delete mode 100644 ampd/proto/third_party/ibc/core/channel/v1/tx.proto delete mode 100644 ampd/proto/third_party/ibc/core/client/v1/client.proto delete mode 100644 ampd/proto/third_party/ibc/core/client/v1/genesis.proto delete mode 100644 ampd/proto/third_party/ibc/core/client/v1/query.proto delete mode 100644 ampd/proto/third_party/ibc/core/client/v1/tx.proto delete mode 100644 ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto delete mode 100644 ampd/proto/third_party/ibc/core/connection/v1/connection.proto delete mode 100644 ampd/proto/third_party/ibc/core/connection/v1/genesis.proto delete mode 100644 ampd/proto/third_party/ibc/core/connection/v1/query.proto delete mode 100644 ampd/proto/third_party/ibc/core/connection/v1/tx.proto delete mode 100644 ampd/proto/third_party/ibc/core/types/v1/genesis.proto delete mode 100644 ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto delete mode 100644 ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto delete mode 100644 ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto delete mode 100644 ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto delete mode 100644 ampd/proto/third_party/proofs.proto delete mode 100644 ampd/proto/third_party/tendermint/abci/types.proto delete mode 100644 ampd/proto/third_party/tendermint/crypto/keys.proto delete mode 100644 ampd/proto/third_party/tendermint/crypto/proof.proto delete mode 100644 ampd/proto/third_party/tendermint/libs/bits/types.proto delete mode 100644 ampd/proto/third_party/tendermint/p2p/types.proto delete mode 100644 ampd/proto/third_party/tendermint/types/block.proto delete mode 100644 ampd/proto/third_party/tendermint/types/evidence.proto delete mode 100644 ampd/proto/third_party/tendermint/types/params.proto delete mode 100644 ampd/proto/third_party/tendermint/types/types.proto delete mode 100644 ampd/proto/third_party/tendermint/types/validator.proto delete mode 100644 ampd/proto/third_party/tendermint/version/types.proto delete mode 100644 ampd/src/broadcaster/confirm_tx.rs delete mode 100644 ampd/src/queue/proto.rs diff --git a/ampd/build.rs b/ampd/build.rs index cd5acc3b9..7581fa013 100644 --- a/ampd/build.rs +++ b/ampd/build.rs @@ -8,13 +8,5 @@ fn main() -> Result<(), Box> { .build_client(true) .compile(&["proto/ampd.proto"], &["proto"])?; - tonic_build::configure() - .build_server(false) - .build_client(false) - .compile( - &["proto/axelar/auxiliary/v1beta1/tx.proto"], - &["proto", "proto/third_party"], - )?; - Ok(()) } diff --git a/ampd/proto/axelar/README.md b/ampd/proto/axelar/README.md deleted file mode 100644 index 519187b2b..000000000 --- a/ampd/proto/axelar/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Axelar Protobufs - -This folder defines protobufs used by Axelar specific Cosmos SDK msg, event, and query types. - -## REST API - -The REST API (LCD) gets generated automatically from the gRPC service definitions. -The request/response types are defined in `query.proto` for the respective modules, and the query is defined in the `service.proto`. - -Note: The request types cannot make use of custom types encoded as bytes as that would be awkward -for REST-based calls. Instead, primitive types such as string is used (for e.g. when specifying addresses, instead of using sdk.AccAddress). diff --git a/ampd/proto/axelar/auxiliary/v1beta1/events.proto b/ampd/proto/axelar/auxiliary/v1beta1/events.proto deleted file mode 100644 index 90956b702..000000000 --- a/ampd/proto/axelar/auxiliary/v1beta1/events.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; -package axelar.auxiliary.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; -option (gogoproto.messagename_all) = true; - -import "gogoproto/gogo.proto"; - -message BatchedMessageFailed { - int32 index = 1; - string error = 2; -} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto b/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto deleted file mode 100644 index 0d766e10f..000000000 --- a/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto +++ /dev/null @@ -1,11 +0,0 @@ -syntax = "proto3"; -package axelar.auxiliary.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState {} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/service.proto b/ampd/proto/axelar/auxiliary/v1beta1/service.proto deleted file mode 100644 index 6d2a08e9b..000000000 --- a/ampd/proto/axelar/auxiliary/v1beta1/service.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; -package axelar.auxiliary.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/auxiliary/v1beta1/tx.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the nexus Msg service. -service MsgService { - rpc Batch(BatchRequest) returns (BatchResponse) { - option (google.api.http) = { - post : "/axelar/auxiliary/batch" - body : "*" - }; - } -} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/tx.proto b/ampd/proto/axelar/auxiliary/v1beta1/tx.proto deleted file mode 100644 index 065016da4..000000000 --- a/ampd/proto/axelar/auxiliary/v1beta1/tx.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; -package axelar.auxiliary.v1beta1; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; - -import "axelar/permission/exported/v1beta1/types.proto"; -import "cosmos/base/abci/v1beta1/abci.proto"; -import "cosmos_proto/cosmos.proto"; - -option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; - -message BatchRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - repeated google.protobuf.Any messages = 2 - [ (gogoproto.nullable) = false, (cosmos_proto.accepts_interface) = "cosmos.base.v1beta1.Msg" ]; -} - -message BatchResponse { - message Response { - oneof res { - cosmos.base.abci.v1beta1.Result result = 1; - string err = 2; - } - } - repeated Response responses = 1 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/events.proto b/ampd/proto/axelar/axelarnet/v1beta1/events.proto deleted file mode 100644 index a5e9e0a67..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/events.proto +++ /dev/null @@ -1,131 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option (gogoproto.messagename_all) = true; - -message IBCTransferSent { - uint64 id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string receipient = 2 [ deprecated = true ]; - cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; - uint64 sequence = 4; - string port_id = 5 [ (gogoproto.customname) = "PortID" ]; - string channel_id = 6 [ (gogoproto.customname) = "ChannelID" ]; - string recipient = 7; -} - -message IBCTransferCompleted { - uint64 id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - uint64 sequence = 2; - string port_id = 3 [ (gogoproto.customname) = "PortID" ]; - string channel_id = 4 [ (gogoproto.customname) = "ChannelID" ]; -} - -message IBCTransferFailed { - uint64 id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - uint64 sequence = 2; - string port_id = 3 [ (gogoproto.customname) = "PortID" ]; - string channel_id = 4 [ (gogoproto.customname) = "ChannelID" ]; -} - -message IBCTransferRetried { - uint64 id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string receipient = 2 [ deprecated = true ]; - cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; - uint64 sequence = 4; - string port_id = 5 [ (gogoproto.customname) = "PortID" ]; - string channel_id = 6 [ (gogoproto.customname) = "ChannelID" ]; - string recipient = 7; -} - -message AxelarTransferCompleted { - uint64 id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string receipient = 2 [ deprecated = true ]; - cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; - string recipient = 4; -} - -message FeeCollected { - bytes collector = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - cosmos.base.v1beta1.Coin fee = 2 [ (gogoproto.nullable) = false ]; -} - -message FeePaid { - string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; - bytes recipient = 2 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - cosmos.base.v1beta1.Coin fee = 3 [ (gogoproto.nullable) = false ]; - string refund_recipient = 4; - string asset = 5; // registered asset name in nexus -} - -message ContractCallSubmitted { - string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; - string sender = 2; - string source_chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_chain = 4 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 5; - bytes payload = 6; - bytes payload_hash = 7; -} - -message ContractCallWithTokenSubmitted { - string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; - string sender = 2; - string source_chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_chain = 4 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 5; - bytes payload = 6; - bytes payload_hash = 7; - cosmos.base.v1beta1.Coin asset = 8 [ (gogoproto.nullable) = false ]; -} - -message TokenSent { - uint64 transfer_id = 1 [ - (gogoproto.customname) = "TransferID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string sender = 2; - string source_chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_chain = 4 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_address = 5; - cosmos.base.v1beta1.Coin asset = 6 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto b/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto deleted file mode 100644 index 8cfea9cd5..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; - -import "gogoproto/gogo.proto"; -import "axelar/axelarnet/v1beta1/params.proto"; -import "axelar/axelarnet/v1beta1/types.proto"; -import "axelar/utils/v1beta1/queuer.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message GenesisState { - option (gogoproto.stable_marshaler) = true; - - Params params = 1 [ (gogoproto.nullable) = false ]; - bytes collector_address = 2 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - repeated CosmosChain chains = 3 [ (gogoproto.nullable) = false ]; - reserved 4; // pending_transfers was removed in v0.20 - utils.v1beta1.QueueState transfer_queue = 5 [ (gogoproto.nullable) = false ]; - reserved 6; // failed_transfers was removed in v0.22 - repeated IBCTransfer ibc_transfers = 7 - [ (gogoproto.nullable) = false, (gogoproto.customname) = "IBCTransfers" ]; - map seq_id_mapping = 8 - [ (gogoproto.nullable) = false, (gogoproto.customname) = "SeqIDMapping" ]; -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/params.proto b/ampd/proto/axelar/axelarnet/v1beta1/params.proto deleted file mode 100644 index 5d669fbc6..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/params.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params { - // IBC packet route timeout window - uint64 route_timeout_window = 1; - reserved 2; // transaction_fee_rate was removed in v0.15 - uint64 transfer_limit = 3; - uint64 end_blocker_limit = 4; - repeated CallContractProposalMinDeposit call_contracts_proposal_min_deposits = - 5 [ - (gogoproto.castrepeated) = "CallContractProposalMinDeposits", - (gogoproto.nullable) = false - ]; -} - -message CallContractProposalMinDeposit { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 2; - repeated cosmos.base.v1beta1.Coin min_deposits = 3 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.nullable) = false - ]; -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto b/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto deleted file mode 100644 index 2994ca8c8..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package axelar.axelarnet.v1beta1; - -import "gogoproto/gogo.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; - -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; -option (gogoproto.goproto_getters_all) = false; - -// CallContractsProposal is a gov Content type for calling contracts on other -// chains -message CallContractsProposal { - option (gogoproto.goproto_stringer) = false; - - string title = 1; - string description = 2; - repeated ContractCall contract_calls = 3 [ (gogoproto.nullable) = false ]; -} - -message ContractCall { - option (gogoproto.goproto_stringer) = false; - - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 2; - bytes payload = 3; -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/query.proto b/ampd/proto/axelar/axelarnet/v1beta1/query.proto deleted file mode 100644 index 64fc7088d..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/query.proto +++ /dev/null @@ -1,39 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; - -import "gogoproto/gogo.proto"; -import "axelar/axelarnet/v1beta1/types.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "axelar/nexus/v1beta1/query.proto"; -import "axelar/axelarnet/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message PendingIBCTransferCountRequest {} - -message PendingIBCTransferCountResponse { - map transfers_by_chain = 1 [ (gogoproto.nullable) = false ]; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } - -// IBCPathRequest represents a message that queries the IBC path registered for -// a given chain -message IBCPathRequest { string chain = 1; } - -message IBCPathResponse { string ibc_path = 1 [ (gogoproto.customname) = "IBCPath" ]; } - -// ChainByIBCPathRequest represents a message that queries the chain that an IBC -// path is registered to -message ChainByIBCPathRequest { string ibc_path = 1; } - -message ChainByIBCPathResponse { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/service.proto b/ampd/proto/axelar/axelarnet/v1beta1/service.proto deleted file mode 100644 index c2ed583e8..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/service.proto +++ /dev/null @@ -1,118 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/axelarnet/v1beta1/tx.proto"; -import "axelar/axelarnet/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the axelarnet Msg service. -service MsgService { - rpc Link(LinkRequest) returns (LinkResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/link" - body : "*" - }; - } - - rpc ConfirmDeposit(ConfirmDepositRequest) returns (ConfirmDepositResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/confirm_deposit" - body : "*" - }; - } - - rpc ExecutePendingTransfers(ExecutePendingTransfersRequest) - returns (ExecutePendingTransfersResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/execute_pending_transfers" - body : "*" - }; - } - - rpc AddCosmosBasedChain(AddCosmosBasedChainRequest) - returns (AddCosmosBasedChainResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/add_cosmos_based_chain" - body : "*" - }; - } - - rpc RegisterAsset(RegisterAssetRequest) returns (RegisterAssetResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/register_asset" - body : "*" - }; - } - - rpc RouteIBCTransfers(RouteIBCTransfersRequest) - returns (RouteIBCTransfersResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/route_ibc_transfers" - body : "*" - }; - } - - rpc RegisterFeeCollector(RegisterFeeCollectorRequest) - returns (RegisterFeeCollectorResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/register_fee_collector" - body : "*" - }; - } - - rpc RetryIBCTransfer(RetryIBCTransferRequest) - returns (RetryIBCTransferResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/retry_ibc_transfer" - body : "*" - }; - } - - rpc RouteMessage(RouteMessageRequest) returns (RouteMessageResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/route_message" - body : "*" - }; - } - - rpc CallContract(CallContractRequest) returns (CallContractResponse) { - option (google.api.http) = { - post : "/axelar/axelarnet/call_contract" - body : "*" - }; - } -} - -// QueryService defines the gRPC querier service. -service QueryService { - - // PendingIBCTransferCount queries the pending ibc transfers for all chains - rpc PendingIBCTransferCount(PendingIBCTransferCountRequest) - returns (PendingIBCTransferCountResponse) { - option (google.api.http).get = - "/axelar/axelarnet/v1beta1/ibc_transfer_count"; - } - - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/axelarnet/v1beta1/params" - }; - } - - rpc IBCPath(IBCPathRequest) returns (IBCPathResponse) { - option (google.api.http) = { - get : "/axelar/axelarnet/v1beta1/ibc_path/{chain}" - }; - } - - rpc ChainByIBCPath(ChainByIBCPathRequest) returns (ChainByIBCPathResponse) { - option (google.api.http) = { - get : "/axelar/axelarnet/v1beta1/chain_by_ibc_path/{ibc_path}" - }; - } -} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/tx.proto b/ampd/proto/axelar/axelarnet/v1beta1/tx.proto deleted file mode 100644 index 95c5e5c7c..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/tx.proto +++ /dev/null @@ -1,188 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; - -import "google/protobuf/any.proto"; -import "google/protobuf/duration.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; -import "axelar/axelarnet/v1beta1/types.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// MsgLink represents a message to link a cross-chain address to an Axelar -// address -message LinkRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string recipient_addr = 2; - string recipient_chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string asset = 4; -} - -message LinkResponse { string deposit_addr = 1; }; - -// MsgConfirmDeposit represents a deposit confirmation message -message ConfirmDepositRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - - reserved 2; // tx_id was removed in v0.14 - - reserved 3; // token was removed in v0.15 - - bytes deposit_address = 4 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - - string denom = 5; -} - -message ConfirmDepositResponse {} - -// MsgExecutePendingTransfers represents a message to trigger transfer all -// pending transfers -message ExecutePendingTransfersRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message ExecutePendingTransfersResponse {} - -// MSgRegisterIBCPath represents a message to register an IBC tracing path for -// a cosmos chain -message RegisterIBCPathRequest { - option deprecated = true; - - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string path = 3; -} - -message RegisterIBCPathResponse {} - -// MsgAddCosmosBasedChain represents a message to register a cosmos based chain -// to nexus -message AddCosmosBasedChainRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - nexus.exported.v1beta1.Chain chain = 2 [ - deprecated = true, - (gogoproto.nullable) = false - ]; // chain was deprecated in v0.27 - string addr_prefix = 3; - reserved 4; // min_amount was removed in v0.15 - repeated nexus.exported.v1beta1.Asset native_assets = 5 [ - deprecated = true, - (gogoproto.nullable) = false - ]; // native_assets was deprecated in v0.27 - // TODO: Rename this to `chain` after v1beta1 -> v1 version bump - string cosmos_chain = 6 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string ibc_path = 7 [ (gogoproto.customname) = "IBCPath" ]; -} - -message AddCosmosBasedChainResponse {} - -// RegisterAssetRequest represents a message to register an asset to a cosmos -// based chain -message RegisterAssetRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - nexus.exported.v1beta1.Asset asset = 3 [ (gogoproto.nullable) = false ]; - bytes limit = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - google.protobuf.Duration window = 5 - [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; -} - -message RegisterAssetResponse {} - -// RouteIBCTransfersRequest represents a message to route pending transfers to -// cosmos based chains -message RouteIBCTransfersRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message RouteIBCTransfersResponse {} - -// RegisterFeeCollectorRequest represents a message to register axelarnet fee -// collector account -message RegisterFeeCollectorRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - bytes fee_collector = 2 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message RegisterFeeCollectorResponse {} - -message RetryIBCTransferRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 [ - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName", - deprecated = true - ]; - uint64 id = 3 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; -} - -message RetryIBCTransferResponse {} - -message RouteMessageRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string id = 2 [ (gogoproto.customname) = "ID" ]; - bytes payload = 3; - bytes feegranter = 4 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message RouteMessageResponse {} - -message CallContractRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 3; - bytes payload = 4; - Fee fee = 5; -} - -message CallContractResponse {} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/types.proto b/ampd/proto/axelar/axelarnet/v1beta1/types.proto deleted file mode 100644 index b20ae2799..000000000 --- a/ampd/proto/axelar/axelarnet/v1beta1/types.proto +++ /dev/null @@ -1,62 +0,0 @@ -syntax = "proto3"; -package axelar.axelarnet.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message IBCTransfer { - enum Status { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - STATUS_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "TransferNonExistent" ]; - STATUS_PENDING = 1 [ (gogoproto.enumvalue_customname) = "TransferPending" ]; - STATUS_COMPLETED = 2 - [ (gogoproto.enumvalue_customname) = "TransferCompleted" ]; - STATUS_FAILED = 3 [ (gogoproto.enumvalue_customname) = "TransferFailed" ]; - } - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string receiver = 2; - cosmos.base.v1beta1.Coin token = 3 [ (gogoproto.nullable) = false ]; - string port_id = 4 [ (gogoproto.customname) = "PortID" ]; - string channel_id = 5 [ (gogoproto.customname) = "ChannelID" ]; - uint64 sequence = 6 [ deprecated = true ]; - uint64 id = 7 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - Status status = 8; -} - -message CosmosChain { - string name = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string ibc_path = 2 [ (gogoproto.customname) = "IBCPath" ]; - repeated Asset assets = 3 [ (gogoproto.nullable) = false, deprecated = true ]; - string addr_prefix = 4; -} - -message Asset { - option deprecated = true; - string denom = 1; - bytes min_amount = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; -} - -message Fee { - cosmos.base.v1beta1.Coin amount = 1 [ (gogoproto.nullable) = false ]; - bytes recipient = 2 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - bytes refund_recipient = 3 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} diff --git a/ampd/proto/axelar/evm/v1beta1/events.proto b/ampd/proto/axelar/evm/v1beta1/events.proto deleted file mode 100644 index bcdd74e99..000000000 --- a/ampd/proto/axelar/evm/v1beta1/events.proto +++ /dev/null @@ -1,340 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; -option (gogoproto.messagename_all) = true; - -import "gogoproto/gogo.proto"; -import "axelar/vote/exported/v1beta1/types.proto"; -import "axelar/evm/v1beta1/types.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -message PollFailed { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - uint64 poll_id = 3 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", - (gogoproto.nullable) = false - ]; -} - -message PollExpired { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - uint64 poll_id = 3 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", - (gogoproto.nullable) = false - ]; -} - -message PollCompleted { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - uint64 poll_id = 3 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", - (gogoproto.nullable) = false - ]; -} - -message NoEventsConfirmed { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - uint64 poll_id = 3 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", - (gogoproto.nullable) = false - ]; -} - -message ConfirmKeyTransferStarted { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 2 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - bytes gateway_address = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - uint64 confirmation_height = 4; - vote.exported.v1beta1.PollParticipants participants = 5 - [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; -} - -message ConfirmGatewayTxStarted { - option deprecated = true; - - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes gateway_address = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - uint64 confirmation_height = 4; - vote.exported.v1beta1.PollParticipants participants = 5 - [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; -} - -message PollMapping { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - uint64 poll_id = 2 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID" - ]; -} - -message ConfirmGatewayTxsStarted { - repeated PollMapping poll_mappings = 1 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "poll_mappings,omitempty" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes gateway_address = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - uint64 confirmation_height = 4; - repeated bytes participants = 5 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; -} - -message ConfirmDepositStarted { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes deposit_address = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes token_address = 4 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - uint64 confirmation_height = 5; - vote.exported.v1beta1.PollParticipants participants = 6 - [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; - string asset = 7; -} - -message ConfirmTokenStarted { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes gateway_address = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes token_address = 4 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - evm.v1beta1.TokenDetails token_details = 5 [ (gogoproto.nullable) = false ]; - uint64 confirmation_height = 6; - vote.exported.v1beta1.PollParticipants participants = 7 - [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; -} - -message ChainAdded { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message CommandBatchSigned { - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; -} - -message CommandBatchAborted { - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; -} - -message EVMEventConfirmed { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - string type = 3; -} - -message EVMEventCompleted { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - string type = 3; -} - -message EVMEventFailed { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - string type = 3; -} - -message EVMEventRetryFailed { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - string type = 3; -} - -message ContractCallApproved { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - bytes command_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "CommandID", - (gogoproto.customtype) = "CommandID" - ]; - string sender = 4; - string destination_chain = 5 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 6; - bytes payload_hash = 7 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; -} - -message ContractCallFailed { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string msg_id = 2 [ (gogoproto.customname) = "MessageID" ]; -} - -message ContractCallWithMintApproved { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - bytes command_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "CommandID", - (gogoproto.customtype) = "CommandID" - ]; - string sender = 4; - string destination_chain = 5 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 6; - bytes payload_hash = 7 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; - cosmos.base.v1beta1.Coin asset = 8 [ (gogoproto.nullable) = false ]; -} - -message TokenSent { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 2 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; - uint64 transfer_id = 3 [ - (gogoproto.customname) = "TransferID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string sender = 4; - string destination_chain = 5 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_address = 6; - cosmos.base.v1beta1.Coin asset = 7 [ (gogoproto.nullable) = false ]; -} - -message MintCommand { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - uint64 transfer_id = 2 [ - (gogoproto.customname) = "TransferID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - bytes command_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "CommandID", - (gogoproto.customtype) = "CommandID" - ]; - string destination_chain = 4 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_address = 5; - cosmos.base.v1beta1.Coin asset = 6 [ (gogoproto.nullable) = false ]; -} - -message BurnCommand { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes command_id = 2 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "CommandID", - (gogoproto.customtype) = "CommandID" - ]; - string destination_chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string deposit_address = 4; - string asset = 5; -} diff --git a/ampd/proto/axelar/evm/v1beta1/genesis.proto b/ampd/proto/axelar/evm/v1beta1/genesis.proto deleted file mode 100644 index 3e0edc463..000000000 --- a/ampd/proto/axelar/evm/v1beta1/genesis.proto +++ /dev/null @@ -1,39 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; - -import "axelar/utils/v1beta1/queuer.proto"; -import "gogoproto/gogo.proto"; -import "axelar/evm/v1beta1/params.proto"; -import "axelar/evm/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState { - option (gogoproto.stable_marshaler) = true; - - message Chain { - Params params = 1 [ (gogoproto.nullable) = false ]; - repeated BurnerInfo burner_infos = 2 [ (gogoproto.nullable) = false ]; - utils.v1beta1.QueueState command_queue = 3 [ (gogoproto.nullable) = false ]; - repeated ERC20Deposit confirmed_deposits = 4 - [ (gogoproto.nullable) = false ]; - repeated ERC20Deposit burned_deposits = 5 [ (gogoproto.nullable) = false ]; - - repeated CommandBatchMetadata command_batches = 8 - [ (gogoproto.nullable) = false ]; - - Gateway gateway = 9 [ (gogoproto.nullable) = false ]; - repeated ERC20TokenMetadata tokens = 10 [ (gogoproto.nullable) = false ]; - repeated Event events = 11 [ (gogoproto.nullable) = false ]; - utils.v1beta1.QueueState confirmed_event_queue = 12 - [ (gogoproto.nullable) = false ]; - repeated ERC20Deposit legacy_confirmed_deposits = 13 - [ (gogoproto.nullable) = false ]; - repeated ERC20Deposit legacy_burned_deposits = 14 - [ (gogoproto.nullable) = false ]; - } - - repeated Chain chains = 3 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/evm/v1beta1/params.proto b/ampd/proto/axelar/evm/v1beta1/params.proto deleted file mode 100644 index 6fc387be1..000000000 --- a/ampd/proto/axelar/evm/v1beta1/params.proto +++ /dev/null @@ -1,37 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; - -import "axelar/utils/v1beta1/threshold.proto"; -import "axelar/evm/v1beta1/types.proto"; -import "gogoproto/gogo.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params is the parameter set for this module -message Params { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - uint64 confirmation_height = 2; - string network = 3; - reserved 4; // gateway_code was removed in v0.16 - bytes token_code = 5; - bytes burnable = 6; - int64 revote_locking_period = 7; - repeated evm.v1beta1.NetworkInfo networks = 8 - [ (gogoproto.nullable) = false ]; - utils.v1beta1.Threshold voting_threshold = 9 [ (gogoproto.nullable) = false ]; - int64 min_voter_count = 10; - uint32 commands_gas_limit = 11; - reserved 12; // transaction_fee_rate was removed in v0.15 - int64 voting_grace_period = 13; - int64 end_blocker_limit = 14; - uint64 transfer_limit = 15; -} - -message PendingChain { - Params params = 1 [ (gogoproto.nullable) = false ]; - nexus.exported.v1beta1.Chain chain = 2 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/evm/v1beta1/query.proto b/ampd/proto/axelar/evm/v1beta1/query.proto deleted file mode 100644 index 61de10b01..000000000 --- a/ampd/proto/axelar/evm/v1beta1/query.proto +++ /dev/null @@ -1,243 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; - -import "gogoproto/gogo.proto"; -import "axelar/evm/v1beta1/types.proto"; -import "axelar/evm/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// DepositQueryParams describe the parameters used to query for an EVM -// deposit address -message DepositQueryParams { - string address = 1; - string asset = 2; - string chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message BatchedCommandsRequest { - string chain = 1; - // id defines an optional id for the commandsbatch. If not specified the - // latest will be returned - string id = 2; -} - -message BatchedCommandsResponse { - string id = 1 [ (gogoproto.customname) = "ID" ]; - string data = 2; - BatchedCommandsStatus status = 3; - string key_id = 4 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - reserved 5; // signature was removed in v0.20.0 - string execute_data = 6; - string prev_batched_commands_id = 7 - [ (gogoproto.customname) = "PrevBatchedCommandsID" ]; - repeated string command_ids = 8 [ (gogoproto.customname) = "CommandIDs" ]; - Proof proof = 9; -} - -message KeyAddressRequest { - reserved 2, 3; - - string chain = 1; - string key_id = 4 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message KeyAddressResponse { - message WeightedAddress { - string address = 1; - string weight = 2; - }; - - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - repeated WeightedAddress addresses = 2 [ (gogoproto.nullable) = false ]; - string threshold = 3; -} - -message QueryTokenAddressResponse { - option deprecated = true; // Deprecated in v19 - - string address = 1; - bool confirmed = 2; -} - -message QueryDepositStateParams { - option deprecated = true; - - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - bytes burner_address = 2 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; -} - -message DepositStateRequest { - option deprecated = true; - - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - QueryDepositStateParams params = 2; -} - -message DepositStateResponse { - option deprecated = true; - - DepositStatus status = 2; -} - -message EventRequest { - string chain = 1; - string event_id = 2; -} - -message EventResponse { Event event = 1; } - -message QueryBurnerAddressResponse { string address = 1; } - -enum ChainStatus { - option (gogoproto.goproto_enum_prefix) = false; - - CHAIN_STATUS_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "StatusUnspecified" ]; - CHAIN_STATUS_ACTIVATED = 1 [ (gogoproto.enumvalue_customname) = "Activated" ]; - CHAIN_STATUS_DEACTIVATED = 2 - [ (gogoproto.enumvalue_customname) = "Deactivated" ]; -} - -message ChainsRequest { ChainStatus status = 1; } - -message ChainsResponse { - repeated string chains = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message CommandRequest { - string chain = 1; - string id = 2 [ (gogoproto.customname) = "ID" ]; -} - -message CommandResponse { - string id = 1 [ (gogoproto.customname) = "ID" ]; - string type = 2; - map params = 3 [ (gogoproto.nullable) = false ]; - string key_id = 4 [ (gogoproto.customname) = "KeyID" ]; - uint32 max_gas_cost = 5; -} - -message PendingCommandsRequest { string chain = 1; } - -message PendingCommandsResponse { - repeated QueryCommandResponse commands = 1 [ (gogoproto.nullable) = false ]; -} - -message QueryCommandResponse { - string id = 1 [ (gogoproto.customname) = "ID" ]; - string type = 2; - map params = 3 [ (gogoproto.nullable) = false ]; - string key_id = 4 [ (gogoproto.customname) = "KeyID" ]; - uint32 max_gas_cost = 5; -} - -message BurnerInfoRequest { - bytes address = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; -} - -message BurnerInfoResponse { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - BurnerInfo burner_info = 2; -} - -message ConfirmationHeightRequest { string chain = 1; } - -message ConfirmationHeightResponse { uint64 height = 1; } - -message GatewayAddressRequest { string chain = 1; } - -message GatewayAddressResponse { string address = 1; } - -message BytecodeRequest { - string chain = 1; - string contract = 2; -} - -message BytecodeResponse { string bytecode = 1; } - -enum TokenType { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - TOKEN_TYPE_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "Unspecified" ]; - TOKEN_TYPE_INTERNAL = 1 [ (gogoproto.enumvalue_customname) = "Internal" ]; - TOKEN_TYPE_EXTERNAL = 2 [ (gogoproto.enumvalue_customname) = "External" ]; -} - -// ERC20TokensRequest describes the chain for which the type of ERC20 tokens are -// requested. -message ERC20TokensRequest { - string chain = 1; - TokenType type = 2; -} - -// ERC20TokensResponse describes the asset and symbol for all -// ERC20 tokens requested for a chain -message ERC20TokensResponse { - message Token { - string asset = 1; - string symbol = 2; - } - - repeated Token tokens = 1 [ (gogoproto.nullable) = false ]; -} - -message TokenInfoRequest { - string chain = 1; - oneof find_by { - string asset = 2; - string symbol = 3; - string address = 4; - } -} - -message TokenInfoResponse { - string asset = 1; - TokenDetails details = 2 [ (gogoproto.nullable) = false ]; - string address = 3; - bool confirmed = 4; - bool is_external = 5; - string burner_code_hash = 6; -} - -message Proof { - repeated string addresses = 1; - repeated string weights = 2; - string threshold = 3; - repeated string signatures = 4; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest { string chain = 1; } - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/evm/v1beta1/service.proto b/ampd/proto/axelar/evm/v1beta1/service.proto deleted file mode 100644 index 6cc9b02f0..000000000 --- a/ampd/proto/axelar/evm/v1beta1/service.proto +++ /dev/null @@ -1,208 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/evm/v1beta1/tx.proto"; -import "axelar/evm/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the evm Msg service. -service MsgService { - rpc SetGateway(SetGatewayRequest) returns (SetGatewayResponse) { - option (google.api.http) = { - post : "/axelar/evm/set_gateway" - body : "*" - }; - } - - // Deprecated: use ConfirmGatewayTxs instead - rpc ConfirmGatewayTx(ConfirmGatewayTxRequest) - returns (ConfirmGatewayTxResponse) { - option (google.api.http) = { - post : "/axelar/evm/confirm_gateway_tx" - body : "*" - }; - } - - rpc ConfirmGatewayTxs(ConfirmGatewayTxsRequest) - returns (ConfirmGatewayTxsResponse) { - option (google.api.http) = { - post : "/axelar/evm/confirm_gateway_txs" - body : "*" - }; - } - - rpc Link(LinkRequest) returns (LinkResponse) { - option (google.api.http) = { - post : "/axelar/evm/link" - body : "*" - }; - } - - rpc ConfirmToken(ConfirmTokenRequest) returns (ConfirmTokenResponse) { - option (google.api.http) = { - post : "/axelar/evm/confirm_token" - body : "*" - }; - } - - rpc ConfirmDeposit(ConfirmDepositRequest) returns (ConfirmDepositResponse) { - option (google.api.http) = { - post : "/axelar/evm/confirm_deposit" - body : "*" - }; - } - - rpc ConfirmTransferKey(ConfirmTransferKeyRequest) - returns (ConfirmTransferKeyResponse) { - option (google.api.http) = { - post : "/axelar/evm/confirm_transfer_key" - body : "*" - }; - } - - rpc CreateDeployToken(CreateDeployTokenRequest) - returns (CreateDeployTokenResponse) { - option (google.api.http) = { - post : "/axelar/evm/create_deploy_token" - body : "*" - }; - } - - rpc CreateBurnTokens(CreateBurnTokensRequest) - returns (CreateBurnTokensResponse) { - option (google.api.http) = { - post : "/axelar/evm/create_burn_tokens" - body : "*" - }; - } - - rpc CreatePendingTransfers(CreatePendingTransfersRequest) - returns (CreatePendingTransfersResponse) { - option (google.api.http) = { - post : "/axelar/evm/create_pending_transfers" - body : "*" - }; - } - - rpc CreateTransferOperatorship(CreateTransferOperatorshipRequest) - returns (CreateTransferOperatorshipResponse) { - option (google.api.http) = { - post : "/axelar/evm/create_transfer_operatorship" - body : "*" - }; - } - - rpc SignCommands(SignCommandsRequest) returns (SignCommandsResponse) { - option (google.api.http) = { - post : "/axelar/evm/sign_commands" - body : "*" - }; - } - - rpc AddChain(AddChainRequest) returns (AddChainResponse) { - option (google.api.http) = { - post : "/axelar/evm/add_chain" - body : "*" - }; - } - - rpc RetryFailedEvent(RetryFailedEventRequest) - returns (RetryFailedEventResponse) { - option (google.api.http) = { - post : "/axelar/evm/retry-failed-event" - body : "*" - }; - } -} - -// QueryService defines the gRPC querier service. -service QueryService { - - // BatchedCommands queries the batched commands for a specified chain and - // BatchedCommandsID if no BatchedCommandsID is specified, then it returns the - // latest batched commands - rpc BatchedCommands(BatchedCommandsRequest) - returns (BatchedCommandsResponse) { - option (google.api.http).get = - "/axelar/evm/v1beta1/batched_commands/{chain}/{id}"; - } - - // BurnerInfo queries the burner info for the specified address - rpc BurnerInfo(BurnerInfoRequest) returns (BurnerInfoResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/burner_info"; - } - - // ConfirmationHeight queries the confirmation height for the specified chain - rpc ConfirmationHeight(ConfirmationHeightRequest) - returns (ConfirmationHeightResponse) { - option (google.api.http).get = - "/axelar/evm/v1beta1/confirmation_height/{chain}"; - } - - // DepositState queries the state of the specified deposit - rpc DepositState(DepositStateRequest) returns (DepositStateResponse) { - option deprecated = true; - option (google.api.http).get = "/axelar/evm/v1beta1/deposit_state"; - } - - // PendingCommands queries the pending commands for the specified chain - rpc PendingCommands(PendingCommandsRequest) - returns (PendingCommandsResponse) { - option (google.api.http).get = - "/axelar/evm/v1beta1/pending_commands/{chain}"; - } - - // Chains queries the available evm chains - rpc Chains(ChainsRequest) returns (ChainsResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/chains"; - } - - // Command queries the command of a chain provided the command id - rpc Command(CommandRequest) returns (CommandResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/command_request"; - } - - // KeyAddress queries the address of key of a chain - rpc KeyAddress(KeyAddressRequest) returns (KeyAddressResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/key_address/{chain}"; - } - - // GatewayAddress queries the address of axelar gateway at the specified - // chain - rpc GatewayAddress(GatewayAddressRequest) returns (GatewayAddressResponse) { - option (google.api.http).get = - "/axelar/evm/v1beta1/gateway_address/{chain}"; - } - - // Bytecode queries the bytecode of a specified gateway at the specified - // chain - rpc Bytecode(BytecodeRequest) returns (BytecodeResponse) { - option (google.api.http).get = - "/axelar/evm/v1beta1/bytecode/{chain}/{contract}"; - } - - // Event queries an event at the specified chain - rpc Event(EventRequest) returns (EventResponse) { - option (google.api.http).get = - "/axelar/evm/v1beta1/event/{chain}/{event_id}"; - } - - // ERC20Tokens queries the ERC20 tokens registered for a chain - rpc ERC20Tokens(ERC20TokensRequest) returns (ERC20TokensResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/erc20_tokens/{chain}"; - } - - // TokenInfo queries the token info for a registered ERC20 Token - rpc TokenInfo(TokenInfoRequest) returns (TokenInfoResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/token_info/{chain}"; - } - - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http).get = "/axelar/evm/v1beta1/params/{chain}"; - } -} diff --git a/ampd/proto/axelar/evm/v1beta1/tx.proto b/ampd/proto/axelar/evm/v1beta1/tx.proto deleted file mode 100644 index 9aaef12e4..000000000 --- a/ampd/proto/axelar/evm/v1beta1/tx.proto +++ /dev/null @@ -1,259 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; - -import "gogoproto/gogo.proto"; -import "axelar/vote/exported/v1beta1/types.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; -import "axelar/evm/v1beta1/types.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message SetGatewayRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes address = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; -} - -message SetGatewayResponse {} - -message ConfirmGatewayTxRequest { - option deprecated = true; - - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; -} - -message ConfirmGatewayTxResponse { option deprecated = true; } - -message ConfirmGatewayTxsRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - repeated bytes tx_ids = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxIDs" - ]; -} - -message ConfirmGatewayTxsResponse {} - -// MsgConfirmDeposit represents an erc20 deposit confirmation message -message ConfirmDepositRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - bytes amount = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false, - deprecated = true - ]; - bytes burner_address = 5 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; -} - -message ConfirmDepositResponse {} - -// MsgConfirmToken represents a token deploy confirmation message -message ConfirmTokenRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - Asset asset = 4 [ (gogoproto.nullable) = false ]; -} - -message ConfirmTokenResponse {} - -message ConfirmTransferKeyRequest { - reserved 4, 5; // transfer_type and key_id were deleted in v0.20 - - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 3 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; -} - -message ConfirmTransferKeyResponse {} - -// MsgLink represents the message that links a cross chain address to a burner -// address -message LinkRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string recipient_addr = 3; - string asset = 4; - string recipient_chain = 5 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message LinkResponse { string deposit_addr = 1; } - -// CreateBurnTokensRequest represents the message to create commands to burn -// tokens with AxelarGateway -message CreateBurnTokensRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message CreateBurnTokensResponse {} - -// CreateDeployTokenRequest represents the message to create a deploy token -// command for AxelarGateway -message CreateDeployTokenRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - Asset asset = 3 [ (gogoproto.nullable) = false ]; - TokenDetails token_details = 4 [ (gogoproto.nullable) = false ]; - reserved 5; // min_amount was removed in v0.15 - bytes address = 6 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - string daily_mint_limit = 7; -} - -message CreateDeployTokenResponse {} - -// CreatePendingTransfersRequest represents a message to trigger the creation of -// commands handling all pending transfers -message CreatePendingTransfersRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message CreatePendingTransfersResponse {} - -message CreateTransferOwnershipRequest { - option deprecated = true; - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message CreateTransferOwnershipResponse { option deprecated = true; } - -message CreateTransferOperatorshipRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message CreateTransferOperatorshipResponse {} - -message SignCommandsRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message SignCommandsResponse { - bytes batched_commands_id = 1 - [ (gogoproto.customname) = "BatchedCommandsID" ]; - uint32 command_count = 2; -} - -message AddChainRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - reserved 3; // native_asset was removed in v0.14 - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string name = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - tss.exported.v1beta1.KeyType key_type = 4 [ deprecated = true ]; - bytes params = 5 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Params" ]; -} - -message AddChainResponse {} - -message RetryFailedEventRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string event_id = 3 - [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; -} - -message RetryFailedEventResponse {} diff --git a/ampd/proto/axelar/evm/v1beta1/types.proto b/ampd/proto/axelar/evm/v1beta1/types.proto deleted file mode 100644 index 13a849cf9..000000000 --- a/ampd/proto/axelar/evm/v1beta1/types.proto +++ /dev/null @@ -1,375 +0,0 @@ -syntax = "proto3"; -package axelar.evm.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; -import "axelar/multisig/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message VoteEvents { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - repeated Event events = 2 [ (gogoproto.nullable) = false ]; -} - -message Event { - enum Status { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - STATUS_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "EventNonExistent" ]; - STATUS_CONFIRMED = 1 - [ (gogoproto.enumvalue_customname) = "EventConfirmed" ]; - STATUS_COMPLETED = 2 - [ (gogoproto.enumvalue_customname) = "EventCompleted" ]; - STATUS_FAILED = 3 [ (gogoproto.enumvalue_customname) = "EventFailed" ]; - } - - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 2 [ - (gogoproto.customname) = "TxID", - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash" - ]; - uint64 index = 3; - Status status = 4; - - oneof event { - EventTokenSent token_sent = 5; - EventContractCall contract_call = 6; - EventContractCallWithToken contract_call_with_token = 7; - EventTransfer transfer = 8; - EventTokenDeployed token_deployed = 9; - EventMultisigOwnershipTransferred multisig_ownership_transferred = 10 - [ deprecated = true ]; - EventMultisigOperatorshipTransferred multisig_operatorship_transferred = 11; - } - - reserved 12; // singlesig_ownership_transferred was removed in v0.23 - reserved 13; // singlesig_operatorship_transferred was removed in v0.23 -} - -message EventTokenSent { - bytes sender = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - string destination_chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string destination_address = 3; - string symbol = 4; - bytes amount = 5 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} - -message EventContractCall { - bytes sender = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - string destination_chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 3; - bytes payload_hash = 4 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; -} - -message EventContractCallWithToken { - bytes sender = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - string destination_chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string contract_address = 3; - bytes payload_hash = 4 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; - string symbol = 5; - bytes amount = 6 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} - -message EventTransfer { - bytes to = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes amount = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} - -message EventTokenDeployed { - string symbol = 1; - bytes token_address = 2 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; -} - -message EventMultisigOwnershipTransferred { - option deprecated = true; - - repeated bytes pre_owners = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes prev_threshold = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - repeated bytes new_owners = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes new_threshold = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} - -message EventMultisigOperatorshipTransferred { - reserved 1, 2; // pre_operators and prev_threshold were removed in v0.20 - - repeated bytes new_operators = 3 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes new_threshold = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - repeated bytes new_weights = 5 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} - -// NetworkInfo describes information about a network -message NetworkInfo { - string name = 1; - bytes id = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; -} - -// BurnerInfo describes information required to burn token at an burner address -// that is deposited by an user -message BurnerInfo { - bytes burner_address = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - bytes token_address = 2 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - string destination_chain = 3 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string symbol = 4; - string asset = 5; - bytes salt = 6 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; -} - -// ERC20Deposit contains information for an ERC20 deposit -message ERC20Deposit { - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - bytes amount = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - string asset = 3; - string destination_chain = 4 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes burner_address = 5 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - uint64 log_index = 6; -} - -// ERC20TokenMetadata describes information about an ERC20 token -message ERC20TokenMetadata { - string asset = 1; - bytes chain_id = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.customname) = "ChainID", - (gogoproto.nullable) = false - ]; - TokenDetails details = 3 [ (gogoproto.nullable) = false ]; - string token_address = 4 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; - string tx_hash = 5 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; - reserved 6; // min_amount was removed in v0.15 - Status status = 7; - bool is_external = 8; - bytes burner_code = 9; -} - -enum Status { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - // these enum values are used for bitwise operations, therefore they need to - // be powers of 2 - STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "NonExistent" ]; - STATUS_INITIALIZED = 1 [ (gogoproto.enumvalue_customname) = "Initialized" ]; - STATUS_PENDING = 2 [ (gogoproto.enumvalue_customname) = "Pending" ]; - STATUS_CONFIRMED = 4 [ (gogoproto.enumvalue_customname) = "Confirmed" ]; -} - -message TransactionMetadata { - bytes raw_tx = 1 [ (gogoproto.customname) = "RawTX" ]; - bytes pub_key = 2; -} - -enum CommandType { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = false; - - COMMAND_TYPE_UNSPECIFIED = 0; - COMMAND_TYPE_MINT_TOKEN = 1; - COMMAND_TYPE_DEPLOY_TOKEN = 2; - COMMAND_TYPE_BURN_TOKEN = 3; - COMMAND_TYPE_TRANSFER_OPERATORSHIP = 4; - COMMAND_TYPE_APPROVE_CONTRACT_CALL_WITH_MINT = 5; - COMMAND_TYPE_APPROVE_CONTRACT_CALL = 6; -} - -message Command { - bytes id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "ID", - (gogoproto.customtype) = "CommandID" - ]; - string command = 2 [ deprecated = true ]; - bytes params = 3; - string key_id = 4 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - uint32 max_gas_cost = 5; - CommandType type = 6; -} - -enum BatchedCommandsStatus { - option (gogoproto.goproto_enum_prefix) = false; - - BATCHED_COMMANDS_STATUS_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "BatchNonExistent" ]; - BATCHED_COMMANDS_STATUS_SIGNING = 1 - [ (gogoproto.enumvalue_customname) = "BatchSigning" ]; - BATCHED_COMMANDS_STATUS_ABORTED = 2 - [ (gogoproto.enumvalue_customname) = "BatchAborted" ]; - BATCHED_COMMANDS_STATUS_SIGNED = 3 - [ (gogoproto.enumvalue_customname) = "BatchSigned" ]; -} - -message CommandBatchMetadata { - bytes id = 1 [ (gogoproto.customname) = "ID" ]; - repeated bytes command_ids = 2 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "CommandIDs", - (gogoproto.customtype) = "CommandID" - ]; - bytes data = 3; - bytes sig_hash = 4 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; - BatchedCommandsStatus status = 5; - string key_id = 6 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - bytes prev_batched_commands_id = 7 - [ (gogoproto.customname) = "PrevBatchedCommandsID" ]; - google.protobuf.Any signature = 8 - [ (cosmos_proto.accepts_interface) = - "github.com/cosmos/codec/ProtoMarshaler" ]; -} - -// SigMetadata stores necessary information for external apps to map signature -// results to evm relay transaction types -message SigMetadata { - SigType type = 1; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; -} - -enum SigType { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - SIG_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "None" ]; - SIG_TYPE_TX = 1 [ (gogoproto.enumvalue_customname) = "SigTx" ]; - SIG_TYPE_COMMAND = 2 [ (gogoproto.enumvalue_customname) = "SigCommand" ]; -} - -// TransferKey contains information for a transfer operatorship -message TransferKey { - reserved 2; // type was deleted in v0.20 - - bytes tx_id = 1 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash", - (gogoproto.customname) = "TxID" - ]; - string next_key_id = 3 [ - (gogoproto.customname) = "NextKeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -enum DepositStatus { - option (gogoproto.goproto_enum_prefix) = true; - option (gogoproto.goproto_enum_stringer) = true; - - DEPOSIT_STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "None" ]; - DEPOSIT_STATUS_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; - DEPOSIT_STATUS_CONFIRMED = 2 - [ (gogoproto.enumvalue_customname) = "Confirmed" ]; - DEPOSIT_STATUS_BURNED = 3 [ (gogoproto.enumvalue_customname) = "Burned" ]; -} - -message Asset { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string name = 2; -} - -message TokenDetails { - string token_name = 1; - string symbol = 2; - uint32 decimals = 3 [ (gogoproto.casttype) = "uint8" ]; - bytes capacity = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; -} - -message Gateway { - reserved 2; // status was removed in v0.27 - - bytes address = 1 - [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; -} - -message PollMetadata { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - bytes tx_id = 2 [ - (gogoproto.customname) = "TxID", - (gogoproto.nullable) = false, - (gogoproto.customtype) = "Hash" - ]; -} diff --git a/ampd/proto/axelar/multisig/exported/v1beta1/types.proto b/ampd/proto/axelar/multisig/exported/v1beta1/types.proto deleted file mode 100644 index 97014922f..000000000 --- a/ampd/proto/axelar/multisig/exported/v1beta1/types.proto +++ /dev/null @@ -1,28 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.exported.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/exported"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -enum MultisigState { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - MULTISIG_STATE_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "NonExistent" ]; - MULTISIG_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; - MULTISIG_STATE_COMPLETED = 2 - [ (gogoproto.enumvalue_customname) = "Completed" ]; -} - -enum KeyState { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - KEY_STATE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "Inactive" ]; - KEY_STATE_ASSIGNED = 1 [ (gogoproto.enumvalue_customname) = "Assigned" ]; - KEY_STATE_ACTIVE = 2 [ (gogoproto.enumvalue_customname) = "Active" ]; -} diff --git a/ampd/proto/axelar/multisig/v1beta1/events.proto b/ampd/proto/axelar/multisig/v1beta1/events.proto deleted file mode 100644 index 80607c48e..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/events.proto +++ /dev/null @@ -1,127 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; - -import "gogoproto/gogo.proto"; - -message KeygenStarted { - string module = 1; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - repeated bytes participants = 3 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; -} - -message KeygenCompleted { - option (gogoproto.messagename) = true; - - string module = 1; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message KeygenExpired { - option (gogoproto.messagename) = true; - - string module = 1; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message PubKeySubmitted { - string module = 1; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - bytes participant = 3 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - bytes pub_key = 4 [ - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" - ]; -} - -message SigningStarted { - option (gogoproto.stable_marshaler) = true; - - string module = 1; - uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - map pub_keys = 4 [ - (gogoproto.castvalue) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" - ]; - bytes payload_hash = 5 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.Hash" ]; - string requesting_module = 6; -} - -message SigningCompleted { - string module = 1; - uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; -} - -message SigningExpired { - string module = 1; - uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; -} - -message SignatureSubmitted { - string module = 1; - uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; - bytes participant = 3 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - bytes signature = 4 [ (gogoproto.casttype) = "Signature" ]; -} - -message KeyAssigned { - string module = 1; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message KeyRotated { - string module = 1; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message KeygenOptOut { - bytes participant = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message KeygenOptIn { - bytes participant = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} diff --git a/ampd/proto/axelar/multisig/v1beta1/genesis.proto b/ampd/proto/axelar/multisig/v1beta1/genesis.proto deleted file mode 100644 index adbe82867..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/genesis.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; - -import "gogoproto/gogo.proto"; -import "axelar/multisig/v1beta1/params.proto"; -import "axelar/multisig/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - - repeated KeygenSession keygen_sessions = 2 [ (gogoproto.nullable) = false ]; - repeated SigningSession signing_sessions = 3 [ (gogoproto.nullable) = false ]; - repeated Key keys = 4 [ (gogoproto.nullable) = false ]; - repeated KeyEpoch key_epochs = 5 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/multisig/v1beta1/params.proto b/ampd/proto/axelar/multisig/v1beta1/params.proto deleted file mode 100644 index da500f485..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/params.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; - -import "gogoproto/gogo.proto"; -import "axelar/utils/v1beta1/threshold.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params { - utils.v1beta1.Threshold keygen_threshold = 1 [ (gogoproto.nullable) = false ]; - utils.v1beta1.Threshold signing_threshold = 2 - [ (gogoproto.nullable) = false ]; - int64 keygen_timeout = 3; - int64 keygen_grace_period = 4; - int64 signing_timeout = 5; - int64 signing_grace_period = 6; - uint64 active_epoch_count = 7; -} diff --git a/ampd/proto/axelar/multisig/v1beta1/query.proto b/ampd/proto/axelar/multisig/v1beta1/query.proto deleted file mode 100644 index d3b33c622..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/query.proto +++ /dev/null @@ -1,114 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "axelar/multisig/exported/v1beta1/types.proto"; -import "axelar/multisig/v1beta1/types.proto"; -import "axelar/utils/v1beta1/threshold.proto"; -import "axelar/multisig/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message KeyIDRequest { string chain = 1; } - -// KeyIDResponse contains the key ID of the key assigned to a given chain. -message KeyIDResponse { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message NextKeyIDRequest { string chain = 1; } - -// NextKeyIDResponse contains the key ID for the next rotation on the given -// chain -message NextKeyIDResponse { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message KeyRequest { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message KeygenParticipant { - string address = 1; - bytes weight = 2 [ - (gogoproto.nullable) = false, - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint" - ]; - string pub_key = 3; -} - -// KeyResponse contains the key corresponding to a given key id. -message KeyResponse { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - multisig.exported.v1beta1.KeyState state = 2; - int64 started_at = 3; - google.protobuf.Timestamp started_at_timestamp = 4 - [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; - bytes threshold_weight = 5 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - bytes bonded_weight = 6 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - // Keygen participants in descending order by weight - repeated KeygenParticipant participants = 7 [ (gogoproto.nullable) = false ]; -} - -message KeygenSessionRequest { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -// KeygenSessionResponse contains the keygen session info for a given key ID. -message KeygenSessionResponse { - int64 started_at = 1; - google.protobuf.Timestamp started_at_timestamp = 2 - [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; - int64 expires_at = 3; - int64 completed_at = 4; - int64 grace_period = 5; - multisig.exported.v1beta1.MultisigState state = 6; - bytes keygen_threshold_weight = 7 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - bytes signing_threshold_weight = 8 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - bytes bonded_weight = 9 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - // Keygen candidates in descending order by weight - repeated KeygenParticipant participants = 10 [ (gogoproto.nullable) = false ]; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/multisig/v1beta1/service.proto b/ampd/proto/axelar/multisig/v1beta1/service.proto deleted file mode 100644 index c7c39ae60..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/service.proto +++ /dev/null @@ -1,92 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/multisig/v1beta1/tx.proto"; -import "axelar/multisig/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the multisig Msg service. -service MsgService { - rpc StartKeygen(StartKeygenRequest) returns (StartKeygenResponse) { - option (google.api.http) = { - post : "/axelar/multisig/start_keygen" - body : "*" - }; - } - - rpc SubmitPubKey(SubmitPubKeyRequest) returns (SubmitPubKeyResponse) { - option (google.api.http) = { - post : "/axelar/multisig/submit_pub_key" - body : "*" - }; - } - - rpc SubmitSignature(SubmitSignatureRequest) - returns (SubmitSignatureResponse) { - option (google.api.http) = { - post : "/axelar/multisig/submit_signature" - body : "*" - }; - } - - rpc RotateKey(RotateKeyRequest) returns (RotateKeyResponse) { - option (google.api.http) = { - post : "/axelar/multisig/rotate_key" - body : "*" - }; - } - - rpc KeygenOptOut(KeygenOptOutRequest) returns (KeygenOptOutResponse) { - option (google.api.http) = { - post : "/axelar/multisig/v1beta1/keygen_opt_out" - body : "*" - }; - } - - rpc KeygenOptIn(KeygenOptInRequest) returns (KeygenOptInResponse) { - option (google.api.http) = { - post : "/axelar/multisig/v1beta1/keygen_opt_in" - body : "*" - }; - } -} - -// Query defines the gRPC querier service. -service QueryService { - // KeyID returns the key ID of a key assigned to a given chain. - // If no key is assigned, it returns the grpc NOT_FOUND error. - rpc KeyID(KeyIDRequest) returns (KeyIDResponse) { - option (google.api.http).get = "/axelar/multisig/v1beta1/key_id/{chain}"; - } - - // NextKeyID returns the key ID assigned for the next rotation on a given - // chain. If no key rotation is in progress, it returns the grpc NOT_FOUND - // error. - rpc NextKeyID(NextKeyIDRequest) returns (NextKeyIDResponse) { - option (google.api.http).get = - "/axelar/multisig/v1beta1/next_key_id/{chain}"; - } - - // Key returns the key corresponding to a given key ID. - // If no key is found, it returns the grpc NOT_FOUND error. - rpc Key(KeyRequest) returns (KeyResponse) { - option (google.api.http).get = "/axelar/multisig/v1beta1/key"; - } - - // KeygenSession returns the keygen session info for a given key ID. - // If no key is found, it returns the grpc NOT_FOUND error. - rpc KeygenSession(KeygenSessionRequest) returns (KeygenSessionResponse) { - option (google.api.http).get = "/axelar/multisig/v1beta1/keygen_session"; - } - - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/multisig/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/multisig/v1beta1/tx.proto b/ampd/proto/axelar/multisig/v1beta1/tx.proto deleted file mode 100644 index f816389e3..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/tx.proto +++ /dev/null @@ -1,86 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; -option (gogoproto.goproto_getters_all) = false; - -import "gogoproto/gogo.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -message StartKeygenRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - - string sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message StartKeygenResponse {} - -message SubmitPubKeyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - string sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - bytes pub_key = 3 [ - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" - ]; - bytes signature = 4 [ (gogoproto.casttype) = "Signature" ]; -} - -message SubmitPubKeyResponse {} - -message SubmitSignatureRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - string sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; - bytes signature = 3 [ (gogoproto.casttype) = "Signature" ]; -} - -message SubmitSignatureResponse {} - -message RotateKeyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} - -message RotateKeyResponse {} - -message KeygenOptOutRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message KeygenOptOutResponse {} - -message KeygenOptInRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message KeygenOptInResponse {} diff --git a/ampd/proto/axelar/multisig/v1beta1/types.proto b/ampd/proto/axelar/multisig/v1beta1/types.proto deleted file mode 100644 index fe32c3da6..000000000 --- a/ampd/proto/axelar/multisig/v1beta1/types.proto +++ /dev/null @@ -1,84 +0,0 @@ -syntax = "proto3"; -package axelar.multisig.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/utils/v1beta1/threshold.proto"; -import "axelar/snapshot/exported/v1beta1/types.proto"; -import "axelar/multisig/exported/v1beta1/types.proto"; - -message Key { - option (gogoproto.stable_marshaler) = true; - - string id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - snapshot.exported.v1beta1.Snapshot snapshot = 2 - [ (gogoproto.nullable) = false ]; - map pub_keys = 3 [ - (gogoproto.castvalue) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" - ]; - utils.v1beta1.Threshold signing_threshold = 4 - [ (gogoproto.nullable) = false ]; - multisig.exported.v1beta1.KeyState state = 5; -} - -message KeygenSession { - option (gogoproto.stable_marshaler) = true; - - Key key = 1 [ (gogoproto.nullable) = false ]; - multisig.exported.v1beta1.MultisigState state = 2; - utils.v1beta1.Threshold keygen_threshold = 3 [ (gogoproto.nullable) = false ]; - int64 expires_at = 4; - int64 completed_at = 5; - map is_pub_key_received = 6; - int64 grace_period = 7; -} - -message MultiSig { - option (gogoproto.stable_marshaler) = true; - - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; - bytes payload_hash = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.Hash" ]; - map sigs = 3 [ (gogoproto.castvalue) = "Signature" ]; -} - -message SigningSession { - option (gogoproto.stable_marshaler) = true; - - uint64 id = 1 [ (gogoproto.customname) = "ID" ]; - MultiSig multi_sig = 2 [ (gogoproto.nullable) = false ]; - multisig.exported.v1beta1.MultisigState state = 3; - Key key = 4 [ (gogoproto.nullable) = false ]; - int64 expires_at = 5; - int64 completed_at = 6; - int64 grace_period = 7; - string module = 8; - google.protobuf.Any module_metadata = 9 - [ (cosmos_proto.accepts_interface) = - "github.com/cosmos/codec/ProtoMarshaler" ]; -} - -message KeyEpoch { - uint64 epoch = 1; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string key_id = 3 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" - ]; -} diff --git a/ampd/proto/axelar/nexus/exported/v1beta1/types.proto b/ampd/proto/axelar/nexus/exported/v1beta1/types.proto deleted file mode 100644 index f108c119f..000000000 --- a/ampd/proto/axelar/nexus/exported/v1beta1/types.proto +++ /dev/null @@ -1,129 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.exported.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/exported"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Chain represents the properties of a registered blockchain -message Chain { - reserved 2; // native_asset was removed in 0.14 - - string name = 1 [ (gogoproto.casttype) = "ChainName" ]; - bool supports_foreign_assets = 3; - tss.exported.v1beta1.KeyType key_type = 4; - string module = 5; -} - -// CrossChainAddress represents a generalized address on any registered chain -message CrossChainAddress { - Chain chain = 1 [ (gogoproto.nullable) = false ]; - string address = 2; -} - -// CrossChainTransfer represents a generalized transfer of some asset to a -// registered blockchain -message CrossChainTransfer { - CrossChainAddress recipient = 1 [ (gogoproto.nullable) = false ]; - cosmos.base.v1beta1.Coin asset = 2 [ (gogoproto.nullable) = false ]; - uint64 id = 3 - [ (gogoproto.customname) = "ID", (gogoproto.casttype) = "TransferID" ]; - TransferState state = 4; -} - -enum TransferState { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - TRANSFER_STATE_UNSPECIFIED = 0; - TRANSFER_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; - TRANSFER_STATE_ARCHIVED = 2 [ (gogoproto.enumvalue_customname) = "Archived" ]; - TRANSFER_STATE_INSUFFICIENT_AMOUNT = 3 - [ (gogoproto.enumvalue_customname) = "InsufficientAmount" ]; -} - -// TransferFee represents accumulated fees generated by the network -message TransferFee { - repeated cosmos.base.v1beta1.Coin coins = 1 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.nullable) = false - ]; -} - -message FeeInfo { - string chain = 1 [ (gogoproto.casttype) = "ChainName" ]; - string asset = 2; - bytes fee_rate = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - bytes min_fee = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; - bytes max_fee = 5 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; -} - -message Asset { - string denom = 1; - reserved 2; // min_amount was removed in v0.15 - bool is_native_asset = 3; -} - -enum TransferDirection { - option (gogoproto.goproto_enum_prefix) = false; - - TRANSFER_DIRECTION_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "Unspecified" ]; - TRANSFER_DIRECTION_FROM = 1 - [ (gogoproto.enumvalue_customname) = "TransferDirectionFrom" ]; - TRANSFER_DIRECTION_TO = 2 - [ (gogoproto.enumvalue_customname) = "TransferDirectionTo" ]; -} - -message GeneralMessage { - enum Status { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "NonExistent" ]; - STATUS_APPROVED = 1 [ (gogoproto.enumvalue_customname) = "Approved" ]; - STATUS_PROCESSING = 2 [ (gogoproto.enumvalue_customname) = "Processing" ]; - STATUS_EXECUTED = 3 [ (gogoproto.enumvalue_customname) = "Executed" ]; - STATUS_FAILED = 4 [ (gogoproto.enumvalue_customname) = "Failed" ]; - } - - string id = 1 [ (gogoproto.customname) = "ID" ]; - CrossChainAddress sender = 2 [ (gogoproto.nullable) = false ]; - CrossChainAddress recipient = 3 [ (gogoproto.nullable) = false ]; - bytes payload_hash = 4; - Status status = 5; - cosmos.base.v1beta1.Coin asset = 6; - bytes source_tx_id = 7 [ (gogoproto.customname) = "SourceTxID" ]; - uint64 source_tx_index = 8; -} - -message WasmMessage { - string source_chain = 1 [ (gogoproto.casttype) = "ChainName" ]; - string source_address = 2; - string destination_chain = 3 [ (gogoproto.casttype) = "ChainName" ]; - string destination_address = 4; - bytes payload_hash = 5 [ (gogoproto.casttype) = "WasmBytes" ]; - bytes source_tx_id = 6 [ - (gogoproto.customname) = "SourceTxID", - (gogoproto.casttype) = "WasmBytes" - ]; - uint64 source_tx_index = 7 [ (gogoproto.jsontag) = "source_tx_index" ]; - bytes sender = 8 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string id = 9 [ - (gogoproto.customname) = "ID" - ]; -} diff --git a/ampd/proto/axelar/nexus/v1beta1/events.proto b/ampd/proto/axelar/nexus/v1beta1/events.proto deleted file mode 100644 index 7ec5ec829..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/events.proto +++ /dev/null @@ -1,66 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; -option (gogoproto.messagename_all) = true; - -import "google/protobuf/duration.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; - -message FeeDeducted { - uint64 transfer_id = 1 [ - (gogoproto.customname) = "TransferID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string recipient_chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string recipient_address = 3; - cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; - cosmos.base.v1beta1.Coin fee = 5 [ (gogoproto.nullable) = false ]; -} - -message InsufficientFee { - uint64 transfer_id = 1 [ - (gogoproto.customname) = "TransferID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" - ]; - string recipient_chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - string recipient_address = 3; - cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; - cosmos.base.v1beta1.Coin fee = 5 [ (gogoproto.nullable) = false ]; -} - -message RateLimitUpdated { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - cosmos.base.v1beta1.Coin limit = 2 [ (gogoproto.nullable) = false ]; - google.protobuf.Duration window = 3 - [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; -} - -message MessageReceived { - string id = 1 [ (gogoproto.customname) = "ID" ]; - bytes payload_hash = 2; - exported.v1beta1.CrossChainAddress sender = 3 - [ (gogoproto.nullable) = false ]; - exported.v1beta1.CrossChainAddress recipient = 4 - [ (gogoproto.nullable) = false ]; -} - -message MessageProcessing { string id = 1 [ (gogoproto.customname) = "ID" ]; } - -message MessageExecuted { string id = 1 [ (gogoproto.customname) = "ID" ]; } - -message MessageFailed { string id = 1 [ (gogoproto.customname) = "ID" ]; } - -message WasmMessageRouted { - exported.v1beta1.WasmMessage message = 1 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/nexus/v1beta1/genesis.proto b/ampd/proto/axelar/nexus/v1beta1/genesis.proto deleted file mode 100644 index 78011ebd7..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/genesis.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; - -import "gogoproto/gogo.proto"; -import "axelar/nexus/v1beta1/params.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; -import "axelar/nexus/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - - uint64 nonce = 2; - repeated nexus.exported.v1beta1.Chain chains = 3 - [ (gogoproto.nullable) = false ]; - repeated ChainState chain_states = 4 [ (gogoproto.nullable) = false ]; - repeated LinkedAddresses linked_addresses = 5 - [ (gogoproto.nullable) = false ]; - repeated nexus.exported.v1beta1.CrossChainTransfer transfers = 6 - [ (gogoproto.nullable) = false ]; - nexus.exported.v1beta1.TransferFee fee = 7 [ (gogoproto.nullable) = false ]; - repeated nexus.exported.v1beta1.FeeInfo fee_infos = 8 - [ (gogoproto.nullable) = false ]; - repeated RateLimit rate_limits = 9 [ (gogoproto.nullable) = false ]; - repeated TransferEpoch transfer_epochs = 10 [ (gogoproto.nullable) = false ]; - repeated nexus.exported.v1beta1.GeneralMessage messages = 11 - [ (gogoproto.nullable) = false ]; - uint64 message_nonce = 12; -} diff --git a/ampd/proto/axelar/nexus/v1beta1/params.proto b/ampd/proto/axelar/nexus/v1beta1/params.proto deleted file mode 100644 index 30c9074fa..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/params.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; - -import "gogoproto/gogo.proto"; -import "axelar/utils/v1beta1/threshold.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params { - utils.v1beta1.Threshold chain_activation_threshold = 1 - [ (gogoproto.nullable) = false ]; - utils.v1beta1.Threshold chain_maintainer_missing_vote_threshold = 2 - [ (gogoproto.nullable) = false ]; - utils.v1beta1.Threshold chain_maintainer_incorrect_vote_threshold = 3 - [ (gogoproto.nullable) = false ]; - int32 chain_maintainer_check_window = 4; - bytes gateway = 5 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - uint64 end_blocker_limit = 6; -} diff --git a/ampd/proto/axelar/nexus/v1beta1/query.proto b/ampd/proto/axelar/nexus/v1beta1/query.proto deleted file mode 100644 index b6371f4a8..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/query.proto +++ /dev/null @@ -1,175 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; - -import "google/protobuf/duration.proto"; -import "gogoproto/gogo.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; -import "axelar/nexus/v1beta1/types.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "axelar/nexus/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// ChainMaintainersRequest represents a message that queries -// the chain maintainers for the specified chain -message ChainMaintainersRequest { string chain = 1; } - -message ChainMaintainersResponse { - repeated bytes maintainers = 1 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; -} - -// LatestDepositAddressRequest represents a message that queries a deposit -// address by recipient address -message LatestDepositAddressRequest { - string recipient_addr = 1; - string recipient_chain = 2; - string deposit_chain = 3; -} - -message LatestDepositAddressResponse { string deposit_addr = 1; }; - -// TransfersForChainRequest represents a message that queries the -// transfers for the specified chain -message TransfersForChainRequest { - string chain = 1; - exported.v1beta1.TransferState state = 2; - cosmos.base.query.v1beta1.PageRequest pagination = 3; -} - -message TransfersForChainResponse { - repeated exported.v1beta1.CrossChainTransfer transfers = 1 - [ (gogoproto.nullable) = false ]; - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// FeeInfoRequest represents a message that queries the transfer fees associated -// to an asset on a chain -message FeeInfoRequest { - string chain = 1; - string asset = 2; -} - -message FeeInfoResponse { exported.v1beta1.FeeInfo fee_info = 1; } - -// TransferFeeRequest represents a message that queries the fees charged by -// the network for a cross-chain transfer -message TransferFeeRequest { - string source_chain = 1; - string destination_chain = 2; - string amount = 3; -} - -message TransferFeeResponse { - cosmos.base.v1beta1.Coin fee = 1 [ (gogoproto.nullable) = false ]; -} - -enum ChainStatus { - option (gogoproto.goproto_enum_prefix) = false; - - CHAIN_STATUS_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "Unspecified" ]; - CHAIN_STATUS_ACTIVATED = 1 [ (gogoproto.enumvalue_customname) = "Activated" ]; - CHAIN_STATUS_DEACTIVATED = 2 - [ (gogoproto.enumvalue_customname) = "Deactivated" ]; -} - -// ChainsRequest represents a message that queries the chains -// registered on the network -message ChainsRequest { ChainStatus status = 1; } - -message ChainsResponse { - repeated string chains = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -// AssetsRequest represents a message that queries the registered assets of a -// chain -message AssetsRequest { string chain = 1; } - -message AssetsResponse { repeated string assets = 1; } - -// ChainStateRequest represents a message that queries the state of a chain -// registered on the network -message ChainStateRequest { string chain = 1; } - -message ChainStateResponse { - ChainState state = 1 [ (gogoproto.nullable) = false ]; -} - -// ChainsByAssetRequest represents a message that queries the chains -// that support an asset on the network -message ChainsByAssetRequest { string asset = 1; } - -message ChainsByAssetResponse { - repeated string chains = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -// RecipientAddressRequest represents a message that queries the registered -// recipient address for a given deposit address -message RecipientAddressRequest { - string deposit_addr = 1; - string deposit_chain = 2; -} - -message RecipientAddressResponse { - string recipient_addr = 1; - string recipient_chain = 2; -}; - -// TransferRateLimitRequest represents a message that queries the registered -// transfer rate limit and current transfer amounts for a given chain and asset -message TransferRateLimitRequest { - string chain = 1; - string asset = 2; -} - -message TransferRateLimitResponse { TransferRateLimit transfer_rate_limit = 1; } - -message TransferRateLimit { - bytes limit = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; - google.protobuf.Duration window = 2 - [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; - bytes incoming = 3 [ - deprecated = true, - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; - bytes outgoing = 4 [ - deprecated = true, - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; - // time_left indicates the time left in the rate limit window - google.protobuf.Duration time_left = 5 - [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; - bytes from = 6 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; - bytes to = 7 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; -} - -message MessageRequest { string id = 1 [ (gogoproto.customname) = "ID" ]; } - -message MessageResponse { - exported.v1beta1.GeneralMessage message = 1 [ (gogoproto.nullable) = false ]; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/nexus/v1beta1/service.proto b/ampd/proto/axelar/nexus/v1beta1/service.proto deleted file mode 100644 index 881d2a4d7..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/service.proto +++ /dev/null @@ -1,150 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/nexus/v1beta1/tx.proto"; -import "axelar/nexus/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the nexus Msg service. -service MsgService { - rpc RegisterChainMaintainer(RegisterChainMaintainerRequest) - returns (RegisterChainMaintainerResponse) { - option (google.api.http) = { - post : "/axelar/nexus/register_chain_maintainer" - body : "*" - }; - } - - rpc DeregisterChainMaintainer(DeregisterChainMaintainerRequest) - returns (DeregisterChainMaintainerResponse) { - option (google.api.http) = { - post : "/axelar/nexus/deregister_chain_maintainer" - body : "*" - }; - } - - rpc ActivateChain(ActivateChainRequest) returns (ActivateChainResponse) { - option (google.api.http) = { - post : "/axelar/nexus/activate_chain" - body : "*" - }; - } - - rpc DeactivateChain(axelar.nexus.v1beta1.DeactivateChainRequest) - returns (axelar.nexus.v1beta1.DeactivateChainResponse) { - option (google.api.http) = { - post : "/axelar/nexus/deactivate_chain" - body : "*" - }; - } - - rpc RegisterAssetFee(RegisterAssetFeeRequest) - returns (RegisterAssetFeeResponse) { - option (google.api.http) = { - post : "/axelar/nexus/register_asset_fee" - body : "*" - }; - } - - rpc SetTransferRateLimit(SetTransferRateLimitRequest) - returns (SetTransferRateLimitResponse) { - option (google.api.http) = { - post : "/axelar/nexus/set_transfer_rate_limit" - body : "*" - }; - } -} - -// QueryService defines the gRPC querier service. -service QueryService { - // LatestDepositAddress queries the a deposit address by recipient - rpc LatestDepositAddress(LatestDepositAddressRequest) - returns (LatestDepositAddressResponse) { - option (google.api.http).get = - "/axelar/nexus/v1beta1/latest_deposit_address/" - "{recipient_addr}/{recipient_chain}/{deposit_chain}"; - } - - // TransfersForChain queries transfers by chain - rpc TransfersForChain(TransfersForChainRequest) - returns (TransfersForChainResponse) { - option (google.api.http).get = - "/axelar/nexus/v1beta1/transfers_for_chain/{chain}/{state}"; - } - - // FeeInfo queries the fee info by chain and asset - rpc FeeInfo(FeeInfoRequest) returns (FeeInfoResponse) { - option (google.api.http) = { - get : "/axelar/nexus/v1beta1/fee_info/{chain}/{asset}" - additional_bindings : {get : "/axelar/nexus/v1beta1/fee"} - }; - } - - // TransferFee queries the transfer fee by the source, destination chain, - // and amount. If amount is 0, the min fee is returned - rpc TransferFee(TransferFeeRequest) returns (TransferFeeResponse) { - option (google.api.http) = { - get : "/axelar/nexus/v1beta1/transfer_fee/{source_chain}/" - "{destination_chain}/{amount}" - additional_bindings : {get : "/axelar/nexus/v1beta1/transfer_fee"} - }; - } - - // Chains queries the chains registered on the network - rpc Chains(ChainsRequest) returns (ChainsResponse) { - option (google.api.http).get = "/axelar/nexus/v1beta1/chains"; - } - - // Assets queries the assets registered for a chain - rpc Assets(AssetsRequest) returns (AssetsResponse) { - option (google.api.http).get = "/axelar/nexus/v1beta1/assets/{chain}"; - } - - // ChainState queries the state of a registered chain on the network - rpc ChainState(ChainStateRequest) returns (ChainStateResponse) { - option (google.api.http).get = "/axelar/nexus/v1beta1/chain_state/{chain}"; - } - - // ChainsByAsset queries the chains that support an asset on the network - rpc ChainsByAsset(ChainsByAssetRequest) returns (ChainsByAssetResponse) { - option (google.api.http).get = - "/axelar/nexus/v1beta1/chains_by_asset/{asset}"; - } - - // RecipientAddress queries the recipient address for a given deposit address - rpc RecipientAddress(RecipientAddressRequest) - returns (RecipientAddressResponse) { - option (google.api.http).get = "/axelar/nexus/v1beta1/recipient_address/" - "{deposit_chain}/{deposit_addr}"; - } - - // ChainMaintainers queries the chain maintainers for a given chain - rpc ChainMaintainers(ChainMaintainersRequest) - returns (ChainMaintainersResponse) { - option (google.api.http).get = - "/axelar/nexus/v1beta1/chain_maintainers/{chain}"; - } - - // TransferRateLimit queries the transfer rate limit for a given chain and - // asset. If a rate limit is not set, nil is returned. - rpc TransferRateLimit(TransferRateLimitRequest) - returns (TransferRateLimitResponse) { - option (google.api.http).get = "/axelar/nexus/v1beta1/transfer_rate_limit/" - "{chain}/{asset}"; - } - - rpc Message(MessageRequest) returns (MessageResponse) { - option (google.api.http).get = "/axelar/nexus/v1beta1/message"; - } - - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/nexus/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/nexus/v1beta1/tx.proto b/ampd/proto/axelar/nexus/v1beta1/tx.proto deleted file mode 100644 index 555930043..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/tx.proto +++ /dev/null @@ -1,87 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; - -import "google/api/annotations.proto"; -import "google/protobuf/duration.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message RegisterChainMaintainerRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - repeated string chains = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message RegisterChainMaintainerResponse {} - -message DeregisterChainMaintainerRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - repeated string chains = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message DeregisterChainMaintainerResponse {} - -// ActivateChainRequest represents a message to activate chains -message ActivateChainRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - repeated string chains = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message ActivateChainResponse {} - -// DeactivateChainRequest represents a message to deactivate chains -message DeactivateChainRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - repeated string chains = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -message DeactivateChainResponse {} - -// RegisterAssetFeeRequest represents a message to register the transfer fee -// info associated to an asset on a chain -message RegisterAssetFeeRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - nexus.exported.v1beta1.FeeInfo fee_info = 2 [ (gogoproto.nullable) = false ]; -} - -message RegisterAssetFeeResponse {} - -// SetTransferRateLimitRequest represents a message to set rate limits on -// transfers -message SetTransferRateLimitRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - cosmos.base.v1beta1.Coin limit = 3 [ (gogoproto.nullable) = false ]; - google.protobuf.Duration window = 4 - [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; -} - -message SetTransferRateLimitResponse {} diff --git a/ampd/proto/axelar/nexus/v1beta1/types.proto b/ampd/proto/axelar/nexus/v1beta1/types.proto deleted file mode 100644 index 14503683f..000000000 --- a/ampd/proto/axelar/nexus/v1beta1/types.proto +++ /dev/null @@ -1,65 +0,0 @@ -syntax = "proto3"; -package axelar.nexus.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; - -import "google/protobuf/duration.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "axelar/nexus/exported/v1beta1/types.proto"; -import "axelar/utils/v1beta1/bitmap.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message MaintainerState { - bytes address = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - axelar.utils.v1beta1.Bitmap missing_votes = 2 - [ (gogoproto.nullable) = false ]; - axelar.utils.v1beta1.Bitmap incorrect_votes = 3 - [ (gogoproto.nullable) = false ]; - string chain = 4 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; -} - -// ChainState represents the state of a registered blockchain -message ChainState { - reserved 4; // total was removed in v0.13 - reserved 2; // maintainers was removed in v0.24 - - axelar.nexus.exported.v1beta1.Chain chain = 1 - [ (gogoproto.nullable) = false ]; - bool activated = 3; - repeated axelar.nexus.exported.v1beta1.Asset assets = 5 - [ (gogoproto.nullable) = false ]; - repeated MaintainerState maintainer_states = 6 - [ (gogoproto.nullable) = false, deprecated = true ]; -} - -message LinkedAddresses { - axelar.nexus.exported.v1beta1.CrossChainAddress deposit_address = 1 - [ (gogoproto.nullable) = false ]; - axelar.nexus.exported.v1beta1.CrossChainAddress recipient_address = 2 - [ (gogoproto.nullable) = false ]; -} - -message RateLimit { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - cosmos.base.v1beta1.Coin limit = 2 [ (gogoproto.nullable) = false ]; - google.protobuf.Duration window = 3 - [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; -} - -message TransferEpoch { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; - uint64 epoch = 3; - axelar.nexus.exported.v1beta1.TransferDirection direction = - 4; // indicates whether the rate tracking is for transfers going - // to that chain or coming from it -} diff --git a/ampd/proto/axelar/permission/exported/v1beta1/types.proto b/ampd/proto/axelar/permission/exported/v1beta1/types.proto deleted file mode 100644 index 7251daa8e..000000000 --- a/ampd/proto/axelar/permission/exported/v1beta1/types.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; -package axelar.permission.exported.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/exported"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/descriptor.proto"; - -option (gogoproto.goproto_getters_all) = false; - -enum Role { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - ROLE_UNSPECIFIED = 0; - ROLE_UNRESTRICTED = 1; - ROLE_CHAIN_MANAGEMENT = 2; - ROLE_ACCESS_CONTROL = 3; -} - -extend google.protobuf.MessageOptions { - permission.exported.v1beta1.Role permission_role = - 50000; // 50000-99999 reserved for use withing individual organizations -} diff --git a/ampd/proto/axelar/permission/v1beta1/genesis.proto b/ampd/proto/axelar/permission/v1beta1/genesis.proto deleted file mode 100644 index 7eef9a82e..000000000 --- a/ampd/proto/axelar/permission/v1beta1/genesis.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; -package axelar.permission.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/crypto/multisig/keys.proto"; -import "axelar/permission/v1beta1/types.proto"; -import "axelar/permission/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - - cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 2; - repeated GovAccount gov_accounts = 3 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/permission/v1beta1/params.proto b/ampd/proto/axelar/permission/v1beta1/params.proto deleted file mode 100644 index 232900e1b..000000000 --- a/ampd/proto/axelar/permission/v1beta1/params.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto3"; -package axelar.permission.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params {} diff --git a/ampd/proto/axelar/permission/v1beta1/query.proto b/ampd/proto/axelar/permission/v1beta1/query.proto deleted file mode 100644 index 997d72a8a..000000000 --- a/ampd/proto/axelar/permission/v1beta1/query.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; -package axelar.permission.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "cosmos/crypto/multisig/keys.proto"; -import "axelar/permission/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// QueryGovernanceKeyRequest is the request type for the -// Query/GovernanceKey RPC method -message QueryGovernanceKeyRequest {} - -// QueryGovernanceKeyResponse is the response type for the -// Query/GovernanceKey RPC method -message QueryGovernanceKeyResponse { - cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 1 - [ (gogoproto.nullable) = false ]; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/permission/v1beta1/service.proto b/ampd/proto/axelar/permission/v1beta1/service.proto deleted file mode 100644 index 02767573f..000000000 --- a/ampd/proto/axelar/permission/v1beta1/service.proto +++ /dev/null @@ -1,54 +0,0 @@ -syntax = "proto3"; -package axelar.permission.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/permission/v1beta1/tx.proto"; -import "axelar/permission/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the gov Msg service. -service Msg { - rpc RegisterController(axelar.permission.v1beta1.RegisterControllerRequest) - returns (axelar.permission.v1beta1.RegisterControllerResponse) { - option (google.api.http) = { - post : "/axelar/permission/register_controller" - body : "*" - }; - } - - rpc DeregisterController( - axelar.permission.v1beta1.DeregisterControllerRequest) - returns (axelar.permission.v1beta1.DeregisterControllerResponse) { - option (google.api.http) = { - post : "/axelar/permission/deregister_controller" - body : "*" - }; - } - - rpc UpdateGovernanceKey(axelar.permission.v1beta1.UpdateGovernanceKeyRequest) - returns (axelar.permission.v1beta1.UpdateGovernanceKeyResponse) { - option (google.api.http) = { - post : "/axelar/permission/update_governance_key" - body : "*" - }; - } -} - -// Query defines the gRPC querier service. -service Query { - // GovernanceKey returns the multisig governance key - rpc GovernanceKey(QueryGovernanceKeyRequest) - returns (QueryGovernanceKeyResponse) { - option (google.api.http).get = "/axelar/permission/v1beta1/governance_key"; - } - - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/permission/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/permission/v1beta1/tx.proto b/ampd/proto/axelar/permission/v1beta1/tx.proto deleted file mode 100644 index c06b467f3..000000000 --- a/ampd/proto/axelar/permission/v1beta1/tx.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; -package axelar.permission.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/crypto/multisig/keys.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message UpdateGovernanceKeyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 2 - [ (gogoproto.nullable) = false ]; -} - -message UpdateGovernanceKeyResponse {} - -// MsgRegisterController represents a message to register a controller account -message RegisterControllerRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - bytes controller = 2 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message RegisterControllerResponse {} - -// DeregisterController represents a message to deregister a controller account -message DeregisterControllerRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - bytes controller = 2 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} -message DeregisterControllerResponse {} diff --git a/ampd/proto/axelar/permission/v1beta1/types.proto b/ampd/proto/axelar/permission/v1beta1/types.proto deleted file mode 100644 index beb401ed0..000000000 --- a/ampd/proto/axelar/permission/v1beta1/types.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; -package axelar.permission.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; - -import "gogoproto/gogo.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message GovAccount { - bytes address = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - permission.exported.v1beta1.Role role = 2; -} diff --git a/ampd/proto/axelar/reward/v1beta1/genesis.proto b/ampd/proto/axelar/reward/v1beta1/genesis.proto deleted file mode 100644 index a805e07e9..000000000 --- a/ampd/proto/axelar/reward/v1beta1/genesis.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package axelar.reward.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; - -import "gogoproto/gogo.proto"; -import "axelar/reward/v1beta1/params.proto"; -import "axelar/reward/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - - repeated Pool pools = 2 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/reward/v1beta1/params.proto b/ampd/proto/axelar/reward/v1beta1/params.proto deleted file mode 100644 index 8fba73ecf..000000000 --- a/ampd/proto/axelar/reward/v1beta1/params.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; -package axelar.reward.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params { - bytes external_chain_voting_inflation_rate = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - bytes key_mgmt_relative_inflation_rate = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; -} diff --git a/ampd/proto/axelar/reward/v1beta1/query.proto b/ampd/proto/axelar/reward/v1beta1/query.proto deleted file mode 100644 index f3f7225ad..000000000 --- a/ampd/proto/axelar/reward/v1beta1/query.proto +++ /dev/null @@ -1,28 +0,0 @@ -syntax = "proto3"; -package axelar.reward.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; - -import "gogoproto/gogo.proto"; -import "axelar/reward/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// InflationRateRequest represents a message that queries the Axelar specific -// inflation RPC method. Ideally, this would use ValAddress as the validator -// field type. However, this makes it awkward for REST-based calls, because it -// would expect a byte array as part of the url. So, the bech32 encoded address -// string is used for this request instead. -message InflationRateRequest { string validator = 1; } - -message InflationRateResponse { - bytes inflation_rate = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/reward/v1beta1/service.proto b/ampd/proto/axelar/reward/v1beta1/service.proto deleted file mode 100644 index 363f136e9..000000000 --- a/ampd/proto/axelar/reward/v1beta1/service.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; -package axelar.reward.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/reward/v1beta1/tx.proto"; -import "axelar/reward/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the axelarnet Msg service. -service MsgService { - rpc RefundMsg(RefundMsgRequest) returns (RefundMsgResponse) { - option (google.api.http) = { - post : "/axelar/reward/refund_message" - body : "*" - }; - } -} - -// QueryService defines the gRPC querier service. -service QueryService { - rpc InflationRate(InflationRateRequest) returns (InflationRateResponse) { - option (google.api.http) = { - get : "/axelar/reward/v1beta1/inflation_rate/{validator}", - additional_bindings : { - get : "/axelar/reward/v1beta1/inflation_rate" // query network inflation - // rate, without having to - // pass empty validator - // `.../inflation_rate//` - } - }; - } - - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/reward/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/reward/v1beta1/tx.proto b/ampd/proto/axelar/reward/v1beta1/tx.proto deleted file mode 100644 index ec472dd52..000000000 --- a/ampd/proto/axelar/reward/v1beta1/tx.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; -package axelar.reward.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message RefundMsgRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - google.protobuf.Any inner_message = 2 - [ (cosmos_proto.accepts_interface) = "Refundable" ]; -} - -message RefundMsgResponse { - bytes data = 1; - string log = 2; -} diff --git a/ampd/proto/axelar/reward/v1beta1/types.proto b/ampd/proto/axelar/reward/v1beta1/types.proto deleted file mode 100644 index b025a95c0..000000000 --- a/ampd/proto/axelar/reward/v1beta1/types.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; -package axelar.reward.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message Pool { - message Reward { - bytes validator = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - repeated cosmos.base.v1beta1.Coin coins = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; - } - - string name = 1; - repeated Reward rewards = 2 [ (gogoproto.nullable) = false ]; -} - -message Refund { - bytes payer = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - - repeated cosmos.base.v1beta1.Coin fees = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} diff --git a/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto b/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto deleted file mode 100644 index 80d4a4435..000000000 --- a/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto +++ /dev/null @@ -1,39 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.exported.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/exported"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "google/protobuf/any.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/staking/v1beta1/staking.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message Participant { - bytes address = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - bytes weight = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} - -message Snapshot { - reserved 1, 4, 5, 6, 7; // validators, total_share_count, counter and - // corruption_threshold were deleted in v0.26 - - option (gogoproto.stable_marshaler) = true; - - google.protobuf.Timestamp timestamp = 2 - [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; - int64 height = 3; - map participants = 8 [ (gogoproto.nullable) = false ]; - bytes bonded_weight = 9 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; -} diff --git a/ampd/proto/axelar/snapshot/v1beta1/genesis.proto b/ampd/proto/axelar/snapshot/v1beta1/genesis.proto deleted file mode 100644 index 08d954526..000000000 --- a/ampd/proto/axelar/snapshot/v1beta1/genesis.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; - -import "gogoproto/gogo.proto"; -import "axelar/snapshot/v1beta1/params.proto"; -import "axelar/snapshot/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// GenesisState represents the genesis state -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - - repeated ProxiedValidator proxied_validators = 2 - [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/snapshot/v1beta1/params.proto b/ampd/proto/axelar/snapshot/v1beta1/params.proto deleted file mode 100644 index c22c60186..000000000 --- a/ampd/proto/axelar/snapshot/v1beta1/params.proto +++ /dev/null @@ -1,11 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params { int64 min_proxy_balance = 1; } diff --git a/ampd/proto/axelar/snapshot/v1beta1/query.proto b/ampd/proto/axelar/snapshot/v1beta1/query.proto deleted file mode 100644 index 0e9f53def..000000000 --- a/ampd/proto/axelar/snapshot/v1beta1/query.proto +++ /dev/null @@ -1,35 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; - -import "gogoproto/gogo.proto"; -import "axelar/snapshot/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message QueryValidatorsResponse { - message TssIllegibilityInfo { - bool tombstoned = 1; - bool jailed = 2; - bool missed_too_many_blocks = 3; - bool no_proxy_registered = 4; - bool tss_suspended = 5; - bool proxy_insuficient_funds = 6; - bool stale_tss_heartbeat = 7; - } - - message Validator { - string operator_address = 1; - string moniker = 2; - TssIllegibilityInfo tss_illegibility_info = 3 - [ (gogoproto.nullable) = false ]; - } - - repeated Validator validators = 1; -} - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/snapshot/v1beta1/service.proto b/ampd/proto/axelar/snapshot/v1beta1/service.proto deleted file mode 100644 index 82f430fd9..000000000 --- a/ampd/proto/axelar/snapshot/v1beta1/service.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/snapshot/v1beta1/tx.proto"; -import "axelar/snapshot/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the snapshot Msg service. -service MsgService { - // RegisterProxy defines a method for registering a proxy account that can act - // in a validator account's stead. - rpc RegisterProxy(RegisterProxyRequest) returns (RegisterProxyResponse) { - option (google.api.http) = { - post : "/axelar/snapshot/register_proxy" - body : "*" - }; - } - - // DeactivateProxy defines a method for deregistering a proxy account. - rpc DeactivateProxy(DeactivateProxyRequest) - returns (DeactivateProxyResponse) { - option (google.api.http) = { - post : "/axelar/snapshot/deactivate_proxy" - body : "*" - }; - } -} - -// QueryService defines the gRPC querier service. -service QueryService { - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/snapshot/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/snapshot/v1beta1/tx.proto b/ampd/proto/axelar/snapshot/v1beta1/tx.proto deleted file mode 100644 index 70a1c2c0e..000000000 --- a/ampd/proto/axelar/snapshot/v1beta1/tx.proto +++ /dev/null @@ -1,28 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message RegisterProxyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - bytes proxy_addr = 2 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; -} - -message RegisterProxyResponse {} - -message DeactivateProxyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; -} - -message DeactivateProxyResponse {} diff --git a/ampd/proto/axelar/snapshot/v1beta1/types.proto b/ampd/proto/axelar/snapshot/v1beta1/types.proto deleted file mode 100644 index 279c6e6fd..000000000 --- a/ampd/proto/axelar/snapshot/v1beta1/types.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package axelar.snapshot.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message ProxiedValidator { - bytes validator = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - bytes proxy = 2 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - bool active = 3; -} diff --git a/ampd/proto/axelar/tss/exported/v1beta1/types.proto b/ampd/proto/axelar/tss/exported/v1beta1/types.proto deleted file mode 100644 index 4b0d8bf1d..000000000 --- a/ampd/proto/axelar/tss/exported/v1beta1/types.proto +++ /dev/null @@ -1,68 +0,0 @@ -syntax = "proto3"; -package axelar.tss.exported.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/exported"; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/utils/v1beta1/threshold.proto"; -import "gogoproto/gogo.proto"; - -// KeyRequirement defines requirements for keys -message KeyRequirement { - KeyRole key_role = 1; - KeyType key_type = 2; - utils.v1beta1.Threshold min_keygen_threshold = 3 - [ (gogoproto.nullable) = false ]; - utils.v1beta1.Threshold safety_threshold = 4 [ (gogoproto.nullable) = false ]; - KeyShareDistributionPolicy key_share_distribution_policy = 5; - int64 max_total_share_count = 6; - int64 min_total_share_count = 7; - utils.v1beta1.Threshold keygen_voting_threshold = 8 - [ (gogoproto.nullable) = false ]; - utils.v1beta1.Threshold sign_voting_threshold = 9 - [ (gogoproto.nullable) = false ]; - int64 keygen_timeout = 10; - int64 sign_timeout = 11; -} - -enum KeyRole { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - KEY_ROLE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "Unknown" ]; - KEY_ROLE_MASTER_KEY = 1 [ (gogoproto.enumvalue_customname) = "MasterKey" ]; - KEY_ROLE_SECONDARY_KEY = 2 - [ (gogoproto.enumvalue_customname) = "SecondaryKey" ]; - KEY_ROLE_EXTERNAL_KEY = 3 - [ (gogoproto.enumvalue_customname) = "ExternalKey" ]; -} - -enum KeyType { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - KEY_TYPE_UNSPECIFIED = 0; - KEY_TYPE_NONE = 1 [ (gogoproto.enumvalue_customname) = "None" ]; - KEY_TYPE_THRESHOLD = 2 [ (gogoproto.enumvalue_customname) = "Threshold" ]; - KEY_TYPE_MULTISIG = 3 [ (gogoproto.enumvalue_customname) = "Multisig" ]; -} - -enum KeyShareDistributionPolicy { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - KEY_SHARE_DISTRIBUTION_POLICY_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "Unspecified" ]; - KEY_SHARE_DISTRIBUTION_POLICY_WEIGHTED_BY_STAKE = 1 - [ (gogoproto.enumvalue_customname) = "WeightedByStake" ]; - KEY_SHARE_DISTRIBUTION_POLICY_ONE_PER_VALIDATOR = 2 - [ (gogoproto.enumvalue_customname) = "OnePerValidator" ]; -} - -// PubKeyInfo holds a pubkey and a signature -message SigKeyPair { - bytes pub_key = 1; - bytes signature = 2; -} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto deleted file mode 100644 index 0683c5189..000000000 --- a/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto +++ /dev/null @@ -1,28 +0,0 @@ -// File copied from golang tofnd with minor tweaks -syntax = "proto3"; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; - -import "gogoproto/gogo.proto"; - -package axelar.tss.tofnd.v1beta1; - -// Key presence check types -message KeyPresenceRequest { - string key_uid = 1; - bytes pub_key = 2; // SEC1-encoded compressed pub key bytes to find the right - // mnemonic. Latest is used, if empty. -} - -message KeyPresenceResponse { - enum Response { - option (gogoproto.goproto_enum_prefix) = false; - - RESPONSE_UNSPECIFIED = 0; - RESPONSE_PRESENT = 1; - RESPONSE_ABSENT = 2; - RESPONSE_FAIL = 3; - } - - Response response = 1; -} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto deleted file mode 100644 index 82abaaf56..000000000 --- a/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto +++ /dev/null @@ -1,40 +0,0 @@ -// File copied from golang tofnd with minor tweaks -syntax = "proto3"; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; -import "axelar/tss/tofnd/v1beta1/common.proto"; // import key presence request/response - -package axelar.tss.tofnd.v1beta1; - -// service Multisig { -// rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); -// rpc Keygen(KeygenRequest) returns (KeygenResponse); -// rpc Sign(SignRequest) returns (SignResponse); -//} - -message KeygenRequest { - string key_uid = 1; - string party_uid = 2; // used only for logging -} - -message KeygenResponse { - oneof keygen_response { - bytes pub_key = 1; // SEC1-encoded compressed curve point - string error = 2; // reply with an error message if keygen fails - } -} - -message SignRequest { - string key_uid = 1; - bytes msg_to_sign = 2; // 32-byte pre-hashed message digest - string party_uid = 3; // used only for logging - bytes pub_key = 4; // SEC1-encoded compressed pub key bytes to find the right - // mnemonic. Latest is used, if empty. -} - -message SignResponse { - oneof sign_response { - bytes signature = 1; // ASN.1 DER-encoded ECDSA signature - string error = 2; // reply with an error message if sign fails - } -} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto deleted file mode 100644 index 96140268a..000000000 --- a/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto +++ /dev/null @@ -1,129 +0,0 @@ -// File copied from golang tofnd with minor tweaks -syntax = "proto3"; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; -import "gogoproto/gogo.proto"; -import "axelar/tss/tofnd/v1beta1/common.proto"; // import key presence request/response - -package axelar.tss.tofnd.v1beta1; - -// TODO: figure out why gogoproto produces unusable services -// GG20 is the protocol https://eprint.iacr.org/2020/540 -// rpc definitions intended to wrap the API for this library: -// https://github.com/axelarnetwork/tofn -// service GG20 { -// rpc Recover(RecoverRequest) returns (RecoverResponse); -// rpc Keygen(stream MessageIn) returns (stream MessageOut); -// rpc Sign(stream MessageIn) returns (stream MessageOut); -// rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); -//} - -message RecoverRequest { - KeygenInit keygen_init = 1; - KeygenOutput keygen_output = 2; -} -message RecoverResponse { - enum Response { - RESPONSE_UNSPECIFIED = 0; - RESPONSE_SUCCESS = 1; - RESPONSE_FAIL = 2; - } - Response response = 1; -} - -// Keygen's success response -message KeygenOutput { - bytes pub_key = 1; // pub_key; common for all parties - bytes group_recover_info = - 2; // recover info of all parties' shares; common for all parties - bytes private_recover_info = - 3; // private recover info of this party's shares; unique for each party -} - -// generic message types shared by Keygen, Sign - -// TODO use nested message types -// eg. KeygenInit, SignInit should be defined inside MessageIn, etc. - -message MessageIn { - oneof data { // TODO don't reuse `data` - KeygenInit keygen_init = 1; // first message only, Keygen - SignInit sign_init = 2; // first message only, Sign - TrafficIn traffic = 3; // all subsequent messages - bool abort = 4; // abort the protocol, ignore the bool value - } -} - -message MessageOut { - oneof data { // TODO don't reuse `data` - TrafficOut traffic = 1; // all but final message - KeygenResult keygen_result = 2; // final message only, Keygen - SignResult sign_result = 3; // final message only, Sign - bool need_recover = 4; // issue recover from client - } - - // Keygen's response types - message KeygenResult { - oneof keygen_result_data { - KeygenOutput data = 1; // Success response - CriminalList criminals = 2; // Faiilure response - } - } - - // Sign's response types - message SignResult { - oneof sign_result_data { - bytes signature = 1; // Success response - CriminalList criminals = 2; // Failure response - } - } - - // Keygen/Sign failure response message - message CriminalList { - repeated Criminal criminals = 1; - - message Criminal { - string party_uid = 1; - - enum CrimeType { - option (gogoproto.goproto_enum_prefix) = false; - - CRIME_TYPE_UNSPECIFIED = 0; - CRIME_TYPE_NON_MALICIOUS = 1; - CRIME_TYPE_MALICIOUS = 2; - } - CrimeType crime_type = 2; - } - } -} - -message TrafficIn { - string from_party_uid = 1; - bytes payload = 2; - bool is_broadcast = 3; -} - -message TrafficOut { - string to_party_uid = 1; - bytes payload = 2; - bool is_broadcast = 3; -} - -// Keygen-specific message types - -message KeygenInit { - string new_key_uid = 1; - repeated string party_uids = 2; - repeated uint32 party_share_counts = 5; - uint32 my_party_index = 3; // parties[my_party_index] belongs to the server - uint32 threshold = 4; -} - -// Sign-specific message types - -message SignInit { - string new_sig_uid = 1; - string key_uid = 2; - repeated string party_uids = 3; // TODO replace this with a subset of indices? - bytes message_to_sign = 4; -} diff --git a/ampd/proto/axelar/tss/v1beta1/genesis.proto b/ampd/proto/axelar/tss/v1beta1/genesis.proto deleted file mode 100644 index 1e411bb56..000000000 --- a/ampd/proto/axelar/tss/v1beta1/genesis.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; -package axelar.tss.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; - -import "gogoproto/gogo.proto"; -import "axelar/tss/v1beta1/params.proto"; -import "axelar/tss/v1beta1/types.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/tss/v1beta1/params.proto b/ampd/proto/axelar/tss/v1beta1/params.proto deleted file mode 100644 index ab44ac748..000000000 --- a/ampd/proto/axelar/tss/v1beta1/params.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; - -package axelar.tss.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; - -import "gogoproto/gogo.proto"; -import "axelar/utils/v1beta1/threshold.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params is the parameter set for this module -message Params { - // KeyRequirements defines the requirement for each key role - repeated tss.exported.v1beta1.KeyRequirement key_requirements = 1 - [ (gogoproto.nullable) = false ]; - // SuspendDurationInBlocks defines the number of blocks a - // validator is disallowed to participate in any TSS ceremony after - // committing a malicious behaviour during signing - int64 suspend_duration_in_blocks = 2; - // HeartBeatPeriodInBlocks defines the time period in blocks for tss to - // emit the event asking validators to send their heartbeats - int64 heartbeat_period_in_blocks = 3; - utils.v1beta1.Threshold max_missed_blocks_per_window = 4 - [ (gogoproto.nullable) = false ]; - int64 unbonding_locking_key_rotation_count = 5; - utils.v1beta1.Threshold external_multisig_threshold = 6 - [ (gogoproto.nullable) = false ]; - int64 max_sign_queue_size = 7; - int64 max_simultaneous_sign_shares = 8; - int64 tss_signed_blocks_window = 9; -} diff --git a/ampd/proto/axelar/tss/v1beta1/query.proto b/ampd/proto/axelar/tss/v1beta1/query.proto deleted file mode 100644 index 748cfefee..000000000 --- a/ampd/proto/axelar/tss/v1beta1/query.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; -package axelar.tss.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; - -import "gogoproto/gogo.proto"; -import "axelar/tss/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/tss/v1beta1/service.proto b/ampd/proto/axelar/tss/v1beta1/service.proto deleted file mode 100644 index 01dfce6ec..000000000 --- a/ampd/proto/axelar/tss/v1beta1/service.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; -package axelar.tss.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/snapshot/v1beta1/tx.proto"; -import "axelar/tss/v1beta1/tx.proto"; -import "axelar/tss/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the tss Msg service. -service MsgService { - rpc HeartBeat(axelar.tss.v1beta1.HeartBeatRequest) - returns (axelar.tss.v1beta1.HeartBeatResponse) { - option (google.api.http) = { - post : "/axelar/tss/heartbeat" - body : "*" - }; - } -} - -// Query defines the gRPC querier service. -service QueryService { - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/tss/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/tss/v1beta1/tx.proto b/ampd/proto/axelar/tss/v1beta1/tx.proto deleted file mode 100644 index 2cc6981d1..000000000 --- a/ampd/proto/axelar/tss/v1beta1/tx.proto +++ /dev/null @@ -1,147 +0,0 @@ -syntax = "proto3"; -package axelar.tss.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; - -import "gogoproto/gogo.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; -import "axelar/tss/v1beta1/types.proto"; -import "axelar/tss/tofnd/v1beta1/tofnd.proto"; -import "axelar/vote/exported/v1beta1/types.proto"; -import "cosmos/crypto/multisig/keys.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// StartKeygenRequest indicate the start of keygen -message StartKeygenRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - string sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - tss.v1beta1.KeyInfo key_info = 2 [ (gogoproto.nullable) = false ]; -} - -message StartKeygenResponse {} - -message RotateKeyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - tss.exported.v1beta1.KeyRole key_role = 3; - string key_id = 4 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; -} - -message RotateKeyResponse {} - -// ProcessKeygenTrafficRequest protocol message -message ProcessKeygenTrafficRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string session_id = 2 [ (gogoproto.customname) = "SessionID" ]; - tss.tofnd.v1beta1.TrafficOut payload = 3 [ (gogoproto.nullable) = false ]; -} - -message ProcessKeygenTrafficResponse {} - -// ProcessSignTrafficRequest protocol message -message ProcessSignTrafficRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string session_id = 2 [ (gogoproto.customname) = "SessionID" ]; - tss.tofnd.v1beta1.TrafficOut payload = 3 [ (gogoproto.nullable) = false ]; -} - -message ProcessSignTrafficResponse {} - -// VotePubKeyRequest represents the message to vote on a public key -message VotePubKeyRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - vote.exported.v1beta1.PollKey poll_key = 2 [ (gogoproto.nullable) = false ]; - tss.tofnd.v1beta1.MessageOut.KeygenResult result = 3 - [ (gogoproto.nullable) = false ]; -} -message VotePubKeyResponse { string log = 1; } - -// VoteSigRequest represents a message to vote for a signature -message VoteSigRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - vote.exported.v1beta1.PollKey poll_key = 2 [ (gogoproto.nullable) = false ]; - tss.tofnd.v1beta1.MessageOut.SignResult result = 3 - [ (gogoproto.nullable) = false ]; -} - -message VoteSigResponse { string log = 1; } - -message HeartBeatRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - - repeated string key_ids = 2 [ - (gogoproto.customname) = "KeyIDs", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; -} - -message HeartBeatResponse {} - -message RegisterExternalKeysRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; - message ExternalKey { - string id = 1 [ - (gogoproto.customname) = "ID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; - bytes pub_key = 2; - } - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string chain = 2 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - repeated ExternalKey external_keys = 3 [ (gogoproto.nullable) = false ]; -} - -message RegisterExternalKeysResponse {}; - -message SubmitMultisigPubKeysRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string key_id = 2 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; - repeated exported.v1beta1.SigKeyPair sig_key_pairs = 3 - [ (gogoproto.nullable) = false ]; -} - -message SubmitMultisigPubKeysResponse {} - -message SubmitMultisigSignaturesRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - string sig_id = 2 [ (gogoproto.customname) = "SigID" ]; - - repeated bytes signatures = 3; -} - -message SubmitMultisigSignaturesResponse {} diff --git a/ampd/proto/axelar/tss/v1beta1/types.proto b/ampd/proto/axelar/tss/v1beta1/types.proto deleted file mode 100644 index 86fd8dae2..000000000 --- a/ampd/proto/axelar/tss/v1beta1/types.proto +++ /dev/null @@ -1,63 +0,0 @@ -syntax = "proto3"; -package axelar.tss.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; - -import "gogoproto/gogo.proto"; -import "axelar/tss/exported/v1beta1/types.proto"; - -message KeygenVoteData { - bytes pub_key = 1; - bytes group_recovery_info = 2; -} - -// KeyInfo holds information about a key -message KeyInfo { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; - tss.exported.v1beta1.KeyRole key_role = 2; - tss.exported.v1beta1.KeyType key_type = 3; -} - -message MultisigInfo { - message Info { - bytes participant = 1 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - repeated bytes data = 2; - } - string id = 1 [ (gogoproto.customname) = "ID" ]; - int64 timeout = 2; - int64 target_num = 3; - repeated Info infos = 4; -} - -message KeyRecoveryInfo { - string key_id = 1 [ - (gogoproto.customname) = "KeyID", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; - bytes public = 2; - map private = 3 [ (gogoproto.nullable) = false ]; -} - -message ExternalKeys { - string chain = 1 - [ (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; - repeated string key_ids = 2 [ - (gogoproto.customname) = "KeyIDs", - (gogoproto.casttype) = - "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" - ]; -} - -message ValidatorStatus { - bytes validator = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; - uint64 suspended_until = 2; -} diff --git a/ampd/proto/axelar/utils/v1beta1/bitmap.proto b/ampd/proto/axelar/utils/v1beta1/bitmap.proto deleted file mode 100644 index 4f9c714c2..000000000 --- a/ampd/proto/axelar/utils/v1beta1/bitmap.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package axelar.utils.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/utils"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message Bitmap { CircularBuffer true_count_cache = 2; } - -message CircularBuffer { - repeated uint64 cumulative_value = 1; - int32 index = 2; - int32 max_size = 3; -} diff --git a/ampd/proto/axelar/utils/v1beta1/queuer.proto b/ampd/proto/axelar/utils/v1beta1/queuer.proto deleted file mode 100644 index 663d9b5a5..000000000 --- a/ampd/proto/axelar/utils/v1beta1/queuer.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; -package axelar.utils.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/utils"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message QueueState { - option (gogoproto.stable_marshaler) = true; - - message Item { - bytes key = 1; - bytes value = 2; - } - - map items = 1 [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/utils/v1beta1/threshold.proto b/ampd/proto/axelar/utils/v1beta1/threshold.proto deleted file mode 100644 index 3d0f17a70..000000000 --- a/ampd/proto/axelar/utils/v1beta1/threshold.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package axelar.utils.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/utils"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message Threshold { - option (gogoproto.goproto_stringer) = false; - // split threshold into Numerator and denominator to avoid floating point - // errors down the line - int64 numerator = 1; - int64 denominator = 2; -} diff --git a/ampd/proto/axelar/vote/exported/v1beta1/types.proto b/ampd/proto/axelar/vote/exported/v1beta1/types.proto deleted file mode 100644 index bc5e9f32e..000000000 --- a/ampd/proto/axelar/vote/exported/v1beta1/types.proto +++ /dev/null @@ -1,73 +0,0 @@ -syntax = "proto3"; -package axelar.vote.exported.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/exported"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/snapshot/exported/v1beta1/types.proto"; -import "axelar/utils/v1beta1/threshold.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// PollMetadata represents a poll with write-in voting, i.e. the result of the -// vote can have any data type -message PollMetadata { - reserved 1, 8, 9, 14; // deleted poll key, total voting power, voters and - // module_metadata in 0.20.x - - int64 expires_at = 3; - google.protobuf.Any result = 4 - [ (cosmos_proto.accepts_interface) = - "github.com/cosmos/codec/ProtoMarshaler" ]; - utils.v1beta1.Threshold voting_threshold = 5 [ (gogoproto.nullable) = false ]; - PollState state = 6; - int64 min_voter_count = 7; - string reward_pool_name = 10; - int64 grace_period = 11; - int64 completed_at = 12; - uint64 id = 13 [ - (gogoproto.customname) = "ID", - (gogoproto.customtype) = "PollID", - (gogoproto.nullable) = false - ]; - snapshot.exported.v1beta1.Snapshot snapshot = 15 - [ (gogoproto.nullable) = false ]; - string module = 16; - google.protobuf.Any module_metadata = 17 - [ (cosmos_proto.accepts_interface) = - "github.com/cosmos/codec/ProtoMarshaler" ]; -} - -// PollKey represents the key data for a poll -message PollKey { - option deprecated = true; - option (gogoproto.goproto_stringer) = false; - - string module = 1; - string id = 2 [ (gogoproto.customname) = "ID" ]; -} - -enum PollState { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = true; - - POLL_STATE_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "NonExistent" ]; - POLL_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; - POLL_STATE_COMPLETED = 2 [ (gogoproto.enumvalue_customname) = "Completed" ]; - POLL_STATE_FAILED = 3 [ (gogoproto.enumvalue_customname) = "Failed" ]; -} - -// PollParticipants should be embedded in poll events in other modules -message PollParticipants { - uint64 poll_id = 1 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = "PollID", - (gogoproto.nullable) = false - ]; - repeated bytes participants = 2 - [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; -} diff --git a/ampd/proto/axelar/vote/v1beta1/events.proto b/ampd/proto/axelar/vote/v1beta1/events.proto deleted file mode 100644 index 8a81dad60..000000000 --- a/ampd/proto/axelar/vote/v1beta1/events.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package axelar.vote.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "gogoproto/gogo.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message Voted { - string module = 1; - string action = 2; - string poll = 3; - string voter = 4; - string state = 5; -} diff --git a/ampd/proto/axelar/vote/v1beta1/genesis.proto b/ampd/proto/axelar/vote/v1beta1/genesis.proto deleted file mode 100644 index b26503c51..000000000 --- a/ampd/proto/axelar/vote/v1beta1/genesis.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -package axelar.vote.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "gogoproto/gogo.proto"; -import "axelar/vote/v1beta1/params.proto"; -import "axelar/vote/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - - repeated vote.exported.v1beta1.PollMetadata poll_metadatas = 2 - [ (gogoproto.nullable) = false ]; -} diff --git a/ampd/proto/axelar/vote/v1beta1/params.proto b/ampd/proto/axelar/vote/v1beta1/params.proto deleted file mode 100644 index 95f853532..000000000 --- a/ampd/proto/axelar/vote/v1beta1/params.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package axelar.vote.v1beta1; -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "gogoproto/gogo.proto"; -import "axelar/utils/v1beta1/threshold.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// Params represent the genesis parameters for the module -message Params { - utils.v1beta1.Threshold default_voting_threshold = 1 - [ (gogoproto.nullable) = false ]; - int64 end_blocker_limit = 2; -} diff --git a/ampd/proto/axelar/vote/v1beta1/query.proto b/ampd/proto/axelar/vote/v1beta1/query.proto deleted file mode 100644 index d99457a28..000000000 --- a/ampd/proto/axelar/vote/v1beta1/query.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; -package axelar.vote.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "gogoproto/gogo.proto"; -import "axelar/vote/v1beta1/params.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// ParamsRequest represents a message that queries the params -message ParamsRequest {} - -message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/vote/v1beta1/service.proto b/ampd/proto/axelar/vote/v1beta1/service.proto deleted file mode 100644 index 1dfd1574f..000000000 --- a/ampd/proto/axelar/vote/v1beta1/service.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; -package axelar.vote.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "axelar/vote/v1beta1/tx.proto"; -import "axelar/vote/v1beta1/query.proto"; - -option (gogoproto.goproto_registration) = true; - -// Msg defines the vote Msg service. -service MsgService { - rpc Vote(VoteRequest) returns (VoteResponse) { - option (google.api.http) = { - post : "/axelar/vote/vote" - body : "*" - }; - } -} - -// QueryService defines the gRPC querier service. -service QueryService { - rpc Params(ParamsRequest) returns (ParamsResponse) { - option (google.api.http) = { - get : "/axelar/vote/v1beta1/params" - }; - } -} diff --git a/ampd/proto/axelar/vote/v1beta1/tx.proto b/ampd/proto/axelar/vote/v1beta1/tx.proto deleted file mode 100644 index 771005831..000000000 --- a/ampd/proto/axelar/vote/v1beta1/tx.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto3"; -package axelar.vote.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/permission/exported/v1beta1/types.proto"; -import "axelar/vote/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -message VoteRequest { - option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; - - reserved 2, 3; // poll_key and vote were removed in v0.20 - - bytes sender = 1 [ (gogoproto.casttype) = - "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; - uint64 poll_id = 4 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", - (gogoproto.nullable) = false - ]; - google.protobuf.Any vote = 5 [ (cosmos_proto.accepts_interface) = - "github.com/cosmos/codec/ProtoMarshaler" ]; -} - -message VoteResponse { string log = 1; } diff --git a/ampd/proto/axelar/vote/v1beta1/types.proto b/ampd/proto/axelar/vote/v1beta1/types.proto deleted file mode 100644 index 92b64ce57..000000000 --- a/ampd/proto/axelar/vote/v1beta1/types.proto +++ /dev/null @@ -1,33 +0,0 @@ -syntax = "proto3"; -package axelar.vote.v1beta1; - -option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "axelar/vote/exported/v1beta1/types.proto"; - -option (gogoproto.goproto_getters_all) = false; - -// TalliedVote represents a vote for a poll with the accumulated stake of all -// validators voting for the same data -message TalliedVote { - reserved 2; // voters is deleted in version 0.20.x - - option (gogoproto.stable_marshaler) = true; - - bytes tally = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", - (gogoproto.nullable) = false - ]; - google.protobuf.Any data = 3 [ (cosmos_proto.accepts_interface) = - "github.com/cosmos/codec/ProtoMarshaler" ]; - uint64 poll_id = 4 [ - (gogoproto.customname) = "PollID", - (gogoproto.customtype) = - "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", - (gogoproto.nullable) = false - ]; - map is_voter_late = 5; -} diff --git a/ampd/proto/third_party/buf.yaml b/ampd/proto/third_party/buf.yaml deleted file mode 100644 index aae636f0a..000000000 --- a/ampd/proto/third_party/buf.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by "buf config migrate-v1beta1". Edit as necessary, and -# remove this comment when you're finished. -# -# This module represents the "proto" root found in -# the previous configuration. -version: v1 -breaking: - use: - - FILE -lint: - use: - - DEFAULT - - COMMENTS - - FILE_LOWER_SNAKE_CASE - except: - - UNARY_RPC - - COMMENT_FIELD - - SERVICE_SUFFIX - - PACKAGE_VERSION_SUFFIX - - RPC_REQUEST_STANDARD_NAME diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto deleted file mode 100644 index 72e1d9ec2..000000000 --- a/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto +++ /dev/null @@ -1,50 +0,0 @@ -syntax = "proto3"; -package cosmos.auth.v1beta1; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; - -// BaseAccount defines a base account type. It contains all the necessary fields -// for basic account functionality. Any custom account type should extend this -// type for additional functionality (e.g. vesting). -message BaseAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.equal) = false; - - option (cosmos_proto.implements_interface) = "AccountI"; - - string address = 1; - google.protobuf.Any pub_key = 2 - [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; - uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""]; - uint64 sequence = 4; -} - -// ModuleAccount defines an account for modules that holds coins on a pool. -message ModuleAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (cosmos_proto.implements_interface) = "ModuleAccountI"; - - BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; - string name = 2; - repeated string permissions = 3; -} - -// Params defines the parameters for the auth module. -message Params { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - uint64 max_memo_characters = 1 [(gogoproto.moretags) = "yaml:\"max_memo_characters\""]; - uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""]; - uint64 tx_size_cost_per_byte = 3 [(gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\""]; - uint64 sig_verify_cost_ed25519 = 4 - [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""]; - uint64 sig_verify_cost_secp256k1 = 5 - [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; -} diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto deleted file mode 100644 index c88b94ee4..000000000 --- a/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package cosmos.auth.v1beta1; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/auth/v1beta1/auth.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; - -// GenesisState defines the auth module's genesis state. -message GenesisState { - // params defines all the paramaters of the module. - Params params = 1 [(gogoproto.nullable) = false]; - - // accounts are the accounts present at genesis. - repeated google.protobuf.Any accounts = 2; -} diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto deleted file mode 100644 index 79799a4b7..000000000 --- a/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto +++ /dev/null @@ -1,89 +0,0 @@ -syntax = "proto3"; -package cosmos.auth.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "cosmos/auth/v1beta1/auth.proto"; -import "cosmos_proto/cosmos.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; - -// Query defines the gRPC querier service. -service Query { - // Accounts returns all the existing accounts - // - // Since: cosmos-sdk 0.43 - rpc Accounts(QueryAccountsRequest) returns (QueryAccountsResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/accounts"; - } - - // Account returns account details based on address. - rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; - } - - // Params queries all parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/params"; - } - - // ModuleAccountByName returns the module account info by module name - rpc ModuleAccountByName(QueryModuleAccountByNameRequest) returns (QueryModuleAccountByNameResponse) { - option (google.api.http).get = "/cosmos/auth/v1beta1/module_accounts/{name}"; - } -} - -// QueryAccountsRequest is the request type for the Query/Accounts RPC method. -// -// Since: cosmos-sdk 0.43 -message QueryAccountsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryAccountsResponse is the response type for the Query/Accounts RPC method. -// -// Since: cosmos-sdk 0.43 -message QueryAccountsResponse { - // accounts are the existing accounts - repeated google.protobuf.Any accounts = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryAccountRequest is the request type for the Query/Account RPC method. -message QueryAccountRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address defines the address to query for. - string address = 1; -} - -// QueryAccountResponse is the response type for the Query/Account RPC method. -message QueryAccountResponse { - // account defines the account of the corresponding address. - google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [(gogoproto.nullable) = false]; -} - -// QueryModuleAccountByNameRequest is the request type for the Query/ModuleAccountByName RPC method. -message QueryModuleAccountByNameRequest { - string name = 1; -} - -// QueryModuleAccountByNameResponse is the response type for the Query/ModuleAccountByName RPC method. -message QueryModuleAccountByNameResponse { - google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "ModuleAccountI"]; -} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto deleted file mode 100644 index 05b1feefa..000000000 --- a/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto +++ /dev/null @@ -1,39 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.authz.v1beta1; - -import "cosmos_proto/cosmos.proto"; -import "google/protobuf/timestamp.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; -option (gogoproto.goproto_getters_all) = false; - -// GenericAuthorization gives the grantee unrestricted permissions to execute -// the provided method on behalf of the granter's account. -message GenericAuthorization { - option (cosmos_proto.implements_interface) = "Authorization"; - - // Msg, identified by it's type URL, to grant unrestricted permissions to execute - string msg = 1; -} - -// Grant gives permissions to execute -// the provide method with expiration time. -message Grant { - google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"]; - google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; -} - -// GrantAuthorization extends a grant with both the addresses of the grantee and granter. -// It is used in genesis.proto and query.proto -// -// Since: cosmos-sdk 0.45.2 -message GrantAuthorization { - string granter = 1; - string grantee = 2; - - google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"]; - google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; -} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto deleted file mode 100644 index 7a3cf7c8c..000000000 --- a/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto +++ /dev/null @@ -1,25 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.authz.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; - -// EventGrant is emitted on Msg/Grant -message EventGrant { - // Msg type URL for which an autorization is granted - string msg_type_url = 2; - // Granter account address - string granter = 3; - // Grantee account address - string grantee = 4; -} - -// EventRevoke is emitted on Msg/Revoke -message EventRevoke { - // Msg type URL for which an autorization is revoked - string msg_type_url = 2; - // Granter account address - string granter = 3; - // Grantee account address - string grantee = 4; -} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto deleted file mode 100644 index 310f62656..000000000 --- a/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto +++ /dev/null @@ -1,13 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.authz.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/authz/v1beta1/authz.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; - -// GenesisState defines the authz module's genesis state. -message GenesisState { - repeated GrantAuthorization authorization = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto deleted file mode 100644 index f668309be..000000000 --- a/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto +++ /dev/null @@ -1,81 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.authz.v1beta1; - -import "google/api/annotations.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "cosmos/authz/v1beta1/authz.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; - -// Query defines the gRPC querier service. -service Query { - // Returns list of `Authorization`, granted to the grantee by the granter. - rpc Grants(QueryGrantsRequest) returns (QueryGrantsResponse) { - option (google.api.http).get = "/cosmos/authz/v1beta1/grants"; - } - - // GranterGrants returns list of `GrantAuthorization`, granted by granter. - // - // Since: cosmos-sdk 0.45.2 - rpc GranterGrants(QueryGranterGrantsRequest) returns (QueryGranterGrantsResponse) { - option (google.api.http).get = "/cosmos/authz/v1beta1/grants/granter/{granter}"; - } - - // GranteeGrants returns a list of `GrantAuthorization` by grantee. - // - // Since: cosmos-sdk 0.45.2 - rpc GranteeGrants(QueryGranteeGrantsRequest) returns (QueryGranteeGrantsResponse) { - option (google.api.http).get = "/cosmos/authz/v1beta1/grants/grantee/{grantee}"; - } -} - -// QueryGrantsRequest is the request type for the Query/Grants RPC method. -message QueryGrantsRequest { - string granter = 1; - string grantee = 2; - // Optional, msg_type_url, when set, will query only grants matching given msg type. - string msg_type_url = 3; - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 4; -} - -// QueryGrantsResponse is the response type for the Query/Authorizations RPC method. -message QueryGrantsResponse { - // authorizations is a list of grants granted for grantee by granter. - repeated Grant grants = 1; - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryGranterGrantsRequest is the request type for the Query/GranterGrants RPC method. -message QueryGranterGrantsRequest { - string granter = 1; - - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryGranterGrantsResponse is the response type for the Query/GranterGrants RPC method. -message QueryGranterGrantsResponse { - // grants is a list of grants granted by the granter. - repeated GrantAuthorization grants = 1; - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryGranteeGrantsRequest is the request type for the Query/IssuedGrants RPC method. -message QueryGranteeGrantsRequest { - string grantee = 1; - - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryGranteeGrantsResponse is the response type for the Query/GranteeGrants RPC method. -message QueryGranteeGrantsResponse { - // grants is a list of grants granted to the grantee. - repeated GrantAuthorization grants = 1; - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto deleted file mode 100644 index 457f0d662..000000000 --- a/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto +++ /dev/null @@ -1,70 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.authz.v1beta1; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "google/protobuf/any.proto"; -import "cosmos/base/abci/v1beta1/abci.proto"; -import "cosmos/authz/v1beta1/authz.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; -option (gogoproto.goproto_getters_all) = false; - -// Msg defines the authz Msg service. -service Msg { - // Grant grants the provided authorization to the grantee on the granter's - // account with the provided expiration time. If there is already a grant - // for the given (granter, grantee, Authorization) triple, then the grant - // will be overwritten. - rpc Grant(MsgGrant) returns (MsgGrantResponse); - - // Exec attempts to execute the provided messages using - // authorizations granted to the grantee. Each message should have only - // one signer corresponding to the granter of the authorization. - rpc Exec(MsgExec) returns (MsgExecResponse); - - // Revoke revokes any authorization corresponding to the provided method name on the - // granter's account that has been granted to the grantee. - rpc Revoke(MsgRevoke) returns (MsgRevokeResponse); -} - -// MsgGrant is a request type for Grant method. It declares authorization to the grantee -// on behalf of the granter with the provided expiration time. -message MsgGrant { - string granter = 1; - string grantee = 2; - - cosmos.authz.v1beta1.Grant grant = 3 [(gogoproto.nullable) = false]; -} - -// MsgExecResponse defines the Msg/MsgExecResponse response type. -message MsgExecResponse { - repeated bytes results = 1; -} - -// MsgExec attempts to execute the provided messages using -// authorizations granted to the grantee. Each message should have only -// one signer corresponding to the granter of the authorization. -message MsgExec { - string grantee = 1; - // Authorization Msg requests to execute. Each msg must implement Authorization interface - // The x/authz will try to find a grant matching (msg.signers[0], grantee, MsgTypeURL(msg)) - // triple and validate it. - repeated google.protobuf.Any msgs = 2 [(cosmos_proto.accepts_interface) = "sdk.Msg, authz.Authorization"]; -} - -// MsgGrantResponse defines the Msg/MsgGrant response type. -message MsgGrantResponse {} - -// MsgRevoke revokes any authorization with the provided sdk.Msg type on the -// granter's account with that has been granted to the grantee. -message MsgRevoke { - string granter = 1; - string grantee = 2; - string msg_type_url = 3; -} - -// MsgRevokeResponse defines the Msg/MsgRevokeResponse response type. -message MsgRevokeResponse {} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto deleted file mode 100644 index 4f58b15e4..000000000 --- a/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; -package cosmos.bank.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; - -// SendAuthorization allows the grantee to spend up to spend_limit coins from -// the granter's account. -// -// Since: cosmos-sdk 0.43 -message SendAuthorization { - option (cosmos_proto.implements_interface) = "Authorization"; - - repeated cosmos.base.v1beta1.Coin spend_limit = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto deleted file mode 100644 index df91008df..000000000 --- a/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto +++ /dev/null @@ -1,96 +0,0 @@ -syntax = "proto3"; -package cosmos.bank.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; - -// Params defines the parameters for the bank module. -message Params { - option (gogoproto.goproto_stringer) = false; - repeated SendEnabled send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled,omitempty\""]; - bool default_send_enabled = 2 [(gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\""]; -} - -// SendEnabled maps coin denom to a send_enabled status (whether a denom is -// sendable). -message SendEnabled { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - string denom = 1; - bool enabled = 2; -} - -// Input models transaction input. -message Input { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string address = 1; - repeated cosmos.base.v1beta1.Coin coins = 2 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// Output models transaction outputs. -message Output { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string address = 1; - repeated cosmos.base.v1beta1.Coin coins = 2 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// Supply represents a struct that passively keeps track of the total supply -// amounts in the network. -// This message is deprecated now that supply is indexed by denom. -message Supply { - option deprecated = true; - - option (gogoproto.equal) = true; - option (gogoproto.goproto_getters) = false; - - option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/legacy/v040.SupplyI"; - - repeated cosmos.base.v1beta1.Coin total = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// DenomUnit represents a struct that describes a given -// denomination unit of the basic token. -message DenomUnit { - // denom represents the string name of the given denom unit (e.g uatom). - string denom = 1; - // exponent represents power of 10 exponent that one must - // raise the base_denom to in order to equal the given DenomUnit's denom - // 1 denom = 1^exponent base_denom - // (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with - // exponent = 6, thus: 1 atom = 10^6 uatom). - uint32 exponent = 2; - // aliases is a list of string aliases for the given denom - repeated string aliases = 3; -} - -// Metadata represents a struct that describes -// a basic token. -message Metadata { - string description = 1; - // denom_units represents the list of DenomUnit's for a given coin - repeated DenomUnit denom_units = 2; - // base represents the base denom (should be the DenomUnit with exponent = 0). - string base = 3; - // display indicates the suggested denom that should be - // displayed in clients. - string display = 4; - // name defines the name of the token (eg: Cosmos Atom) - // - // Since: cosmos-sdk 0.43 - string name = 5; - // symbol is the token symbol usually shown on exchanges (eg: ATOM). This can - // be the same as the display. - // - // Since: cosmos-sdk 0.43 - string symbol = 6; -} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto deleted file mode 100644 index 8fd7329a0..000000000 --- a/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto +++ /dev/null @@ -1,39 +0,0 @@ -syntax = "proto3"; -package cosmos.bank.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/bank/v1beta1/bank.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; - -// GenesisState defines the bank module's genesis state. -message GenesisState { - // params defines all the paramaters of the module. - Params params = 1 [(gogoproto.nullable) = false]; - - // balances is an array containing the balances of all the accounts. - repeated Balance balances = 2 [(gogoproto.nullable) = false]; - - // supply represents the total supply. If it is left empty, then supply will be calculated based on the provided - // balances. Otherwise, it will be used to validate that the sum of the balances equals this amount. - repeated cosmos.base.v1beta1.Coin supply = 3 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; - - // denom_metadata defines the metadata of the differents coins. - repeated Metadata denom_metadata = 4 [(gogoproto.moretags) = "yaml:\"denom_metadata\"", (gogoproto.nullable) = false]; -} - -// Balance defines an account address and balance pair used in the bank module's -// genesis state. -message Balance { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address is the address of the balance holder. - string address = 1; - - // coins defines the different coins this balance holds. - repeated cosmos.base.v1beta1.Coin coins = 2 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto deleted file mode 100644 index a567e073f..000000000 --- a/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto +++ /dev/null @@ -1,193 +0,0 @@ -syntax = "proto3"; -package cosmos.bank.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/bank/v1beta1/bank.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; - -// Query defines the gRPC querier service. -service Query { - // Balance queries the balance of a single coin for a single account. - rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}/by_denom"; - } - - // AllBalances queries the balance of all coins for a single account. - rpc AllBalances(QueryAllBalancesRequest) returns (QueryAllBalancesResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}"; - } - - // SpendableBalances queries the spenable balance of all coins for a single - // account. - rpc SpendableBalances(QuerySpendableBalancesRequest) returns (QuerySpendableBalancesResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/spendable_balances/{address}"; - } - - // TotalSupply queries the total supply of all coins. - rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/supply"; - } - - // SupplyOf queries the supply of a single coin. - rpc SupplyOf(QuerySupplyOfRequest) returns (QuerySupplyOfResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/supply/{denom}"; - } - - // Params queries the parameters of x/bank module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/params"; - } - - // DenomsMetadata queries the client metadata of a given coin denomination. - rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata/{denom}"; - } - - // DenomsMetadata queries the client metadata for all registered coin denominations. - rpc DenomsMetadata(QueryDenomsMetadataRequest) returns (QueryDenomsMetadataResponse) { - option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata"; - } -} - -// QueryBalanceRequest is the request type for the Query/Balance RPC method. -message QueryBalanceRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address is the address to query balances for. - string address = 1; - - // denom is the coin denom to query balances for. - string denom = 2; -} - -// QueryBalanceResponse is the response type for the Query/Balance RPC method. -message QueryBalanceResponse { - // balance is the balance of the coin. - cosmos.base.v1beta1.Coin balance = 1; -} - -// QueryBalanceRequest is the request type for the Query/AllBalances RPC method. -message QueryAllBalancesRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address is the address to query balances for. - string address = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC -// method. -message QueryAllBalancesResponse { - // balances is the balances of all the coins. - repeated cosmos.base.v1beta1.Coin balances = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QuerySpendableBalancesRequest defines the gRPC request structure for querying -// an account's spendable balances. -message QuerySpendableBalancesRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address is the address to query spendable balances for. - string address = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QuerySpendableBalancesResponse defines the gRPC response structure for querying -// an account's spendable balances. -message QuerySpendableBalancesResponse { - // balances is the spendable balances of all the coins. - repeated cosmos.base.v1beta1.Coin balances = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC -// method. -message QueryTotalSupplyRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // pagination defines an optional pagination for the request. - // - // Since: cosmos-sdk 0.43 - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC -// method -message QueryTotalSupplyResponse { - // supply is the supply of the coins - repeated cosmos.base.v1beta1.Coin supply = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // pagination defines the pagination in the response. - // - // Since: cosmos-sdk 0.43 - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method. -message QuerySupplyOfRequest { - // denom is the coin denom to query balances for. - string denom = 1; -} - -// QuerySupplyOfResponse is the response type for the Query/SupplyOf RPC method. -message QuerySupplyOfResponse { - // amount is the supply of the coin. - cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; -} - -// QueryParamsRequest defines the request type for querying x/bank parameters. -message QueryParamsRequest {} - -// QueryParamsResponse defines the response type for querying x/bank parameters. -message QueryParamsResponse { - Params params = 1 [(gogoproto.nullable) = false]; -} - -// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method. -message QueryDenomsMetadataRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC -// method. -message QueryDenomsMetadataResponse { - // metadata provides the client information for all the registered tokens. - repeated Metadata metadatas = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method. -message QueryDenomMetadataRequest { - // denom is the coin denom to query the metadata for. - string denom = 1; -} - -// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC -// method. -message QueryDenomMetadataResponse { - // metadata describes and provides all the client information for the requested token. - Metadata metadata = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto deleted file mode 100644 index 26b2ab41f..000000000 --- a/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto +++ /dev/null @@ -1,42 +0,0 @@ -syntax = "proto3"; -package cosmos.bank.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/bank/v1beta1/bank.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; - -// Msg defines the bank Msg service. -service Msg { - // Send defines a method for sending coins from one account to another account. - rpc Send(MsgSend) returns (MsgSendResponse); - - // MultiSend defines a method for sending coins from some accounts to other accounts. - rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse); -} - -// MsgSend represents a message to send coins from one account to another. -message MsgSend { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; - string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; - repeated cosmos.base.v1beta1.Coin amount = 3 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// MsgSendResponse defines the Msg/Send response type. -message MsgSendResponse {} - -// MsgMultiSend represents an arbitrary multi-in, multi-out send message. -message MsgMultiSend { - option (gogoproto.equal) = false; - - repeated Input inputs = 1 [(gogoproto.nullable) = false]; - repeated Output outputs = 2 [(gogoproto.nullable) = false]; -} - -// MsgMultiSendResponse defines the Msg/MultiSend response type. -message MsgMultiSendResponse {} diff --git a/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto b/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto deleted file mode 100644 index e24ae7bd5..000000000 --- a/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto +++ /dev/null @@ -1,144 +0,0 @@ -syntax = "proto3"; -package cosmos.base.abci.v1beta1; - -import "gogoproto/gogo.proto"; -import "tendermint/abci/types.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/types"; -option (gogoproto.goproto_stringer_all) = false; - -// TxResponse defines a structure containing relevant tx data and metadata. The -// tags are stringified and the log is JSON decoded. -message TxResponse { - option (gogoproto.goproto_getters) = false; - // The block height - int64 height = 1; - // The transaction hash. - string txhash = 2 [(gogoproto.customname) = "TxHash"]; - // Namespace for the Code - string codespace = 3; - // Response code. - uint32 code = 4; - // Result bytes, if any. - string data = 5; - // The output of the application's logger (raw string). May be - // non-deterministic. - string raw_log = 6; - // The output of the application's logger (typed). May be non-deterministic. - repeated ABCIMessageLog logs = 7 [(gogoproto.castrepeated) = "ABCIMessageLogs", (gogoproto.nullable) = false]; - // Additional information. May be non-deterministic. - string info = 8; - // Amount of gas requested for transaction. - int64 gas_wanted = 9; - // Amount of gas consumed by transaction. - int64 gas_used = 10; - // The request transaction bytes. - google.protobuf.Any tx = 11; - // Time of the previous block. For heights > 1, it's the weighted median of - // the timestamps of the valid votes in the block.LastCommit. For height == 1, - // it's genesis time. - string timestamp = 12; - // Events defines all the events emitted by processing a transaction. Note, - // these events include those emitted by processing all the messages and those - // emitted from the ante handler. Whereas Logs contains the events, with - // additional metadata, emitted only by processing the messages. - // - // Since: cosmos-sdk 0.42.11, 0.44.5, 0.45 - repeated tendermint.abci.Event events = 13 [(gogoproto.nullable) = false]; -} - -// ABCIMessageLog defines a structure containing an indexed tx ABCI message log. -message ABCIMessageLog { - option (gogoproto.stringer) = true; - - uint32 msg_index = 1; - string log = 2; - - // Events contains a slice of Event objects that were emitted during some - // execution. - repeated StringEvent events = 3 [(gogoproto.castrepeated) = "StringEvents", (gogoproto.nullable) = false]; -} - -// StringEvent defines en Event object wrapper where all the attributes -// contain key/value pairs that are strings instead of raw bytes. -message StringEvent { - option (gogoproto.stringer) = true; - - string type = 1; - repeated Attribute attributes = 2 [(gogoproto.nullable) = false]; -} - -// Attribute defines an attribute wrapper where the key and value are -// strings instead of raw bytes. -message Attribute { - string key = 1; - string value = 2; -} - -// GasInfo defines tx execution gas context. -message GasInfo { - // GasWanted is the maximum units of work we allow this tx to perform. - uint64 gas_wanted = 1 [(gogoproto.moretags) = "yaml:\"gas_wanted\""]; - - // GasUsed is the amount of gas actually consumed. - uint64 gas_used = 2 [(gogoproto.moretags) = "yaml:\"gas_used\""]; -} - -// Result is the union of ResponseFormat and ResponseCheckTx. -message Result { - option (gogoproto.goproto_getters) = false; - - // Data is any data returned from message or handler execution. It MUST be - // length prefixed in order to separate data from multiple message executions. - bytes data = 1; - - // Log contains the log information from message or handler execution. - string log = 2; - - // Events contains a slice of Event objects that were emitted during message - // or handler execution. - repeated tendermint.abci.Event events = 3 [(gogoproto.nullable) = false]; -} - -// SimulationResponse defines the response generated when a transaction is -// successfully simulated. -message SimulationResponse { - GasInfo gas_info = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; - Result result = 2; -} - -// MsgData defines the data returned in a Result object during message -// execution. -message MsgData { - option (gogoproto.stringer) = true; - - string msg_type = 1; - bytes data = 2; -} - -// TxMsgData defines a list of MsgData. A transaction will have a MsgData object -// for each message. -message TxMsgData { - option (gogoproto.stringer) = true; - - repeated MsgData data = 1; -} - -// SearchTxsResult defines a structure for querying txs pageable -message SearchTxsResult { - option (gogoproto.stringer) = true; - - // Count of all txs - uint64 total_count = 1 [(gogoproto.moretags) = "yaml:\"total_count\"", (gogoproto.jsontag) = "total_count"]; - // Count of txs in current page - uint64 count = 2; - // Index of current page, start from 1 - uint64 page_number = 3 [(gogoproto.moretags) = "yaml:\"page_number\"", (gogoproto.jsontag) = "page_number"]; - // Count of total pages - uint64 page_total = 4 [(gogoproto.moretags) = "yaml:\"page_total\"", (gogoproto.jsontag) = "page_total"]; - // Max count txs per page - uint64 limit = 5; - // List of txs in current page - repeated TxResponse txs = 6; -} diff --git a/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto b/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto deleted file mode 100644 index 4e9b8d285..000000000 --- a/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package cosmos.base.kv.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/types/kv"; - -// Pairs defines a repeated slice of Pair objects. -message Pairs { - repeated Pair pairs = 1 [(gogoproto.nullable) = false]; -} - -// Pair defines a key/value bytes tuple. -message Pair { - bytes key = 1; - bytes value = 2; -} diff --git a/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto b/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto deleted file mode 100644 index 8070f7b90..000000000 --- a/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; -package cosmos.base.node.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/node"; - -// Service defines the gRPC querier service for node related queries. -service Service { - // Config queries for the operator configuration. - rpc Config(ConfigRequest) returns (ConfigResponse) { - option (google.api.http).get = "/cosmos/base/node/v1beta1/config"; - } -} - -// ConfigRequest defines the request structure for the Config gRPC query. -message ConfigRequest {} - -// ConfigResponse defines the response structure for the Config gRPC query. -message ConfigResponse { - string minimum_gas_price = 1; -} diff --git a/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto b/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto deleted file mode 100644 index cd5eb066d..000000000 --- a/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto +++ /dev/null @@ -1,55 +0,0 @@ -syntax = "proto3"; -package cosmos.base.query.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/types/query"; - -// PageRequest is to be embedded in gRPC request messages for efficient -// pagination. Ex: -// -// message SomeRequest { -// Foo some_parameter = 1; -// PageRequest pagination = 2; -// } -message PageRequest { - // key is a value returned in PageResponse.next_key to begin - // querying the next page most efficiently. Only one of offset or key - // should be set. - bytes key = 1; - - // offset is a numeric offset that can be used when key is unavailable. - // It is less efficient than using key. Only one of offset or key should - // be set. - uint64 offset = 2; - - // limit is the total number of results to be returned in the result page. - // If left empty it will default to a value to be set by each app. - uint64 limit = 3; - - // count_total is set to true to indicate that the result set should include - // a count of the total number of items available for pagination in UIs. - // count_total is only respected when offset is used. It is ignored when key - // is set. - bool count_total = 4; - - // reverse is set to true if results are to be returned in the descending order. - // - // Since: cosmos-sdk 0.43 - bool reverse = 5; -} - -// PageResponse is to be embedded in gRPC response messages where the -// corresponding request message has used PageRequest. -// -// message SomeResponse { -// repeated Bar results = 1; -// PageResponse page = 2; -// } -message PageResponse { - // next_key is the key to be passed to PageRequest.key to - // query the next page most efficiently - bytes next_key = 1; - - // total is total number of results available if PageRequest.count_total - // was set, its value is undefined otherwise - uint64 total = 2; -} diff --git a/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto b/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto deleted file mode 100644 index 22670e72b..000000000 --- a/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; -package cosmos.base.reflection.v1beta1; - -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/reflection"; - -// ReflectionService defines a service for interface reflection. -service ReflectionService { - // ListAllInterfaces lists all the interfaces registered in the interface - // registry. - rpc ListAllInterfaces(ListAllInterfacesRequest) returns (ListAllInterfacesResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces"; - }; - - // ListImplementations list all the concrete types that implement a given - // interface. - rpc ListImplementations(ListImplementationsRequest) returns (ListImplementationsResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/" - "{interface_name}/implementations"; - }; -} - -// ListAllInterfacesRequest is the request type of the ListAllInterfaces RPC. -message ListAllInterfacesRequest {} - -// ListAllInterfacesResponse is the response type of the ListAllInterfaces RPC. -message ListAllInterfacesResponse { - // interface_names is an array of all the registered interfaces. - repeated string interface_names = 1; -} - -// ListImplementationsRequest is the request type of the ListImplementations -// RPC. -message ListImplementationsRequest { - // interface_name defines the interface to query the implementations for. - string interface_name = 1; -} - -// ListImplementationsResponse is the response type of the ListImplementations -// RPC. -message ListImplementationsResponse { - repeated string implementation_message_names = 1; -} diff --git a/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto b/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto deleted file mode 100644 index d5b048558..000000000 --- a/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto +++ /dev/null @@ -1,218 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.base.reflection.v2alpha1; - -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/server/grpc/reflection/v2alpha1"; - -// AppDescriptor describes a cosmos-sdk based application -message AppDescriptor { - // AuthnDescriptor provides information on how to authenticate transactions on the application - // NOTE: experimental and subject to change in future releases. - AuthnDescriptor authn = 1; - // chain provides the chain descriptor - ChainDescriptor chain = 2; - // codec provides metadata information regarding codec related types - CodecDescriptor codec = 3; - // configuration provides metadata information regarding the sdk.Config type - ConfigurationDescriptor configuration = 4; - // query_services provides metadata information regarding the available queriable endpoints - QueryServicesDescriptor query_services = 5; - // tx provides metadata information regarding how to send transactions to the given application - TxDescriptor tx = 6; -} - -// TxDescriptor describes the accepted transaction type -message TxDescriptor { - // fullname is the protobuf fullname of the raw transaction type (for instance the tx.Tx type) - // it is not meant to support polymorphism of transaction types, it is supposed to be used by - // reflection clients to understand if they can handle a specific transaction type in an application. - string fullname = 1; - // msgs lists the accepted application messages (sdk.Msg) - repeated MsgDescriptor msgs = 2; -} - -// AuthnDescriptor provides information on how to sign transactions without relying -// on the online RPCs GetTxMetadata and CombineUnsignedTxAndSignatures -message AuthnDescriptor { - // sign_modes defines the supported signature algorithm - repeated SigningModeDescriptor sign_modes = 1; -} - -// SigningModeDescriptor provides information on a signing flow of the application -// NOTE(fdymylja): here we could go as far as providing an entire flow on how -// to sign a message given a SigningModeDescriptor, but it's better to think about -// this another time -message SigningModeDescriptor { - // name defines the unique name of the signing mode - string name = 1; - // number is the unique int32 identifier for the sign_mode enum - int32 number = 2; - // authn_info_provider_method_fullname defines the fullname of the method to call to get - // the metadata required to authenticate using the provided sign_modes - string authn_info_provider_method_fullname = 3; -} - -// ChainDescriptor describes chain information of the application -message ChainDescriptor { - // id is the chain id - string id = 1; -} - -// CodecDescriptor describes the registered interfaces and provides metadata information on the types -message CodecDescriptor { - // interfaces is a list of the registerted interfaces descriptors - repeated InterfaceDescriptor interfaces = 1; -} - -// InterfaceDescriptor describes the implementation of an interface -message InterfaceDescriptor { - // fullname is the name of the interface - string fullname = 1; - // interface_accepting_messages contains information regarding the proto messages which contain the interface as - // google.protobuf.Any field - repeated InterfaceAcceptingMessageDescriptor interface_accepting_messages = 2; - // interface_implementers is a list of the descriptors of the interface implementers - repeated InterfaceImplementerDescriptor interface_implementers = 3; -} - -// InterfaceImplementerDescriptor describes an interface implementer -message InterfaceImplementerDescriptor { - // fullname is the protobuf queryable name of the interface implementer - string fullname = 1; - // type_url defines the type URL used when marshalling the type as any - // this is required so we can provide type safe google.protobuf.Any marshalling and - // unmarshalling, making sure that we don't accept just 'any' type - // in our interface fields - string type_url = 2; -} - -// InterfaceAcceptingMessageDescriptor describes a protobuf message which contains -// an interface represented as a google.protobuf.Any -message InterfaceAcceptingMessageDescriptor { - // fullname is the protobuf fullname of the type containing the interface - string fullname = 1; - // field_descriptor_names is a list of the protobuf name (not fullname) of the field - // which contains the interface as google.protobuf.Any (the interface is the same, but - // it can be in multiple fields of the same proto message) - repeated string field_descriptor_names = 2; -} - -// ConfigurationDescriptor contains metadata information on the sdk.Config -message ConfigurationDescriptor { - // bech32_account_address_prefix is the account address prefix - string bech32_account_address_prefix = 1; -} - -// MsgDescriptor describes a cosmos-sdk message that can be delivered with a transaction -message MsgDescriptor { - // msg_type_url contains the TypeURL of a sdk.Msg. - string msg_type_url = 1; -} - -// ReflectionService defines a service for application reflection. -service ReflectionService { - // GetAuthnDescriptor returns information on how to authenticate transactions in the application - // NOTE: this RPC is still experimental and might be subject to breaking changes or removal in - // future releases of the cosmos-sdk. - rpc GetAuthnDescriptor(GetAuthnDescriptorRequest) returns (GetAuthnDescriptorResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/authn"; - } - // GetChainDescriptor returns the description of the chain - rpc GetChainDescriptor(GetChainDescriptorRequest) returns (GetChainDescriptorResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/chain"; - }; - // GetCodecDescriptor returns the descriptor of the codec of the application - rpc GetCodecDescriptor(GetCodecDescriptorRequest) returns (GetCodecDescriptorResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/codec"; - } - // GetConfigurationDescriptor returns the descriptor for the sdk.Config of the application - rpc GetConfigurationDescriptor(GetConfigurationDescriptorRequest) returns (GetConfigurationDescriptorResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/configuration"; - } - // GetQueryServicesDescriptor returns the available gRPC queryable services of the application - rpc GetQueryServicesDescriptor(GetQueryServicesDescriptorRequest) returns (GetQueryServicesDescriptorResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/query_services"; - } - // GetTxDescriptor returns information on the used transaction object and available msgs that can be used - rpc GetTxDescriptor(GetTxDescriptorRequest) returns (GetTxDescriptorResponse) { - option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/tx_descriptor"; - } -} - -// GetAuthnDescriptorRequest is the request used for the GetAuthnDescriptor RPC -message GetAuthnDescriptorRequest {} -// GetAuthnDescriptorResponse is the response returned by the GetAuthnDescriptor RPC -message GetAuthnDescriptorResponse { - // authn describes how to authenticate to the application when sending transactions - AuthnDescriptor authn = 1; -} - -// GetChainDescriptorRequest is the request used for the GetChainDescriptor RPC -message GetChainDescriptorRequest {} -// GetChainDescriptorResponse is the response returned by the GetChainDescriptor RPC -message GetChainDescriptorResponse { - // chain describes application chain information - ChainDescriptor chain = 1; -} - -// GetCodecDescriptorRequest is the request used for the GetCodecDescriptor RPC -message GetCodecDescriptorRequest {} -// GetCodecDescriptorResponse is the response returned by the GetCodecDescriptor RPC -message GetCodecDescriptorResponse { - // codec describes the application codec such as registered interfaces and implementations - CodecDescriptor codec = 1; -} - -// GetConfigurationDescriptorRequest is the request used for the GetConfigurationDescriptor RPC -message GetConfigurationDescriptorRequest {} -// GetConfigurationDescriptorResponse is the response returned by the GetConfigurationDescriptor RPC -message GetConfigurationDescriptorResponse { - // config describes the application's sdk.Config - ConfigurationDescriptor config = 1; -} - -// GetQueryServicesDescriptorRequest is the request used for the GetQueryServicesDescriptor RPC -message GetQueryServicesDescriptorRequest {} -// GetQueryServicesDescriptorResponse is the response returned by the GetQueryServicesDescriptor RPC -message GetQueryServicesDescriptorResponse { - // queries provides information on the available queryable services - QueryServicesDescriptor queries = 1; -} - -// GetTxDescriptorRequest is the request used for the GetTxDescriptor RPC -message GetTxDescriptorRequest {} -// GetTxDescriptorResponse is the response returned by the GetTxDescriptor RPC -message GetTxDescriptorResponse { - // tx provides information on msgs that can be forwarded to the application - // alongside the accepted transaction protobuf type - TxDescriptor tx = 1; -} - -// QueryServicesDescriptor contains the list of cosmos-sdk queriable services -message QueryServicesDescriptor { - // query_services is a list of cosmos-sdk QueryServiceDescriptor - repeated QueryServiceDescriptor query_services = 1; -} - -// QueryServiceDescriptor describes a cosmos-sdk queryable service -message QueryServiceDescriptor { - // fullname is the protobuf fullname of the service descriptor - string fullname = 1; - // is_module describes if this service is actually exposed by an application's module - bool is_module = 2; - // methods provides a list of query service methods - repeated QueryMethodDescriptor methods = 3; -} - -// QueryMethodDescriptor describes a queryable method of a query service -// no other info is provided beside method name and tendermint queryable path -// because it would be redundant with the grpc reflection service -message QueryMethodDescriptor { - // name is the protobuf name (not fullname) of the method - string name = 1; - // full_query_path is the path that can be used to query - // this method via tendermint abci.Query - string full_query_path = 2; -} diff --git a/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto b/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto deleted file mode 100644 index 6dcc4a933..000000000 --- a/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto +++ /dev/null @@ -1,57 +0,0 @@ -syntax = "proto3"; -package cosmos.base.snapshots.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/snapshots/types"; - -// Snapshot contains Tendermint state sync snapshot info. -message Snapshot { - uint64 height = 1; - uint32 format = 2; - uint32 chunks = 3; - bytes hash = 4; - Metadata metadata = 5 [(gogoproto.nullable) = false]; -} - -// Metadata contains SDK-specific snapshot metadata. -message Metadata { - repeated bytes chunk_hashes = 1; // SHA-256 chunk hashes -} - -// SnapshotItem is an item contained in a rootmulti.Store snapshot. -message SnapshotItem { - // item is the specific type of snapshot item. - oneof item { - SnapshotStoreItem store = 1; - SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; - SnapshotExtensionMeta extension = 3; - SnapshotExtensionPayload extension_payload = 4; - } -} - -// SnapshotStoreItem contains metadata about a snapshotted store. -message SnapshotStoreItem { - string name = 1; -} - -// SnapshotIAVLItem is an exported IAVL node. -message SnapshotIAVLItem { - bytes key = 1; - bytes value = 2; - // version is block height - int64 version = 3; - // height is depth of the tree. - int32 height = 4; -} - -// SnapshotExtensionMeta contains metadata about an external snapshotter. -message SnapshotExtensionMeta { - string name = 1; - uint32 format = 2; -} - -// SnapshotExtensionPayload contains payloads of an external snapshotter. -message SnapshotExtensionPayload { - bytes payload = 1; -} diff --git a/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto b/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto deleted file mode 100644 index 98a33d30e..000000000 --- a/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; -package cosmos.base.store.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/store/types"; - -// CommitInfo defines commit information used by the multi-store when committing -// a version/height. -message CommitInfo { - int64 version = 1; - repeated StoreInfo store_infos = 2 [(gogoproto.nullable) = false]; -} - -// StoreInfo defines store-specific commit information. It contains a reference -// between a store name and the commit ID. -message StoreInfo { - string name = 1; - CommitID commit_id = 2 [(gogoproto.nullable) = false]; -} - -// CommitID defines the committment information when a specific store is -// committed. -message CommitID { - option (gogoproto.goproto_stringer) = false; - - int64 version = 1; - bytes hash = 2; -} diff --git a/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto b/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto deleted file mode 100644 index 753f7c165..000000000 --- a/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto +++ /dev/null @@ -1,34 +0,0 @@ -syntax = "proto3"; -package cosmos.base.store.v1beta1; - -import "tendermint/abci/types.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/store/types"; - -// StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) -// It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and -// Deletes -// -// Since: cosmos-sdk 0.43 -message StoreKVPair { - string store_key = 1; // the store key for the KVStore this pair originates from - bool delete = 2; // true indicates a delete operation, false indicates a set operation - bytes key = 3; - bytes value = 4; -} - -// BlockMetadata contains all the abci event data of a block -// the file streamer dump them into files together with the state changes. -message BlockMetadata { - // DeliverTx encapulate deliver tx request and response. - message DeliverTx { - tendermint.abci.RequestDeliverTx request = 1; - tendermint.abci.ResponseDeliverTx response = 2; - } - tendermint.abci.RequestBeginBlock request_begin_block = 1; - tendermint.abci.ResponseBeginBlock response_begin_block = 2; - repeated DeliverTx deliver_txs = 3; - tendermint.abci.RequestEndBlock request_end_block = 4; - tendermint.abci.ResponseEndBlock response_end_block = 5; - tendermint.abci.ResponseCommit response_commit = 6; -} diff --git a/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto b/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto deleted file mode 100644 index 98542d23d..000000000 --- a/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto +++ /dev/null @@ -1,138 +0,0 @@ -syntax = "proto3"; -package cosmos.base.tendermint.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "tendermint/p2p/types.proto"; -import "tendermint/types/block.proto"; -import "tendermint/types/types.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"; - -// Service defines the gRPC querier service for tendermint queries. -service Service { - // GetNodeInfo queries the current node info. - rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse) { - option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/node_info"; - } - // GetSyncing queries node syncing. - rpc GetSyncing(GetSyncingRequest) returns (GetSyncingResponse) { - option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/syncing"; - } - // GetLatestBlock returns the latest block. - rpc GetLatestBlock(GetLatestBlockRequest) returns (GetLatestBlockResponse) { - option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/latest"; - } - // GetBlockByHeight queries block for given height. - rpc GetBlockByHeight(GetBlockByHeightRequest) returns (GetBlockByHeightResponse) { - option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/{height}"; - } - - // GetLatestValidatorSet queries latest validator-set. - rpc GetLatestValidatorSet(GetLatestValidatorSetRequest) returns (GetLatestValidatorSetResponse) { - option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/latest"; - } - // GetValidatorSetByHeight queries validator-set at a given height. - rpc GetValidatorSetByHeight(GetValidatorSetByHeightRequest) returns (GetValidatorSetByHeightResponse) { - option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/{height}"; - } -} - -// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method. -message GetValidatorSetByHeightRequest { - int64 height = 1; - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method. -message GetValidatorSetByHeightResponse { - int64 block_height = 1; - repeated Validator validators = 2; - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 3; -} - -// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method. -message GetLatestValidatorSetRequest { - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method. -message GetLatestValidatorSetResponse { - int64 block_height = 1; - repeated Validator validators = 2; - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 3; -} - -// Validator is the type for the validator-set. -message Validator { - string address = 1; - google.protobuf.Any pub_key = 2; - int64 voting_power = 3; - int64 proposer_priority = 4; -} - -// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method. -message GetBlockByHeightRequest { - int64 height = 1; -} - -// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method. -message GetBlockByHeightResponse { - .tendermint.types.BlockID block_id = 1; - .tendermint.types.Block block = 2; -} - -// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method. -message GetLatestBlockRequest {} - -// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method. -message GetLatestBlockResponse { - .tendermint.types.BlockID block_id = 1; - .tendermint.types.Block block = 2; -} - -// GetSyncingRequest is the request type for the Query/GetSyncing RPC method. -message GetSyncingRequest {} - -// GetSyncingResponse is the response type for the Query/GetSyncing RPC method. -message GetSyncingResponse { - bool syncing = 1; -} - -// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method. -message GetNodeInfoRequest {} - -// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method. -message GetNodeInfoResponse { - .tendermint.p2p.DefaultNodeInfo default_node_info = 1; - VersionInfo application_version = 2; -} - -// VersionInfo is the type for the GetNodeInfoResponse message. -message VersionInfo { - string name = 1; - string app_name = 2; - string version = 3; - string git_commit = 4; - string build_tags = 5; - string go_version = 6; - repeated Module build_deps = 7; - // Since: cosmos-sdk 0.43 - string cosmos_sdk_version = 8; -} - -// Module is the type for VersionInfo -message Module { - // module path - string path = 1; - // module version - string version = 2; - // checksum - string sum = 3; -} diff --git a/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto b/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto deleted file mode 100644 index fab75284b..000000000 --- a/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; -package cosmos.base.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/types"; -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.stringer_all) = false; - -// Coin defines a token with a denomination and an amount. -// -// NOTE: The amount field is an Int which implements the custom method -// signatures required by gogoproto. -message Coin { - option (gogoproto.equal) = true; - - string denom = 1; - string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; -} - -// DecCoin defines a token with a denomination and a decimal amount. -// -// NOTE: The amount field is an Dec which implements the custom method -// signatures required by gogoproto. -message DecCoin { - option (gogoproto.equal) = true; - - string denom = 1; - string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; -} - -// IntProto defines a Protobuf wrapper around an Int object. -message IntProto { - string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; -} - -// DecProto defines a Protobuf wrapper around a Dec object. -message DecProto { - string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto b/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto deleted file mode 100644 index 1c8332f34..000000000 --- a/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; -package cosmos.capability.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; - -import "gogoproto/gogo.proto"; - -// Capability defines an implementation of an object capability. The index -// provided to a Capability must be globally unique. -message Capability { - option (gogoproto.goproto_stringer) = false; - - uint64 index = 1 [(gogoproto.moretags) = "yaml:\"index\""]; -} - -// Owner defines a single capability owner. An owner is defined by the name of -// capability and the module name. -message Owner { - option (gogoproto.goproto_stringer) = false; - option (gogoproto.goproto_getters) = false; - - string module = 1 [(gogoproto.moretags) = "yaml:\"module\""]; - string name = 2 [(gogoproto.moretags) = "yaml:\"name\""]; -} - -// CapabilityOwners defines a set of owners of a single Capability. The set of -// owners must be unique. -message CapabilityOwners { - repeated Owner owners = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto deleted file mode 100644 index 05bb0afc4..000000000 --- a/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; -package cosmos.capability.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/capability/v1beta1/capability.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; - -// GenesisOwners defines the capability owners with their corresponding index. -message GenesisOwners { - // index is the index of the capability owner. - uint64 index = 1; - - // index_owners are the owners at the given index. - CapabilityOwners index_owners = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"index_owners\""]; -} - -// GenesisState defines the capability module's genesis state. -message GenesisState { - // index is the capability global index. - uint64 index = 1; - - // owners represents a map from index to owners of the capability index - // index key is string to allow amino marshalling. - repeated GenesisOwners owners = 2 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto deleted file mode 100644 index 5b0ff7ec7..000000000 --- a/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; -package cosmos.crisis.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -// GenesisState defines the crisis module's genesis state. -message GenesisState { - // constant_fee is the fee used to verify the invariant in the crisis - // module. - cosmos.base.v1beta1.Coin constant_fee = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"constant_fee\""]; -} diff --git a/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto deleted file mode 100644 index 26457ad6d..000000000 --- a/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package cosmos.crisis.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; - -import "gogoproto/gogo.proto"; - -// Msg defines the bank Msg service. -service Msg { - // VerifyInvariant defines a method to verify a particular invariance. - rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse); -} - -// MsgVerifyInvariant represents a message to verify a particular invariance. -message MsgVerifyInvariant { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string sender = 1; - string invariant_module_name = 2 [(gogoproto.moretags) = "yaml:\"invariant_module_name\""]; - string invariant_route = 3 [(gogoproto.moretags) = "yaml:\"invariant_route\""]; -} - -// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type. -message MsgVerifyInvariantResponse {} diff --git a/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto b/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto deleted file mode 100644 index 6ffec3448..000000000 --- a/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; -package cosmos.crypto.ed25519; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"; - -// PubKey is an ed25519 public key for handling Tendermint keys in SDK. -// It's needed for Any serialization and SDK compatibility. -// It must not be used in a non Tendermint key context because it doesn't implement -// ADR-28. Nevertheless, you will like to use ed25519 in app user level -// then you must create a new proto message and follow ADR-28 for Address construction. -message PubKey { - option (gogoproto.goproto_stringer) = false; - - bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PublicKey"]; -} - -// Deprecated: PrivKey defines a ed25519 private key. -// NOTE: ed25519 keys must not be used in SDK apps except in a tendermint validator context. -message PrivKey { - bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PrivateKey"]; -} diff --git a/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto b/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto deleted file mode 100644 index f8398e805..000000000 --- a/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package cosmos.crypto.multisig; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"; - -// LegacyAminoPubKey specifies a public key type -// which nests multiple public keys and a threshold, -// it uses legacy amino address rules. -message LegacyAminoPubKey { - option (gogoproto.goproto_getters) = false; - - uint32 threshold = 1 [(gogoproto.moretags) = "yaml:\"threshold\""]; - repeated google.protobuf.Any public_keys = 2 - [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""]; -} diff --git a/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto b/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto deleted file mode 100644 index bf671f171..000000000 --- a/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package cosmos.crypto.multisig.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/crypto/types"; - -// MultiSignature wraps the signatures from a multisig.LegacyAminoPubKey. -// See cosmos.tx.v1betata1.ModeInfo.Multi for how to specify which signers -// signed and with which modes. -message MultiSignature { - option (gogoproto.goproto_unrecognized) = true; - repeated bytes signatures = 1; -} - -// CompactBitArray is an implementation of a space efficient bit array. -// This is used to ensure that the encoded data takes up a minimal amount of -// space after proto encoding. -// This is not thread safe, and is not intended for concurrent usage. -message CompactBitArray { - option (gogoproto.goproto_stringer) = false; - - uint32 extra_bits_stored = 1; - bytes elems = 2; -} diff --git a/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto b/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto deleted file mode 100644 index a22725713..000000000 --- a/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto +++ /dev/null @@ -1,22 +0,0 @@ -syntax = "proto3"; -package cosmos.crypto.secp256k1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"; - -// PubKey defines a secp256k1 public key -// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte -// if the y-coordinate is the lexicographically largest of the two associated with -// the x-coordinate. Otherwise the first byte is a 0x03. -// This prefix is followed with the x-coordinate. -message PubKey { - option (gogoproto.goproto_stringer) = false; - - bytes key = 1; -} - -// PrivKey defines a secp256k1 private key. -message PrivKey { - bytes key = 1; -} diff --git a/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto b/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto deleted file mode 100644 index 2e96c6e3c..000000000 --- a/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto +++ /dev/null @@ -1,23 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.crypto.secp256r1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1"; -option (gogoproto.messagename_all) = true; -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.goproto_getters_all) = false; - -// PubKey defines a secp256r1 ECDSA public key. -message PubKey { - // Point on secp256r1 curve in a compressed representation as specified in section - // 4.3.6 of ANSI X9.62: https://webstore.ansi.org/standards/ascx9/ansix9621998 - bytes key = 1 [(gogoproto.customtype) = "ecdsaPK"]; -} - -// PrivKey defines a secp256r1 ECDSA private key. -message PrivKey { - // secret number serialized using big-endian encoding - bytes secret = 1 [(gogoproto.customtype) = "ecdsaSK"]; -} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto deleted file mode 100644 index ae98ec0b9..000000000 --- a/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto +++ /dev/null @@ -1,157 +0,0 @@ -syntax = "proto3"; -package cosmos.distribution.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -// Params defines the set of params for the distribution module. -message Params { - option (gogoproto.goproto_stringer) = false; - string community_tax = 1 [ - (gogoproto.moretags) = "yaml:\"community_tax\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - string base_proposer_reward = 2 [ - (gogoproto.moretags) = "yaml:\"base_proposer_reward\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - string bonus_proposer_reward = 3 [ - (gogoproto.moretags) = "yaml:\"bonus_proposer_reward\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - bool withdraw_addr_enabled = 4 [(gogoproto.moretags) = "yaml:\"withdraw_addr_enabled\""]; -} - -// ValidatorHistoricalRewards represents historical rewards for a validator. -// Height is implicit within the store key. -// Cumulative reward ratio is the sum from the zeroeth period -// until this period of rewards / tokens, per the spec. -// The reference count indicates the number of objects -// which might need to reference this historical entry at any point. -// ReferenceCount = -// number of outstanding delegations which ended the associated period (and -// might need to read that record) -// + number of slashes which ended the associated period (and might need to -// read that record) -// + one per validator for the zeroeth period, set on initialization -message ValidatorHistoricalRewards { - repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [ - (gogoproto.moretags) = "yaml:\"cumulative_reward_ratio\"", - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", - (gogoproto.nullable) = false - ]; - uint32 reference_count = 2 [(gogoproto.moretags) = "yaml:\"reference_count\""]; -} - -// ValidatorCurrentRewards represents current rewards and current -// period for a validator kept as a running counter and incremented -// each block as long as the validator's tokens remain constant. -message ValidatorCurrentRewards { - repeated cosmos.base.v1beta1.DecCoin rewards = 1 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; - uint64 period = 2; -} - -// ValidatorAccumulatedCommission represents accumulated commission -// for a validator kept as a running counter, can be withdrawn at any time. -message ValidatorAccumulatedCommission { - repeated cosmos.base.v1beta1.DecCoin commission = 1 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; -} - -// ValidatorOutstandingRewards represents outstanding (un-withdrawn) rewards -// for a validator inexpensive to track, allows simple sanity checks. -message ValidatorOutstandingRewards { - repeated cosmos.base.v1beta1.DecCoin rewards = 1 [ - (gogoproto.moretags) = "yaml:\"rewards\"", - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", - (gogoproto.nullable) = false - ]; -} - -// ValidatorSlashEvent represents a validator slash event. -// Height is implicit within the store key. -// This is needed to calculate appropriate amount of staking tokens -// for delegations which are withdrawn after a slash has occurred. -message ValidatorSlashEvent { - uint64 validator_period = 1 [(gogoproto.moretags) = "yaml:\"validator_period\""]; - string fraction = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; -} - -// ValidatorSlashEvents is a collection of ValidatorSlashEvent messages. -message ValidatorSlashEvents { - option (gogoproto.goproto_stringer) = false; - repeated ValidatorSlashEvent validator_slash_events = 1 - [(gogoproto.moretags) = "yaml:\"validator_slash_events\"", (gogoproto.nullable) = false]; -} - -// FeePool is the global fee pool for distribution. -message FeePool { - repeated cosmos.base.v1beta1.DecCoin community_pool = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", - (gogoproto.moretags) = "yaml:\"community_pool\"" - ]; -} - -// CommunityPoolSpendProposal details a proposal for use of community funds, -// together with how many coins are proposed to be spent, and to which -// recipient account. -message CommunityPoolSpendProposal { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - string title = 1; - string description = 2; - string recipient = 3; - repeated cosmos.base.v1beta1.Coin amount = 4 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// DelegatorStartingInfo represents the starting info for a delegator reward -// period. It tracks the previous validator period, the delegation's amount of -// staking token, and the creation height (to check later on if any slashes have -// occurred). NOTE: Even though validators are slashed to whole staking tokens, -// the delegators within the validator may be left with less than a full token, -// thus sdk.Dec is used. -message DelegatorStartingInfo { - uint64 previous_period = 1 [(gogoproto.moretags) = "yaml:\"previous_period\""]; - string stake = 2 [ - (gogoproto.moretags) = "yaml:\"stake\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - uint64 height = 3 [(gogoproto.moretags) = "yaml:\"creation_height\"", (gogoproto.jsontag) = "creation_height"]; -} - -// DelegationDelegatorReward represents the properties -// of a delegator's delegation reward. -message DelegationDelegatorReward { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = true; - - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - - repeated cosmos.base.v1beta1.DecCoin reward = 2 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; -} - -// CommunityPoolSpendProposalWithDeposit defines a CommunityPoolSpendProposal -// with a deposit -message CommunityPoolSpendProposalWithDeposit { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = true; - - string title = 1 [(gogoproto.moretags) = "yaml:\"title\""]; - string description = 2 [(gogoproto.moretags) = "yaml:\"description\""]; - string recipient = 3 [(gogoproto.moretags) = "yaml:\"recipient\""]; - string amount = 4 [(gogoproto.moretags) = "yaml:\"amount\""]; - string deposit = 5 [(gogoproto.moretags) = "yaml:\"deposit\""]; -} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto deleted file mode 100644 index c0b17cdf1..000000000 --- a/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto +++ /dev/null @@ -1,155 +0,0 @@ -syntax = "proto3"; -package cosmos.distribution.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/distribution/v1beta1/distribution.proto"; - -// DelegatorWithdrawInfo is the address for where distributions rewards are -// withdrawn to by default this struct is only used at genesis to feed in -// default withdraw addresses. -message DelegatorWithdrawInfo { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_address is the address of the delegator. - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - - // withdraw_address is the address to withdraw the delegation rewards to. - string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; -} - -// ValidatorOutstandingRewardsRecord is used for import/export via genesis json. -message ValidatorOutstandingRewardsRecord { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // validator_address is the address of the validator. - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - - // outstanding_rewards represents the oustanding rewards of a validator. - repeated cosmos.base.v1beta1.DecCoin outstanding_rewards = 2 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"outstanding_rewards\"" - ]; -} - -// ValidatorAccumulatedCommissionRecord is used for import / export via genesis -// json. -message ValidatorAccumulatedCommissionRecord { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // validator_address is the address of the validator. - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - - // accumulated is the accumulated commission of a validator. - ValidatorAccumulatedCommission accumulated = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"accumulated\""]; -} - -// ValidatorHistoricalRewardsRecord is used for import / export via genesis -// json. -message ValidatorHistoricalRewardsRecord { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // validator_address is the address of the validator. - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - - // period defines the period the historical rewards apply to. - uint64 period = 2; - - // rewards defines the historical rewards of a validator. - ValidatorHistoricalRewards rewards = 3 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; -} - -// ValidatorCurrentRewardsRecord is used for import / export via genesis json. -message ValidatorCurrentRewardsRecord { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // validator_address is the address of the validator. - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - - // rewards defines the current rewards of a validator. - ValidatorCurrentRewards rewards = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; -} - -// DelegatorStartingInfoRecord used for import / export via genesis json. -message DelegatorStartingInfoRecord { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_address is the address of the delegator. - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - - // validator_address is the address of the validator. - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - - // starting_info defines the starting info of a delegator. - DelegatorStartingInfo starting_info = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"starting_info\""]; -} - -// ValidatorSlashEventRecord is used for import / export via genesis json. -message ValidatorSlashEventRecord { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // validator_address is the address of the validator. - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - // height defines the block height at which the slash event occured. - uint64 height = 2; - // period is the period of the slash event. - uint64 period = 3; - // validator_slash_event describes the slash event. - ValidatorSlashEvent validator_slash_event = 4 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"event\""]; -} - -// GenesisState defines the distribution module's genesis state. -message GenesisState { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // params defines all the paramaters of the module. - Params params = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"params\""]; - - // fee_pool defines the fee pool at genesis. - FeePool fee_pool = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"fee_pool\""]; - - // fee_pool defines the delegator withdraw infos at genesis. - repeated DelegatorWithdrawInfo delegator_withdraw_infos = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_withdraw_infos\""]; - - // fee_pool defines the previous proposer at genesis. - string previous_proposer = 4 [(gogoproto.moretags) = "yaml:\"previous_proposer\""]; - - // fee_pool defines the outstanding rewards of all validators at genesis. - repeated ValidatorOutstandingRewardsRecord outstanding_rewards = 5 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"outstanding_rewards\""]; - - // fee_pool defines the accumulated commisions of all validators at genesis. - repeated ValidatorAccumulatedCommissionRecord validator_accumulated_commissions = 6 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_accumulated_commissions\""]; - - // fee_pool defines the historical rewards of all validators at genesis. - repeated ValidatorHistoricalRewardsRecord validator_historical_rewards = 7 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_historical_rewards\""]; - - // fee_pool defines the current rewards of all validators at genesis. - repeated ValidatorCurrentRewardsRecord validator_current_rewards = 8 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_current_rewards\""]; - - // fee_pool defines the delegator starting infos at genesis. - repeated DelegatorStartingInfoRecord delegator_starting_infos = 9 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_starting_infos\""]; - - // fee_pool defines the validator slash events at genesis. - repeated ValidatorSlashEventRecord validator_slash_events = 10 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_slash_events\""]; -} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto deleted file mode 100644 index 2991218d8..000000000 --- a/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto +++ /dev/null @@ -1,218 +0,0 @@ -syntax = "proto3"; -package cosmos.distribution.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/distribution/v1beta1/distribution.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; - -// Query defines the gRPC querier service for distribution module. -service Query { - // Params queries params of the distribution module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/params"; - } - - // ValidatorOutstandingRewards queries rewards of a validator address. - rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest) - returns (QueryValidatorOutstandingRewardsResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" - "{validator_address}/outstanding_rewards"; - } - - // ValidatorCommission queries accumulated commission for a validator. - rpc ValidatorCommission(QueryValidatorCommissionRequest) returns (QueryValidatorCommissionResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" - "{validator_address}/commission"; - } - - // ValidatorSlashes queries slash events of a validator. - rpc ValidatorSlashes(QueryValidatorSlashesRequest) returns (QueryValidatorSlashesResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes"; - } - - // DelegationRewards queries the total rewards accrued by a delegation. - rpc DelegationRewards(QueryDelegationRewardsRequest) returns (QueryDelegationRewardsResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards/" - "{validator_address}"; - } - - // DelegationTotalRewards queries the total rewards accrued by a each - // validator. - rpc DelegationTotalRewards(QueryDelegationTotalRewardsRequest) returns (QueryDelegationTotalRewardsResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards"; - } - - // DelegatorValidators queries the validators of a delegator. - rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" - "{delegator_address}/validators"; - } - - // DelegatorWithdrawAddress queries withdraw address of a delegator. - rpc DelegatorWithdrawAddress(QueryDelegatorWithdrawAddressRequest) returns (QueryDelegatorWithdrawAddressResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" - "{delegator_address}/withdraw_address"; - } - - // CommunityPool queries the community pool coins. - rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) { - option (google.api.http).get = "/cosmos/distribution/v1beta1/community_pool"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [(gogoproto.nullable) = false]; -} - -// QueryValidatorOutstandingRewardsRequest is the request type for the -// Query/ValidatorOutstandingRewards RPC method. -message QueryValidatorOutstandingRewardsRequest { - // validator_address defines the validator address to query for. - string validator_address = 1; -} - -// QueryValidatorOutstandingRewardsResponse is the response type for the -// Query/ValidatorOutstandingRewards RPC method. -message QueryValidatorOutstandingRewardsResponse { - ValidatorOutstandingRewards rewards = 1 [(gogoproto.nullable) = false]; -} - -// QueryValidatorCommissionRequest is the request type for the -// Query/ValidatorCommission RPC method -message QueryValidatorCommissionRequest { - // validator_address defines the validator address to query for. - string validator_address = 1; -} - -// QueryValidatorCommissionResponse is the response type for the -// Query/ValidatorCommission RPC method -message QueryValidatorCommissionResponse { - // commission defines the commision the validator received. - ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false]; -} - -// QueryValidatorSlashesRequest is the request type for the -// Query/ValidatorSlashes RPC method -message QueryValidatorSlashesRequest { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = true; - - // validator_address defines the validator address to query for. - string validator_address = 1; - // starting_height defines the optional starting height to query the slashes. - uint64 starting_height = 2; - // starting_height defines the optional ending height to query the slashes. - uint64 ending_height = 3; - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 4; -} - -// QueryValidatorSlashesResponse is the response type for the -// Query/ValidatorSlashes RPC method. -message QueryValidatorSlashesResponse { - // slashes defines the slashes the validator received. - repeated ValidatorSlashEvent slashes = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDelegationRewardsRequest is the request type for the -// Query/DelegationRewards RPC method. -message QueryDelegationRewardsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_address defines the delegator address to query for. - string delegator_address = 1; - // validator_address defines the validator address to query for. - string validator_address = 2; -} - -// QueryDelegationRewardsResponse is the response type for the -// Query/DelegationRewards RPC method. -message QueryDelegationRewardsResponse { - // rewards defines the rewards accrued by a delegation. - repeated cosmos.base.v1beta1.DecCoin rewards = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; -} - -// QueryDelegationTotalRewardsRequest is the request type for the -// Query/DelegationTotalRewards RPC method. -message QueryDelegationTotalRewardsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - // delegator_address defines the delegator address to query for. - string delegator_address = 1; -} - -// QueryDelegationTotalRewardsResponse is the response type for the -// Query/DelegationTotalRewards RPC method. -message QueryDelegationTotalRewardsResponse { - // rewards defines all the rewards accrued by a delegator. - repeated DelegationDelegatorReward rewards = 1 [(gogoproto.nullable) = false]; - // total defines the sum of all the rewards. - repeated cosmos.base.v1beta1.DecCoin total = 2 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; -} - -// QueryDelegatorValidatorsRequest is the request type for the -// Query/DelegatorValidators RPC method. -message QueryDelegatorValidatorsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_address defines the delegator address to query for. - string delegator_address = 1; -} - -// QueryDelegatorValidatorsResponse is the response type for the -// Query/DelegatorValidators RPC method. -message QueryDelegatorValidatorsResponse { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // validators defines the validators a delegator is delegating for. - repeated string validators = 1; -} - -// QueryDelegatorWithdrawAddressRequest is the request type for the -// Query/DelegatorWithdrawAddress RPC method. -message QueryDelegatorWithdrawAddressRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_address defines the delegator address to query for. - string delegator_address = 1; -} - -// QueryDelegatorWithdrawAddressResponse is the response type for the -// Query/DelegatorWithdrawAddress RPC method. -message QueryDelegatorWithdrawAddressResponse { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // withdraw_address defines the delegator address to query for. - string withdraw_address = 1; -} - -// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC -// method. -message QueryCommunityPoolRequest {} - -// QueryCommunityPoolResponse is the response type for the Query/CommunityPool -// RPC method. -message QueryCommunityPoolResponse { - // pool defines community pool's coins. - repeated cosmos.base.v1beta1.DecCoin pool = 1 - [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto deleted file mode 100644 index e6ce478bc..000000000 --- a/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto +++ /dev/null @@ -1,79 +0,0 @@ -syntax = "proto3"; -package cosmos.distribution.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -// Msg defines the distribution Msg service. -service Msg { - // SetWithdrawAddress defines a method to change the withdraw address - // for a delegator (or validator self-delegation). - rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse); - - // WithdrawDelegatorReward defines a method to withdraw rewards of delegator - // from a single validator. - rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse); - - // WithdrawValidatorCommission defines a method to withdraw the - // full commission to the validator address. - rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse); - - // FundCommunityPool defines a method to allow an account to directly - // fund the community pool. - rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse); -} - -// MsgSetWithdrawAddress sets the withdraw address for -// a delegator (or validator self-delegation). -message MsgSetWithdrawAddress { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; -} - -// MsgSetWithdrawAddressResponse defines the Msg/SetWithdrawAddress response type. -message MsgSetWithdrawAddressResponse {} - -// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator -// from a single validator. -message MsgWithdrawDelegatorReward { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; -} - -// MsgWithdrawDelegatorRewardResponse defines the Msg/WithdrawDelegatorReward response type. -message MsgWithdrawDelegatorRewardResponse {} - -// MsgWithdrawValidatorCommission withdraws the full commission to the validator -// address. -message MsgWithdrawValidatorCommission { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; -} - -// MsgWithdrawValidatorCommissionResponse defines the Msg/WithdrawValidatorCommission response type. -message MsgWithdrawValidatorCommissionResponse {} - -// MsgFundCommunityPool allows an account to directly -// fund the community pool. -message MsgFundCommunityPool { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - repeated cosmos.base.v1beta1.Coin amount = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - string depositor = 2; -} - -// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type. -message MsgFundCommunityPoolResponse {} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto deleted file mode 100644 index 14612c314..000000000 --- a/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; -package cosmos.evidence.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; - -// Equivocation implements the Evidence interface and defines evidence of double -// signing misbehavior. -message Equivocation { - option (gogoproto.goproto_stringer) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.equal) = false; - - int64 height = 1; - google.protobuf.Timestamp time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - int64 power = 3; - string consensus_address = 4 [(gogoproto.moretags) = "yaml:\"consensus_address\""]; -} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto deleted file mode 100644 index 199f446f7..000000000 --- a/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; -package cosmos.evidence.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; - -import "google/protobuf/any.proto"; - -// GenesisState defines the evidence module's genesis state. -message GenesisState { - // evidence defines all the evidence at genesis. - repeated google.protobuf.Any evidence = 1; -} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto deleted file mode 100644 index eda00544c..000000000 --- a/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto +++ /dev/null @@ -1,51 +0,0 @@ -syntax = "proto3"; -package cosmos.evidence.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; - -// Query defines the gRPC querier service. -service Query { - // Evidence queries evidence based on evidence hash. - rpc Evidence(QueryEvidenceRequest) returns (QueryEvidenceResponse) { - option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence/{evidence_hash}"; - } - - // AllEvidence queries all evidence. - rpc AllEvidence(QueryAllEvidenceRequest) returns (QueryAllEvidenceResponse) { - option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence"; - } -} - -// QueryEvidenceRequest is the request type for the Query/Evidence RPC method. -message QueryEvidenceRequest { - // evidence_hash defines the hash of the requested evidence. - bytes evidence_hash = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"]; -} - -// QueryEvidenceResponse is the response type for the Query/Evidence RPC method. -message QueryEvidenceResponse { - // evidence returns the requested evidence. - google.protobuf.Any evidence = 1; -} - -// QueryEvidenceRequest is the request type for the Query/AllEvidence RPC -// method. -message QueryAllEvidenceRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryAllEvidenceResponse is the response type for the Query/AllEvidence RPC -// method. -message QueryAllEvidenceResponse { - // evidence returns all evidences. - repeated google.protobuf.Any evidence = 1; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto deleted file mode 100644 index 38795f25d..000000000 --- a/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; -package cosmos.evidence.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "cosmos_proto/cosmos.proto"; - -// Msg defines the evidence Msg service. -service Msg { - // SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or - // counterfactual signing. - rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse); -} - -// MsgSubmitEvidence represents a message that supports submitting arbitrary -// Evidence of misbehavior such as equivocation or counterfactual signing. -message MsgSubmitEvidence { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string submitter = 1; - google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"]; -} - -// MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type. -message MsgSubmitEvidenceResponse { - // hash defines the hash of the evidence. - bytes hash = 4; -} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto deleted file mode 100644 index a86691f91..000000000 --- a/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.feegrant.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "google/protobuf/timestamp.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; - -// BasicAllowance implements Allowance with a one-time grant of tokens -// that optionally expires. The grantee can use up to SpendLimit to cover fees. -message BasicAllowance { - option (cosmos_proto.implements_interface) = "FeeAllowanceI"; - - // spend_limit specifies the maximum amount of tokens that can be spent - // by this allowance and will be updated as tokens are spent. If it is - // empty, there is no spend limit and any amount of coins can be spent. - repeated cosmos.base.v1beta1.Coin spend_limit = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // expiration specifies an optional time when this allowance expires - google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true]; -} - -// PeriodicAllowance extends Allowance to allow for both a maximum cap, -// as well as a limit per time period. -message PeriodicAllowance { - option (cosmos_proto.implements_interface) = "FeeAllowanceI"; - - // basic specifies a struct of `BasicAllowance` - BasicAllowance basic = 1 [(gogoproto.nullable) = false]; - - // period specifies the time duration in which period_spend_limit coins can - // be spent before that allowance is reset - google.protobuf.Duration period = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; - - // period_spend_limit specifies the maximum number of coins that can be spent - // in the period - repeated cosmos.base.v1beta1.Coin period_spend_limit = 3 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // period_can_spend is the number of coins left to be spent before the period_reset time - repeated cosmos.base.v1beta1.Coin period_can_spend = 4 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // period_reset is the time at which this period resets and a new one begins, - // it is calculated from the start time of the first transaction after the - // last period ended - google.protobuf.Timestamp period_reset = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; -} - -// AllowedMsgAllowance creates allowance only for specified message types. -message AllowedMsgAllowance { - option (gogoproto.goproto_getters) = false; - option (cosmos_proto.implements_interface) = "FeeAllowanceI"; - - // allowance can be any of basic and filtered fee allowance. - google.protobuf.Any allowance = 1 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; - - // allowed_messages are the messages for which the grantee has the access. - repeated string allowed_messages = 2; -} - -// Grant is stored in the KVStore to record a grant with full context -message Grant { - // granter is the address of the user granting an allowance of their funds. - string granter = 1; - - // grantee is the address of the user being granted an allowance of another user's funds. - string grantee = 2; - - // allowance can be any of basic and filtered fee allowance. - google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; -} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto deleted file mode 100644 index 5b1ac4ca5..000000000 --- a/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto +++ /dev/null @@ -1,13 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.feegrant.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/feegrant/v1beta1/feegrant.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; - -// GenesisState contains a set of fee allowances, persisted from the store -message GenesisState { - repeated Grant allowances = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto deleted file mode 100644 index 42d7a842d..000000000 --- a/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto +++ /dev/null @@ -1,78 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.feegrant.v1beta1; - -import "cosmos/feegrant/v1beta1/feegrant.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; - -// Query defines the gRPC querier service. -service Query { - - // Allowance returns fee granted to the grantee by the granter. - rpc Allowance(QueryAllowanceRequest) returns (QueryAllowanceResponse) { - option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowance/{granter}/{grantee}"; - } - - // Allowances returns all the grants for address. - rpc Allowances(QueryAllowancesRequest) returns (QueryAllowancesResponse) { - option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowances/{grantee}"; - } - - // AllowancesByGranter returns all the grants given by an address - // Since v0.46 - rpc AllowancesByGranter(QueryAllowancesByGranterRequest) returns (QueryAllowancesByGranterResponse) { - option (google.api.http).get = "/cosmos/feegrant/v1beta1/issued/{granter}"; - } -} - -// QueryAllowanceRequest is the request type for the Query/Allowance RPC method. -message QueryAllowanceRequest { - // granter is the address of the user granting an allowance of their funds. - string granter = 1; - - // grantee is the address of the user being granted an allowance of another user's funds. - string grantee = 2; -} - -// QueryAllowanceResponse is the response type for the Query/Allowance RPC method. -message QueryAllowanceResponse { - // allowance is a allowance granted for grantee by granter. - cosmos.feegrant.v1beta1.Grant allowance = 1; -} - -// QueryAllowancesRequest is the request type for the Query/Allowances RPC method. -message QueryAllowancesRequest { - string grantee = 1; - - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryAllowancesResponse is the response type for the Query/Allowances RPC method. -message QueryAllowancesResponse { - // allowances are allowance's granted for grantee by granter. - repeated cosmos.feegrant.v1beta1.Grant allowances = 1; - - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryAllowancesByGranterRequest is the request type for the Query/AllowancesByGranter RPC method. -message QueryAllowancesByGranterRequest { - string granter = 1; - - // pagination defines an pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryAllowancesByGranterResponse is the response type for the Query/AllowancesByGranter RPC method. -message QueryAllowancesByGranterResponse { - // allowances that have been issued by the granter. - repeated cosmos.feegrant.v1beta1.Grant allowances = 1; - - // pagination defines an pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto deleted file mode 100644 index 2d875e922..000000000 --- a/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto +++ /dev/null @@ -1,49 +0,0 @@ -// Since: cosmos-sdk 0.43 -syntax = "proto3"; -package cosmos.feegrant.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "cosmos_proto/cosmos.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; - -// Msg defines the feegrant msg service. -service Msg { - - // GrantAllowance grants fee allowance to the grantee on the granter's - // account with the provided expiration time. - rpc GrantAllowance(MsgGrantAllowance) returns (MsgGrantAllowanceResponse); - - // RevokeAllowance revokes any fee allowance of granter's account that - // has been granted to the grantee. - rpc RevokeAllowance(MsgRevokeAllowance) returns (MsgRevokeAllowanceResponse); -} - -// MsgGrantAllowance adds permission for Grantee to spend up to Allowance -// of fees from the account of Granter. -message MsgGrantAllowance { - // granter is the address of the user granting an allowance of their funds. - string granter = 1; - - // grantee is the address of the user being granted an allowance of another user's funds. - string grantee = 2; - - // allowance can be any of basic and filtered fee allowance. - google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; -} - -// MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type. -message MsgGrantAllowanceResponse {} - -// MsgRevokeAllowance removes any existing Allowance from Granter to Grantee. -message MsgRevokeAllowance { - // granter is the address of the user granting an allowance of their funds. - string granter = 1; - - // grantee is the address of the user being granted an allowance of another user's funds. - string grantee = 2; -} - -// MsgRevokeAllowanceResponse defines the Msg/RevokeAllowanceResponse response type. -message MsgRevokeAllowanceResponse {} diff --git a/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto deleted file mode 100644 index a0207793d..000000000 --- a/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package cosmos.genutil.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/genutil/types"; - -// GenesisState defines the raw genesis transaction in JSON. -message GenesisState { - // gen_txs defines the genesis transactions. - repeated bytes gen_txs = 1 [ - (gogoproto.casttype) = "encoding/json.RawMessage", - (gogoproto.jsontag) = "gentxs", - (gogoproto.moretags) = "yaml:\"gentxs\"" - ]; -} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto deleted file mode 100644 index a99950044..000000000 --- a/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; - -package cosmos.gov.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/gov/v1beta1/gov.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; - -// GenesisState defines the gov module's genesis state. -message GenesisState { - // starting_proposal_id is the ID of the starting proposal. - uint64 starting_proposal_id = 1 [(gogoproto.moretags) = "yaml:\"starting_proposal_id\""]; - // deposits defines all the deposits present at genesis. - repeated Deposit deposits = 2 [(gogoproto.castrepeated) = "Deposits", (gogoproto.nullable) = false]; - // votes defines all the votes present at genesis. - repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false]; - // proposals defines all the proposals present at genesis. - repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false]; - // params defines all the paramaters of related to deposit. - DepositParams deposit_params = 5 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_params\""]; - // params defines all the paramaters of related to voting. - VotingParams voting_params = 6 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_params\""]; - // params defines all the paramaters of related to tally. - TallyParams tally_params = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"tally_params\""]; -} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto deleted file mode 100644 index 01aebf950..000000000 --- a/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto +++ /dev/null @@ -1,200 +0,0 @@ -syntax = "proto3"; -package cosmos.gov.v1beta1; - -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "google/protobuf/timestamp.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.stringer_all) = false; -option (gogoproto.goproto_getters_all) = false; - -// VoteOption enumerates the valid vote options for a given governance proposal. -enum VoteOption { - option (gogoproto.goproto_enum_prefix) = false; - - // VOTE_OPTION_UNSPECIFIED defines a no-op vote option. - VOTE_OPTION_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "OptionEmpty"]; - // VOTE_OPTION_YES defines a yes vote option. - VOTE_OPTION_YES = 1 [(gogoproto.enumvalue_customname) = "OptionYes"]; - // VOTE_OPTION_ABSTAIN defines an abstain vote option. - VOTE_OPTION_ABSTAIN = 2 [(gogoproto.enumvalue_customname) = "OptionAbstain"]; - // VOTE_OPTION_NO defines a no vote option. - VOTE_OPTION_NO = 3 [(gogoproto.enumvalue_customname) = "OptionNo"]; - // VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option. - VOTE_OPTION_NO_WITH_VETO = 4 [(gogoproto.enumvalue_customname) = "OptionNoWithVeto"]; -} - -// WeightedVoteOption defines a unit of vote for vote split. -// -// Since: cosmos-sdk 0.43 -message WeightedVoteOption { - VoteOption option = 1; - string weight = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"weight\"" - ]; -} - -// TextProposal defines a standard text proposal whose changes need to be -// manually updated in case of approval. -message TextProposal { - option (cosmos_proto.implements_interface) = "Content"; - - option (gogoproto.equal) = true; - - string title = 1; - string description = 2; -} - -// Deposit defines an amount deposited by an account address to an active -// proposal. -message Deposit { - option (gogoproto.goproto_getters) = false; - option (gogoproto.equal) = false; - - uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; - string depositor = 2; - repeated cosmos.base.v1beta1.Coin amount = 3 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// Proposal defines the core field members of a governance proposal. -message Proposal { - option (gogoproto.equal) = true; - - uint64 proposal_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""]; - google.protobuf.Any content = 2 [(cosmos_proto.accepts_interface) = "Content"]; - ProposalStatus status = 3 [(gogoproto.moretags) = "yaml:\"proposal_status\""]; - TallyResult final_tally_result = 4 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"final_tally_result\""]; - google.protobuf.Timestamp submit_time = 5 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"submit_time\""]; - google.protobuf.Timestamp deposit_end_time = 6 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_end_time\""]; - repeated cosmos.base.v1beta1.Coin total_deposit = 7 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"total_deposit\"" - ]; - google.protobuf.Timestamp voting_start_time = 8 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_start_time\""]; - google.protobuf.Timestamp voting_end_time = 9 - [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_end_time\""]; -} - -// ProposalStatus enumerates the valid statuses of a proposal. -enum ProposalStatus { - option (gogoproto.goproto_enum_prefix) = false; - - // PROPOSAL_STATUS_UNSPECIFIED defines the default propopsal status. - PROPOSAL_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusNil"]; - // PROPOSAL_STATUS_DEPOSIT_PERIOD defines a proposal status during the deposit - // period. - PROPOSAL_STATUS_DEPOSIT_PERIOD = 1 [(gogoproto.enumvalue_customname) = "StatusDepositPeriod"]; - // PROPOSAL_STATUS_VOTING_PERIOD defines a proposal status during the voting - // period. - PROPOSAL_STATUS_VOTING_PERIOD = 2 [(gogoproto.enumvalue_customname) = "StatusVotingPeriod"]; - // PROPOSAL_STATUS_PASSED defines a proposal status of a proposal that has - // passed. - PROPOSAL_STATUS_PASSED = 3 [(gogoproto.enumvalue_customname) = "StatusPassed"]; - // PROPOSAL_STATUS_REJECTED defines a proposal status of a proposal that has - // been rejected. - PROPOSAL_STATUS_REJECTED = 4 [(gogoproto.enumvalue_customname) = "StatusRejected"]; - // PROPOSAL_STATUS_FAILED defines a proposal status of a proposal that has - // failed. - PROPOSAL_STATUS_FAILED = 5 [(gogoproto.enumvalue_customname) = "StatusFailed"]; -} - -// TallyResult defines a standard tally for a governance proposal. -message TallyResult { - option (gogoproto.equal) = true; - - string yes = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; - string abstain = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; - string no = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; - string no_with_veto = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"no_with_veto\"" - ]; -} - -// Vote defines a vote on a governance proposal. -// A Vote consists of a proposal ID, the voter, and the vote option. -message Vote { - option (gogoproto.goproto_stringer) = false; - option (gogoproto.equal) = false; - - uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; - string voter = 2; - // Deprecated: Prefer to use `options` instead. This field is set in queries - // if and only if `len(options) == 1` and that option has weight 1. In all - // other cases, this field will default to VOTE_OPTION_UNSPECIFIED. - VoteOption option = 3 [deprecated = true]; - // Since: cosmos-sdk 0.43 - repeated WeightedVoteOption options = 4 [(gogoproto.nullable) = false]; -} - -// DepositParams defines the params for deposits on governance proposals. -message DepositParams { - // Minimum deposit for a proposal to enter voting period. - repeated cosmos.base.v1beta1.Coin min_deposit = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"min_deposit\"", - (gogoproto.jsontag) = "min_deposit,omitempty" - ]; - - // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 - // months. - google.protobuf.Duration max_deposit_period = 2 [ - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true, - (gogoproto.jsontag) = "max_deposit_period,omitempty", - (gogoproto.moretags) = "yaml:\"max_deposit_period\"" - ]; -} - -// VotingParams defines the params for voting on governance proposals. -message VotingParams { - // Length of the voting period. - google.protobuf.Duration voting_period = 1 [ - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true, - (gogoproto.jsontag) = "voting_period,omitempty", - (gogoproto.moretags) = "yaml:\"voting_period\"" - ]; -} - -// TallyParams defines the params for tallying votes on governance proposals. -message TallyParams { - // Minimum percentage of total stake needed to vote for a result to be - // considered valid. - bytes quorum = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "quorum,omitempty" - ]; - - // Minimum proportion of Yes votes for proposal to pass. Default value: 0.5. - bytes threshold = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "threshold,omitempty" - ]; - - // Minimum value of Veto votes to Total votes ratio for proposal to be - // vetoed. Default value: 1/3. - bytes veto_threshold = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "veto_threshold,omitempty", - (gogoproto.moretags) = "yaml:\"veto_threshold\"" - ]; -} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto deleted file mode 100644 index da62bdbad..000000000 --- a/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto +++ /dev/null @@ -1,190 +0,0 @@ -syntax = "proto3"; -package cosmos.gov.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/gov/v1beta1/gov.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; - -// Query defines the gRPC querier service for gov module -service Query { - // Proposal queries proposal details based on ProposalID. - rpc Proposal(QueryProposalRequest) returns (QueryProposalResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}"; - } - - // Proposals queries all proposals based on given status. - rpc Proposals(QueryProposalsRequest) returns (QueryProposalsResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals"; - } - - // Vote queries voted information based on proposalID, voterAddr. - rpc Vote(QueryVoteRequest) returns (QueryVoteResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}"; - } - - // Votes queries votes of a given proposal. - rpc Votes(QueryVotesRequest) returns (QueryVotesResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes"; - } - - // Params queries all parameters of the gov module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/params/{params_type}"; - } - - // Deposit queries single deposit information based proposalID, depositAddr. - rpc Deposit(QueryDepositRequest) returns (QueryDepositResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}"; - } - - // Deposits queries all deposits of a single proposal. - rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits"; - } - - // TallyResult queries the tally of a proposal vote. - rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) { - option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/tally"; - } -} - -// QueryProposalRequest is the request type for the Query/Proposal RPC method. -message QueryProposalRequest { - // proposal_id defines the unique id of the proposal. - uint64 proposal_id = 1; -} - -// QueryProposalResponse is the response type for the Query/Proposal RPC method. -message QueryProposalResponse { - Proposal proposal = 1 [(gogoproto.nullable) = false]; -} - -// QueryProposalsRequest is the request type for the Query/Proposals RPC method. -message QueryProposalsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // proposal_status defines the status of the proposals. - ProposalStatus proposal_status = 1; - - // voter defines the voter address for the proposals. - string voter = 2; - - // depositor defines the deposit addresses from the proposals. - string depositor = 3; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 4; -} - -// QueryProposalsResponse is the response type for the Query/Proposals RPC -// method. -message QueryProposalsResponse { - repeated Proposal proposals = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryVoteRequest is the request type for the Query/Vote RPC method. -message QueryVoteRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // proposal_id defines the unique id of the proposal. - uint64 proposal_id = 1; - - // voter defines the oter address for the proposals. - string voter = 2; -} - -// QueryVoteResponse is the response type for the Query/Vote RPC method. -message QueryVoteResponse { - // vote defined the queried vote. - Vote vote = 1 [(gogoproto.nullable) = false]; -} - -// QueryVotesRequest is the request type for the Query/Votes RPC method. -message QueryVotesRequest { - // proposal_id defines the unique id of the proposal. - uint64 proposal_id = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryVotesResponse is the response type for the Query/Votes RPC method. -message QueryVotesResponse { - // votes defined the queried votes. - repeated Vote votes = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest { - // params_type defines which parameters to query for, can be one of "voting", - // "tallying" or "deposit". - string params_type = 1; -} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // voting_params defines the parameters related to voting. - VotingParams voting_params = 1 [(gogoproto.nullable) = false]; - // deposit_params defines the parameters related to deposit. - DepositParams deposit_params = 2 [(gogoproto.nullable) = false]; - // tally_params defines the parameters related to tally. - TallyParams tally_params = 3 [(gogoproto.nullable) = false]; -} - -// QueryDepositRequest is the request type for the Query/Deposit RPC method. -message QueryDepositRequest { - option (gogoproto.goproto_getters) = false; - option (gogoproto.equal) = false; - - // proposal_id defines the unique id of the proposal. - uint64 proposal_id = 1; - - // depositor defines the deposit addresses from the proposals. - string depositor = 2; -} - -// QueryDepositResponse is the response type for the Query/Deposit RPC method. -message QueryDepositResponse { - // deposit defines the requested deposit. - Deposit deposit = 1 [(gogoproto.nullable) = false]; -} - -// QueryDepositsRequest is the request type for the Query/Deposits RPC method. -message QueryDepositsRequest { - // proposal_id defines the unique id of the proposal. - uint64 proposal_id = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryDepositsResponse is the response type for the Query/Deposits RPC method. -message QueryDepositsResponse { - repeated Deposit deposits = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryTallyResultRequest is the request type for the Query/Tally RPC method. -message QueryTallyResultRequest { - // proposal_id defines the unique id of the proposal. - uint64 proposal_id = 1; -} - -// QueryTallyResultResponse is the response type for the Query/Tally RPC method. -message QueryTallyResultResponse { - // tally defines the requested tally. - TallyResult tally = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto deleted file mode 100644 index 36c0a95d2..000000000 --- a/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto +++ /dev/null @@ -1,99 +0,0 @@ -syntax = "proto3"; -package cosmos.gov.v1beta1; - -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/gov/v1beta1/gov.proto"; -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; - -// Msg defines the bank Msg service. -service Msg { - // SubmitProposal defines a method to create new proposal given a content. - rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse); - - // Vote defines a method to add a vote on a specific proposal. - rpc Vote(MsgVote) returns (MsgVoteResponse); - - // VoteWeighted defines a method to add a weighted vote on a specific proposal. - // - // Since: cosmos-sdk 0.43 - rpc VoteWeighted(MsgVoteWeighted) returns (MsgVoteWeightedResponse); - - // Deposit defines a method to add deposit on a specific proposal. - rpc Deposit(MsgDeposit) returns (MsgDepositResponse); -} - -// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary -// proposal Content. -message MsgSubmitProposal { - option (gogoproto.equal) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.stringer) = false; - option (gogoproto.goproto_getters) = false; - - google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"]; - repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"initial_deposit\"" - ]; - string proposer = 3; -} - -// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type. -message MsgSubmitProposalResponse { - uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; -} - -// MsgVote defines a message to cast a vote. -message MsgVote { - option (gogoproto.equal) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.stringer) = false; - option (gogoproto.goproto_getters) = false; - - uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; - string voter = 2; - VoteOption option = 3; -} - -// MsgVoteResponse defines the Msg/Vote response type. -message MsgVoteResponse {} - -// MsgVoteWeighted defines a message to cast a vote. -// -// Since: cosmos-sdk 0.43 -message MsgVoteWeighted { - option (gogoproto.equal) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.stringer) = false; - option (gogoproto.goproto_getters) = false; - - uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; - string voter = 2; - repeated WeightedVoteOption options = 3 [(gogoproto.nullable) = false]; -} - -// MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. -// -// Since: cosmos-sdk 0.43 -message MsgVoteWeightedResponse {} - -// MsgDeposit defines a message to submit a deposit to an existing proposal. -message MsgDeposit { - option (gogoproto.equal) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.stringer) = false; - option (gogoproto.goproto_getters) = false; - - uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; - string depositor = 2; - repeated cosmos.base.v1beta1.Coin amount = 3 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// MsgDepositResponse defines the Msg/Deposit response type. -message MsgDepositResponse {} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto deleted file mode 100644 index 4e783fb54..000000000 --- a/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package cosmos.mint.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/mint/v1beta1/mint.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; - -// GenesisState defines the mint module's genesis state. -message GenesisState { - // minter is a space for holding current inflation information. - Minter minter = 1 [(gogoproto.nullable) = false]; - - // params defines all the paramaters of the module. - Params params = 2 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto deleted file mode 100644 index f94d4ae2e..000000000 --- a/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto +++ /dev/null @@ -1,53 +0,0 @@ -syntax = "proto3"; -package cosmos.mint.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; - -import "gogoproto/gogo.proto"; - -// Minter represents the minting state. -message Minter { - // current annual inflation rate - string inflation = 1 - [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; - // current annual expected provisions - string annual_provisions = 2 [ - (gogoproto.moretags) = "yaml:\"annual_provisions\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; -} - -// Params holds parameters for the mint module. -message Params { - option (gogoproto.goproto_stringer) = false; - - // type of coin to mint - string mint_denom = 1; - // maximum annual change in inflation rate - string inflation_rate_change = 2 [ - (gogoproto.moretags) = "yaml:\"inflation_rate_change\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // maximum inflation rate - string inflation_max = 3 [ - (gogoproto.moretags) = "yaml:\"inflation_max\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // minimum inflation rate - string inflation_min = 4 [ - (gogoproto.moretags) = "yaml:\"inflation_min\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // goal of percent bonded atoms - string goal_bonded = 5 [ - (gogoproto.moretags) = "yaml:\"goal_bonded\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // expected blocks per year - uint64 blocks_per_year = 6 [(gogoproto.moretags) = "yaml:\"blocks_per_year\""]; -} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto deleted file mode 100644 index acd341d77..000000000 --- a/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto +++ /dev/null @@ -1,57 +0,0 @@ -syntax = "proto3"; -package cosmos.mint.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/mint/v1beta1/mint.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; - -// Query provides defines the gRPC querier service. -service Query { - // Params returns the total set of minting parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/mint/v1beta1/params"; - } - - // Inflation returns the current minting inflation value. - rpc Inflation(QueryInflationRequest) returns (QueryInflationResponse) { - option (google.api.http).get = "/cosmos/mint/v1beta1/inflation"; - } - - // AnnualProvisions current minting annual provisions value. - rpc AnnualProvisions(QueryAnnualProvisionsRequest) returns (QueryAnnualProvisionsResponse) { - option (google.api.http).get = "/cosmos/mint/v1beta1/annual_provisions"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [(gogoproto.nullable) = false]; -} - -// QueryInflationRequest is the request type for the Query/Inflation RPC method. -message QueryInflationRequest {} - -// QueryInflationResponse is the response type for the Query/Inflation RPC -// method. -message QueryInflationResponse { - // inflation is the current minting inflation value. - bytes inflation = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; -} - -// QueryAnnualProvisionsRequest is the request type for the -// Query/AnnualProvisions RPC method. -message QueryAnnualProvisionsRequest {} - -// QueryAnnualProvisionsResponse is the response type for the -// Query/AnnualProvisions RPC method. -message QueryAnnualProvisionsResponse { - // annual_provisions is the current minting annual provisions value. - bytes annual_provisions = 1 - [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/params/v1beta1/params.proto b/ampd/proto/third_party/cosmos/params/v1beta1/params.proto deleted file mode 100644 index 5382fd799..000000000 --- a/ampd/proto/third_party/cosmos/params/v1beta1/params.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; -package cosmos.params.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; - -// ParameterChangeProposal defines a proposal to change one or more parameters. -message ParameterChangeProposal { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - string title = 1; - string description = 2; - repeated ParamChange changes = 3 [(gogoproto.nullable) = false]; -} - -// ParamChange defines an individual parameter change, for use in -// ParameterChangeProposal. -message ParamChange { - option (gogoproto.goproto_stringer) = false; - - string subspace = 1; - string key = 2; - string value = 3; -} diff --git a/ampd/proto/third_party/cosmos/params/v1beta1/query.proto b/ampd/proto/third_party/cosmos/params/v1beta1/query.proto deleted file mode 100644 index 1078e02ae..000000000 --- a/ampd/proto/third_party/cosmos/params/v1beta1/query.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; -package cosmos.params.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/params/v1beta1/params.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; - -// Query defines the gRPC querier service. -service Query { - // Params queries a specific parameter of a module, given its subspace and - // key. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/params/v1beta1/params"; - } -} - -// QueryParamsRequest is request type for the Query/Params RPC method. -message QueryParamsRequest { - // subspace defines the module to query the parameter for. - string subspace = 1; - - // key defines the key of the parameter in the subspace. - string key = 2; -} - -// QueryParamsResponse is response type for the Query/Params RPC method. -message QueryParamsResponse { - // param defines the queried parameter. - ParamChange param = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto deleted file mode 100644 index a7aebcfba..000000000 --- a/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto +++ /dev/null @@ -1,50 +0,0 @@ -syntax = "proto3"; -package cosmos.slashing.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/slashing/v1beta1/slashing.proto"; - -// GenesisState defines the slashing module's genesis state. -message GenesisState { - // params defines all the paramaters of related to deposit. - Params params = 1 [(gogoproto.nullable) = false]; - - // signing_infos represents a map between validator addresses and their - // signing infos. - repeated SigningInfo signing_infos = 2 - [(gogoproto.moretags) = "yaml:\"signing_infos\"", (gogoproto.nullable) = false]; - - // missed_blocks represents a map between validator addresses and their - // missed blocks. - repeated ValidatorMissedBlocks missed_blocks = 3 - [(gogoproto.moretags) = "yaml:\"missed_blocks\"", (gogoproto.nullable) = false]; -} - -// SigningInfo stores validator signing info of corresponding address. -message SigningInfo { - // address is the validator address. - string address = 1; - // validator_signing_info represents the signing info of this validator. - ValidatorSigningInfo validator_signing_info = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_signing_info\""]; -} - -// ValidatorMissedBlocks contains array of missed blocks of corresponding -// address. -message ValidatorMissedBlocks { - // address is the validator address. - string address = 1; - // missed_blocks is an array of missed blocks by the validator. - repeated MissedBlock missed_blocks = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"missed_blocks\""]; -} - -// MissedBlock contains height and missed status as boolean. -message MissedBlock { - // index is the height at which the block was missed. - int64 index = 1; - // missed is the missed status. - bool missed = 2; -} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto deleted file mode 100644 index 869049a0e..000000000 --- a/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto +++ /dev/null @@ -1,63 +0,0 @@ -syntax = "proto3"; -package cosmos.slashing.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/slashing/v1beta1/slashing.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; - -// Query provides defines the gRPC querier service -service Query { - // Params queries the parameters of slashing module - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/slashing/v1beta1/params"; - } - - // SigningInfo queries the signing info of given cons address - rpc SigningInfo(QuerySigningInfoRequest) returns (QuerySigningInfoResponse) { - option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos/{cons_address}"; - } - - // SigningInfos queries signing info of all validators - rpc SigningInfos(QuerySigningInfosRequest) returns (QuerySigningInfosResponse) { - option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos"; - } -} - -// QueryParamsRequest is the request type for the Query/Params RPC method -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method -message QueryParamsResponse { - Params params = 1 [(gogoproto.nullable) = false]; -} - -// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC -// method -message QuerySigningInfoRequest { - // cons_address is the address to query signing info of - string cons_address = 1; -} - -// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC -// method -message QuerySigningInfoResponse { - // val_signing_info is the signing info of requested val cons address - ValidatorSigningInfo val_signing_info = 1 [(gogoproto.nullable) = false]; -} - -// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC -// method -message QuerySigningInfosRequest { - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC -// method -message QuerySigningInfosResponse { - // info is the signing info of all validators - repeated cosmos.slashing.v1beta1.ValidatorSigningInfo info = 1 [(gogoproto.nullable) = false]; - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto deleted file mode 100644 index 882a0fb60..000000000 --- a/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto +++ /dev/null @@ -1,58 +0,0 @@ -syntax = "proto3"; -package cosmos.slashing.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; - -// ValidatorSigningInfo defines a validator's signing info for monitoring their -// liveness activity. -message ValidatorSigningInfo { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - string address = 1; - // Height at which validator was first a candidate OR was unjailed - int64 start_height = 2 [(gogoproto.moretags) = "yaml:\"start_height\""]; - // Index which is incremented each time the validator was a bonded - // in a block and may have signed a precommit or not. This in conjunction with the - // `SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`. - int64 index_offset = 3 [(gogoproto.moretags) = "yaml:\"index_offset\""]; - // Timestamp until which the validator is jailed due to liveness downtime. - google.protobuf.Timestamp jailed_until = 4 - [(gogoproto.moretags) = "yaml:\"jailed_until\"", (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - // Whether or not a validator has been tombstoned (killed out of validator set). It is set - // once the validator commits an equivocation or for any other configured misbehiavor. - bool tombstoned = 5; - // A counter kept to avoid unnecessary array reads. - // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. - int64 missed_blocks_counter = 6 [(gogoproto.moretags) = "yaml:\"missed_blocks_counter\""]; -} - -// Params represents the parameters used for by the slashing module. -message Params { - int64 signed_blocks_window = 1 [(gogoproto.moretags) = "yaml:\"signed_blocks_window\""]; - bytes min_signed_per_window = 2 [ - (gogoproto.moretags) = "yaml:\"min_signed_per_window\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - google.protobuf.Duration downtime_jail_duration = 3 [ - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true, - (gogoproto.moretags) = "yaml:\"downtime_jail_duration\"" - ]; - bytes slash_fraction_double_sign = 4 [ - (gogoproto.moretags) = "yaml:\"slash_fraction_double_sign\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - bytes slash_fraction_downtime = 5 [ - (gogoproto.moretags) = "yaml:\"slash_fraction_downtime\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; -} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto deleted file mode 100644 index 4d63370ec..000000000 --- a/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto +++ /dev/null @@ -1,26 +0,0 @@ -syntax = "proto3"; -package cosmos.slashing.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; -option (gogoproto.equal_all) = true; - -import "gogoproto/gogo.proto"; - -// Msg defines the slashing Msg service. -service Msg { - // Unjail defines a method for unjailing a jailed validator, thus returning - // them into the bonded validator set, so they can begin receiving provisions - // and rewards again. - rpc Unjail(MsgUnjail) returns (MsgUnjailResponse); -} - -// MsgUnjail defines the Msg/Unjail request type -message MsgUnjail { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = true; - - string validator_addr = 1 [(gogoproto.moretags) = "yaml:\"address\"", (gogoproto.jsontag) = "address"]; -} - -// MsgUnjailResponse defines the Msg/Unjail response type -message MsgUnjailResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto deleted file mode 100644 index d50c329c9..000000000 --- a/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto +++ /dev/null @@ -1,47 +0,0 @@ -syntax = "proto3"; -package cosmos.staking.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; - -// StakeAuthorization defines authorization for delegate/undelegate/redelegate. -// -// Since: cosmos-sdk 0.43 -message StakeAuthorization { - option (cosmos_proto.implements_interface) = "Authorization"; - - // max_tokens specifies the maximum amount of tokens can be delegate to a validator. If it is - // empty, there is no spend limit and any amount of coins can be delegated. - cosmos.base.v1beta1.Coin max_tokens = 1 [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"]; - // validators is the oneof that represents either allow_list or deny_list - oneof validators { - // allow_list specifies list of validator addresses to whom grantee can delegate tokens on behalf of granter's - // account. - Validators allow_list = 2; - // deny_list specifies list of validator addresses to whom grantee can not delegate tokens. - Validators deny_list = 3; - } - // Validators defines list of validator addresses. - message Validators { - repeated string address = 1; - } - // authorization_type defines one of AuthorizationType. - AuthorizationType authorization_type = 4; -} - -// AuthorizationType defines the type of staking module authorization type -// -// Since: cosmos-sdk 0.43 -enum AuthorizationType { - // AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type - AUTHORIZATION_TYPE_UNSPECIFIED = 0; - // AUTHORIZATION_TYPE_DELEGATE defines an authorization type for Msg/Delegate - AUTHORIZATION_TYPE_DELEGATE = 1; - // AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for Msg/Undelegate - AUTHORIZATION_TYPE_UNDELEGATE = 2; - // AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for Msg/BeginRedelegate - AUTHORIZATION_TYPE_REDELEGATE = 3; -} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto deleted file mode 100644 index d1563dbc5..000000000 --- a/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto +++ /dev/null @@ -1,53 +0,0 @@ -syntax = "proto3"; -package cosmos.staking.v1beta1; - -option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/staking/v1beta1/staking.proto"; - -// GenesisState defines the staking module's genesis state. -message GenesisState { - // params defines all the paramaters of related to deposit. - Params params = 1 [(gogoproto.nullable) = false]; - - // last_total_power tracks the total amounts of bonded tokens recorded during - // the previous end block. - bytes last_total_power = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.moretags) = "yaml:\"last_total_power\"", - (gogoproto.nullable) = false - ]; - - // last_validator_powers is a special index that provides a historical list - // of the last-block's bonded validators. - repeated LastValidatorPower last_validator_powers = 3 - [(gogoproto.moretags) = "yaml:\"last_validator_powers\"", (gogoproto.nullable) = false]; - - // delegations defines the validator set at genesis. - repeated Validator validators = 4 [(gogoproto.nullable) = false]; - - // delegations defines the delegations active at genesis. - repeated Delegation delegations = 5 [(gogoproto.nullable) = false]; - - // unbonding_delegations defines the unbonding delegations active at genesis. - repeated UnbondingDelegation unbonding_delegations = 6 - [(gogoproto.moretags) = "yaml:\"unbonding_delegations\"", (gogoproto.nullable) = false]; - - // redelegations defines the redelegations active at genesis. - repeated Redelegation redelegations = 7 [(gogoproto.nullable) = false]; - - bool exported = 8; -} - -// LastValidatorPower required for validator set update logic. -message LastValidatorPower { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // address is the address of the validator. - string address = 1; - - // power defines the power of the validator. - int64 power = 2; -} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto deleted file mode 100644 index 4852c5353..000000000 --- a/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto +++ /dev/null @@ -1,348 +0,0 @@ -syntax = "proto3"; -package cosmos.staking.v1beta1; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/staking/v1beta1/staking.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; - -// Query defines the gRPC querier service. -service Query { - // Validators queries all validators that match the given status. - rpc Validators(QueryValidatorsRequest) returns (QueryValidatorsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/validators"; - } - - // Validator queries validator info for given validator address. - rpc Validator(QueryValidatorRequest) returns (QueryValidatorResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}"; - } - - // ValidatorDelegations queries delegate info for given validator. - rpc ValidatorDelegations(QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations"; - } - - // ValidatorUnbondingDelegations queries unbonding delegations of a validator. - rpc ValidatorUnbondingDelegations(QueryValidatorUnbondingDelegationsRequest) - returns (QueryValidatorUnbondingDelegationsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/validators/" - "{validator_addr}/unbonding_delegations"; - } - - // Delegation queries delegate info for given validator delegator pair. - rpc Delegation(QueryDelegationRequest) returns (QueryDelegationResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" - "{delegator_addr}"; - } - - // UnbondingDelegation queries unbonding info for given validator delegator - // pair. - rpc UnbondingDelegation(QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" - "{delegator_addr}/unbonding_delegation"; - } - - // DelegatorDelegations queries all delegations of a given delegator address. - rpc DelegatorDelegations(QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/delegations/{delegator_addr}"; - } - - // DelegatorUnbondingDelegations queries all unbonding delegations of a given - // delegator address. - rpc DelegatorUnbondingDelegations(QueryDelegatorUnbondingDelegationsRequest) - returns (QueryDelegatorUnbondingDelegationsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/" - "{delegator_addr}/unbonding_delegations"; - } - - // Redelegations queries redelegations of given address. - rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/redelegations"; - } - - // DelegatorValidators queries all validators info for given delegator - // address. - rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators"; - } - - // DelegatorValidator queries validator info for given delegator validator - // pair. - rpc DelegatorValidator(QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators/" - "{validator_addr}"; - } - - // HistoricalInfo queries the historical info for given height. - rpc HistoricalInfo(QueryHistoricalInfoRequest) returns (QueryHistoricalInfoResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/historical_info/{height}"; - } - - // Pool queries the pool info. - rpc Pool(QueryPoolRequest) returns (QueryPoolResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/pool"; - } - - // Parameters queries the staking parameters. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/staking/v1beta1/params"; - } -} - -// QueryValidatorsRequest is request type for Query/Validators RPC method. -message QueryValidatorsRequest { - // status enables to query for validators matching a given status. - string status = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryValidatorsResponse is response type for the Query/Validators RPC method -message QueryValidatorsResponse { - // validators contains all the queried validators. - repeated Validator validators = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryValidatorRequest is response type for the Query/Validator RPC method -message QueryValidatorRequest { - // validator_addr defines the validator address to query for. - string validator_addr = 1; -} - -// QueryValidatorResponse is response type for the Query/Validator RPC method -message QueryValidatorResponse { - // validator defines the the validator info. - Validator validator = 1 [(gogoproto.nullable) = false]; -} - -// QueryValidatorDelegationsRequest is request type for the -// Query/ValidatorDelegations RPC method -message QueryValidatorDelegationsRequest { - // validator_addr defines the validator address to query for. - string validator_addr = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryValidatorDelegationsResponse is response type for the -// Query/ValidatorDelegations RPC method -message QueryValidatorDelegationsResponse { - repeated DelegationResponse delegation_responses = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "DelegationResponses"]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryValidatorUnbondingDelegationsRequest is required type for the -// Query/ValidatorUnbondingDelegations RPC method -message QueryValidatorUnbondingDelegationsRequest { - // validator_addr defines the validator address to query for. - string validator_addr = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryValidatorUnbondingDelegationsResponse is response type for the -// Query/ValidatorUnbondingDelegations RPC method. -message QueryValidatorUnbondingDelegationsResponse { - repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDelegationRequest is request type for the Query/Delegation RPC method. -message QueryDelegationRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // validator_addr defines the validator address to query for. - string validator_addr = 2; -} - -// QueryDelegationResponse is response type for the Query/Delegation RPC method. -message QueryDelegationResponse { - // delegation_responses defines the delegation info of a delegation. - DelegationResponse delegation_response = 1; -} - -// QueryUnbondingDelegationRequest is request type for the -// Query/UnbondingDelegation RPC method. -message QueryUnbondingDelegationRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // validator_addr defines the validator address to query for. - string validator_addr = 2; -} - -// QueryDelegationResponse is response type for the Query/UnbondingDelegation -// RPC method. -message QueryUnbondingDelegationResponse { - // unbond defines the unbonding information of a delegation. - UnbondingDelegation unbond = 1 [(gogoproto.nullable) = false]; -} - -// QueryDelegatorDelegationsRequest is request type for the -// Query/DelegatorDelegations RPC method. -message QueryDelegatorDelegationsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryDelegatorDelegationsResponse is response type for the -// Query/DelegatorDelegations RPC method. -message QueryDelegatorDelegationsResponse { - // delegation_responses defines all the delegations' info of a delegator. - repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDelegatorUnbondingDelegationsRequest is request type for the -// Query/DelegatorUnbondingDelegations RPC method. -message QueryDelegatorUnbondingDelegationsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryUnbondingDelegatorDelegationsResponse is response type for the -// Query/UnbondingDelegatorDelegations RPC method. -message QueryDelegatorUnbondingDelegationsResponse { - repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryRedelegationsRequest is request type for the Query/Redelegations RPC -// method. -message QueryRedelegationsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // src_validator_addr defines the validator address to redelegate from. - string src_validator_addr = 2; - - // dst_validator_addr defines the validator address to redelegate to. - string dst_validator_addr = 3; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 4; -} - -// QueryRedelegationsResponse is response type for the Query/Redelegations RPC -// method. -message QueryRedelegationsResponse { - repeated RedelegationResponse redelegation_responses = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDelegatorValidatorsRequest is request type for the -// Query/DelegatorValidators RPC method. -message QueryDelegatorValidatorsRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryDelegatorValidatorsResponse is response type for the -// Query/DelegatorValidators RPC method. -message QueryDelegatorValidatorsResponse { - // validators defines the the validators' info of a delegator. - repeated Validator validators = 1 [(gogoproto.nullable) = false]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryDelegatorValidatorRequest is request type for the -// Query/DelegatorValidator RPC method. -message QueryDelegatorValidatorRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // delegator_addr defines the delegator address to query for. - string delegator_addr = 1; - - // validator_addr defines the validator address to query for. - string validator_addr = 2; -} - -// QueryDelegatorValidatorResponse response type for the -// Query/DelegatorValidator RPC method. -message QueryDelegatorValidatorResponse { - // validator defines the the validator info. - Validator validator = 1 [(gogoproto.nullable) = false]; -} - -// QueryHistoricalInfoRequest is request type for the Query/HistoricalInfo RPC -// method. -message QueryHistoricalInfoRequest { - // height defines at which height to query the historical info. - int64 height = 1; -} - -// QueryHistoricalInfoResponse is response type for the Query/HistoricalInfo RPC -// method. -message QueryHistoricalInfoResponse { - // hist defines the historical info at the given height. - HistoricalInfo hist = 1; -} - -// QueryPoolRequest is request type for the Query/Pool RPC method. -message QueryPoolRequest {} - -// QueryPoolResponse is response type for the Query/Pool RPC method. -message QueryPoolResponse { - // pool defines the pool info. - Pool pool = 1 [(gogoproto.nullable) = false]; -} - -// QueryParamsRequest is request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is response type for the Query/Params RPC method. -message QueryParamsResponse { - // params holds all the parameters of this module. - Params params = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto deleted file mode 100644 index 76e9599e2..000000000 --- a/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto +++ /dev/null @@ -1,334 +0,0 @@ -syntax = "proto3"; -package cosmos.staking.v1beta1; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; - -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "tendermint/types/types.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; - -// HistoricalInfo contains header and validator information for a given block. -// It is stored as part of staking module's state, which persists the `n` most -// recent HistoricalInfo -// (`n` is set by the staking module's `historical_entries` parameter). -message HistoricalInfo { - tendermint.types.Header header = 1 [(gogoproto.nullable) = false]; - repeated Validator valset = 2 [(gogoproto.nullable) = false]; -} - -// CommissionRates defines the initial commission rates to be used for creating -// a validator. -message CommissionRates { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // rate is the commission rate charged to delegators, as a fraction. - string rate = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; - // max_rate defines the maximum commission rate which validator can ever charge, as a fraction. - string max_rate = 2 [ - (gogoproto.moretags) = "yaml:\"max_rate\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // max_change_rate defines the maximum daily increase of the validator commission, as a fraction. - string max_change_rate = 3 [ - (gogoproto.moretags) = "yaml:\"max_change_rate\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; -} - -// Commission defines commission parameters for a given validator. -message Commission { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // commission_rates defines the initial commission rates to be used for creating a validator. - CommissionRates commission_rates = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; - // update_time is the last time the commission rate was changed. - google.protobuf.Timestamp update_time = 2 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"update_time\""]; -} - -// Description defines a validator description. -message Description { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // moniker defines a human-readable name for the validator. - string moniker = 1; - // identity defines an optional identity signature (ex. UPort or Keybase). - string identity = 2; - // website defines an optional website link. - string website = 3; - // security_contact defines an optional email for security contact. - string security_contact = 4 [(gogoproto.moretags) = "yaml:\"security_contact\""]; - // details define other optional details. - string details = 5; -} - -// Validator defines a validator, together with the total amount of the -// Validator's bond shares and their exchange rate to coins. Slashing results in -// a decrease in the exchange rate, allowing correct calculation of future -// undelegations without iterating over delegators. When coins are delegated to -// this validator, the validator is credited with a delegation whose number of -// bond shares is based on the amount of coins delegated divided by the current -// exchange rate. Voting power can be calculated as total bonded shares -// multiplied by exchange rate. -message Validator { - option (gogoproto.equal) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.goproto_getters) = false; - - // operator_address defines the address of the validator's operator; bech encoded in JSON. - string operator_address = 1 [(gogoproto.moretags) = "yaml:\"operator_address\""]; - // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. - google.protobuf.Any consensus_pubkey = 2 - [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\""]; - // jailed defined whether the validator has been jailed from bonded status or not. - bool jailed = 3; - // status is the validator status (bonded/unbonding/unbonded). - BondStatus status = 4; - // tokens define the delegated tokens (incl. self-delegation). - string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; - // delegator_shares defines total shares issued to a validator's delegators. - string delegator_shares = 6 [ - (gogoproto.moretags) = "yaml:\"delegator_shares\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // description defines the description terms for the validator. - Description description = 7 [(gogoproto.nullable) = false]; - // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding. - int64 unbonding_height = 8 [(gogoproto.moretags) = "yaml:\"unbonding_height\""]; - // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding. - google.protobuf.Timestamp unbonding_time = 9 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; - // commission defines the commission parameters. - Commission commission = 10 [(gogoproto.nullable) = false]; - // min_self_delegation is the validator's self declared minimum self delegation. - string min_self_delegation = 11 [ - (gogoproto.moretags) = "yaml:\"min_self_delegation\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; -} - -// BondStatus is the status of a validator. -enum BondStatus { - option (gogoproto.goproto_enum_prefix) = false; - - // UNSPECIFIED defines an invalid validator status. - BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"]; - // UNBONDED defines a validator that is not bonded. - BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"]; - // UNBONDING defines a validator that is unbonding. - BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"]; - // BONDED defines a validator that is bonded. - BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"]; -} - -// ValAddresses defines a repeated set of validator addresses. -message ValAddresses { - option (gogoproto.goproto_stringer) = false; - option (gogoproto.stringer) = true; - - repeated string addresses = 1; -} - -// DVPair is struct that just has a delegator-validator pair with no other data. -// It is intended to be used as a marshalable pointer. For example, a DVPair can -// be used to construct the key to getting an UnbondingDelegation from state. -message DVPair { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; -} - -// DVPairs defines an array of DVPair objects. -message DVPairs { - repeated DVPair pairs = 1 [(gogoproto.nullable) = false]; -} - -// DVVTriplet is struct that just has a delegator-validator-validator triplet -// with no other data. It is intended to be used as a marshalable pointer. For -// example, a DVVTriplet can be used to construct the key to getting a -// Redelegation from state. -message DVVTriplet { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; - string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; -} - -// DVVTriplets defines an array of DVVTriplet objects. -message DVVTriplets { - repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false]; -} - -// Delegation represents the bond with tokens held by an account. It is -// owned by one delegator, and is associated with the voting power of one -// validator. -message Delegation { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // delegator_address is the bech32-encoded address of the delegator. - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - // validator_address is the bech32-encoded address of the validator. - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - // shares define the delegation shares received. - string shares = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; -} - -// UnbondingDelegation stores all of a single delegator's unbonding bonds -// for a single validator in an time-ordered list. -message UnbondingDelegation { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // delegator_address is the bech32-encoded address of the delegator. - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - // validator_address is the bech32-encoded address of the validator. - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - // entries are the unbonding delegation entries. - repeated UnbondingDelegationEntry entries = 3 [(gogoproto.nullable) = false]; // unbonding delegation entries -} - -// UnbondingDelegationEntry defines an unbonding object with relevant metadata. -message UnbondingDelegationEntry { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // creation_height is the height which the unbonding took place. - int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; - // completion_time is the unix time for unbonding completion. - google.protobuf.Timestamp completion_time = 2 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; - // initial_balance defines the tokens initially scheduled to receive at completion. - string initial_balance = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"initial_balance\"" - ]; - // balance defines the tokens to receive at completion. - string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; -} - -// RedelegationEntry defines a redelegation object with relevant metadata. -message RedelegationEntry { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // creation_height defines the height which the redelegation took place. - int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; - // completion_time defines the unix time for redelegation completion. - google.protobuf.Timestamp completion_time = 2 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; - // initial_balance defines the initial balance when redelegation started. - string initial_balance = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"initial_balance\"" - ]; - // shares_dst is the amount of destination-validator shares created by redelegation. - string shares_dst = 4 - [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; -} - -// Redelegation contains the list of a particular delegator's redelegating bonds -// from a particular source validator to a particular destination validator. -message Redelegation { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // delegator_address is the bech32-encoded address of the delegator. - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - // validator_src_address is the validator redelegation source operator address. - string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; - // validator_dst_address is the validator redelegation destination operator address. - string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; - // entries are the redelegation entries. - repeated RedelegationEntry entries = 4 [(gogoproto.nullable) = false]; // redelegation entries -} - -// Params defines the parameters for the staking module. -message Params { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // unbonding_time is the time duration of unbonding. - google.protobuf.Duration unbonding_time = 1 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; - // max_validators is the maximum number of validators. - uint32 max_validators = 2 [(gogoproto.moretags) = "yaml:\"max_validators\""]; - // max_entries is the max entries for either unbonding delegation or redelegation (per pair/trio). - uint32 max_entries = 3 [(gogoproto.moretags) = "yaml:\"max_entries\""]; - // historical_entries is the number of historical entries to persist. - uint32 historical_entries = 4 [(gogoproto.moretags) = "yaml:\"historical_entries\""]; - // bond_denom defines the bondable coin denomination. - string bond_denom = 5 [(gogoproto.moretags) = "yaml:\"bond_denom\""]; -} - -// DelegationResponse is equivalent to Delegation except that it contains a -// balance in addition to shares which is more suitable for client responses. -message DelegationResponse { - option (gogoproto.equal) = false; - option (gogoproto.goproto_stringer) = false; - - Delegation delegation = 1 [(gogoproto.nullable) = false]; - - cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false]; -} - -// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it -// contains a balance in addition to shares which is more suitable for client -// responses. -message RedelegationEntryResponse { - option (gogoproto.equal) = true; - - RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false]; - string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; -} - -// RedelegationResponse is equivalent to a Redelegation except that its entries -// contain a balance in addition to shares which is more suitable for client -// responses. -message RedelegationResponse { - option (gogoproto.equal) = false; - - Redelegation redelegation = 1 [(gogoproto.nullable) = false]; - repeated RedelegationEntryResponse entries = 2 [(gogoproto.nullable) = false]; -} - -// Pool is used for tracking bonded and not-bonded token supply of the bond -// denomination. -message Pool { - option (gogoproto.description) = true; - option (gogoproto.equal) = true; - string not_bonded_tokens = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.jsontag) = "not_bonded_tokens", - (gogoproto.nullable) = false - ]; - string bonded_tokens = 2 [ - (gogoproto.jsontag) = "bonded_tokens", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"bonded_tokens\"" - ]; -} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto deleted file mode 100644 index d074fe010..000000000 --- a/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto +++ /dev/null @@ -1,123 +0,0 @@ -syntax = "proto3"; -package cosmos.staking.v1beta1; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; -import "gogoproto/gogo.proto"; - -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/staking/v1beta1/staking.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; - -// Msg defines the staking Msg service. -service Msg { - // CreateValidator defines a method for creating a new validator. - rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse); - - // EditValidator defines a method for editing an existing validator. - rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse); - - // Delegate defines a method for performing a delegation of coins - // from a delegator to a validator. - rpc Delegate(MsgDelegate) returns (MsgDelegateResponse); - - // BeginRedelegate defines a method for performing a redelegation - // of coins from a delegator and source validator to a destination validator. - rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse); - - // Undelegate defines a method for performing an undelegation from a - // delegate and a validator. - rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse); -} - -// MsgCreateValidator defines a SDK message for creating a new validator. -message MsgCreateValidator { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - Description description = 1 [(gogoproto.nullable) = false]; - CommissionRates commission = 2 [(gogoproto.nullable) = false]; - string min_self_delegation = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.moretags) = "yaml:\"min_self_delegation\"", - (gogoproto.nullable) = false - ]; - string delegator_address = 4 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_address = 5 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"]; - cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false]; -} - -// MsgCreateValidatorResponse defines the Msg/CreateValidator response type. -message MsgCreateValidatorResponse {} - -// MsgEditValidator defines a SDK message for editing an existing validator. -message MsgEditValidator { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - Description description = 1 [(gogoproto.nullable) = false]; - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"address\""]; - - // We pass a reference to the new commission rate and min self delegation as - // it's not mandatory to update. If not updated, the deserialized rate will be - // zero with no way to distinguish if an update was intended. - // REF: #2373 - string commission_rate = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.moretags) = "yaml:\"commission_rate\"" - ]; - string min_self_delegation = 4 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.moretags) = "yaml:\"min_self_delegation\"" - ]; -} - -// MsgEditValidatorResponse defines the Msg/EditValidator response type. -message MsgEditValidatorResponse {} - -// MsgDelegate defines a SDK message for performing a delegation of coins -// from a delegator to a validator. -message MsgDelegate { - option (gogoproto.equal) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; -} - -// MsgDelegateResponse defines the Msg/Delegate response type. -message MsgDelegateResponse {} - -// MsgBeginRedelegate defines a SDK message for performing a redelegation -// of coins from a delegator and source validator to a destination validator. -message MsgBeginRedelegate { - option (gogoproto.equal) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; - string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; - cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false]; -} - -// MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type. -message MsgBeginRedelegateResponse { - google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; -} - -// MsgUndelegate defines a SDK message for performing an undelegation from a -// delegate and a validator. -message MsgUndelegate { - option (gogoproto.equal) = false; - - string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; - string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; - cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; -} - -// MsgUndelegateResponse defines the Msg/Undelegate response type. -message MsgUndelegateResponse { - google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; -} diff --git a/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto b/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto deleted file mode 100644 index 50de89c8f..000000000 --- a/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto +++ /dev/null @@ -1,91 +0,0 @@ -syntax = "proto3"; -package cosmos.tx.signing.v1beta1; - -import "cosmos/crypto/multisig/v1beta1/multisig.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/types/tx/signing"; - -// SignMode represents a signing mode with its own security guarantees. -enum SignMode { - // SIGN_MODE_UNSPECIFIED specifies an unknown signing mode and will be - // rejected - SIGN_MODE_UNSPECIFIED = 0; - - // SIGN_MODE_DIRECT specifies a signing mode which uses SignDoc and is - // verified with raw bytes from Tx - SIGN_MODE_DIRECT = 1; - - // SIGN_MODE_TEXTUAL is a future signing mode that will verify some - // human-readable textual representation on top of the binary representation - // from SIGN_MODE_DIRECT - SIGN_MODE_TEXTUAL = 2; - - // SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses - // Amino JSON and will be removed in the future - SIGN_MODE_LEGACY_AMINO_JSON = 127; - - // SIGN_MODE_EIP_191 specifies the sign mode for EIP 191 signing on the Cosmos - // SDK. Ref: https://eips.ethereum.org/EIPS/eip-191 - // - // Currently, SIGN_MODE_EIP_191 is registered as a SignMode enum variant, - // but is not implemented on the SDK by default. To enable EIP-191, you need - // to pass a custom `TxConfig` that has an implementation of - // `SignModeHandler` for EIP-191. The SDK may decide to fully support - // EIP-191 in the future. - // - // Since: cosmos-sdk 0.45.2 - SIGN_MODE_EIP_191 = 191; -} - -// SignatureDescriptors wraps multiple SignatureDescriptor's. -message SignatureDescriptors { - // signatures are the signature descriptors - repeated SignatureDescriptor signatures = 1; -} - -// SignatureDescriptor is a convenience type which represents the full data for -// a signature including the public key of the signer, signing modes and the -// signature itself. It is primarily used for coordinating signatures between -// clients. -message SignatureDescriptor { - // public_key is the public key of the signer - google.protobuf.Any public_key = 1; - - Data data = 2; - - // sequence is the sequence of the account, which describes the - // number of committed transactions signed by a given address. It is used to prevent - // replay attacks. - uint64 sequence = 3; - - // Data represents signature data - message Data { - // sum is the oneof that specifies whether this represents single or multi-signature data - oneof sum { - // single represents a single signer - Single single = 1; - - // multi represents a multisig signer - Multi multi = 2; - } - - // Single is the signature data for a single signer - message Single { - // mode is the signing mode of the single signer - SignMode mode = 1; - - // signature is the raw signature bytes - bytes signature = 2; - } - - // Multi is the signature data for a multisig public key - message Multi { - // bitarray specifies which keys within the multisig are signing - cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; - - // signatures is the signatures of the multi-signature - repeated Data signatures = 2; - } - } -} diff --git a/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto b/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto deleted file mode 100644 index d9f828f76..000000000 --- a/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto +++ /dev/null @@ -1,165 +0,0 @@ -syntax = "proto3"; -package cosmos.tx.v1beta1; - -import "google/api/annotations.proto"; -import "cosmos/base/abci/v1beta1/abci.proto"; -import "cosmos/tx/v1beta1/tx.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "tendermint/types/block.proto"; -import "tendermint/types/types.proto"; - -option (gogoproto.goproto_registration) = true; -option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; - -// Service defines a gRPC service for interacting with transactions. -service Service { - // Simulate simulates executing a transaction for estimating gas usage. - rpc Simulate(SimulateRequest) returns (SimulateResponse) { - option (google.api.http) = { - post: "/cosmos/tx/v1beta1/simulate" - body: "*" - }; - } - // GetTx fetches a tx by hash. - rpc GetTx(GetTxRequest) returns (GetTxResponse) { - option (google.api.http).get = "/cosmos/tx/v1beta1/txs/{hash}"; - } - // BroadcastTx broadcast transaction. - rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) { - option (google.api.http) = { - post: "/cosmos/tx/v1beta1/txs" - body: "*" - }; - } - // GetTxsEvent fetches txs by event. - rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) { - option (google.api.http).get = "/cosmos/tx/v1beta1/txs"; - } - // GetBlockWithTxs fetches a block with decoded txs. - // - // Since: cosmos-sdk 0.45.2 - rpc GetBlockWithTxs(GetBlockWithTxsRequest) returns (GetBlockWithTxsResponse) { - option (google.api.http).get = "/cosmos/tx/v1beta1/txs/block/{height}"; - } -} - -// GetTxsEventRequest is the request type for the Service.TxsByEvents -// RPC method. -message GetTxsEventRequest { - // events is the list of transaction event type. - repeated string events = 1; - // pagination defines a pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; - OrderBy order_by = 3; -} - -// OrderBy defines the sorting order -enum OrderBy { - // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. - ORDER_BY_UNSPECIFIED = 0; - // ORDER_BY_ASC defines ascending order - ORDER_BY_ASC = 1; - // ORDER_BY_DESC defines descending order - ORDER_BY_DESC = 2; -} - -// GetTxsEventResponse is the response type for the Service.TxsByEvents -// RPC method. -message GetTxsEventResponse { - // txs is the list of queried transactions. - repeated cosmos.tx.v1beta1.Tx txs = 1; - // tx_responses is the list of queried TxResponses. - repeated cosmos.base.abci.v1beta1.TxResponse tx_responses = 2; - // pagination defines a pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 3; -} - -// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest -// RPC method. -message BroadcastTxRequest { - // tx_bytes is the raw transaction. - bytes tx_bytes = 1; - BroadcastMode mode = 2; -} - -// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. -enum BroadcastMode { - // zero-value for mode ordering - BROADCAST_MODE_UNSPECIFIED = 0; - // BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for - // the tx to be committed in a block. - BROADCAST_MODE_BLOCK = 1; - // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for - // a CheckTx execution response only. - BROADCAST_MODE_SYNC = 2; - // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns - // immediately. - BROADCAST_MODE_ASYNC = 3; -} - -// BroadcastTxResponse is the response type for the -// Service.BroadcastTx method. -message BroadcastTxResponse { - // tx_response is the queried TxResponses. - cosmos.base.abci.v1beta1.TxResponse tx_response = 1; -} - -// SimulateRequest is the request type for the Service.Simulate -// RPC method. -message SimulateRequest { - // tx is the transaction to simulate. - // Deprecated. Send raw tx bytes instead. - cosmos.tx.v1beta1.Tx tx = 1 [deprecated = true]; - // tx_bytes is the raw transaction. - // - // Since: cosmos-sdk 0.43 - bytes tx_bytes = 2; -} - -// SimulateResponse is the response type for the -// Service.SimulateRPC method. -message SimulateResponse { - // gas_info is the information about gas used in the simulation. - cosmos.base.abci.v1beta1.GasInfo gas_info = 1; - // result is the result of the simulation. - cosmos.base.abci.v1beta1.Result result = 2; -} - -// GetTxRequest is the request type for the Service.GetTx -// RPC method. -message GetTxRequest { - // hash is the tx hash to query, encoded as a hex string. - string hash = 1; -} - -// GetTxResponse is the response type for the Service.GetTx method. -message GetTxResponse { - // tx is the queried transaction. - cosmos.tx.v1beta1.Tx tx = 1; - // tx_response is the queried TxResponses. - cosmos.base.abci.v1beta1.TxResponse tx_response = 2; -} - -// GetBlockWithTxsRequest is the request type for the Service.GetBlockWithTxs -// RPC method. -// -// Since: cosmos-sdk 0.45.2 -message GetBlockWithTxsRequest { - // height is the height of the block to query. - int64 height = 1; - // pagination defines a pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method. -// -// Since: cosmos-sdk 0.45.2 -message GetBlockWithTxsResponse { - // txs are the transactions in the block. - repeated cosmos.tx.v1beta1.Tx txs = 1; - .tendermint.types.BlockID block_id = 2; - .tendermint.types.Block block = 3; - // pagination defines a pagination for the response. - cosmos.base.query.v1beta1.PageResponse pagination = 4; -} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto deleted file mode 100644 index 6d5caf12c..000000000 --- a/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto +++ /dev/null @@ -1,183 +0,0 @@ -syntax = "proto3"; -package cosmos.tx.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/crypto/multisig/v1beta1/multisig.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/tx/signing/v1beta1/signing.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; - -// Tx is the standard type used for broadcasting transactions. -message Tx { - // body is the processable content of the transaction - TxBody body = 1; - - // auth_info is the authorization related content of the transaction, - // specifically signers, signer modes and fee - AuthInfo auth_info = 2; - - // signatures is a list of signatures that matches the length and order of - // AuthInfo's signer_infos to allow connecting signature meta information like - // public key and signing mode by position. - repeated bytes signatures = 3; -} - -// TxRaw is a variant of Tx that pins the signer's exact binary representation -// of body and auth_info. This is used for signing, broadcasting and -// verification. The binary `serialize(tx: TxRaw)` is stored in Tendermint and -// the hash `sha256(serialize(tx: TxRaw))` becomes the "txhash", commonly used -// as the transaction ID. -message TxRaw { - // body_bytes is a protobuf serialization of a TxBody that matches the - // representation in SignDoc. - bytes body_bytes = 1; - - // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the - // representation in SignDoc. - bytes auth_info_bytes = 2; - - // signatures is a list of signatures that matches the length and order of - // AuthInfo's signer_infos to allow connecting signature meta information like - // public key and signing mode by position. - repeated bytes signatures = 3; -} - -// SignDoc is the type used for generating sign bytes for SIGN_MODE_DIRECT. -message SignDoc { - // body_bytes is protobuf serialization of a TxBody that matches the - // representation in TxRaw. - bytes body_bytes = 1; - - // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the - // representation in TxRaw. - bytes auth_info_bytes = 2; - - // chain_id is the unique identifier of the chain this transaction targets. - // It prevents signed transactions from being used on another chain by an - // attacker - string chain_id = 3; - - // account_number is the account number of the account in state - uint64 account_number = 4; -} - -// TxBody is the body of a transaction that all signers sign over. -message TxBody { - // messages is a list of messages to be executed. The required signers of - // those messages define the number and order of elements in AuthInfo's - // signer_infos and Tx's signatures. Each required signer address is added to - // the list only the first time it occurs. - // By convention, the first required signer (usually from the first message) - // is referred to as the primary signer and pays the fee for the whole - // transaction. - repeated google.protobuf.Any messages = 1; - - // memo is any arbitrary note/comment to be added to the transaction. - // WARNING: in clients, any publicly exposed text should not be called memo, - // but should be called `note` instead (see https://github.com/cosmos/cosmos-sdk/issues/9122). - string memo = 2; - - // timeout is the block height after which this transaction will not - // be processed by the chain - uint64 timeout_height = 3; - - // extension_options are arbitrary options that can be added by chains - // when the default options are not sufficient. If any of these are present - // and can't be handled, the transaction will be rejected - repeated google.protobuf.Any extension_options = 1023; - - // extension_options are arbitrary options that can be added by chains - // when the default options are not sufficient. If any of these are present - // and can't be handled, they will be ignored - repeated google.protobuf.Any non_critical_extension_options = 2047; -} - -// AuthInfo describes the fee and signer modes that are used to sign a -// transaction. -message AuthInfo { - // signer_infos defines the signing modes for the required signers. The number - // and order of elements must match the required signers from TxBody's - // messages. The first element is the primary signer and the one which pays - // the fee. - repeated SignerInfo signer_infos = 1; - - // Fee is the fee and gas limit for the transaction. The first signer is the - // primary signer and the one which pays the fee. The fee can be calculated - // based on the cost of evaluating the body and doing signature verification - // of the signers. This can be estimated via simulation. - Fee fee = 2; -} - -// SignerInfo describes the public key and signing mode of a single top-level -// signer. -message SignerInfo { - // public_key is the public key of the signer. It is optional for accounts - // that already exist in state. If unset, the verifier can use the required \ - // signer address for this position and lookup the public key. - google.protobuf.Any public_key = 1; - - // mode_info describes the signing mode of the signer and is a nested - // structure to support nested multisig pubkey's - ModeInfo mode_info = 2; - - // sequence is the sequence of the account, which describes the - // number of committed transactions signed by a given address. It is used to - // prevent replay attacks. - uint64 sequence = 3; -} - -// ModeInfo describes the signing mode of a single or nested multisig signer. -message ModeInfo { - // sum is the oneof that specifies whether this represents a single or nested - // multisig signer - oneof sum { - // single represents a single signer - Single single = 1; - - // multi represents a nested multisig signer - Multi multi = 2; - } - - // Single is the mode info for a single signer. It is structured as a message - // to allow for additional fields such as locale for SIGN_MODE_TEXTUAL in the - // future - message Single { - // mode is the signing mode of the single signer - cosmos.tx.signing.v1beta1.SignMode mode = 1; - } - - // Multi is the mode info for a multisig public key - message Multi { - // bitarray specifies which keys within the multisig are signing - cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; - - // mode_infos is the corresponding modes of the signers of the multisig - // which could include nested multisig public keys - repeated ModeInfo mode_infos = 2; - } -} - -// Fee includes the amount of coins paid in fees and the maximum -// gas to be used by the transaction. The ratio yields an effective "gasprice", -// which must be above some miminum to be accepted into the mempool. -message Fee { - // amount is the amount of coins to be paid as a fee - repeated cosmos.base.v1beta1.Coin amount = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - // gas_limit is the maximum gas that can be used in transaction processing - // before an out of gas error occurs - uint64 gas_limit = 2; - - // if unset, the first signer is responsible for paying the fees. If set, the specified account must pay the fees. - // the payer must be a tx signer (and thus have signed this field in AuthInfo). - // setting this field does *not* change the ordering of required signers for the transaction. - string payer = 3; - - // if set, the fee payer (either the first signer or the value of the payer field) requests that a fee grant be used - // to pay fees instead of the fee payer's own balance. If an appropriate fee grant does not exist or the chain does - // not support fee grants, this will fail - string granter = 4; -} diff --git a/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto b/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto deleted file mode 100644 index dd14ba640..000000000 --- a/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto +++ /dev/null @@ -1,104 +0,0 @@ -syntax = "proto3"; -package cosmos.upgrade.v1beta1; - -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "cosmos/upgrade/v1beta1/upgrade.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; - -// Query defines the gRPC upgrade querier service. -service Query { - // CurrentPlan queries the current upgrade plan. - rpc CurrentPlan(QueryCurrentPlanRequest) returns (QueryCurrentPlanResponse) { - option (google.api.http).get = "/cosmos/upgrade/v1beta1/current_plan"; - } - - // AppliedPlan queries a previously applied upgrade plan by its name. - rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) { - option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}"; - } - - // UpgradedConsensusState queries the consensus state that will serve - // as a trusted kernel for the next version of this chain. It will only be - // stored at the last height of this chain. - // UpgradedConsensusState RPC not supported with legacy querier - // This rpc is deprecated now that IBC has its own replacement - // (https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) - rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { - option deprecated = true; - option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}"; - } - - // ModuleVersions queries the list of module versions from state. - // - // Since: cosmos-sdk 0.43 - rpc ModuleVersions(QueryModuleVersionsRequest) returns (QueryModuleVersionsResponse) { - option (google.api.http).get = "/cosmos/upgrade/v1beta1/module_versions"; - } -} - -// QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC -// method. -message QueryCurrentPlanRequest {} - -// QueryCurrentPlanResponse is the response type for the Query/CurrentPlan RPC -// method. -message QueryCurrentPlanResponse { - // plan is the current upgrade plan. - Plan plan = 1; -} - -// QueryCurrentPlanRequest is the request type for the Query/AppliedPlan RPC -// method. -message QueryAppliedPlanRequest { - // name is the name of the applied plan to query for. - string name = 1; -} - -// QueryAppliedPlanResponse is the response type for the Query/AppliedPlan RPC -// method. -message QueryAppliedPlanResponse { - // height is the block height at which the plan was applied. - int64 height = 1; -} - -// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState -// RPC method. -message QueryUpgradedConsensusStateRequest { - option deprecated = true; - - // last height of the current chain must be sent in request - // as this is the height under which next consensus state is stored - int64 last_height = 1; -} - -// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState -// RPC method. -message QueryUpgradedConsensusStateResponse { - option deprecated = true; - reserved 1; - - // Since: cosmos-sdk 0.43 - bytes upgraded_consensus_state = 2; -} - -// QueryModuleVersionsRequest is the request type for the Query/ModuleVersions -// RPC method. -// -// Since: cosmos-sdk 0.43 -message QueryModuleVersionsRequest { - // module_name is a field to query a specific module - // consensus version from state. Leaving this empty will - // fetch the full list of module versions from state - string module_name = 1; -} - -// QueryModuleVersionsResponse is the response type for the Query/ModuleVersions -// RPC method. -// -// Since: cosmos-sdk 0.43 -message QueryModuleVersionsResponse { - // module_versions is a list of module names with their consensus versions. - repeated ModuleVersion module_versions = 1; -} diff --git a/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto b/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto deleted file mode 100644 index e888b393d..000000000 --- a/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto +++ /dev/null @@ -1,78 +0,0 @@ -syntax = "proto3"; -package cosmos.upgrade.v1beta1; - -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; -option (gogoproto.goproto_getters_all) = false; - -// Plan specifies information about a planned upgrade and when it should occur. -message Plan { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - // Sets the name for the upgrade. This name will be used by the upgraded - // version of the software to apply any special "on-upgrade" commands during - // the first BeginBlock method after the upgrade is applied. It is also used - // to detect whether a software version can handle a given upgrade. If no - // upgrade handler with this name has been set in the software, it will be - // assumed that the software is out-of-date when the upgrade Time or Height is - // reached and the software will exit. - string name = 1; - - // Deprecated: Time based upgrades have been deprecated. Time based upgrade logic - // has been removed from the SDK. - // If this field is not empty, an error will be thrown. - google.protobuf.Timestamp time = 2 [deprecated = true, (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; - - // The height at which the upgrade must be performed. - // Only used if Time is not set. - int64 height = 3; - - // Any application specific upgrade info to be included on-chain - // such as a git commit that validators could automatically upgrade to - string info = 4; - - // Deprecated: UpgradedClientState field has been deprecated. IBC upgrade logic has been - // moved to the IBC module in the sub module 02-client. - // If this field is not empty, an error will be thrown. - google.protobuf.Any upgraded_client_state = 5 - [deprecated = true, (gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; -} - -// SoftwareUpgradeProposal is a gov Content type for initiating a software -// upgrade. -message SoftwareUpgradeProposal { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - string title = 1; - string description = 2; - Plan plan = 3 [(gogoproto.nullable) = false]; -} - -// CancelSoftwareUpgradeProposal is a gov Content type for cancelling a software -// upgrade. -message CancelSoftwareUpgradeProposal { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = false; - - string title = 1; - string description = 2; -} - -// ModuleVersion specifies a module and its consensus version. -// -// Since: cosmos-sdk 0.43 -message ModuleVersion { - option (gogoproto.equal) = true; - option (gogoproto.goproto_stringer) = true; - - // name of the app module - string name = 1; - - // consensus version of the app module - uint64 version = 2; -} diff --git a/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto deleted file mode 100644 index c49be802a..000000000 --- a/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto3"; -package cosmos.vesting.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; - -// Msg defines the bank Msg service. -service Msg { - // CreateVestingAccount defines a method that enables creating a vesting - // account. - rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse); -} - -// MsgCreateVestingAccount defines a message that enables creating a vesting -// account. -message MsgCreateVestingAccount { - option (gogoproto.equal) = true; - - string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; - string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; - repeated cosmos.base.v1beta1.Coin amount = 3 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; - - int64 end_time = 4 [(gogoproto.moretags) = "yaml:\"end_time\""]; - bool delayed = 5; -} - -// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. -message MsgCreateVestingAccountResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto b/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto deleted file mode 100644 index e9f661f93..000000000 --- a/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto +++ /dev/null @@ -1,85 +0,0 @@ -syntax = "proto3"; -package cosmos.vesting.v1beta1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/auth/v1beta1/auth.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; - -// BaseVestingAccount implements the VestingAccount interface. It contains all -// the necessary fields needed for any vesting account implementation. -message BaseVestingAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; - repeated cosmos.base.v1beta1.Coin original_vesting = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"original_vesting\"" - ]; - repeated cosmos.base.v1beta1.Coin delegated_free = 3 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"delegated_free\"" - ]; - repeated cosmos.base.v1beta1.Coin delegated_vesting = 4 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"delegated_vesting\"" - ]; - int64 end_time = 5 [(gogoproto.moretags) = "yaml:\"end_time\""]; -} - -// ContinuousVestingAccount implements the VestingAccount interface. It -// continuously vests by unlocking coins linearly with respect to time. -message ContinuousVestingAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; - int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; -} - -// DelayedVestingAccount implements the VestingAccount interface. It vests all -// coins after a specific time, but non prior. In other words, it keeps them -// locked until a specified time. -message DelayedVestingAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; -} - -// Period defines a length of time and amount of coins that will vest. -message Period { - option (gogoproto.goproto_stringer) = false; - - int64 length = 1; - repeated cosmos.base.v1beta1.Coin amount = 2 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; -} - -// PeriodicVestingAccount implements the VestingAccount interface. It -// periodically vests by unlocking coins during each specified period. -message PeriodicVestingAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; - int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; - repeated Period vesting_periods = 3 [(gogoproto.moretags) = "yaml:\"vesting_periods\"", (gogoproto.nullable) = false]; -} - -// PermanentLockedAccount implements the VestingAccount interface. It does -// not ever release coins, locking them indefinitely. Coins in this account can -// still be used for delegating and for governance votes even while locked. -// -// Since: cosmos-sdk 0.43 -message PermanentLockedAccount { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; -} diff --git a/ampd/proto/third_party/cosmos_proto/cosmos.proto b/ampd/proto/third_party/cosmos_proto/cosmos.proto deleted file mode 100644 index 167b17075..000000000 --- a/ampd/proto/third_party/cosmos_proto/cosmos.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; -package cosmos_proto; - -import "google/protobuf/descriptor.proto"; - -option go_package = "github.com/regen-network/cosmos-proto"; - -extend google.protobuf.MessageOptions { - string interface_type = 93001; - - string implements_interface = 93002; -} - -extend google.protobuf.FieldOptions { - string accepts_interface = 93001; -} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto deleted file mode 100644 index 97a82275d..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto +++ /dev/null @@ -1,118 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -option (gogoproto.goproto_getters_all) = false; - -// ContractExecutionAuthorization defines authorization for wasm execute. -// Since: wasmd 0.30 -message ContractExecutionAuthorization { - option (cosmos_proto.implements_interface) = - "cosmos.authz.v1beta1.Authorization"; - - // Grants for contract executions - repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; -} - -// ContractMigrationAuthorization defines authorization for wasm contract -// migration. Since: wasmd 0.30 -message ContractMigrationAuthorization { - option (cosmos_proto.implements_interface) = - "cosmos.authz.v1beta1.Authorization"; - - // Grants for contract migrations - repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; -} - -// ContractGrant a granted permission for a single contract -// Since: wasmd 0.30 -message ContractGrant { - // Contract is the bech32 address of the smart contract - string contract = 1; - - // Limit defines execution limits that are enforced and updated when the grant - // is applied. When the limit lapsed the grant is removed. - google.protobuf.Any limit = 2 [ (cosmos_proto.accepts_interface) = - "cosmwasm.wasm.v1.ContractAuthzLimitX" ]; - - // Filter define more fine-grained control on the message payload passed - // to the contract in the operation. When no filter applies on execution, the - // operation is prohibited. - google.protobuf.Any filter = 3 - [ (cosmos_proto.accepts_interface) = - "cosmwasm.wasm.v1.ContractAuthzFilterX" ]; -} - -// MaxCallsLimit limited number of calls to the contract. No funds transferable. -// Since: wasmd 0.30 -message MaxCallsLimit { - option (cosmos_proto.implements_interface) = - "cosmwasm.wasm.v1.ContractAuthzLimitX"; - - // Remaining number that is decremented on each execution - uint64 remaining = 1; -} - -// MaxFundsLimit defines the maximal amounts that can be sent to the contract. -// Since: wasmd 0.30 -message MaxFundsLimit { - option (cosmos_proto.implements_interface) = - "cosmwasm.wasm.v1.ContractAuthzLimitX"; - - // Amounts is the maximal amount of tokens transferable to the contract. - repeated cosmos.base.v1beta1.Coin amounts = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// CombinedLimit defines the maximal amounts that can be sent to a contract and -// the maximal number of calls executable. Both need to remain >0 to be valid. -// Since: wasmd 0.30 -message CombinedLimit { - option (cosmos_proto.implements_interface) = - "cosmwasm.wasm.v1.ContractAuthzLimitX"; - - // Remaining number that is decremented on each execution - uint64 calls_remaining = 1; - // Amounts is the maximal amount of tokens transferable to the contract. - repeated cosmos.base.v1beta1.Coin amounts = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// AllowAllMessagesFilter is a wildcard to allow any type of contract payload -// message. -// Since: wasmd 0.30 -message AllowAllMessagesFilter { - option (cosmos_proto.implements_interface) = - "cosmwasm.wasm.v1.ContractAuthzFilterX"; -} - -// AcceptedMessageKeysFilter accept only the specific contract message keys in -// the json object to be executed. -// Since: wasmd 0.30 -message AcceptedMessageKeysFilter { - option (cosmos_proto.implements_interface) = - "cosmwasm.wasm.v1.ContractAuthzFilterX"; - - // Messages is the list of unique keys - repeated string keys = 1; -} - -// AcceptedMessagesFilter accept only the specific raw contract messages to be -// executed. -// Since: wasmd 0.30 -message AcceptedMessagesFilter { - option (cosmos_proto.implements_interface) = - "cosmwasm.wasm.v1.ContractAuthzFilterX"; - - // Messages is the list of raw contract messages - repeated bytes messages = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; -} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto deleted file mode 100644 index 4e728ff4b..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto +++ /dev/null @@ -1,46 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "gogoproto/gogo.proto"; -import "cosmwasm/wasm/v1/types.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; - -// GenesisState - genesis state of x/wasm -message GenesisState { - Params params = 1 [ (gogoproto.nullable) = false ]; - repeated Code codes = 2 - [ (gogoproto.nullable) = false, (gogoproto.jsontag) = "codes,omitempty" ]; - repeated Contract contracts = 3 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "contracts,omitempty" - ]; - repeated Sequence sequences = 4 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "sequences,omitempty" - ]; -} - -// Code struct encompasses CodeInfo and CodeBytes -message Code { - uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; - CodeInfo code_info = 2 [ (gogoproto.nullable) = false ]; - bytes code_bytes = 3; - // Pinned to wasmvm cache - bool pinned = 4; -} - -// Contract struct encompasses ContractAddress, ContractInfo, and ContractState -message Contract { - string contract_address = 1; - ContractInfo contract_info = 2 [ (gogoproto.nullable) = false ]; - repeated Model contract_state = 3 [ (gogoproto.nullable) = false ]; - repeated ContractCodeHistoryEntry contract_code_history = 4 - [ (gogoproto.nullable) = false ]; -} - -// Sequence key and value of an id generation counter -message Sequence { - bytes id_key = 1 [ (gogoproto.customname) = "IDKey" ]; - uint64 value = 2; -} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto deleted file mode 100644 index feaad2936..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto +++ /dev/null @@ -1,37 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -option (gogoproto.goproto_getters_all) = false; - -// MsgIBCSend -message MsgIBCSend { - // the channel by which the packet will be sent - string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; - - // Timeout height relative to the current block height. - // The timeout is disabled when set to 0. - uint64 timeout_height = 4 - [ (gogoproto.moretags) = "yaml:\"timeout_height\"" ]; - // Timeout timestamp (in nanoseconds) relative to the current block timestamp. - // The timeout is disabled when set to 0. - uint64 timeout_timestamp = 5 - [ (gogoproto.moretags) = "yaml:\"timeout_timestamp\"" ]; - - // Data is the payload to transfer. We must not make assumption what format or - // content is in here. - bytes data = 6; -} - -// MsgIBCSendResponse -message MsgIBCSendResponse { - // Sequence number of the IBC packet sent - uint64 sequence = 1; -} - -// MsgIBCCloseChannel port and channel need to be owned by the contract -message MsgIBCCloseChannel { - string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; -} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto deleted file mode 100644 index b1c484bc9..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto +++ /dev/null @@ -1,272 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "gogoproto/gogo.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmwasm/wasm/v1/types.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -option (gogoproto.goproto_stringer_all) = false; -option (gogoproto.goproto_getters_all) = false; -option (gogoproto.equal_all) = true; - -// StoreCodeProposal gov proposal content type to submit WASM code to the system -message StoreCodeProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // RunAs is the address that is passed to the contract's environment as sender - string run_as = 3; - // WASMByteCode can be raw or gzip compressed - bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; - // Used in v1beta1 - reserved 5, 6; - // InstantiatePermission to apply on contract creation, optional - AccessConfig instantiate_permission = 7; - // UnpinCode code on upload, optional - bool unpin_code = 8; - // Source is the URL where the code is hosted - string source = 9; - // Builder is the docker image used to build the code deterministically, used - // for smart contract verification - string builder = 10; - // CodeHash is the SHA256 sum of the code outputted by builder, used for smart - // contract verification - bytes code_hash = 11; -} - -// InstantiateContractProposal gov proposal content type to instantiate a -// contract. -message InstantiateContractProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // RunAs is the address that is passed to the contract's environment as sender - string run_as = 3; - // Admin is an optional address that can execute migrations - string admin = 4; - // CodeID is the reference to the stored WASM code - uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; - // Label is optional metadata to be stored with a constract instance. - string label = 6; - // Msg json encoded message to be passed to the contract on instantiation - bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on instantiation - repeated cosmos.base.v1beta1.Coin funds = 8 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// InstantiateContract2Proposal gov proposal content type to instantiate -// contract 2 -message InstantiateContract2Proposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // RunAs is the address that is passed to the contract's enviroment as sender - string run_as = 3; - // Admin is an optional address that can execute migrations - string admin = 4; - // CodeID is the reference to the stored WASM code - uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; - // Label is optional metadata to be stored with a constract instance. - string label = 6; - // Msg json encode message to be passed to the contract on instantiation - bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on instantiation - repeated cosmos.base.v1beta1.Coin funds = 8 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; - // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. - bytes salt = 9; - // FixMsg include the msg value into the hash for the predictable address. - // Default is false - bool fix_msg = 10; -} - -// MigrateContractProposal gov proposal content type to migrate a contract. -message MigrateContractProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // Note: skipping 3 as this was previously used for unneeded run_as - - // Contract is the address of the smart contract - string contract = 4; - // CodeID references the new WASM code - uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; - // Msg json encoded message to be passed to the contract on migration - bytes msg = 6 [ (gogoproto.casttype) = "RawContractMessage" ]; -} - -// SudoContractProposal gov proposal content type to call sudo on a contract. -message SudoContractProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // Contract is the address of the smart contract - string contract = 3; - // Msg json encoded message to be passed to the contract as sudo - bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; -} - -// ExecuteContractProposal gov proposal content type to call execute on a -// contract. -message ExecuteContractProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // RunAs is the address that is passed to the contract's environment as sender - string run_as = 3; - // Contract is the address of the smart contract - string contract = 4; - // Msg json encoded message to be passed to the contract as execute - bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on instantiation - repeated cosmos.base.v1beta1.Coin funds = 6 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// UpdateAdminProposal gov proposal content type to set an admin for a contract. -message UpdateAdminProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // NewAdmin address to be set - string new_admin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; - // Contract is the address of the smart contract - string contract = 4; -} - -// ClearAdminProposal gov proposal content type to clear the admin of a -// contract. -message ClearAdminProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // Contract is the address of the smart contract - string contract = 3; -} - -// PinCodesProposal gov proposal content type to pin a set of code ids in the -// wasmvm cache. -message PinCodesProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; - // Description is a human readable text - string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; - // CodeIDs references the new WASM codes - repeated uint64 code_ids = 3 [ - (gogoproto.customname) = "CodeIDs", - (gogoproto.moretags) = "yaml:\"code_ids\"" - ]; -} - -// UnpinCodesProposal gov proposal content type to unpin a set of code ids in -// the wasmvm cache. -message UnpinCodesProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; - // Description is a human readable text - string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; - // CodeIDs references the WASM codes - repeated uint64 code_ids = 3 [ - (gogoproto.customname) = "CodeIDs", - (gogoproto.moretags) = "yaml:\"code_ids\"" - ]; -} - -// AccessConfigUpdate contains the code id and the access config to be -// applied. -message AccessConfigUpdate { - // CodeID is the reference to the stored WASM code to be updated - uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; - // InstantiatePermission to apply to the set of code ids - AccessConfig instantiate_permission = 2 [ (gogoproto.nullable) = false ]; -} - -// UpdateInstantiateConfigProposal gov proposal content type to update -// instantiate config to a set of code ids. -message UpdateInstantiateConfigProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; - // Description is a human readable text - string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; - // AccessConfigUpdate contains the list of code ids and the access config - // to be applied. - repeated AccessConfigUpdate access_config_updates = 3 - [ (gogoproto.nullable) = false ]; -} - -// StoreAndInstantiateContractProposal gov proposal content type to store -// and instantiate the contract. -message StoreAndInstantiateContractProposal { - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - // Title is a short summary - string title = 1; - // Description is a human readable text - string description = 2; - // RunAs is the address that is passed to the contract's environment as sender - string run_as = 3; - // WASMByteCode can be raw or gzip compressed - bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; - // InstantiatePermission to apply on contract creation, optional - AccessConfig instantiate_permission = 5; - // UnpinCode code on upload, optional - bool unpin_code = 6; - // Admin is an optional address that can execute migrations - string admin = 7; - // Label is optional metadata to be stored with a constract instance. - string label = 8; - // Msg json encoded message to be passed to the contract on instantiation - bytes msg = 9 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on instantiation - repeated cosmos.base.v1beta1.Coin funds = 10 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; - // Source is the URL where the code is hosted - string source = 11; - // Builder is the docker image used to build the code deterministically, used - // for smart contract verification - string builder = 12; - // CodeHash is the SHA256 sum of the code outputted by builder, used for smart - // contract verification - bytes code_hash = 13; -} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto deleted file mode 100644 index ffe48d242..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto +++ /dev/null @@ -1,263 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "gogoproto/gogo.proto"; -import "cosmwasm/wasm/v1/types.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -option (gogoproto.goproto_getters_all) = false; -option (gogoproto.equal_all) = false; - -// Query provides defines the gRPC querier service -service Query { - // ContractInfo gets the contract meta data - rpc ContractInfo(QueryContractInfoRequest) - returns (QueryContractInfoResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/contract/{address}"; - } - // ContractHistory gets the contract code history - rpc ContractHistory(QueryContractHistoryRequest) - returns (QueryContractHistoryResponse) { - option (google.api.http).get = - "/cosmwasm/wasm/v1/contract/{address}/history"; - } - // ContractsByCode lists all smart contracts for a code id - rpc ContractsByCode(QueryContractsByCodeRequest) - returns (QueryContractsByCodeResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}/contracts"; - } - // AllContractState gets all raw store data for a single contract - rpc AllContractState(QueryAllContractStateRequest) - returns (QueryAllContractStateResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/contract/{address}/state"; - } - // RawContractState gets single key from the raw store data of a contract - rpc RawContractState(QueryRawContractStateRequest) - returns (QueryRawContractStateResponse) { - option (google.api.http).get = - "/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}"; - } - // SmartContractState get smart query result from the contract - rpc SmartContractState(QuerySmartContractStateRequest) - returns (QuerySmartContractStateResponse) { - option (google.api.http).get = - "/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}"; - } - // Code gets the binary code and metadata for a singe wasm code - rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}"; - } - // Codes gets the metadata for all stored wasm codes - rpc Codes(QueryCodesRequest) returns (QueryCodesResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/code"; - } - - // PinnedCodes gets the pinned code ids - rpc PinnedCodes(QueryPinnedCodesRequest) returns (QueryPinnedCodesResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/codes/pinned"; - } - - // Params gets the module params - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmwasm/wasm/v1/codes/params"; - } - - // ContractsByCreator gets the contracts by creator - rpc ContractsByCreator(QueryContractsByCreatorRequest) - returns (QueryContractsByCreatorResponse) { - option (google.api.http).get = - "/cosmwasm/wasm/v1/contracts/creator/{creator_address}"; - } -} - -// QueryContractInfoRequest is the request type for the Query/ContractInfo RPC -// method -message QueryContractInfoRequest { - // address is the address of the contract to query - string address = 1; -} -// QueryContractInfoResponse is the response type for the Query/ContractInfo RPC -// method -message QueryContractInfoResponse { - option (gogoproto.equal) = true; - - // address is the address of the contract - string address = 1; - ContractInfo contract_info = 2 [ - (gogoproto.embed) = true, - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "" - ]; -} - -// QueryContractHistoryRequest is the request type for the Query/ContractHistory -// RPC method -message QueryContractHistoryRequest { - // address is the address of the contract to query - string address = 1; - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryContractHistoryResponse is the response type for the -// Query/ContractHistory RPC method -message QueryContractHistoryResponse { - repeated ContractCodeHistoryEntry entries = 1 - [ (gogoproto.nullable) = false ]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryContractsByCodeRequest is the request type for the Query/ContractsByCode -// RPC method -message QueryContractsByCodeRequest { - uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryContractsByCodeResponse is the response type for the -// Query/ContractsByCode RPC method -message QueryContractsByCodeResponse { - // contracts are a set of contract addresses - repeated string contracts = 1; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryAllContractStateRequest is the request type for the -// Query/AllContractState RPC method -message QueryAllContractStateRequest { - // address is the address of the contract - string address = 1; - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryAllContractStateResponse is the response type for the -// Query/AllContractState RPC method -message QueryAllContractStateResponse { - repeated Model models = 1 [ (gogoproto.nullable) = false ]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryRawContractStateRequest is the request type for the -// Query/RawContractState RPC method -message QueryRawContractStateRequest { - // address is the address of the contract - string address = 1; - bytes query_data = 2; -} - -// QueryRawContractStateResponse is the response type for the -// Query/RawContractState RPC method -message QueryRawContractStateResponse { - // Data contains the raw store data - bytes data = 1; -} - -// QuerySmartContractStateRequest is the request type for the -// Query/SmartContractState RPC method -message QuerySmartContractStateRequest { - // address is the address of the contract - string address = 1; - // QueryData contains the query data passed to the contract - bytes query_data = 2 [ (gogoproto.casttype) = "RawContractMessage" ]; -} - -// QuerySmartContractStateResponse is the response type for the -// Query/SmartContractState RPC method -message QuerySmartContractStateResponse { - // Data contains the json data returned from the smart contract - bytes data = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; -} - -// QueryCodeRequest is the request type for the Query/Code RPC method -message QueryCodeRequest { - uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID -} - -// CodeInfoResponse contains code meta data from CodeInfo -message CodeInfoResponse { - option (gogoproto.equal) = true; - - uint64 code_id = 1 [ - (gogoproto.customname) = "CodeID", - (gogoproto.jsontag) = "id" - ]; // id for legacy support - string creator = 2; - bytes data_hash = 3 - [ (gogoproto.casttype) = - "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; - // Used in v1beta1 - reserved 4, 5; - AccessConfig instantiate_permission = 6 [ (gogoproto.nullable) = false ]; -} - -// QueryCodeResponse is the response type for the Query/Code RPC method -message QueryCodeResponse { - option (gogoproto.equal) = true; - CodeInfoResponse code_info = 1 - [ (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; - bytes data = 2 [ (gogoproto.jsontag) = "data" ]; -} - -// QueryCodesRequest is the request type for the Query/Codes RPC method -message QueryCodesRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryCodesResponse is the response type for the Query/Codes RPC method -message QueryCodesResponse { - repeated CodeInfoResponse code_infos = 1 [ (gogoproto.nullable) = false ]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryPinnedCodesRequest is the request type for the Query/PinnedCodes -// RPC method -message QueryPinnedCodesRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryPinnedCodesResponse is the response type for the -// Query/PinnedCodes RPC method -message QueryPinnedCodesResponse { - repeated uint64 code_ids = 1 - [ (gogoproto.nullable) = false, (gogoproto.customname) = "CodeIDs" ]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1 [ (gogoproto.nullable) = false ]; -} - -// QueryContractsByCreatorRequest is the request type for the -// Query/ContractsByCreator RPC method. -message QueryContractsByCreatorRequest { - // CreatorAddress is the address of contract creator - string creator_address = 1; - // Pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryContractsByCreatorResponse is the response type for the -// Query/ContractsByCreator RPC method. -message QueryContractsByCreatorResponse { - // ContractAddresses result set - repeated string contract_addresses = 1; - // Pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto deleted file mode 100644 index 741fbc494..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto +++ /dev/null @@ -1,192 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; -import "cosmwasm/wasm/v1/types.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -option (gogoproto.goproto_getters_all) = false; - -// Msg defines the wasm Msg service. -service Msg { - // StoreCode to submit Wasm code to the system - rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); - // InstantiateContract creates a new smart contract instance for the given - // code id. - rpc InstantiateContract(MsgInstantiateContract) - returns (MsgInstantiateContractResponse); - // InstantiateContract2 creates a new smart contract instance for the given - // code id with a predictable address - rpc InstantiateContract2(MsgInstantiateContract2) - returns (MsgInstantiateContract2Response); - // Execute submits the given message data to a smart contract - rpc ExecuteContract(MsgExecuteContract) returns (MsgExecuteContractResponse); - // Migrate runs a code upgrade/ downgrade for a smart contract - rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); - // UpdateAdmin sets a new admin for a smart contract - rpc UpdateAdmin(MsgUpdateAdmin) returns (MsgUpdateAdminResponse); - // ClearAdmin removes any admin stored for a smart contract - rpc ClearAdmin(MsgClearAdmin) returns (MsgClearAdminResponse); - // UpdateInstantiateConfig updates instantiate config for a smart contract - rpc UpdateInstantiateConfig(MsgUpdateInstantiateConfig) - returns (MsgUpdateInstantiateConfigResponse); -} - -// MsgStoreCode submit Wasm code to the system -message MsgStoreCode { - // Sender is the actor that signed the messages - string sender = 1; - // WASMByteCode can be raw or gzip compressed - bytes wasm_byte_code = 2 [ (gogoproto.customname) = "WASMByteCode" ]; - // Used in v1beta1 - reserved 3, 4; - // InstantiatePermission access control to apply on contract creation, - // optional - AccessConfig instantiate_permission = 5; -} -// MsgStoreCodeResponse returns store result data. -message MsgStoreCodeResponse { - // CodeID is the reference to the stored WASM code - uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; - // Checksum is the sha256 hash of the stored code - bytes checksum = 2; -} - -// MsgInstantiateContract create a new smart contract instance for the given -// code id. -message MsgInstantiateContract { - // Sender is the that actor that signed the messages - string sender = 1; - // Admin is an optional address that can execute migrations - string admin = 2; - // CodeID is the reference to the stored WASM code - uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; - // Label is optional metadata to be stored with a contract instance. - string label = 4; - // Msg json encoded message to be passed to the contract on instantiation - bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on instantiation - repeated cosmos.base.v1beta1.Coin funds = 6 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// MsgInstantiateContract2 create a new smart contract instance for the given -// code id with a predicable address. -message MsgInstantiateContract2 { - // Sender is the that actor that signed the messages - string sender = 1; - // Admin is an optional address that can execute migrations - string admin = 2; - // CodeID is the reference to the stored WASM code - uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; - // Label is optional metadata to be stored with a contract instance. - string label = 4; - // Msg json encoded message to be passed to the contract on instantiation - bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on instantiation - repeated cosmos.base.v1beta1.Coin funds = 6 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; - // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. - bytes salt = 7; - // FixMsg include the msg value into the hash for the predictable address. - // Default is false - bool fix_msg = 8; -} - -// MsgInstantiateContractResponse return instantiation result data -message MsgInstantiateContractResponse { - // Address is the bech32 address of the new contract instance. - string address = 1; - // Data contains bytes to returned from the contract - bytes data = 2; -} - -// MsgInstantiateContract2Response return instantiation result data -message MsgInstantiateContract2Response { - // Address is the bech32 address of the new contract instance. - string address = 1; - // Data contains bytes to returned from the contract - bytes data = 2; -} - -// MsgExecuteContract submits the given message data to a smart contract -message MsgExecuteContract { - // Sender is the that actor that signed the messages - string sender = 1; - // Contract is the address of the smart contract - string contract = 2; - // Msg json encoded message to be passed to the contract - bytes msg = 3 [ (gogoproto.casttype) = "RawContractMessage" ]; - // Funds coins that are transferred to the contract on execution - repeated cosmos.base.v1beta1.Coin funds = 5 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// MsgExecuteContractResponse returns execution result data. -message MsgExecuteContractResponse { - // Data contains bytes to returned from the contract - bytes data = 1; -} - -// MsgMigrateContract runs a code upgrade/ downgrade for a smart contract -message MsgMigrateContract { - // Sender is the that actor that signed the messages - string sender = 1; - // Contract is the address of the smart contract - string contract = 2; - // CodeID references the new WASM code - uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; - // Msg json encoded message to be passed to the contract on migration - bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; -} - -// MsgMigrateContractResponse returns contract migration result data. -message MsgMigrateContractResponse { - // Data contains same raw bytes returned as data from the wasm contract. - // (May be empty) - bytes data = 1; -} - -// MsgUpdateAdmin sets a new admin for a smart contract -message MsgUpdateAdmin { - // Sender is the that actor that signed the messages - string sender = 1; - // NewAdmin address to be set - string new_admin = 2; - // Contract is the address of the smart contract - string contract = 3; -} - -// MsgUpdateAdminResponse returns empty data -message MsgUpdateAdminResponse {} - -// MsgClearAdmin removes any admin stored for a smart contract -message MsgClearAdmin { - // Sender is the actor that signed the messages - string sender = 1; - // Contract is the address of the smart contract - string contract = 3; -} - -// MsgClearAdminResponse returns empty data -message MsgClearAdminResponse {} - -// MsgUpdateInstantiateConfig updates instantiate config for a smart contract -message MsgUpdateInstantiateConfig { - // Sender is the that actor that signed the messages - string sender = 1; - // CodeID references the stored WASM code - uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; - // NewInstantiatePermission is the new access control - AccessConfig new_instantiate_permission = 3; -} - -// MsgUpdateInstantiateConfigResponse returns empty data -message MsgUpdateInstantiateConfigResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto deleted file mode 100644 index b68179e2e..000000000 --- a/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto +++ /dev/null @@ -1,145 +0,0 @@ -syntax = "proto3"; -package cosmwasm.wasm.v1; - -import "cosmos_proto/cosmos.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; -option (gogoproto.goproto_getters_all) = false; -option (gogoproto.equal_all) = true; - -// AccessType permission types -enum AccessType { - option (gogoproto.goproto_enum_prefix) = false; - option (gogoproto.goproto_enum_stringer) = false; - // AccessTypeUnspecified placeholder for empty value - ACCESS_TYPE_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = "AccessTypeUnspecified" ]; - // AccessTypeNobody forbidden - ACCESS_TYPE_NOBODY = 1 - [ (gogoproto.enumvalue_customname) = "AccessTypeNobody" ]; - // AccessTypeOnlyAddress restricted to a single address - // Deprecated: use AccessTypeAnyOfAddresses instead - ACCESS_TYPE_ONLY_ADDRESS = 2 - [ (gogoproto.enumvalue_customname) = "AccessTypeOnlyAddress" ]; - // AccessTypeEverybody unrestricted - ACCESS_TYPE_EVERYBODY = 3 - [ (gogoproto.enumvalue_customname) = "AccessTypeEverybody" ]; - // AccessTypeAnyOfAddresses allow any of the addresses - ACCESS_TYPE_ANY_OF_ADDRESSES = 4 - [ (gogoproto.enumvalue_customname) = "AccessTypeAnyOfAddresses" ]; -} - -// AccessTypeParam -message AccessTypeParam { - option (gogoproto.goproto_stringer) = true; - AccessType value = 1 [ (gogoproto.moretags) = "yaml:\"value\"" ]; -} - -// AccessConfig access control type. -message AccessConfig { - option (gogoproto.goproto_stringer) = true; - AccessType permission = 1 [ (gogoproto.moretags) = "yaml:\"permission\"" ]; - - // Address - // Deprecated: replaced by addresses - string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; - repeated string addresses = 3 [ (gogoproto.moretags) = "yaml:\"addresses\"" ]; -} - -// Params defines the set of wasm parameters. -message Params { - option (gogoproto.goproto_stringer) = false; - AccessConfig code_upload_access = 1 [ - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"code_upload_access\"" - ]; - AccessType instantiate_default_permission = 2 - [ (gogoproto.moretags) = "yaml:\"instantiate_default_permission\"" ]; -} - -// CodeInfo is data for the uploaded contract WASM code -message CodeInfo { - // CodeHash is the unique identifier created by wasmvm - bytes code_hash = 1; - // Creator address who initially stored the code - string creator = 2; - // Used in v1beta1 - reserved 3, 4; - // InstantiateConfig access control to apply on contract creation, optional - AccessConfig instantiate_config = 5 [ (gogoproto.nullable) = false ]; -} - -// ContractInfo stores a WASM contract instance -message ContractInfo { - option (gogoproto.equal) = true; - - // CodeID is the reference to the stored Wasm code - uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; - // Creator address who initially instantiated the contract - string creator = 2; - // Admin is an optional address that can execute migrations - string admin = 3; - // Label is optional metadata to be stored with a contract instance. - string label = 4; - // Created Tx position when the contract was instantiated. - AbsoluteTxPosition created = 5; - string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; - - // Extension is an extension point to store custom metadata within the - // persistence model. - google.protobuf.Any extension = 7 - [ (cosmos_proto.accepts_interface) = - "cosmwasm.wasm.v1.ContractInfoExtension" ]; -} - -// ContractCodeHistoryOperationType actions that caused a code change -enum ContractCodeHistoryOperationType { - option (gogoproto.goproto_enum_prefix) = false; - // ContractCodeHistoryOperationTypeUnspecified placeholder for empty value - CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED = 0 - [ (gogoproto.enumvalue_customname) = - "ContractCodeHistoryOperationTypeUnspecified" ]; - // ContractCodeHistoryOperationTypeInit on chain contract instantiation - CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT = 1 - [ (gogoproto.enumvalue_customname) = - "ContractCodeHistoryOperationTypeInit" ]; - // ContractCodeHistoryOperationTypeMigrate code migration - CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE = 2 - [ (gogoproto.enumvalue_customname) = - "ContractCodeHistoryOperationTypeMigrate" ]; - // ContractCodeHistoryOperationTypeGenesis based on genesis data - CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS = 3 - [ (gogoproto.enumvalue_customname) = - "ContractCodeHistoryOperationTypeGenesis" ]; -} - -// ContractCodeHistoryEntry metadata to a contract. -message ContractCodeHistoryEntry { - ContractCodeHistoryOperationType operation = 1; - // CodeID is the reference to the stored WASM code - uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; - // Updated Tx position when the operation was executed. - AbsoluteTxPosition updated = 3; - bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; -} - -// AbsoluteTxPosition is a unique transaction position that allows for global -// ordering of transactions. -message AbsoluteTxPosition { - // BlockHeight is the block the contract was created at - uint64 block_height = 1; - // TxIndex is a monotonic counter within the block (actual transaction index, - // or gas consumed) - uint64 tx_index = 2; -} - -// Model is a struct that holds a KV pair -message Model { - // hex-encode key to read it better (this is often ascii) - bytes key = 1 [ (gogoproto.casttype) = - "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; - // base64-encode raw value - bytes value = 2; -} diff --git a/ampd/proto/third_party/gogoproto/gogo.proto b/ampd/proto/third_party/gogoproto/gogo.proto deleted file mode 100644 index 49e78f99f..000000000 --- a/ampd/proto/third_party/gogoproto/gogo.proto +++ /dev/null @@ -1,145 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto2"; -package gogoproto; - -import "google/protobuf/descriptor.proto"; - -option java_package = "com.google.protobuf"; -option java_outer_classname = "GoGoProtos"; -option go_package = "github.com/gogo/protobuf/gogoproto"; - -extend google.protobuf.EnumOptions { - optional bool goproto_enum_prefix = 62001; - optional bool goproto_enum_stringer = 62021; - optional bool enum_stringer = 62022; - optional string enum_customname = 62023; - optional bool enumdecl = 62024; -} - -extend google.protobuf.EnumValueOptions { - optional string enumvalue_customname = 66001; -} - -extend google.protobuf.FileOptions { - optional bool goproto_getters_all = 63001; - optional bool goproto_enum_prefix_all = 63002; - optional bool goproto_stringer_all = 63003; - optional bool verbose_equal_all = 63004; - optional bool face_all = 63005; - optional bool gostring_all = 63006; - optional bool populate_all = 63007; - optional bool stringer_all = 63008; - optional bool onlyone_all = 63009; - - optional bool equal_all = 63013; - optional bool description_all = 63014; - optional bool testgen_all = 63015; - optional bool benchgen_all = 63016; - optional bool marshaler_all = 63017; - optional bool unmarshaler_all = 63018; - optional bool stable_marshaler_all = 63019; - - optional bool sizer_all = 63020; - - optional bool goproto_enum_stringer_all = 63021; - optional bool enum_stringer_all = 63022; - - optional bool unsafe_marshaler_all = 63023; - optional bool unsafe_unmarshaler_all = 63024; - - optional bool goproto_extensions_map_all = 63025; - optional bool goproto_unrecognized_all = 63026; - optional bool gogoproto_import = 63027; - optional bool protosizer_all = 63028; - optional bool compare_all = 63029; - optional bool typedecl_all = 63030; - optional bool enumdecl_all = 63031; - - optional bool goproto_registration = 63032; - optional bool messagename_all = 63033; - - optional bool goproto_sizecache_all = 63034; - optional bool goproto_unkeyed_all = 63035; -} - -extend google.protobuf.MessageOptions { - optional bool goproto_getters = 64001; - optional bool goproto_stringer = 64003; - optional bool verbose_equal = 64004; - optional bool face = 64005; - optional bool gostring = 64006; - optional bool populate = 64007; - optional bool stringer = 67008; - optional bool onlyone = 64009; - - optional bool equal = 64013; - optional bool description = 64014; - optional bool testgen = 64015; - optional bool benchgen = 64016; - optional bool marshaler = 64017; - optional bool unmarshaler = 64018; - optional bool stable_marshaler = 64019; - - optional bool sizer = 64020; - - optional bool unsafe_marshaler = 64023; - optional bool unsafe_unmarshaler = 64024; - - optional bool goproto_extensions_map = 64025; - optional bool goproto_unrecognized = 64026; - - optional bool protosizer = 64028; - optional bool compare = 64029; - - optional bool typedecl = 64030; - - optional bool messagename = 64033; - - optional bool goproto_sizecache = 64034; - optional bool goproto_unkeyed = 64035; -} - -extend google.protobuf.FieldOptions { - optional bool nullable = 65001; - optional bool embed = 65002; - optional string customtype = 65003; - optional string customname = 65004; - optional string jsontag = 65005; - optional string moretags = 65006; - optional string casttype = 65007; - optional string castkey = 65008; - optional string castvalue = 65009; - - optional bool stdtime = 65010; - optional bool stdduration = 65011; - optional bool wktpointer = 65012; - - optional string castrepeated = 65013; -} diff --git a/ampd/proto/third_party/google/api/annotations.proto b/ampd/proto/third_party/google/api/annotations.proto deleted file mode 100644 index efdab3db6..000000000 --- a/ampd/proto/third_party/google/api/annotations.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/http.proto"; -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "AnnotationsProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.MethodOptions { - // See `HttpRule`. - HttpRule http = 72295728; -} diff --git a/ampd/proto/third_party/google/api/http.proto b/ampd/proto/third_party/google/api/http.proto deleted file mode 100644 index 31d867a27..000000000 --- a/ampd/proto/third_party/google/api/http.proto +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option cc_enable_arenas = true; -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "HttpProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Defines the HTTP configuration for an API service. It contains a list of -// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method -// to one or more HTTP REST API methods. -message Http { - // A list of HTTP configuration rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated HttpRule rules = 1; - - // When set to true, URL path parameters will be fully URI-decoded except in - // cases of single segment matches in reserved expansion, where "%2F" will be - // left encoded. - // - // The default behavior is to not decode RFC 6570 reserved characters in multi - // segment matches. - bool fully_decode_reserved_expansion = 2; -} - -// # gRPC Transcoding -// -// gRPC Transcoding is a feature for mapping between a gRPC method and one or -// more HTTP REST endpoints. It allows developers to build a single API service -// that supports both gRPC APIs and REST APIs. Many systems, including [Google -// APIs](https://github.com/googleapis/googleapis), -// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC -// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), -// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature -// and use it for large scale production services. -// -// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies -// how different portions of the gRPC request message are mapped to the URL -// path, URL query parameters, and HTTP request body. It also controls how the -// gRPC response message is mapped to the HTTP response body. `HttpRule` is -// typically specified as an `google.api.http` annotation on the gRPC method. -// -// Each mapping specifies a URL path template and an HTTP method. The path -// template may refer to one or more fields in the gRPC request message, as long -// as each field is a non-repeated field with a primitive (non-message) type. -// The path template controls how fields of the request message are mapped to -// the URL path. -// -// Example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/{name=messages/*}" -// }; -// } -// } -// message GetMessageRequest { -// string name = 1; // Mapped to URL path. -// } -// message Message { -// string text = 1; // The resource content. -// } -// -// This enables an HTTP REST to gRPC mapping as below: -// -// HTTP | gRPC -// -----|----- -// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` -// -// Any fields in the request message which are not bound by the path template -// automatically become HTTP query parameters if there is no HTTP request body. -// For example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get:"/v1/messages/{message_id}" -// }; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // Mapped to URL path. -// int64 revision = 2; // Mapped to URL query parameter `revision`. -// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. -// } -// -// This enables a HTTP JSON to RPC mapping as below: -// -// HTTP | gRPC -// -----|----- -// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | -// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: -// "foo"))` -// -// Note that fields which are mapped to URL query parameters must have a -// primitive type or a repeated primitive type or a non-repeated message type. -// In the case of a repeated type, the parameter can be repeated in the URL -// as `...?param=A¶m=B`. In the case of a message type, each field of the -// message is mapped to a separate parameter, such as -// `...?foo.a=A&foo.b=B&foo.c=C`. -// -// For HTTP methods that allow a request body, the `body` field -// specifies the mapping. Consider a REST update method on the -// message resource collection: -// -// service Messaging { -// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { -// option (google.api.http) = { -// patch: "/v1/messages/{message_id}" -// body: "message" -// }; -// } -// } -// message UpdateMessageRequest { -// string message_id = 1; // mapped to the URL -// Message message = 2; // mapped to the body -// } -// -// The following HTTP JSON to RPC mapping is enabled, where the -// representation of the JSON in the request body is determined by -// protos JSON encoding: -// -// HTTP | gRPC -// -----|----- -// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: -// "123456" message { text: "Hi!" })` -// -// The special name `*` can be used in the body mapping to define that -// every field not bound by the path template should be mapped to the -// request body. This enables the following alternative definition of -// the update method: -// -// service Messaging { -// rpc UpdateMessage(Message) returns (Message) { -// option (google.api.http) = { -// patch: "/v1/messages/{message_id}" -// body: "*" -// }; -// } -// } -// message Message { -// string message_id = 1; -// string text = 2; -// } -// -// -// The following HTTP JSON to RPC mapping is enabled: -// -// HTTP | gRPC -// -----|----- -// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: -// "123456" text: "Hi!")` -// -// Note that when using `*` in the body mapping, it is not possible to -// have HTTP parameters, as all fields not bound by the path end in -// the body. This makes this option more rarely used in practice when -// defining REST APIs. The common usage of `*` is in custom methods -// which don't use the URL at all for transferring data. -// -// It is possible to define multiple HTTP methods for one RPC by using -// the `additional_bindings` option. Example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/messages/{message_id}" -// additional_bindings { -// get: "/v1/users/{user_id}/messages/{message_id}" -// } -// }; -// } -// } -// message GetMessageRequest { -// string message_id = 1; -// string user_id = 2; -// } -// -// This enables the following two alternative HTTP JSON to RPC mappings: -// -// HTTP | gRPC -// -----|----- -// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` -// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: -// "123456")` -// -// ## Rules for HTTP mapping -// -// 1. Leaf request fields (recursive expansion nested messages in the request -// message) are classified into three categories: -// - Fields referred by the path template. They are passed via the URL path. -// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They -// are passed via the HTTP -// request body. -// - All other fields are passed via the URL query parameters, and the -// parameter name is the field path in the request message. A repeated -// field can be represented as multiple query parameters under the same -// name. -// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL -// query parameter, all fields -// are passed via URL path and HTTP request body. -// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP -// request body, all -// fields are passed via URL path and URL query parameters. -// -// ### Path template syntax -// -// Template = "/" Segments [ Verb ] ; -// Segments = Segment { "/" Segment } ; -// Segment = "*" | "**" | LITERAL | Variable ; -// Variable = "{" FieldPath [ "=" Segments ] "}" ; -// FieldPath = IDENT { "." IDENT } ; -// Verb = ":" LITERAL ; -// -// The syntax `*` matches a single URL path segment. The syntax `**` matches -// zero or more URL path segments, which must be the last part of the URL path -// except the `Verb`. -// -// The syntax `Variable` matches part of the URL path as specified by its -// template. A variable template must not contain other variables. If a variable -// matches a single path segment, its template may be omitted, e.g. `{var}` -// is equivalent to `{var=*}`. -// -// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` -// contains any reserved character, such characters should be percent-encoded -// before the matching. -// -// If a variable contains exactly one path segment, such as `"{var}"` or -// `"{var=*}"`, when such a variable is expanded into a URL path on the client -// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The -// server side does the reverse decoding. Such variables show up in the -// [Discovery -// Document](https://developers.google.com/discovery/v1/reference/apis) as -// `{var}`. -// -// If a variable contains multiple path segments, such as `"{var=foo/*}"` -// or `"{var=**}"`, when such a variable is expanded into a URL path on the -// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. -// The server side does the reverse decoding, except "%2F" and "%2f" are left -// unchanged. Such variables show up in the -// [Discovery -// Document](https://developers.google.com/discovery/v1/reference/apis) as -// `{+var}`. -// -// ## Using gRPC API Service Configuration -// -// gRPC API Service Configuration (service config) is a configuration language -// for configuring a gRPC service to become a user-facing product. The -// service config is simply the YAML representation of the `google.api.Service` -// proto message. -// -// As an alternative to annotating your proto file, you can configure gRPC -// transcoding in your service config YAML files. You do this by specifying a -// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same -// effect as the proto annotation. This can be particularly useful if you -// have a proto that is reused in multiple services. Note that any transcoding -// specified in the service config will override any matching transcoding -// configuration in the proto. -// -// Example: -// -// http: -// rules: -// # Selects a gRPC method and applies HttpRule to it. -// - selector: example.v1.Messaging.GetMessage -// get: /v1/messages/{message_id}/{sub.subfield} -// -// ## Special notes -// -// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the -// proto to JSON conversion must follow the [proto3 -// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). -// -// While the single segment variable follows the semantics of -// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String -// Expansion, the multi segment variable **does not** follow RFC 6570 Section -// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion -// does not expand special characters like `?` and `#`, which would lead -// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding -// for multi segment variables. -// -// The path variables **must not** refer to any repeated or mapped field, -// because client libraries are not capable of handling such variable expansion. -// -// The path variables **must not** capture the leading "/" character. The reason -// is that the most common use case "{var}" does not capture the leading "/" -// character. For consistency, all path variables must share the same behavior. -// -// Repeated message fields must not be mapped to URL query parameters, because -// no client library can support such complicated mapping. -// -// If an API needs to use a JSON array for request or response body, it can map -// the request or response body to a repeated field. However, some gRPC -// Transcoding implementations may not support this feature. -message HttpRule { - // Selects a method to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // Determines the URL pattern is matched by this rules. This pattern can be - // used with any of the {get|put|post|delete|patch} methods. A custom method - // can be defined using the 'custom' field. - oneof pattern { - // Maps to HTTP GET. Used for listing and getting information about - // resources. - string get = 2; - - // Maps to HTTP PUT. Used for replacing a resource. - string put = 3; - - // Maps to HTTP POST. Used for creating a resource or performing an action. - string post = 4; - - // Maps to HTTP DELETE. Used for deleting a resource. - string delete = 5; - - // Maps to HTTP PATCH. Used for updating a resource. - string patch = 6; - - // The custom pattern is used for specifying an HTTP method that is not - // included in the `pattern` field, such as HEAD, or "*" to leave the - // HTTP method unspecified for this rule. The wild-card rule is useful - // for services that provide content to Web (HTML) clients. - CustomHttpPattern custom = 8; - } - - // The name of the request field whose value is mapped to the HTTP request - // body, or `*` for mapping all request fields not captured by the path - // pattern to the HTTP body, or omitted for not having any HTTP request body. - // - // NOTE: the referred field must be present at the top-level of the request - // message type. - string body = 7; - - // Optional. The name of the response field whose value is mapped to the HTTP - // response body. When omitted, the entire response message will be used - // as the HTTP response body. - // - // NOTE: The referred field must be present at the top-level of the response - // message type. - string response_body = 12; - - // Additional HTTP bindings for the selector. Nested bindings must - // not contain an `additional_bindings` field themselves (that is, - // the nesting may only be one level deep). - repeated HttpRule additional_bindings = 11; -} - -// A custom pattern is used for defining custom HTTP verb. -message CustomHttpPattern { - // The name of this custom HTTP verb. - string kind = 1; - - // The path matched by this custom verb. - string path = 2; -} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto deleted file mode 100644 index 34672fdeb..000000000 --- a/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; - -import "ibc/applications/transfer/v1/transfer.proto"; -import "gogoproto/gogo.proto"; - -// GenesisState defines the ibc-transfer genesis state -message GenesisState { - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - repeated DenomTrace denom_traces = 2 [ - (gogoproto.castrepeated) = "Traces", - (gogoproto.nullable) = false, - (gogoproto.moretags) = "yaml:\"denom_traces\"" - ]; - Params params = 3 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto deleted file mode 100644 index 52f2f2400..000000000 --- a/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto +++ /dev/null @@ -1,105 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/applications/transfer/v1/transfer.proto"; -import "google/api/annotations.proto"; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; - -// Query provides defines the gRPC querier service. -service Query { - // DenomTraces queries all denomination traces. - rpc DenomTraces(QueryDenomTracesRequest) returns (QueryDenomTracesResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces"; - } - - // DenomTrace queries a denomination trace information. - rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; - } - - // Params queries all parameters of the ibc-transfer module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/params"; - } - - // DenomHash queries a denomination hash information. - rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace=**}"; - } - - // EscrowAddress returns the escrow address for a particular port and channel id. - rpc EscrowAddress(QueryEscrowAddressRequest) returns (QueryEscrowAddressResponse) { - option (google.api.http).get = "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address"; - } -} - -// QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC -// method -message QueryDenomTraceRequest { - // hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. - string hash = 1; -} - -// QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC -// method. -message QueryDenomTraceResponse { - // denom_trace returns the requested denomination trace information. - DenomTrace denom_trace = 1; -} - -// QueryConnectionsRequest is the request type for the Query/DenomTraces RPC -// method -message QueryDenomTracesRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryConnectionsResponse is the response type for the Query/DenomTraces RPC -// method. -message QueryDenomTracesResponse { - // denom_traces returns all denominations trace information. - repeated DenomTrace denom_traces = 1 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} - -// QueryDenomHashRequest is the request type for the Query/DenomHash RPC -// method -message QueryDenomHashRequest { - // The denomination trace ([port_id]/[channel_id])+/[denom] - string trace = 1; -} - -// QueryDenomHashResponse is the response type for the Query/DenomHash RPC -// method. -message QueryDenomHashResponse { - // hash (in hex format) of the denomination trace information. - string hash = 1; -} - -// QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. -message QueryEscrowAddressRequest { - // unique port identifier - string port_id = 1; - // unique channel identifier - string channel_id = 2; -} - -// QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. -message QueryEscrowAddressResponse { - // the escrow account address - string escrow_address = 1; -} \ No newline at end of file diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto deleted file mode 100644 index 1f92e81a6..000000000 --- a/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; - -import "gogoproto/gogo.proto"; - -// DenomTrace contains the base denomination for ICS20 fungible tokens and the -// source tracing information path. -message DenomTrace { - // path defines the chain of port/channel identifiers used for tracing the - // source of the fungible token. - string path = 1; - // base denomination of the relayed fungible token. - string base_denom = 2; -} - -// Params defines the set of IBC transfer parameters. -// NOTE: To prevent a single token from being transferred, set the -// TransfersEnabled parameter to true and then set the bank module's SendEnabled -// parameter for the denomination to false. -message Params { - // send_enabled enables or disables all cross-chain token transfers from this - // chain. - bool send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled\""]; - // receive_enabled enables or disables all cross-chain token transfers to this - // chain. - bool receive_enabled = 2 [(gogoproto.moretags) = "yaml:\"receive_enabled\""]; -} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto deleted file mode 100644 index 44e068d69..000000000 --- a/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto +++ /dev/null @@ -1,49 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "ibc/core/client/v1/client.proto"; - -// Msg defines the ibc/transfer Msg service. -service Msg { - // Transfer defines a rpc handler method for MsgTransfer. - rpc Transfer(MsgTransfer) returns (MsgTransferResponse); -} - -// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between -// ICS20 enabled chains. See ICS Spec here: -// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures -message MsgTransfer { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // the port on which the packet will be sent - string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""]; - // the channel by which the packet will be sent - string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""]; - // the tokens to be transferred - cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false]; - // the sender address - string sender = 4; - // the recipient address on the destination chain - string receiver = 5; - // Timeout height relative to the current block height. - // The timeout is disabled when set to 0. - ibc.core.client.v1.Height timeout_height = 6 - [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; - // Timeout timestamp in absolute nanoseconds since unix epoch. - // The timeout is disabled when set to 0. - uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; - // optional memo - string memo = 8; -} - -// MsgTransferResponse defines the Msg/Transfer response type. -message MsgTransferResponse { - // sequence number of the transfer packet sent - uint64 sequence = 1; -} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto b/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto deleted file mode 100644 index 129815ebc..000000000 --- a/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v2; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; - -// FungibleTokenPacketData defines a struct for the packet payload -// See FungibleTokenPacketData spec: -// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures -message FungibleTokenPacketData { - // the token denomination to be transferred - string denom = 1; - // the token amount to be transferred - string amount = 2; - // the sender address - string sender = 3; - // the recipient address on the destination chain - string receiver = 4; - // optional memo - string memo = 5; -} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/channel.proto b/ampd/proto/third_party/ibc/core/channel/v1/channel.proto deleted file mode 100644 index 646884d57..000000000 --- a/ampd/proto/third_party/ibc/core/channel/v1/channel.proto +++ /dev/null @@ -1,162 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; - -// Channel defines pipeline for exactly-once packet delivery between specific -// modules on separate blockchains, which has at least one end capable of -// sending packets and one end capable of receiving packets. -message Channel { - option (gogoproto.goproto_getters) = false; - - // current state of the channel end - State state = 1; - // whether the channel is ordered or unordered - Order ordering = 2; - // counterparty channel end - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - // list of connection identifiers, in order, along which packets sent on - // this channel will travel - repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; - // opaque channel version, which is agreed upon during the handshake - string version = 5; -} - -// IdentifiedChannel defines a channel with additional port and channel -// identifier fields. -message IdentifiedChannel { - option (gogoproto.goproto_getters) = false; - - // current state of the channel end - State state = 1; - // whether the channel is ordered or unordered - Order ordering = 2; - // counterparty channel end - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - // list of connection identifiers, in order, along which packets sent on - // this channel will travel - repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; - // opaque channel version, which is agreed upon during the handshake - string version = 5; - // port identifier - string port_id = 6; - // channel identifier - string channel_id = 7; -} - -// State defines if a channel is in one of the following states: -// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. -enum State { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; - // A channel has just started the opening handshake. - STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; - // A channel has acknowledged the handshake step on the counterparty chain. - STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; - // A channel has completed the handshake. Open channels are - // ready to send and receive packets. - STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; - // A channel has been closed and can no longer be used to send or receive - // packets. - STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; -} - -// Order defines if a channel is ORDERED or UNORDERED -enum Order { - option (gogoproto.goproto_enum_prefix) = false; - - // zero-value for channel ordering - ORDER_NONE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "NONE"]; - // packets can be delivered in any order, which may differ from the order in - // which they were sent. - ORDER_UNORDERED = 1 [(gogoproto.enumvalue_customname) = "UNORDERED"]; - // packets are delivered exactly in the order which they were sent - ORDER_ORDERED = 2 [(gogoproto.enumvalue_customname) = "ORDERED"]; -} - -// Counterparty defines a channel end counterparty -message Counterparty { - option (gogoproto.goproto_getters) = false; - - // port on the counterparty chain which owns the other end of the channel. - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - // channel end on the counterparty chain - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; -} - -// Packet defines a type that carries data across different chains through IBC -message Packet { - option (gogoproto.goproto_getters) = false; - - // number corresponds to the order of sends and receives, where a Packet - // with an earlier sequence number must be sent and received before a Packet - // with a later sequence number. - uint64 sequence = 1; - // identifies the port on the sending chain. - string source_port = 2 [(gogoproto.moretags) = "yaml:\"source_port\""]; - // identifies the channel end on the sending chain. - string source_channel = 3 [(gogoproto.moretags) = "yaml:\"source_channel\""]; - // identifies the port on the receiving chain. - string destination_port = 4 [(gogoproto.moretags) = "yaml:\"destination_port\""]; - // identifies the channel end on the receiving chain. - string destination_channel = 5 [(gogoproto.moretags) = "yaml:\"destination_channel\""]; - // actual opaque bytes transferred directly to the application module - bytes data = 6; - // block height after which the packet times out - ibc.core.client.v1.Height timeout_height = 7 - [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; - // block timestamp (in nanoseconds) after which the packet times out - uint64 timeout_timestamp = 8 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; -} - -// PacketState defines the generic type necessary to retrieve and store -// packet commitments, acknowledgements, and receipts. -// Caller is responsible for knowing the context necessary to interpret this -// state as a commitment, acknowledgement, or a receipt. -message PacketState { - option (gogoproto.goproto_getters) = false; - - // channel port identifier. - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - // channel unique identifier. - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - // packet sequence. - uint64 sequence = 3; - // embedded data that represents packet state. - bytes data = 4; -} - -// PacketId is an identifer for a unique Packet -// Source chains refer to packets by source port/channel -// Destination chains refer to packets by destination port/channel -message PacketId { - option (gogoproto.goproto_getters) = false; - - // channel port identifier - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - // channel unique identifier - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - // packet sequence - uint64 sequence = 3; -} - -// Acknowledgement is the recommended acknowledgement format to be used by -// app-specific protocols. -// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental -// conflicts with other protobuf message formats used for acknowledgements. -// The first byte of any message with this format will be the non-ASCII values -// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: -// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope -message Acknowledgement { - // response contains either a result or an error and must be non-empty - oneof response { - bytes result = 21; - string error = 22; - } -} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto b/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto deleted file mode 100644 index 1c0ff6ee8..000000000 --- a/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// GenesisState defines the ibc channel submodule's genesis state. -message GenesisState { - repeated IdentifiedChannel channels = 1 [(gogoproto.casttype) = "IdentifiedChannel", (gogoproto.nullable) = false]; - repeated PacketState acknowledgements = 2 [(gogoproto.nullable) = false]; - repeated PacketState commitments = 3 [(gogoproto.nullable) = false]; - repeated PacketState receipts = 4 [(gogoproto.nullable) = false]; - repeated PacketSequence send_sequences = 5 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"send_sequences\""]; - repeated PacketSequence recv_sequences = 6 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; - repeated PacketSequence ack_sequences = 7 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; - // the sequence for the next generated channel identifier - uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; -} - -// PacketSequence defines the genesis type necessary to retrieve and store -// next send and receive sequences. -message PacketSequence { - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - uint64 sequence = 3; -} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/query.proto b/ampd/proto/third_party/ibc/core/channel/v1/query.proto deleted file mode 100644 index 986633173..000000000 --- a/ampd/proto/third_party/ibc/core/channel/v1/query.proto +++ /dev/null @@ -1,376 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; - -import "ibc/core/client/v1/client.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "google/api/annotations.proto"; -import "google/protobuf/any.proto"; -import "gogoproto/gogo.proto"; - -// Query provides defines the gRPC querier service -service Query { - // Channel queries an IBC Channel. - rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}"; - } - - // Channels queries all the IBC channels of a chain. - rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels"; - } - - // ConnectionChannels queries all the channels associated with a connection - // end. - rpc ConnectionChannels(QueryConnectionChannelsRequest) returns (QueryConnectionChannelsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/connections/{connection}/channels"; - } - - // ChannelClientState queries for the client state for the channel associated - // with the provided channel identifiers. - rpc ChannelClientState(QueryChannelClientStateRequest) returns (QueryChannelClientStateResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/client_state"; - } - - // ChannelConsensusState queries for the consensus state for the channel - // associated with the provided channel identifiers. - rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/consensus_state/revision/" - "{revision_number}/height/{revision_height}"; - } - - // PacketCommitment queries a stored packet commitment hash. - rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" - "packet_commitments/{sequence}"; - } - - // PacketCommitments returns all the packet commitments hashes associated - // with a channel. - rpc PacketCommitments(QueryPacketCommitmentsRequest) returns (QueryPacketCommitmentsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_commitments"; - } - - // PacketReceipt queries if a given packet sequence has been received on the - // queried chain - rpc PacketReceipt(QueryPacketReceiptRequest) returns (QueryPacketReceiptResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_receipts/{sequence}"; - } - - // PacketAcknowledgement queries a stored packet acknowledgement hash. - rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest) returns (QueryPacketAcknowledgementResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_acks/{sequence}"; - } - - // PacketAcknowledgements returns all the packet acknowledgements associated - // with a channel. - rpc PacketAcknowledgements(QueryPacketAcknowledgementsRequest) returns (QueryPacketAcknowledgementsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_acknowledgements"; - } - - // UnreceivedPackets returns all the unreceived IBC packets associated with a - // channel and sequences. - rpc UnreceivedPackets(QueryUnreceivedPacketsRequest) returns (QueryUnreceivedPacketsResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" - "packet_commitments/" - "{packet_commitment_sequences}/unreceived_packets"; - } - - // UnreceivedAcks returns all the unreceived IBC acknowledgements associated - // with a channel and sequences. - rpc UnreceivedAcks(QueryUnreceivedAcksRequest) returns (QueryUnreceivedAcksResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/packet_commitments/" - "{packet_ack_sequences}/unreceived_acks"; - } - - // NextSequenceReceive returns the next receive sequence for a given channel. - rpc NextSequenceReceive(QueryNextSequenceReceiveRequest) returns (QueryNextSequenceReceiveResponse) { - option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" - "ports/{port_id}/next_sequence"; - } -} - -// QueryChannelRequest is the request type for the Query/Channel RPC method -message QueryChannelRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QueryChannelResponse is the response type for the Query/Channel RPC method. -// Besides the Channel end, it includes a proof and the height from which the -// proof was retrieved. -message QueryChannelResponse { - // channel associated with the request identifiers - ibc.core.channel.v1.Channel channel = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelsRequest is the request type for the Query/Channels RPC method -message QueryChannelsRequest { - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryChannelsResponse is the response type for the Query/Channels RPC method. -message QueryChannelsResponse { - // list of stored channels of the chain. - repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionChannelsRequest is the request type for the -// Query/QueryConnectionChannels RPC method -message QueryConnectionChannelsRequest { - // connection unique identifier - string connection = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConnectionChannelsResponse is the Response type for the -// Query/QueryConnectionChannels RPC method -message QueryConnectionChannelsResponse { - // list of channels associated with a connection. - repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelClientStateRequest is the request type for the Query/ClientState -// RPC method -message QueryChannelClientStateRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QueryChannelClientStateResponse is the Response type for the -// Query/QueryChannelClientState RPC method -message QueryChannelClientStateResponse { - // client state associated with the channel - ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryChannelConsensusStateRequest is the request type for the -// Query/ConsensusState RPC method -message QueryChannelConsensusStateRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // revision number of the consensus state - uint64 revision_number = 3; - // revision height of the consensus state - uint64 revision_height = 4; -} - -// QueryChannelClientStateResponse is the Response type for the -// Query/QueryChannelClientState RPC method -message QueryChannelConsensusStateResponse { - // consensus state associated with the channel - google.protobuf.Any consensus_state = 1; - // client ID associated with the consensus state - string client_id = 2; - // merkle proof of existence - bytes proof = 3; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; -} - -// QueryPacketCommitmentRequest is the request type for the -// Query/PacketCommitment RPC method -message QueryPacketCommitmentRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// QueryPacketCommitmentResponse defines the client query response for a packet -// which also includes a proof and the height from which the proof was -// retrieved -message QueryPacketCommitmentResponse { - // packet associated with the request fields - bytes commitment = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryPacketCommitmentsRequest is the request type for the -// Query/QueryPacketCommitments RPC method -message QueryPacketCommitmentsRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 3; -} - -// QueryPacketCommitmentsResponse is the request type for the -// Query/QueryPacketCommitments RPC method -message QueryPacketCommitmentsResponse { - repeated ibc.core.channel.v1.PacketState commitments = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryPacketReceiptRequest is the request type for the -// Query/PacketReceipt RPC method -message QueryPacketReceiptRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// QueryPacketReceiptResponse defines the client query response for a packet -// receipt which also includes a proof, and the height from which the proof was -// retrieved -message QueryPacketReceiptResponse { - // success flag for if receipt exists - bool received = 2; - // merkle proof of existence - bytes proof = 3; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; -} - -// QueryPacketAcknowledgementRequest is the request type for the -// Query/PacketAcknowledgement RPC method -message QueryPacketAcknowledgementRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // packet sequence - uint64 sequence = 3; -} - -// QueryPacketAcknowledgementResponse defines the client query response for a -// packet which also includes a proof and the height from which the -// proof was retrieved -message QueryPacketAcknowledgementResponse { - // packet associated with the request fields - bytes acknowledgement = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryPacketAcknowledgementsRequest is the request type for the -// Query/QueryPacketCommitments RPC method -message QueryPacketAcknowledgementsRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 3; - // list of packet sequences - repeated uint64 packet_commitment_sequences = 4; -} - -// QueryPacketAcknowledgemetsResponse is the request type for the -// Query/QueryPacketAcknowledgements RPC method -message QueryPacketAcknowledgementsResponse { - repeated ibc.core.channel.v1.PacketState acknowledgements = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryUnreceivedPacketsRequest is the request type for the -// Query/UnreceivedPackets RPC method -message QueryUnreceivedPacketsRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // list of packet sequences - repeated uint64 packet_commitment_sequences = 3; -} - -// QueryUnreceivedPacketsResponse is the response type for the -// Query/UnreceivedPacketCommitments RPC method -message QueryUnreceivedPacketsResponse { - // list of unreceived packet sequences - repeated uint64 sequences = 1; - // query block height - ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; -} - -// QueryUnreceivedAcks is the request type for the -// Query/UnreceivedAcks RPC method -message QueryUnreceivedAcksRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; - // list of acknowledgement sequences - repeated uint64 packet_ack_sequences = 3; -} - -// QueryUnreceivedAcksResponse is the response type for the -// Query/UnreceivedAcks RPC method -message QueryUnreceivedAcksResponse { - // list of unreceived acknowledgement sequences - repeated uint64 sequences = 1; - // query block height - ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; -} - -// QueryNextSequenceReceiveRequest is the request type for the -// Query/QueryNextSequenceReceiveRequest RPC method -message QueryNextSequenceReceiveRequest { - // port unique identifier - string port_id = 1; - // channel unique identifier - string channel_id = 2; -} - -// QuerySequenceResponse is the request type for the -// Query/QueryNextSequenceReceiveResponse RPC method -message QueryNextSequenceReceiveResponse { - // next sequence receive number - uint64 next_sequence_receive = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/tx.proto b/ampd/proto/third_party/ibc/core/channel/v1/tx.proto deleted file mode 100644 index 75248aeb5..000000000 --- a/ampd/proto/third_party/ibc/core/channel/v1/tx.proto +++ /dev/null @@ -1,245 +0,0 @@ -syntax = "proto3"; - -package ibc.core.channel.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/channel/v1/channel.proto"; - -// Msg defines the ibc/channel Msg service. -service Msg { - // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. - rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse); - - // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. - rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse); - - // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. - rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse); - - // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. - rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse); - - // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. - rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse); - - // ChannelCloseConfirm defines a rpc handler method for - // MsgChannelCloseConfirm. - rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse); - - // RecvPacket defines a rpc handler method for MsgRecvPacket. - rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse); - - // Timeout defines a rpc handler method for MsgTimeout. - rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse); - - // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. - rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse); - - // Acknowledgement defines a rpc handler method for MsgAcknowledgement. - rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); -} - -// ResponseResultType defines the possible outcomes of the execution of a message -enum ResponseResultType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default zero value enumeration - RESPONSE_RESULT_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) - RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; - // The message was executed successfully - RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; -} - -// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It -// is called by a relayer on Chain A. -message MsgChannelOpenInit { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - Channel channel = 2 [(gogoproto.nullable) = false]; - string signer = 3; -} - -// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. -message MsgChannelOpenInitResponse { - string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - string version = 2; -} - -// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel -// on Chain B. The version field within the Channel field has been deprecated. Its -// value will be ignored by core IBC. -message MsgChannelOpenTry { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - // Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. - string previous_channel_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_channel_id\""]; - // NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. - Channel channel = 3 [(gogoproto.nullable) = false]; - string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 6 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 7; -} - -// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. -message MsgChannelOpenTryResponse { - string version = 1; -} - -// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge -// the change of channel state to TRYOPEN on Chain B. -message MsgChannelOpenAck { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - string counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""]; - string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_try = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""]; - ibc.core.client.v1.Height proof_height = 6 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 7; -} - -// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. -message MsgChannelOpenAckResponse {} - -// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to -// acknowledge the change of channel state to OPEN on Chain A. -message MsgChannelOpenConfirm { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - bytes proof_ack = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 5; -} - -// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response -// type. -message MsgChannelOpenConfirmResponse {} - -// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A -// to close a channel with Chain B. -message MsgChannelCloseInit { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - string signer = 3; -} - -// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type. -message MsgChannelCloseInitResponse {} - -// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B -// to acknowledge the change of channel state to CLOSED on Chain A. -message MsgChannelCloseConfirm { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - bytes proof_init = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 5; -} - -// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response -// type. -message MsgChannelCloseConfirmResponse {} - -// MsgRecvPacket receives incoming IBC packet -message MsgRecvPacket { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; - ibc.core.client.v1.Height proof_height = 3 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 4; -} - -// MsgRecvPacketResponse defines the Msg/RecvPacket response type. -message MsgRecvPacketResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgTimeout receives timed-out packet -message MsgTimeout { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - ibc.core.client.v1.Height proof_height = 3 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; - string signer = 5; -} - -// MsgTimeoutResponse defines the Msg/Timeout response type. -message MsgTimeoutResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgTimeoutOnClose timed-out packet upon counterparty channel closure. -message MsgTimeoutOnClose { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; - string signer = 6; -} - -// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. -message MsgTimeoutOnCloseResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} - -// MsgAcknowledgement receives incoming IBC acknowledgement -message MsgAcknowledgement { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes acknowledgement = 2; - bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; - ibc.core.client.v1.Height proof_height = 4 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 5; -} - -// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. -message MsgAcknowledgementResponse { - option (gogoproto.goproto_getters) = false; - - ResponseResultType result = 1; -} diff --git a/ampd/proto/third_party/ibc/core/client/v1/client.proto b/ampd/proto/third_party/ibc/core/client/v1/client.proto deleted file mode 100644 index 2ec41ed0c..000000000 --- a/ampd/proto/third_party/ibc/core/client/v1/client.proto +++ /dev/null @@ -1,103 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "cosmos/upgrade/v1beta1/upgrade.proto"; -import "cosmos_proto/cosmos.proto"; - -// IdentifiedClientState defines a client state with an additional client -// identifier field. -message IdentifiedClientState { - // client identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // client state - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; -} - -// ConsensusStateWithHeight defines a consensus state with an additional height -// field. -message ConsensusStateWithHeight { - // consensus state height - Height height = 1 [(gogoproto.nullable) = false]; - // consensus state - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; -} - -// ClientConsensusStates defines all the stored consensus states for a given -// client. -message ClientConsensusStates { - // client identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // consensus states and their heights associated with the client - repeated ConsensusStateWithHeight consensus_states = 2 - [(gogoproto.moretags) = "yaml:\"consensus_states\"", (gogoproto.nullable) = false]; -} - -// ClientUpdateProposal is a governance proposal. If it passes, the substitute -// client's latest consensus state is copied over to the subject client. The proposal -// handler may fail if the subject and the substitute do not match in client and -// chain parameters (with exception to latest height, frozen height, and chain-id). -message ClientUpdateProposal { - option (gogoproto.goproto_getters) = false; - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - // the title of the update proposal - string title = 1; - // the description of the proposal - string description = 2; - // the client identifier for the client to be updated if the proposal passes - string subject_client_id = 3 [(gogoproto.moretags) = "yaml:\"subject_client_id\""]; - // the substitute client identifier for the client standing in for the subject - // client - string substitute_client_id = 4 [(gogoproto.moretags) = "yaml:\"substitute_client_id\""]; -} - -// UpgradeProposal is a gov Content type for initiating an IBC breaking -// upgrade. -message UpgradeProposal { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - option (gogoproto.equal) = true; - option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; - - string title = 1; - string description = 2; - cosmos.upgrade.v1beta1.Plan plan = 3 [(gogoproto.nullable) = false]; - - // An UpgradedClientState must be provided to perform an IBC breaking upgrade. - // This will make the chain commit to the correct upgraded (self) client state - // before the upgrade occurs, so that connecting chains can verify that the - // new upgraded client is valid by verifying a proof on the previous version - // of the chain. This will allow IBC connections to persist smoothly across - // planned chain upgrades - google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; -} - -// Height is a monotonically increasing data type -// that can be compared against another Height for the purposes of updating and -// freezing clients -// -// Normally the RevisionHeight is incremented at each height while keeping -// RevisionNumber the same. However some consensus algorithms may choose to -// reset the height in certain conditions e.g. hard forks, state-machine -// breaking changes In these cases, the RevisionNumber is incremented so that -// height continues to be monitonically increasing even as the RevisionHeight -// gets reset -message Height { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - // the revision that the client is currently on - uint64 revision_number = 1 [(gogoproto.moretags) = "yaml:\"revision_number\""]; - // the height within the given revision - uint64 revision_height = 2 [(gogoproto.moretags) = "yaml:\"revision_height\""]; -} - -// Params defines the set of IBC light client parameters. -message Params { - // allowed_clients defines the list of allowed client state types. - repeated string allowed_clients = 1 [(gogoproto.moretags) = "yaml:\"allowed_clients\""]; -} diff --git a/ampd/proto/third_party/ibc/core/client/v1/genesis.proto b/ampd/proto/third_party/ibc/core/client/v1/genesis.proto deleted file mode 100644 index b2930c484..000000000 --- a/ampd/proto/third_party/ibc/core/client/v1/genesis.proto +++ /dev/null @@ -1,48 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; - -import "ibc/core/client/v1/client.proto"; -import "gogoproto/gogo.proto"; - -// GenesisState defines the ibc client submodule's genesis state. -message GenesisState { - // client states with their corresponding identifiers - repeated IdentifiedClientState clients = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; - // consensus states from each client - repeated ClientConsensusStates clients_consensus = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "ClientsConsensusStates", - (gogoproto.moretags) = "yaml:\"clients_consensus\"" - ]; - // metadata from each client - repeated IdentifiedGenesisMetadata clients_metadata = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"clients_metadata\""]; - Params params = 4 [(gogoproto.nullable) = false]; - // create localhost on initialization - bool create_localhost = 5 [(gogoproto.moretags) = "yaml:\"create_localhost\""]; - // the sequence for the next generated client identifier - uint64 next_client_sequence = 6 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""]; -} - -// GenesisMetadata defines the genesis type for metadata that clients may return -// with ExportMetadata -message GenesisMetadata { - option (gogoproto.goproto_getters) = false; - - // store key of metadata without clientID-prefix - bytes key = 1; - // metadata value - bytes value = 2; -} - -// IdentifiedGenesisMetadata has the client metadata with the corresponding -// client id. -message IdentifiedGenesisMetadata { - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - repeated GenesisMetadata client_metadata = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_metadata\""]; -} diff --git a/ampd/proto/third_party/ibc/core/client/v1/query.proto b/ampd/proto/third_party/ibc/core/client/v1/query.proto deleted file mode 100644 index 2c9618bc8..000000000 --- a/ampd/proto/third_party/ibc/core/client/v1/query.proto +++ /dev/null @@ -1,207 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; - -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/client/v1/client.proto"; -import "google/protobuf/any.proto"; -import "google/api/annotations.proto"; -import "gogoproto/gogo.proto"; - -// Query provides defines the gRPC querier service -service Query { - // ClientState queries an IBC light client. - rpc ClientState(QueryClientStateRequest) returns (QueryClientStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_states/{client_id}"; - } - - // ClientStates queries all the IBC light clients of a chain. - rpc ClientStates(QueryClientStatesRequest) returns (QueryClientStatesResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_states"; - } - - // ConsensusState queries a consensus state associated with a client state at - // a given height. - rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/" - "{client_id}/revision/{revision_number}/" - "height/{revision_height}"; - } - - // ConsensusStates queries all the consensus state associated with a given - // client. - rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}"; - } - - // ConsensusStateHeights queries the height of every consensus states associated with a given client. - rpc ConsensusStateHeights(QueryConsensusStateHeightsRequest) returns (QueryConsensusStateHeightsResponse) { - option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}/heights"; - } - - // Status queries the status of an IBC client. - rpc ClientStatus(QueryClientStatusRequest) returns (QueryClientStatusResponse) { - option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; - } - - // ClientParams queries all parameters of the ibc client. - rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { - option (google.api.http).get = "/ibc/client/v1/params"; - } - - // UpgradedClientState queries an Upgraded IBC light client. - rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states"; - } - - // UpgradedConsensusState queries an Upgraded IBC consensus state. - rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/client/v1/upgraded_consensus_states"; - } -} - -// QueryClientStateRequest is the request type for the Query/ClientState RPC -// method -message QueryClientStateRequest { - // client state unique identifier - string client_id = 1; -} - -// QueryClientStateResponse is the response type for the Query/ClientState RPC -// method. Besides the client state, it includes a proof and the height from -// which the proof was retrieved. -message QueryClientStateResponse { - // client state associated with the request identifier - google.protobuf.Any client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryClientStatesRequest is the request type for the Query/ClientStates RPC -// method -message QueryClientStatesRequest { - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryClientStatesResponse is the response type for the Query/ClientStates RPC -// method. -message QueryClientStatesResponse { - // list of stored ClientStates of the chain. - repeated IdentifiedClientState client_states = 1 - [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryConsensusStateRequest is the request type for the Query/ConsensusState -// RPC method. Besides the consensus state, it includes a proof and the height -// from which the proof was retrieved. -message QueryConsensusStateRequest { - // client identifier - string client_id = 1; - // consensus state revision number - uint64 revision_number = 2; - // consensus state revision height - uint64 revision_height = 3; - // latest_height overrrides the height field and queries the latest stored - // ConsensusState - bool latest_height = 4; -} - -// QueryConsensusStateResponse is the response type for the Query/ConsensusState -// RPC method -message QueryConsensusStateResponse { - // consensus state associated with the client identifier at the given height - google.protobuf.Any consensus_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConsensusStatesRequest is the request type for the Query/ConsensusStates -// RPC method. -message QueryConsensusStatesRequest { - // client identifier - string client_id = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConsensusStatesResponse is the response type for the -// Query/ConsensusStates RPC method -message QueryConsensusStatesResponse { - // consensus states associated with the identifier - repeated ConsensusStateWithHeight consensus_states = 1 [(gogoproto.nullable) = false]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights -// RPC method. -message QueryConsensusStateHeightsRequest { - // client identifier - string client_id = 1; - // pagination request - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryConsensusStateHeightsResponse is the response type for the -// Query/ConsensusStateHeights RPC method -message QueryConsensusStateHeightsResponse { - // consensus state heights - repeated Height consensus_state_heights = 1 [(gogoproto.nullable) = false]; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC -// method -message QueryClientStatusRequest { - // client unique identifier - string client_id = 1; -} - -// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC -// method. It returns the current status of the IBC client. -message QueryClientStatusResponse { - string status = 1; -} - -// QueryClientParamsRequest is the request type for the Query/ClientParams RPC -// method. -message QueryClientParamsRequest {} - -// QueryClientParamsResponse is the response type for the Query/ClientParams RPC -// method. -message QueryClientParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} - -// QueryUpgradedClientStateRequest is the request type for the -// Query/UpgradedClientState RPC method -message QueryUpgradedClientStateRequest {} - -// QueryUpgradedClientStateResponse is the response type for the -// Query/UpgradedClientState RPC method. -message QueryUpgradedClientStateResponse { - // client state associated with the request identifier - google.protobuf.Any upgraded_client_state = 1; -} - -// QueryUpgradedConsensusStateRequest is the request type for the -// Query/UpgradedConsensusState RPC method -message QueryUpgradedConsensusStateRequest {} - -// QueryUpgradedConsensusStateResponse is the response type for the -// Query/UpgradedConsensusState RPC method. -message QueryUpgradedConsensusStateResponse { - // Consensus state associated with the request identifier - google.protobuf.Any upgraded_consensus_state = 1; -} diff --git a/ampd/proto/third_party/ibc/core/client/v1/tx.proto b/ampd/proto/third_party/ibc/core/client/v1/tx.proto deleted file mode 100644 index 11dfdadea..000000000 --- a/ampd/proto/third_party/ibc/core/client/v1/tx.proto +++ /dev/null @@ -1,99 +0,0 @@ -syntax = "proto3"; - -package ibc.core.client.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// Msg defines the ibc/client Msg service. -service Msg { - // CreateClient defines a rpc handler method for MsgCreateClient. - rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); - - // UpdateClient defines a rpc handler method for MsgUpdateClient. - rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse); - - // UpgradeClient defines a rpc handler method for MsgUpgradeClient. - rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse); - - // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. - rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); -} - -// MsgCreateClient defines a message to create an IBC client -message MsgCreateClient { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // light client state - google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""]; - // consensus state associated with the client that corresponds to a given - // height. - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; - // signer address - string signer = 3; -} - -// MsgCreateClientResponse defines the Msg/CreateClient response type. -message MsgCreateClientResponse {} - -// MsgUpdateClient defines an sdk.Msg to update a IBC client state using -// the given header. -message MsgUpdateClient { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // header to update the light client - google.protobuf.Any header = 2; - // signer address - string signer = 3; -} - -// MsgUpdateClientResponse defines the Msg/UpdateClient response type. -message MsgUpdateClientResponse {} - -// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client -// state -message MsgUpgradeClient { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // upgraded client state - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; - // upgraded consensus state, only contains enough information to serve as a - // basis of trust in update logic - google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; - // proof that old chain committed to new client - bytes proof_upgrade_client = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade_client\""]; - // proof that old chain committed to new consensus state - bytes proof_upgrade_consensus_state = 5 [(gogoproto.moretags) = "yaml:\"proof_upgrade_consensus_state\""]; - // signer address - string signer = 6; -} - -// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. -message MsgUpgradeClientResponse {} - -// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for -// light client misbehaviour. -message MsgSubmitMisbehaviour { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - // client unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // misbehaviour used for freezing the light client - google.protobuf.Any misbehaviour = 2; - // signer address - string signer = 3; -} - -// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response -// type. -message MsgSubmitMisbehaviourResponse {} diff --git a/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto b/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto deleted file mode 100644 index b6a68a99f..000000000 --- a/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; - -package ibc.core.commitment.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types"; - -import "gogoproto/gogo.proto"; -import "proofs.proto"; - -// MerkleRoot defines a merkle root hash. -// In the Cosmos SDK, the AppHash of a block header becomes the root. -message MerkleRoot { - option (gogoproto.goproto_getters) = false; - - bytes hash = 1; -} - -// MerklePrefix is merkle path prefixed to the key. -// The constructed key from the Path and the key will be append(Path.KeyPath, -// append(Path.KeyPrefix, key...)) -message MerklePrefix { - bytes key_prefix = 1 [(gogoproto.moretags) = "yaml:\"key_prefix\""]; -} - -// MerklePath is the path used to verify commitment proofs, which can be an -// arbitrary structured object (defined by a commitment type). -// MerklePath is represented from root-to-leaf -message MerklePath { - option (gogoproto.goproto_stringer) = false; - - repeated string key_path = 1 [(gogoproto.moretags) = "yaml:\"key_path\""]; -} - -// MerkleProof is a wrapper type over a chain of CommitmentProofs. -// It demonstrates membership or non-membership for an element or set of -// elements, verifiable in conjunction with a known commitment root. Proofs -// should be succinct. -// MerkleProofs are ordered from leaf-to-root -message MerkleProof { - repeated ics23.CommitmentProof proofs = 1; -} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/connection.proto b/ampd/proto/third_party/ibc/core/connection/v1/connection.proto deleted file mode 100644 index 8360af988..000000000 --- a/ampd/proto/third_party/ibc/core/connection/v1/connection.proto +++ /dev/null @@ -1,114 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/commitment/v1/commitment.proto"; - -// ICS03 - Connection Data Structures as defined in -// https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#data-structures - -// ConnectionEnd defines a stateful object on a chain connected to another -// separate one. -// NOTE: there must only be 2 defined ConnectionEnds to establish -// a connection between two chains. -message ConnectionEnd { - option (gogoproto.goproto_getters) = false; - // client associated with this connection. - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // IBC version which can be utilised to determine encodings or protocols for - // channels or packets utilising this connection. - repeated Version versions = 2; - // current state of the connection end. - State state = 3; - // counterparty chain associated with this connection. - Counterparty counterparty = 4 [(gogoproto.nullable) = false]; - // delay period that must pass before a consensus state can be used for - // packet-verification NOTE: delay period logic is only implemented by some - // clients. - uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; -} - -// IdentifiedConnection defines a connection with additional connection -// identifier field. -message IdentifiedConnection { - option (gogoproto.goproto_getters) = false; - // connection identifier. - string id = 1 [(gogoproto.moretags) = "yaml:\"id\""]; - // client associated with this connection. - string client_id = 2 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // IBC version which can be utilised to determine encodings or protocols for - // channels or packets utilising this connection - repeated Version versions = 3; - // current state of the connection end. - State state = 4; - // counterparty chain associated with this connection. - Counterparty counterparty = 5 [(gogoproto.nullable) = false]; - // delay period associated with this connection. - uint64 delay_period = 6 [(gogoproto.moretags) = "yaml:\"delay_period\""]; -} - -// State defines if a connection is in one of the following states: -// INIT, TRYOPEN, OPEN or UNINITIALIZED. -enum State { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; - // A connection end has just started the opening handshake. - STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; - // A connection end has acknowledged the handshake step on the counterparty - // chain. - STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; - // A connection end has completed the handshake. - STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; -} - -// Counterparty defines the counterparty chain associated with a connection end. -message Counterparty { - option (gogoproto.goproto_getters) = false; - - // identifies the client on the counterparty chain associated with a given - // connection. - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // identifies the connection end on the counterparty chain associated with a - // given connection. - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - // commitment merkle prefix of the counterparty chain. - ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; -} - -// ClientPaths define all the connection paths for a client state. -message ClientPaths { - // list of connection paths - repeated string paths = 1; -} - -// ConnectionPaths define all the connection paths for a given client state. -message ConnectionPaths { - // client state unique identifier - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // list of connection paths - repeated string paths = 2; -} - -// Version defines the versioning scheme used to negotiate the IBC verison in -// the connection handshake. -message Version { - option (gogoproto.goproto_getters) = false; - - // unique version identifier - string identifier = 1; - // list of features compatible with the specified identifier - repeated string features = 2; -} - -// Params defines the set of Connection parameters. -message Params { - // maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the - // largest amount of time that the chain might reasonably take to produce the next block under normal operating - // conditions. A safe choice is 3-5x the expected time per block. - uint64 max_expected_time_per_block = 1 [(gogoproto.moretags) = "yaml:\"max_expected_time_per_block\""]; -} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto b/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto deleted file mode 100644 index f616ae67e..000000000 --- a/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/connection/v1/connection.proto"; - -// GenesisState defines the ibc connection submodule's genesis state. -message GenesisState { - repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; - repeated ConnectionPaths client_connection_paths = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; - // the sequence for the next generated connection identifier - uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; - Params params = 4 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/query.proto b/ampd/proto/third_party/ibc/core/connection/v1/query.proto deleted file mode 100644 index 129f30a71..000000000 --- a/ampd/proto/third_party/ibc/core/connection/v1/query.proto +++ /dev/null @@ -1,138 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/connection/v1/connection.proto"; -import "google/api/annotations.proto"; -import "google/protobuf/any.proto"; - -// Query provides defines the gRPC querier service -service Query { - // Connection queries an IBC connection end. - rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}"; - } - - // Connections queries all the IBC connections of a chain. - rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections"; - } - - // ClientConnections queries the connection paths associated with a client - // state. - rpc ClientConnections(QueryClientConnectionsRequest) returns (QueryClientConnectionsResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/client_connections/{client_id}"; - } - - // ConnectionClientState queries the client state associated with the - // connection. - rpc ConnectionClientState(QueryConnectionClientStateRequest) returns (QueryConnectionClientStateResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/client_state"; - } - - // ConnectionConsensusState queries the consensus state associated with the - // connection. - rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { - option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/consensus_state/" - "revision/{revision_number}/height/{revision_height}"; - } -} - -// QueryConnectionRequest is the request type for the Query/Connection RPC -// method -message QueryConnectionRequest { - // connection unique identifier - string connection_id = 1; -} - -// QueryConnectionResponse is the response type for the Query/Connection RPC -// method. Besides the connection end, it includes a proof and the height from -// which the proof was retrieved. -message QueryConnectionResponse { - // connection associated with the request identifier - ibc.core.connection.v1.ConnectionEnd connection = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionsRequest is the request type for the Query/Connections RPC -// method -message QueryConnectionsRequest { - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryConnectionsResponse is the response type for the Query/Connections RPC -// method. -message QueryConnectionsResponse { - // list of stored connections of the chain. - repeated ibc.core.connection.v1.IdentifiedConnection connections = 1; - // pagination response - cosmos.base.query.v1beta1.PageResponse pagination = 2; - // query block height - ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; -} - -// QueryClientConnectionsRequest is the request type for the -// Query/ClientConnections RPC method -message QueryClientConnectionsRequest { - // client identifier associated with a connection - string client_id = 1; -} - -// QueryClientConnectionsResponse is the response type for the -// Query/ClientConnections RPC method -message QueryClientConnectionsResponse { - // slice of all the connection paths associated with a client. - repeated string connection_paths = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was generated - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionClientStateRequest is the request type for the -// Query/ConnectionClientState RPC method -message QueryConnectionClientStateRequest { - // connection identifier - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; -} - -// QueryConnectionClientStateResponse is the response type for the -// Query/ConnectionClientState RPC method -message QueryConnectionClientStateResponse { - // client state associated with the channel - ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; - // merkle proof of existence - bytes proof = 2; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; -} - -// QueryConnectionConsensusStateRequest is the request type for the -// Query/ConnectionConsensusState RPC method -message QueryConnectionConsensusStateRequest { - // connection identifier - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - uint64 revision_number = 2; - uint64 revision_height = 3; -} - -// QueryConnectionConsensusStateResponse is the response type for the -// Query/ConnectionConsensusState RPC method -message QueryConnectionConsensusStateResponse { - // consensus state associated with the channel - google.protobuf.Any consensus_state = 1; - // client ID associated with the consensus state - string client_id = 2; - // merkle proof of existence - bytes proof = 3; - // height at which the proof was retrieved - ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/tx.proto b/ampd/proto/third_party/ibc/core/connection/v1/tx.proto deleted file mode 100644 index b2fea632c..000000000 --- a/ampd/proto/third_party/ibc/core/connection/v1/tx.proto +++ /dev/null @@ -1,118 +0,0 @@ -syntax = "proto3"; - -package ibc.core.connection.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/connection/v1/connection.proto"; - -// Msg defines the ibc/connection Msg service. -service Msg { - // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. - rpc ConnectionOpenInit(MsgConnectionOpenInit) returns (MsgConnectionOpenInitResponse); - - // ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry. - rpc ConnectionOpenTry(MsgConnectionOpenTry) returns (MsgConnectionOpenTryResponse); - - // ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck. - rpc ConnectionOpenAck(MsgConnectionOpenAck) returns (MsgConnectionOpenAckResponse); - - // ConnectionOpenConfirm defines a rpc handler method for - // MsgConnectionOpenConfirm. - rpc ConnectionOpenConfirm(MsgConnectionOpenConfirm) returns (MsgConnectionOpenConfirmResponse); -} - -// MsgConnectionOpenInit defines the msg sent by an account on Chain A to -// initialize a connection with Chain B. -message MsgConnectionOpenInit { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - Counterparty counterparty = 2 [(gogoproto.nullable) = false]; - Version version = 3; - uint64 delay_period = 4 [(gogoproto.moretags) = "yaml:\"delay_period\""]; - string signer = 5; -} - -// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response -// type. -message MsgConnectionOpenInitResponse {} - -// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a -// connection on Chain B. -message MsgConnectionOpenTry { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - // Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. - string previous_connection_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_connection_id\""]; - google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; - Counterparty counterparty = 4 [(gogoproto.nullable) = false]; - uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; - repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; - ibc.core.client.v1.Height proof_height = 7 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - // proof of the initialization the connection on Chain A: `UNITIALIZED -> - // INIT` - bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - // proof of client state included in message - bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; - // proof of client consensus state - bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 11 - [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 12; -} - -// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. -message MsgConnectionOpenTryResponse {} - -// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to -// acknowledge the change of connection state to TRYOPEN on Chain B. -message MsgConnectionOpenAck { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - string counterparty_connection_id = 2 [(gogoproto.moretags) = "yaml:\"counterparty_connection_id\""]; - Version version = 3; - google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; - ibc.core.client.v1.Height proof_height = 5 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - // proof of the initialization the connection on Chain B: `UNITIALIZED -> - // TRYOPEN` - bytes proof_try = 6 [(gogoproto.moretags) = "yaml:\"proof_try\""]; - // proof of client state included in message - bytes proof_client = 7 [(gogoproto.moretags) = "yaml:\"proof_client\""]; - // proof of client consensus state - bytes proof_consensus = 8 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 9 - [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 10; -} - -// MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. -message MsgConnectionOpenAckResponse {} - -// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to -// acknowledge the change of connection state to OPEN on Chain A. -message MsgConnectionOpenConfirm { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - // proof for the change of the connection state on Chain A: `INIT -> OPEN` - bytes proof_ack = 2 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; - ibc.core.client.v1.Height proof_height = 3 - [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 4; -} - -// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm -// response type. -message MsgConnectionOpenConfirmResponse {} diff --git a/ampd/proto/third_party/ibc/core/types/v1/genesis.proto b/ampd/proto/third_party/ibc/core/types/v1/genesis.proto deleted file mode 100644 index 4cc931d32..000000000 --- a/ampd/proto/third_party/ibc/core/types/v1/genesis.proto +++ /dev/null @@ -1,23 +0,0 @@ -syntax = "proto3"; - -package ibc.core.types.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/genesis.proto"; -import "ibc/core/connection/v1/genesis.proto"; -import "ibc/core/channel/v1/genesis.proto"; - -// GenesisState defines the ibc module's genesis state. -message GenesisState { - // ICS002 - Clients genesis state - ibc.core.client.v1.GenesisState client_genesis = 1 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_genesis\""]; - // ICS003 - Connections genesis state - ibc.core.connection.v1.GenesisState connection_genesis = 2 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"connection_genesis\""]; - // ICS004 - Channel genesis state - ibc.core.channel.v1.GenesisState channel_genesis = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"channel_genesis\""]; -} diff --git a/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto b/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto deleted file mode 100644 index 9eda835eb..000000000 --- a/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.localhost.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types"; - -import "gogoproto/gogo.proto"; -import "ibc/core/client/v1/client.proto"; - -// ClientState defines a loopback (localhost) client. It requires (read-only) -// access to keys outside the client prefix. -message ClientState { - option (gogoproto.goproto_getters) = false; - // self chain ID - string chain_id = 1 [(gogoproto.moretags) = "yaml:\"chain_id\""]; - // self latest block height - ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto b/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto deleted file mode 100644 index 37bd81e92..000000000 --- a/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto +++ /dev/null @@ -1,189 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100"; - -import "ibc/core/connection/v1/connection.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - uint64 frozen_sequence = 2 [(gogoproto.moretags) = "yaml:\"frozen_sequence\""]; - ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; - // when set to true, will allow governance to update a solo machine client. - // The client will be unfrozen if it is frozen. - bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - // sequence to update solo machine public key at - uint64 sequence = 1; - uint64 timestamp = 2; - bytes signature = 3; - google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; - string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - bytes signature = 1; - DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - uint64 timestamp = 2; - string diversifier = 3; - // type of the data used - DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; - // marshaled data - bytes data = 5; -} - -// DataType defines the type of solo machine proof being created. This is done -// to preserve uniqueness of different data sign byte encodings. -enum DataType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Data type for client state verification - DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; - // Data type for consensus state verification - DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; - // Data type for connection state verification - DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; - // Data type for channel state verification - DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; - // Data type for packet commitment verification - DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; - // Data type for packet acknowledgement verification - DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; - // Data type for packet receipt absence verification - DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; - // Data type for next sequence recv verification - DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; - // Data type for header verification - DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; - // header diversifier - string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} - -// ClientStateData returns the SignBytes data for client state verification. -message ClientStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; -} - -// ConsensusStateData returns the SignBytes data for consensus state -// verification. -message ConsensusStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; -} - -// ConnectionStateData returns the SignBytes data for connection state -// verification. -message ConnectionStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.connection.v1.ConnectionEnd connection = 2; -} - -// ChannelStateData returns the SignBytes data for channel state -// verification. -message ChannelStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.channel.v1.Channel channel = 2; -} - -// PacketCommitmentData returns the SignBytes data for packet commitment -// verification. -message PacketCommitmentData { - bytes path = 1; - bytes commitment = 2; -} - -// PacketAcknowledgementData returns the SignBytes data for acknowledgement -// verification. -message PacketAcknowledgementData { - bytes path = 1; - bytes acknowledgement = 2; -} - -// PacketReceiptAbsenceData returns the SignBytes data for -// packet receipt absence verification. -message PacketReceiptAbsenceData { - bytes path = 1; -} - -// NextSequenceRecvData returns the SignBytes data for verification of the next -// sequence to be received. -message NextSequenceRecvData { - bytes path = 1; - uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; -} diff --git a/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto b/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto deleted file mode 100644 index c735fdddd..000000000 --- a/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto +++ /dev/null @@ -1,189 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.solomachine.v2; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types"; - -import "ibc/core/connection/v1/connection.proto"; -import "ibc/core/channel/v1/channel.proto"; -import "gogoproto/gogo.proto"; -import "google/protobuf/any.proto"; - -// ClientState defines a solo machine client that tracks the current consensus -// state and if the client is frozen. -message ClientState { - option (gogoproto.goproto_getters) = false; - // latest sequence of the client state - uint64 sequence = 1; - // frozen sequence of the solo machine - bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; - ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; - // when set to true, will allow governance to update a solo machine client. - // The client will be unfrozen if it is frozen. - bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; -} - -// ConsensusState defines a solo machine consensus state. The sequence of a -// consensus state is contained in the "height" key used in storing the -// consensus state. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - // public key of the solo machine - google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; - // diversifier allows the same public key to be re-used across different solo - // machine clients (potentially on different chains) without being considered - // misbehaviour. - string diversifier = 2; - uint64 timestamp = 3; -} - -// Header defines a solo machine consensus header -message Header { - option (gogoproto.goproto_getters) = false; - // sequence to update solo machine public key at - uint64 sequence = 1; - uint64 timestamp = 2; - bytes signature = 3; - google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; - string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} - -// Misbehaviour defines misbehaviour for a solo machine which consists -// of a sequence and two signatures over different messages at that sequence. -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; -} - -// SignatureAndData contains a signature and the data signed over to create that -// signature. -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - bytes signature = 1; - DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; - bytes data = 3; - uint64 timestamp = 4; -} - -// TimestampedSignatureData contains the signature data and the timestamp of the -// signature. -message TimestampedSignatureData { - option (gogoproto.goproto_getters) = false; - bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; - uint64 timestamp = 2; -} - -// SignBytes defines the signed bytes used for signature verification. -message SignBytes { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - uint64 timestamp = 2; - string diversifier = 3; - // type of the data used - DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; - // marshaled data - bytes data = 5; -} - -// DataType defines the type of solo machine proof being created. This is done -// to preserve uniqueness of different data sign byte encodings. -enum DataType { - option (gogoproto.goproto_enum_prefix) = false; - - // Default State - DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; - // Data type for client state verification - DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; - // Data type for consensus state verification - DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; - // Data type for connection state verification - DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; - // Data type for channel state verification - DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; - // Data type for packet commitment verification - DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; - // Data type for packet acknowledgement verification - DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; - // Data type for packet receipt absence verification - DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; - // Data type for next sequence recv verification - DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; - // Data type for header verification - DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; -} - -// HeaderData returns the SignBytes data for update verification. -message HeaderData { - option (gogoproto.goproto_getters) = false; - - // header public key - google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; - // header diversifier - string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} - -// ClientStateData returns the SignBytes data for client state verification. -message ClientStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; -} - -// ConsensusStateData returns the SignBytes data for consensus state -// verification. -message ConsensusStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; -} - -// ConnectionStateData returns the SignBytes data for connection state -// verification. -message ConnectionStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.connection.v1.ConnectionEnd connection = 2; -} - -// ChannelStateData returns the SignBytes data for channel state -// verification. -message ChannelStateData { - option (gogoproto.goproto_getters) = false; - - bytes path = 1; - ibc.core.channel.v1.Channel channel = 2; -} - -// PacketCommitmentData returns the SignBytes data for packet commitment -// verification. -message PacketCommitmentData { - bytes path = 1; - bytes commitment = 2; -} - -// PacketAcknowledgementData returns the SignBytes data for acknowledgement -// verification. -message PacketAcknowledgementData { - bytes path = 1; - bytes acknowledgement = 2; -} - -// PacketReceiptAbsenceData returns the SignBytes data for -// packet receipt absence verification. -message PacketReceiptAbsenceData { - bytes path = 1; -} - -// NextSequenceRecvData returns the SignBytes data for verification of the next -// sequence to be received. -message NextSequenceRecvData { - bytes path = 1; - uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; -} diff --git a/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto b/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto deleted file mode 100644 index 55a4e0690..000000000 --- a/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto +++ /dev/null @@ -1,114 +0,0 @@ -syntax = "proto3"; - -package ibc.lightclients.tendermint.v1; - -option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types"; - -import "tendermint/types/validator.proto"; -import "tendermint/types/types.proto"; -import "proofs.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/timestamp.proto"; -import "ibc/core/client/v1/client.proto"; -import "ibc/core/commitment/v1/commitment.proto"; -import "gogoproto/gogo.proto"; - -// ClientState from Tendermint tracks the current validator set, latest height, -// and a possible frozen height. -message ClientState { - option (gogoproto.goproto_getters) = false; - - string chain_id = 1; - Fraction trust_level = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trust_level\""]; - // duration of the period since the LastestTimestamp during which the - // submitted headers are valid for upgrade - google.protobuf.Duration trusting_period = 3 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"trusting_period\""]; - // duration of the staking unbonding period - google.protobuf.Duration unbonding_period = 4 [ - (gogoproto.nullable) = false, - (gogoproto.stdduration) = true, - (gogoproto.moretags) = "yaml:\"unbonding_period\"" - ]; - // defines how much new (untrusted) header's Time can drift into the future. - google.protobuf.Duration max_clock_drift = 5 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"max_clock_drift\""]; - // Block height when the client was frozen due to a misbehaviour - ibc.core.client.v1.Height frozen_height = 6 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"frozen_height\""]; - // Latest height the client was updated to - ibc.core.client.v1.Height latest_height = 7 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"latest_height\""]; - - // Proof specifications used in verifying counterparty state - repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; - - // Path at which next upgraded client will be committed. - // Each element corresponds to the key for a single CommitmentProof in the - // chained proof. NOTE: ClientState must stored under - // `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored - // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using - // the default upgrade module, upgrade_path should be []string{"upgrade", - // "upgradedIBCState"}` - repeated string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; - - // allow_update_after_expiry is deprecated - bool allow_update_after_expiry = 10 [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_expiry\""]; - // allow_update_after_misbehaviour is deprecated - bool allow_update_after_misbehaviour = 11 - [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_misbehaviour\""]; -} - -// ConsensusState defines the consensus state from Tendermint. -message ConsensusState { - option (gogoproto.goproto_getters) = false; - - // timestamp that corresponds to the block height in which the ConsensusState - // was stored. - google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - // commitment root (i.e app hash) - ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; - bytes next_validators_hash = 3 [ - (gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes", - (gogoproto.moretags) = "yaml:\"next_validators_hash\"" - ]; -} - -// Misbehaviour is a wrapper over two conflicting Headers -// that implements Misbehaviour interface expected by ICS-02 -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; - Header header_2 = 3 [(gogoproto.customname) = "Header2", (gogoproto.moretags) = "yaml:\"header_2\""]; -} - -// Header defines the Tendermint client consensus Header. -// It encapsulates all the information necessary to update from a trusted -// Tendermint ConsensusState. The inclusion of TrustedHeight and -// TrustedValidators allows this update to process correctly, so long as the -// ConsensusState for the TrustedHeight exists, this removes race conditions -// among relayers The SignedHeader and ValidatorSet are the new untrusted update -// fields for the client. The TrustedHeight is the height of a stored -// ConsensusState on the client that will be used to verify the new untrusted -// header. The Trusted ConsensusState must be within the unbonding period of -// current time in order to correctly verify, and the TrustedValidators must -// hash to TrustedConsensusState.NextValidatorsHash since that is the last -// trusted validator set at the TrustedHeight. -message Header { - .tendermint.types.SignedHeader signed_header = 1 - [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"signed_header\""]; - - .tendermint.types.ValidatorSet validator_set = 2 [(gogoproto.moretags) = "yaml:\"validator_set\""]; - ibc.core.client.v1.Height trusted_height = 3 - [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trusted_height\""]; - .tendermint.types.ValidatorSet trusted_validators = 4 [(gogoproto.moretags) = "yaml:\"trusted_validators\""]; -} - -// Fraction defines the protobuf message type for tmmath.Fraction that only -// supports positive values. -message Fraction { - uint64 numerator = 1; - uint64 denominator = 2; -} diff --git a/ampd/proto/third_party/proofs.proto b/ampd/proto/third_party/proofs.proto deleted file mode 100644 index 88b50c1b3..000000000 --- a/ampd/proto/third_party/proofs.proto +++ /dev/null @@ -1,234 +0,0 @@ -syntax = "proto3"; - -package ics23; -option go_package = "github.com/confio/ics23/go"; -enum HashOp { - // NO_HASH is the default if no data passed. Note this is an illegal argument some places. - NO_HASH = 0; - SHA256 = 1; - SHA512 = 2; - KECCAK = 3; - RIPEMD160 = 4; - BITCOIN = 5; // ripemd160(sha256(x)) - SHA512_256 = 6; -} - -/** -LengthOp defines how to process the key and value of the LeafOp -to include length information. After encoding the length with the given -algorithm, the length will be prepended to the key and value bytes. -(Each one with it's own encoded length) -*/ -enum LengthOp { - // NO_PREFIX don't include any length info - NO_PREFIX = 0; - // VAR_PROTO uses protobuf (and go-amino) varint encoding of the length - VAR_PROTO = 1; - // VAR_RLP uses rlp int encoding of the length - VAR_RLP = 2; - // FIXED32_BIG uses big-endian encoding of the length as a 32 bit integer - FIXED32_BIG = 3; - // FIXED32_LITTLE uses little-endian encoding of the length as a 32 bit integer - FIXED32_LITTLE = 4; - // FIXED64_BIG uses big-endian encoding of the length as a 64 bit integer - FIXED64_BIG = 5; - // FIXED64_LITTLE uses little-endian encoding of the length as a 64 bit integer - FIXED64_LITTLE = 6; - // REQUIRE_32_BYTES is like NONE, but will fail if the input is not exactly 32 bytes (sha256 output) - REQUIRE_32_BYTES = 7; - // REQUIRE_64_BYTES is like NONE, but will fail if the input is not exactly 64 bytes (sha512 output) - REQUIRE_64_BYTES = 8; -} - -/** -ExistenceProof takes a key and a value and a set of steps to perform on it. -The result of peforming all these steps will provide a "root hash", which can -be compared to the value in a header. - -Since it is computationally infeasible to produce a hash collission for any of the used -cryptographic hash functions, if someone can provide a series of operations to transform -a given key and value into a root hash that matches some trusted root, these key and values -must be in the referenced merkle tree. - -The only possible issue is maliablity in LeafOp, such as providing extra prefix data, -which should be controlled by a spec. Eg. with lengthOp as NONE, - prefix = FOO, key = BAR, value = CHOICE -and - prefix = F, key = OOBAR, value = CHOICE -would produce the same value. - -With LengthOp this is tricker but not impossible. Which is why the "leafPrefixEqual" field -in the ProofSpec is valuable to prevent this mutability. And why all trees should -length-prefix the data before hashing it. -*/ -message ExistenceProof { - bytes key = 1; - bytes value = 2; - LeafOp leaf = 3; - repeated InnerOp path = 4; -} - -/* -NonExistenceProof takes a proof of two neighbors, one left of the desired key, -one right of the desired key. If both proofs are valid AND they are neighbors, -then there is no valid proof for the given key. -*/ -message NonExistenceProof { - bytes key = 1; // TODO: remove this as unnecessary??? we prove a range - ExistenceProof left = 2; - ExistenceProof right = 3; -} - -/* -CommitmentProof is either an ExistenceProof or a NonExistenceProof, or a Batch of such messages -*/ -message CommitmentProof { - oneof proof { - ExistenceProof exist = 1; - NonExistenceProof nonexist = 2; - BatchProof batch = 3; - CompressedBatchProof compressed = 4; - } -} - -/** -LeafOp represents the raw key-value data we wish to prove, and -must be flexible to represent the internal transformation from -the original key-value pairs into the basis hash, for many existing -merkle trees. - -key and value are passed in. So that the signature of this operation is: - leafOp(key, value) -> output - -To process this, first prehash the keys and values if needed (ANY means no hash in this case): - hkey = prehashKey(key) - hvalue = prehashValue(value) - -Then combine the bytes, and hash it - output = hash(prefix || length(hkey) || hkey || length(hvalue) || hvalue) -*/ -message LeafOp { - HashOp hash = 1; - HashOp prehash_key = 2; - HashOp prehash_value = 3; - LengthOp length = 4; - // prefix is a fixed bytes that may optionally be included at the beginning to differentiate - // a leaf node from an inner node. - bytes prefix = 5; -} - -/** -InnerOp represents a merkle-proof step that is not a leaf. -It represents concatenating two children and hashing them to provide the next result. - -The result of the previous step is passed in, so the signature of this op is: - innerOp(child) -> output - -The result of applying InnerOp should be: - output = op.hash(op.prefix || child || op.suffix) - - where the || operator is concatenation of binary data, -and child is the result of hashing all the tree below this step. - -Any special data, like prepending child with the length, or prepending the entire operation with -some value to differentiate from leaf nodes, should be included in prefix and suffix. -If either of prefix or suffix is empty, we just treat it as an empty string -*/ -message InnerOp { - HashOp hash = 1; - bytes prefix = 2; - bytes suffix = 3; -} - - -/** -ProofSpec defines what the expected parameters are for a given proof type. -This can be stored in the client and used to validate any incoming proofs. - - verify(ProofSpec, Proof) -> Proof | Error - -As demonstrated in tests, if we don't fix the algorithm used to calculate the -LeafHash for a given tree, there are many possible key-value pairs that can -generate a given hash (by interpretting the preimage differently). -We need this for proper security, requires client knows a priori what -tree format server uses. But not in code, rather a configuration object. -*/ -message ProofSpec { - // any field in the ExistenceProof must be the same as in this spec. - // except Prefix, which is just the first bytes of prefix (spec can be longer) - LeafOp leaf_spec = 1; - InnerSpec inner_spec = 2; - // max_depth (if > 0) is the maximum number of InnerOps allowed (mainly for fixed-depth tries) - int32 max_depth = 3; - // min_depth (if > 0) is the minimum number of InnerOps allowed (mainly for fixed-depth tries) - int32 min_depth = 4; -} - -/* -InnerSpec contains all store-specific structure info to determine if two proofs from a -given store are neighbors. - -This enables: - - isLeftMost(spec: InnerSpec, op: InnerOp) - isRightMost(spec: InnerSpec, op: InnerOp) - isLeftNeighbor(spec: InnerSpec, left: InnerOp, right: InnerOp) -*/ -message InnerSpec { - // Child order is the ordering of the children node, must count from 0 - // iavl tree is [0, 1] (left then right) - // merk is [0, 2, 1] (left, right, here) - repeated int32 child_order = 1; - int32 child_size = 2; - int32 min_prefix_length = 3; - int32 max_prefix_length = 4; - // empty child is the prehash image that is used when one child is nil (eg. 20 bytes of 0) - bytes empty_child = 5; - // hash is the algorithm that must be used for each InnerOp - HashOp hash = 6; -} - -/* -BatchProof is a group of multiple proof types than can be compressed -*/ -message BatchProof { - repeated BatchEntry entries = 1; -} - -// Use BatchEntry not CommitmentProof, to avoid recursion -message BatchEntry { - oneof proof { - ExistenceProof exist = 1; - NonExistenceProof nonexist = 2; - } -} - - -/****** all items here are compressed forms *******/ - -message CompressedBatchProof { - repeated CompressedBatchEntry entries = 1; - repeated InnerOp lookup_inners = 2; -} - -// Use BatchEntry not CommitmentProof, to avoid recursion -message CompressedBatchEntry { - oneof proof { - CompressedExistenceProof exist = 1; - CompressedNonExistenceProof nonexist = 2; - } -} - -message CompressedExistenceProof { - bytes key = 1; - bytes value = 2; - LeafOp leaf = 3; - // these are indexes into the lookup_inners table in CompressedBatchProof - repeated int32 path = 4; -} - -message CompressedNonExistenceProof { - bytes key = 1; // TODO: remove this as unnecessary??? we prove a range - CompressedExistenceProof left = 2; - CompressedExistenceProof right = 3; -} diff --git a/ampd/proto/third_party/tendermint/abci/types.proto b/ampd/proto/third_party/tendermint/abci/types.proto deleted file mode 100644 index 44f861129..000000000 --- a/ampd/proto/third_party/tendermint/abci/types.proto +++ /dev/null @@ -1,413 +0,0 @@ -syntax = "proto3"; -package tendermint.abci; - -option go_package = "github.com/tendermint/tendermint/abci/types"; - -// For more information on gogo.proto, see: -// https://github.com/gogo/protobuf/blob/master/extensions.md -import "tendermint/crypto/proof.proto"; -import "tendermint/types/types.proto"; -import "tendermint/crypto/keys.proto"; -import "tendermint/types/params.proto"; -import "google/protobuf/timestamp.proto"; -import "gogoproto/gogo.proto"; - -// This file is copied from http://github.com/tendermint/abci -// NOTE: When using custom types, mind the warnings. -// https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues - -//---------------------------------------- -// Request types - -message Request { - oneof value { - RequestEcho echo = 1; - RequestFlush flush = 2; - RequestInfo info = 3; - RequestSetOption set_option = 4; - RequestInitChain init_chain = 5; - RequestQuery query = 6; - RequestBeginBlock begin_block = 7; - RequestCheckTx check_tx = 8; - RequestDeliverTx deliver_tx = 9; - RequestEndBlock end_block = 10; - RequestCommit commit = 11; - RequestListSnapshots list_snapshots = 12; - RequestOfferSnapshot offer_snapshot = 13; - RequestLoadSnapshotChunk load_snapshot_chunk = 14; - RequestApplySnapshotChunk apply_snapshot_chunk = 15; - } -} - -message RequestEcho { - string message = 1; -} - -message RequestFlush {} - -message RequestInfo { - string version = 1; - uint64 block_version = 2; - uint64 p2p_version = 3; -} - -// nondeterministic -message RequestSetOption { - string key = 1; - string value = 2; -} - -message RequestInitChain { - google.protobuf.Timestamp time = 1 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - string chain_id = 2; - ConsensusParams consensus_params = 3; - repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false]; - bytes app_state_bytes = 5; - int64 initial_height = 6; -} - -message RequestQuery { - bytes data = 1; - string path = 2; - int64 height = 3; - bool prove = 4; -} - -message RequestBeginBlock { - bytes hash = 1; - tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; - LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; - repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; -} - -enum CheckTxType { - NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; - RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; -} - -message RequestCheckTx { - bytes tx = 1; - CheckTxType type = 2; -} - -message RequestDeliverTx { - bytes tx = 1; -} - -message RequestEndBlock { - int64 height = 1; -} - -message RequestCommit {} - -// lists available snapshots -message RequestListSnapshots {} - -// offers a snapshot to the application -message RequestOfferSnapshot { - Snapshot snapshot = 1; // snapshot offered by peers - bytes app_hash = 2; // light client-verified app hash for snapshot height -} - -// loads a snapshot chunk -message RequestLoadSnapshotChunk { - uint64 height = 1; - uint32 format = 2; - uint32 chunk = 3; -} - -// Applies a snapshot chunk -message RequestApplySnapshotChunk { - uint32 index = 1; - bytes chunk = 2; - string sender = 3; -} - -//---------------------------------------- -// Response types - -message Response { - oneof value { - ResponseException exception = 1; - ResponseEcho echo = 2; - ResponseFlush flush = 3; - ResponseInfo info = 4; - ResponseSetOption set_option = 5; - ResponseInitChain init_chain = 6; - ResponseQuery query = 7; - ResponseBeginBlock begin_block = 8; - ResponseCheckTx check_tx = 9; - ResponseDeliverTx deliver_tx = 10; - ResponseEndBlock end_block = 11; - ResponseCommit commit = 12; - ResponseListSnapshots list_snapshots = 13; - ResponseOfferSnapshot offer_snapshot = 14; - ResponseLoadSnapshotChunk load_snapshot_chunk = 15; - ResponseApplySnapshotChunk apply_snapshot_chunk = 16; - } -} - -// nondeterministic -message ResponseException { - string error = 1; -} - -message ResponseEcho { - string message = 1; -} - -message ResponseFlush {} - -message ResponseInfo { - string data = 1; - - string version = 2; - uint64 app_version = 3; - - int64 last_block_height = 4; - bytes last_block_app_hash = 5; -} - -// nondeterministic -message ResponseSetOption { - uint32 code = 1; - // bytes data = 2; - string log = 3; - string info = 4; -} - -message ResponseInitChain { - ConsensusParams consensus_params = 1; - repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false]; - bytes app_hash = 3; -} - -message ResponseQuery { - uint32 code = 1; - // bytes data = 2; // use "value" instead. - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 index = 5; - bytes key = 6; - bytes value = 7; - tendermint.crypto.ProofOps proof_ops = 8; - int64 height = 9; - string codespace = 10; -} - -message ResponseBeginBlock { - repeated Event events = 1 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCheckTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; - string codespace = 8; - string sender = 9; - int64 priority = 10; - - // mempool_error is set by CometBFT. - // ABCI applictions creating a ResponseCheckTX should not set mempool_error. - string mempool_error = 11; -} - -message ResponseDeliverTx { - uint32 code = 1; - bytes data = 2; - string log = 3; // nondeterministic - string info = 4; // nondeterministic - int64 gas_wanted = 5 [json_name = "gas_wanted"]; - int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "events,omitempty" - ]; // nondeterministic - string codespace = 8; -} - -message ResponseEndBlock { - repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; - ConsensusParams consensus_param_updates = 2; - repeated Event events = 3 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; -} - -message ResponseCommit { - // reserve 1 - bytes data = 2; - int64 retain_height = 3; -} - -message ResponseListSnapshots { - repeated Snapshot snapshots = 1; -} - -message ResponseOfferSnapshot { - Result result = 1; - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Snapshot accepted, apply chunks - ABORT = 2; // Abort all snapshot restoration - REJECT = 3; // Reject this specific snapshot, try others - REJECT_FORMAT = 4; // Reject all snapshots of this format, try others - REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others - } -} - -message ResponseLoadSnapshotChunk { - bytes chunk = 1; -} - -message ResponseApplySnapshotChunk { - Result result = 1; - repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply - repeated string reject_senders = 3; // Chunk senders to reject and ban - - enum Result { - UNKNOWN = 0; // Unknown result, abort all snapshot restoration - ACCEPT = 1; // Chunk successfully accepted - ABORT = 2; // Abort all snapshot restoration - RETRY = 3; // Retry chunk (combine with refetch and reject) - RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject) - REJECT_SNAPSHOT = 5; // Reject this snapshot, try others - } -} - -//---------------------------------------- -// Misc. - -// ConsensusParams contains all consensus-relevant parameters -// that can be adjusted by the abci app -message ConsensusParams { - BlockParams block = 1; - tendermint.types.EvidenceParams evidence = 2; - tendermint.types.ValidatorParams validator = 3; - tendermint.types.VersionParams version = 4; -} - -// BlockParams contains limits on the block size. -message BlockParams { - // Note: must be greater than 0 - int64 max_bytes = 1; - // Note: must be greater or equal to -1 - int64 max_gas = 2; -} - -message LastCommitInfo { - int32 round = 1; - repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; -} - -// Event allows application developers to attach additional information to -// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. -// Later, transactions may be queried using these events. -message Event { - string type = 1; - repeated EventAttribute attributes = 2 [ - (gogoproto.nullable) = false, - (gogoproto.jsontag) = "attributes,omitempty" - ]; -} - -// EventAttribute is a single key-value pair, associated with an event. -message EventAttribute { - bytes key = 1; - bytes value = 2; - bool index = 3; // nondeterministic -} - -// TxResult contains results of executing the transaction. -// -// One usage is indexing transaction results. -message TxResult { - int64 height = 1; - uint32 index = 2; - bytes tx = 3; - ResponseDeliverTx result = 4 [(gogoproto.nullable) = false]; -} - -//---------------------------------------- -// Blockchain Types - -// Validator -message Validator { - bytes address = 1; // The first 20 bytes of SHA256(public key) - // PubKey pub_key = 2 [(gogoproto.nullable)=false]; - int64 power = 3; // The voting power -} - -// ValidatorUpdate -message ValidatorUpdate { - tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; - int64 power = 2; -} - -// VoteInfo -message VoteInfo { - Validator validator = 1 [(gogoproto.nullable) = false]; - bool signed_last_block = 2; -} - -enum EvidenceType { - UNKNOWN = 0; - DUPLICATE_VOTE = 1; - LIGHT_CLIENT_ATTACK = 2; -} - -message Evidence { - EvidenceType type = 1; - // The offending validator - Validator validator = 2 [(gogoproto.nullable) = false]; - // The height when the offense occurred - int64 height = 3; - // The corresponding time where the offense occurred - google.protobuf.Timestamp time = 4 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - // Total voting power of the validator set in case the ABCI application does - // not store historical validators. - // https://github.com/tendermint/tendermint/issues/4581 - int64 total_voting_power = 5; -} - -//---------------------------------------- -// State Sync Types - -message Snapshot { - uint64 height = 1; // The height at which the snapshot was taken - uint32 format = 2; // The application-specific snapshot format - uint32 chunks = 3; // Number of chunks in the snapshot - bytes hash = 4; // Arbitrary snapshot hash, equal only if identical - bytes metadata = 5; // Arbitrary application metadata -} - -//---------------------------------------- -// Service Definition - -service ABCIApplication { - rpc Echo(RequestEcho) returns (ResponseEcho); - rpc Flush(RequestFlush) returns (ResponseFlush); - rpc Info(RequestInfo) returns (ResponseInfo); - rpc SetOption(RequestSetOption) returns (ResponseSetOption); - rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); - rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); - rpc Query(RequestQuery) returns (ResponseQuery); - rpc Commit(RequestCommit) returns (ResponseCommit); - rpc InitChain(RequestInitChain) returns (ResponseInitChain); - rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); - rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); - rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); - rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); - rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) - returns (ResponseLoadSnapshotChunk); - rpc ApplySnapshotChunk(RequestApplySnapshotChunk) - returns (ResponseApplySnapshotChunk); -} diff --git a/ampd/proto/third_party/tendermint/crypto/keys.proto b/ampd/proto/third_party/tendermint/crypto/keys.proto deleted file mode 100644 index 5b94ddaec..000000000 --- a/ampd/proto/third_party/tendermint/crypto/keys.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -// PublicKey defines the keys available for use with Validators -message PublicKey { - option (gogoproto.compare) = true; - option (gogoproto.equal) = true; - - oneof sum { - bytes ed25519 = 1; - bytes secp256k1 = 2; - } -} diff --git a/ampd/proto/third_party/tendermint/crypto/proof.proto b/ampd/proto/third_party/tendermint/crypto/proof.proto deleted file mode 100644 index 975df7685..000000000 --- a/ampd/proto/third_party/tendermint/crypto/proof.proto +++ /dev/null @@ -1,41 +0,0 @@ -syntax = "proto3"; -package tendermint.crypto; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; - -import "gogoproto/gogo.proto"; - -message Proof { - int64 total = 1; - int64 index = 2; - bytes leaf_hash = 3; - repeated bytes aunts = 4; -} - -message ValueOp { - // Encoded in ProofOp.Key. - bytes key = 1; - - // To encode in ProofOp.Data - Proof proof = 2; -} - -message DominoOp { - string key = 1; - string input = 2; - string output = 3; -} - -// ProofOp defines an operation used for calculating Merkle root -// The data could be arbitrary format, providing nessecary data -// for example neighbouring node hash -message ProofOp { - string type = 1; - bytes key = 2; - bytes data = 3; -} - -// ProofOps is Merkle proof defined by the list of ProofOps -message ProofOps { - repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/tendermint/libs/bits/types.proto b/ampd/proto/third_party/tendermint/libs/bits/types.proto deleted file mode 100644 index 3111d113a..000000000 --- a/ampd/proto/third_party/tendermint/libs/bits/types.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; -package tendermint.libs.bits; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits"; - -message BitArray { - int64 bits = 1; - repeated uint64 elems = 2; -} diff --git a/ampd/proto/third_party/tendermint/p2p/types.proto b/ampd/proto/third_party/tendermint/p2p/types.proto deleted file mode 100644 index 0d42ea400..000000000 --- a/ampd/proto/third_party/tendermint/p2p/types.proto +++ /dev/null @@ -1,34 +0,0 @@ -syntax = "proto3"; -package tendermint.p2p; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; - -import "gogoproto/gogo.proto"; - -message NetAddress { - string id = 1 [(gogoproto.customname) = "ID"]; - string ip = 2 [(gogoproto.customname) = "IP"]; - uint32 port = 3; -} - -message ProtocolVersion { - uint64 p2p = 1 [(gogoproto.customname) = "P2P"]; - uint64 block = 2; - uint64 app = 3; -} - -message DefaultNodeInfo { - ProtocolVersion protocol_version = 1 [(gogoproto.nullable) = false]; - string default_node_id = 2 [(gogoproto.customname) = "DefaultNodeID"]; - string listen_addr = 3; - string network = 4; - string version = 5; - bytes channels = 6; - string moniker = 7; - DefaultNodeInfoOther other = 8 [(gogoproto.nullable) = false]; -} - -message DefaultNodeInfoOther { - string tx_index = 1; - string rpc_address = 2 [(gogoproto.customname) = "RPCAddress"]; -} diff --git a/ampd/proto/third_party/tendermint/types/block.proto b/ampd/proto/third_party/tendermint/types/block.proto deleted file mode 100644 index 84e9bb15d..000000000 --- a/ampd/proto/third_party/tendermint/types/block.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "tendermint/types/types.proto"; -import "tendermint/types/evidence.proto"; - -message Block { - Header header = 1 [(gogoproto.nullable) = false]; - Data data = 2 [(gogoproto.nullable) = false]; - tendermint.types.EvidenceList evidence = 3 [(gogoproto.nullable) = false]; - Commit last_commit = 4; -} diff --git a/ampd/proto/third_party/tendermint/types/evidence.proto b/ampd/proto/third_party/tendermint/types/evidence.proto deleted file mode 100644 index 451b8dca3..000000000 --- a/ampd/proto/third_party/tendermint/types/evidence.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/types/types.proto"; -import "tendermint/types/validator.proto"; - -message Evidence { - oneof sum { - DuplicateVoteEvidence duplicate_vote_evidence = 1; - LightClientAttackEvidence light_client_attack_evidence = 2; - } -} - -// DuplicateVoteEvidence contains evidence of a validator signed two conflicting votes. -message DuplicateVoteEvidence { - tendermint.types.Vote vote_a = 1; - tendermint.types.Vote vote_b = 2; - int64 total_voting_power = 3; - int64 validator_power = 4; - google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; -} - -// LightClientAttackEvidence contains evidence of a set of validators attempting to mislead a light client. -message LightClientAttackEvidence { - tendermint.types.LightBlock conflicting_block = 1; - int64 common_height = 2; - repeated tendermint.types.Validator byzantine_validators = 3; - int64 total_voting_power = 4; - google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; -} - -message EvidenceList { - repeated Evidence evidence = 1 [(gogoproto.nullable) = false]; -} diff --git a/ampd/proto/third_party/tendermint/types/params.proto b/ampd/proto/third_party/tendermint/types/params.proto deleted file mode 100644 index 0de7d846f..000000000 --- a/ampd/proto/third_party/tendermint/types/params.proto +++ /dev/null @@ -1,80 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/duration.proto"; - -option (gogoproto.equal_all) = true; - -// ConsensusParams contains consensus critical parameters that determine the -// validity of blocks. -message ConsensusParams { - BlockParams block = 1 [(gogoproto.nullable) = false]; - EvidenceParams evidence = 2 [(gogoproto.nullable) = false]; - ValidatorParams validator = 3 [(gogoproto.nullable) = false]; - VersionParams version = 4 [(gogoproto.nullable) = false]; -} - -// BlockParams contains limits on the block size. -message BlockParams { - // Max block size, in bytes. - // Note: must be greater than 0 - int64 max_bytes = 1; - // Max gas per block. - // Note: must be greater or equal to -1 - int64 max_gas = 2; - // Minimum time increment between consecutive blocks (in milliseconds) If the - // block header timestamp is ahead of the system clock, decrease this value. - // - // Not exposed to the application. - int64 time_iota_ms = 3; -} - -// EvidenceParams determine how we handle evidence of malfeasance. -message EvidenceParams { - // Max age of evidence, in blocks. - // - // The basic formula for calculating this is: MaxAgeDuration / {average block - // time}. - int64 max_age_num_blocks = 1; - - // Max age of evidence, in time. - // - // It should correspond with an app's "unbonding period" or other similar - // mechanism for handling [Nothing-At-Stake - // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). - google.protobuf.Duration max_age_duration = 2 - [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; - - // This sets the maximum size of total evidence in bytes that can be committed in a single block. - // and should fall comfortably under the max block bytes. - // Default is 1048576 or 1MB - int64 max_bytes = 3; -} - -// ValidatorParams restrict the public key types validators can use. -// NOTE: uses ABCI pubkey naming, not Amino names. -message ValidatorParams { - option (gogoproto.populate) = true; - option (gogoproto.equal) = true; - - repeated string pub_key_types = 1; -} - -// VersionParams contains the ABCI application version. -message VersionParams { - option (gogoproto.populate) = true; - option (gogoproto.equal) = true; - - uint64 app_version = 1; -} - -// HashedParams is a subset of ConsensusParams. -// -// It is hashed into the Header.ConsensusHash. -message HashedParams { - int64 block_max_bytes = 1; - int64 block_max_gas = 2; -} diff --git a/ampd/proto/third_party/tendermint/types/types.proto b/ampd/proto/third_party/tendermint/types/types.proto deleted file mode 100644 index 3ce169459..000000000 --- a/ampd/proto/third_party/tendermint/types/types.proto +++ /dev/null @@ -1,157 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/crypto/proof.proto"; -import "tendermint/version/types.proto"; -import "tendermint/types/validator.proto"; - -// BlockIdFlag indicates which BlcokID the signature is for -enum BlockIDFlag { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; - BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; - BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; - BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; -} - -// SignedMsgType is a type of signed message in the consensus. -enum SignedMsgType { - option (gogoproto.goproto_enum_stringer) = true; - option (gogoproto.goproto_enum_prefix) = false; - - SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"]; - // Votes - SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"]; - SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"]; - - // Proposals - SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"]; -} - -// PartsetHeader -message PartSetHeader { - uint32 total = 1; - bytes hash = 2; -} - -message Part { - uint32 index = 1; - bytes bytes = 2; - tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; -} - -// BlockID -message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; -} - -// -------------------------------- - -// Header defines the structure of a block header. -message Header { - // basic block info - tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; - string chain_id = 2 [(gogoproto.customname) = "ChainID"]; - int64 height = 3; - google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - - // prev block info - BlockID last_block_id = 5 [(gogoproto.nullable) = false]; - - // hashes of block data - bytes last_commit_hash = 6; // commit from validators from the last block - bytes data_hash = 7; // transactions - - // hashes from the app output from the prev block - bytes validators_hash = 8; // validators for the current block - bytes next_validators_hash = 9; // validators for the next block - bytes consensus_hash = 10; // consensus params for current block - bytes app_hash = 11; // state after txs from the previous block - bytes last_results_hash = 12; // root hash of all results from the txs from the previous block - - // consensus info - bytes evidence_hash = 13; // evidence included in the block - bytes proposer_address = 14; // original proposer of the block -} - -// Data contains the set of transactions included in the block -message Data { - // Txs that will be applied by state @ block.Height+1. - // NOTE: not all txs here are valid. We're just agreeing on the order first. - // This means that block.AppHash does not include these txs. - repeated bytes txs = 1; -} - -// Vote represents a prevote, precommit, or commit vote from validators for -// consensus. -message Vote { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - BlockID block_id = 4 - [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil. - google.protobuf.Timestamp timestamp = 5 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes validator_address = 6; - int32 validator_index = 7; - bytes signature = 8; -} - -// Commit contains the evidence that a block was committed by a set of validators. -message Commit { - int64 height = 1; - int32 round = 2; - BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; - repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; -} - -// CommitSig is a part of the Vote included in a Commit. -message CommitSig { - BlockIDFlag block_id_flag = 1; - bytes validator_address = 2; - google.protobuf.Timestamp timestamp = 3 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 4; -} - -message Proposal { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - int32 pol_round = 4; - BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - google.protobuf.Timestamp timestamp = 6 - [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; - bytes signature = 7; -} - -message SignedHeader { - Header header = 1; - Commit commit = 2; -} - -message LightBlock { - SignedHeader signed_header = 1; - tendermint.types.ValidatorSet validator_set = 2; -} - -message BlockMeta { - BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; - int64 block_size = 2; - Header header = 3 [(gogoproto.nullable) = false]; - int64 num_txs = 4; -} - -// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree. -message TxProof { - bytes root_hash = 1; - bytes data = 2; - tendermint.crypto.Proof proof = 3; -} diff --git a/ampd/proto/third_party/tendermint/types/validator.proto b/ampd/proto/third_party/tendermint/types/validator.proto deleted file mode 100644 index 49860b96d..000000000 --- a/ampd/proto/third_party/tendermint/types/validator.proto +++ /dev/null @@ -1,25 +0,0 @@ -syntax = "proto3"; -package tendermint.types; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; - -import "gogoproto/gogo.proto"; -import "tendermint/crypto/keys.proto"; - -message ValidatorSet { - repeated Validator validators = 1; - Validator proposer = 2; - int64 total_voting_power = 3; -} - -message Validator { - bytes address = 1; - tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; - int64 voting_power = 3; - int64 proposer_priority = 4; -} - -message SimpleValidator { - tendermint.crypto.PublicKey pub_key = 1; - int64 voting_power = 2; -} diff --git a/ampd/proto/third_party/tendermint/version/types.proto b/ampd/proto/third_party/tendermint/version/types.proto deleted file mode 100644 index 6061868bd..000000000 --- a/ampd/proto/third_party/tendermint/version/types.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; -package tendermint.version; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; - -import "gogoproto/gogo.proto"; - -// App includes the protocol and software version for the application. -// This information is included in ResponseInfo. The App.Protocol can be -// updated in ResponseEndBlock. -message App { - uint64 protocol = 1; - string software = 2; -} - -// Consensus captures the consensus rules for processing a block in the blockchain, -// including all blockchain data structures and the rules of the application's -// state transition machine. -message Consensus { - option (gogoproto.equal) = true; - - uint64 block = 1; - uint64 app = 2; -} diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs deleted file mode 100644 index c9770ec97..000000000 --- a/ampd/src/broadcaster/confirm_tx.rs +++ /dev/null @@ -1,352 +0,0 @@ -use std::time::Duration; - -use axelar_wasm_std::FnExt; -use cosmrs::proto::cosmos::tx::v1beta1::{GetTxRequest, GetTxResponse}; -use error_stack::{report, Report, Result}; -use futures::{StreamExt, TryFutureExt}; -use thiserror::Error; -use tokio::sync::{mpsc, Mutex}; -use tokio::time; -use tokio_stream::wrappers::ReceiverStream; -use tonic::Status; -use tracing::error; - -use super::cosmos; - -#[derive(Debug, PartialEq)] -pub enum TxStatus { - Success, - Failure, -} - -impl From for TxStatus { - fn from(code: u32) -> Self { - match code { - 0 => Self::Success, - _ => Self::Failure, - } - } -} - -#[derive(Debug, PartialEq)] -pub struct TxResponse { - pub status: TxStatus, - pub response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse, -} - -impl From for TxResponse { - fn from(response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse) -> Self { - Self { - status: response.code.into(), - response, - } - } -} - -#[derive(Error, Debug)] -pub enum Error { - #[error("failed confirming tx due to tx not found: {tx_hash}")] - Confirmation { tx_hash: String }, - #[error("failed confirming tx due to grpc error {status}: {tx_hash}")] - Grpc { status: Status, tx_hash: String }, - #[error("failed sending tx response")] - SendTxRes(#[from] Box>), -} - -enum ConfirmationResult { - Confirmed(Box), - NotFound, - GRPCError(Status), -} - -pub struct TxConfirmer -where - T: cosmos::BroadcastClient, -{ - client: T, - sleep: Duration, - max_attempts: u32, - tx_hash_receiver: mpsc::Receiver, - tx_res_sender: mpsc::Sender, -} - -impl TxConfirmer -where - T: cosmos::BroadcastClient, -{ - pub fn new( - client: T, - sleep: Duration, - max_attempts: u32, - tx_hash_receiver: mpsc::Receiver, - tx_res_sender: mpsc::Sender, - ) -> Self { - Self { - client, - sleep, - max_attempts, - tx_hash_receiver, - tx_res_sender, - } - } - - pub async fn run(self) -> Result<(), Error> { - let Self { - client, - sleep, - max_attempts, - tx_hash_receiver, - tx_res_sender, - } = self; - let limit = tx_hash_receiver.capacity(); - let client = Mutex::new(client); - let mut tx_hash_stream = ReceiverStream::new(tx_hash_receiver) - .map(|tx_hash| { - confirm_tx(&client, tx_hash, sleep, max_attempts).and_then(|tx| async { - tx_res_sender - .send(tx) - .await - .map_err(Box::new) - .map_err(Into::into) - .map_err(Report::new) - }) - }) - .buffer_unordered(limit); - - while let Some(res) = tx_hash_stream.next().await { - res?; - } - - Ok(()) - } -} - -async fn confirm_tx( - client: &Mutex, - tx_hash: String, - sleep: Duration, - attempts: u32, -) -> Result -where - T: cosmos::BroadcastClient, -{ - for i in 0..attempts { - let req = GetTxRequest { - hash: tx_hash.clone(), - }; - - match client - .lock() - .await - .get_tx(req) - .await - .then(evaluate_tx_response) - { - ConfirmationResult::Confirmed(tx) => return Ok(*tx), - ConfirmationResult::NotFound if i == attempts.saturating_sub(1) => { - return Err(report!(Error::Confirmation { tx_hash })) - } - ConfirmationResult::GRPCError(status) if i == attempts.saturating_sub(1) => { - return Err(report!(Error::Grpc { status, tx_hash })) - } - _ => time::sleep(sleep).await, - } - } - - unreachable!("confirmation loop should have returned by now") -} - -fn evaluate_tx_response( - response: core::result::Result, -) -> ConfirmationResult { - match response { - Err(status) => ConfirmationResult::GRPCError(status), - Ok(GetTxResponse { - tx_response: None, .. - }) => ConfirmationResult::NotFound, - Ok(GetTxResponse { - tx_response: Some(response), - .. - }) => ConfirmationResult::Confirmed(Box::new(response.into())), - } -} - -#[cfg(test)] -mod test { - use std::time::Duration; - - use cosmrs::proto::cosmos::tx::v1beta1::GetTxRequest; - use mockall::predicate; - use tokio::sync::mpsc; - use tokio::test; - - use super::{Error, TxConfirmer, TxResponse, TxStatus}; - use crate::broadcaster::cosmos::MockBroadcastClient; - - #[test] - async fn should_confirm_successful_tx_and_send_it_back() { - let tx_hash = "tx_hash".to_string(); - let tx_response = cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse { - code: 0, - txhash: tx_hash.clone(), - ..Default::default() - }; - let tx_res = cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse { - tx_response: Some(tx_response.clone()), - ..Default::default() - }; - - let mut client = MockBroadcastClient::new(); - client - .expect_get_tx() - .with(predicate::eq(GetTxRequest { - hash: tx_hash.clone(), - })) - .return_once(|_| Ok(tx_res)); - - let sleep = Duration::from_secs(5); - let max_attempts = 3; - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); - let (tx_res_sender, mut tx_res_receiver) = mpsc::channel(100); - - let tx_confirmer = TxConfirmer::new( - client, - sleep, - max_attempts, - tx_confirmer_receiver, - tx_res_sender, - ); - let handle = tokio::spawn(tx_confirmer.run()); - - tx_confirmer_sender.send(tx_hash).await.unwrap(); - assert_eq!( - tx_res_receiver.recv().await.unwrap(), - TxResponse { - status: TxStatus::Success, - response: tx_response - } - ); - drop(tx_confirmer_sender); - assert!(handle.await.unwrap().is_ok()); - } - - #[test] - async fn should_confirm_failed_tx_and_send_it_back() { - let tx_hash = "tx_hash".to_string(); - let tx_response = cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse { - code: 1, - txhash: tx_hash.clone(), - ..Default::default() - }; - let tx_res = cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse { - tx_response: Some(tx_response.clone()), - ..Default::default() - }; - - let mut client = MockBroadcastClient::new(); - client - .expect_get_tx() - .with(predicate::eq(GetTxRequest { - hash: tx_hash.clone(), - })) - .return_once(|_| Ok(tx_res)); - - let sleep = Duration::from_secs(5); - let max_attempts = 3; - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); - let (tx_res_sender, mut tx_res_receiver) = mpsc::channel(100); - - let tx_confirmer = TxConfirmer::new( - client, - sleep, - max_attempts, - tx_confirmer_receiver, - tx_res_sender, - ); - let handle = tokio::spawn(tx_confirmer.run()); - - tx_confirmer_sender.send(tx_hash).await.unwrap(); - assert_eq!( - tx_res_receiver.recv().await.unwrap(), - TxResponse { - status: TxStatus::Failure, - response: tx_response - } - ); - drop(tx_confirmer_sender); - assert!(handle.await.unwrap().is_ok()); - } - - #[test] - async fn should_retry_when_tx_is_not_found() { - let tx_hash = "tx_hash".to_string(); - - let mut client = MockBroadcastClient::new(); - client - .expect_get_tx() - .with(predicate::eq(GetTxRequest { - hash: tx_hash.clone(), - })) - .times(3) - .returning(|_| Ok(cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse::default())); - - let sleep = Duration::from_millis(100); - let max_attempts = 3; - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); - let (tx_res_sender, _tx_res_receiver) = mpsc::channel(100); - - let tx_confirmer = TxConfirmer::new( - client, - sleep, - max_attempts, - tx_confirmer_receiver, - tx_res_sender, - ); - let handle = tokio::spawn(tx_confirmer.run()); - - tx_confirmer_sender.send(tx_hash.clone()).await.unwrap(); - assert!(matches!( - handle.await.unwrap().unwrap_err().current_context(), - Error::Confirmation { tx_hash: actual } if *actual == tx_hash - )); - } - - #[test] - async fn should_retry_when_grpc_error() { - let tx_hash = "tx_hash".to_string(); - - let mut client = MockBroadcastClient::new(); - client - .expect_get_tx() - .with(predicate::eq(GetTxRequest { - hash: tx_hash.clone(), - })) - .times(3) - .returning(|_| { - Err(tonic::Status::new( - tonic::Code::Internal, - "internal server error", - )) - }); - - let sleep = Duration::from_millis(100); - let max_attempts = 3; - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); - let (tx_res_sender, _tx_res_receiver) = mpsc::channel(100); - - let tx_confirmer = TxConfirmer::new( - client, - sleep, - max_attempts, - tx_confirmer_receiver, - tx_res_sender, - ); - let handle = tokio::spawn(tx_confirmer.run()); - - tx_confirmer_sender.send(tx_hash.clone()).await.unwrap(); - assert!(matches!( - handle.await.unwrap().unwrap_err().current_context(), - Error::Grpc { tx_hash: actual, status } if *actual == tx_hash && status.code() == tonic::Code::Internal - )); - } -} diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index 487c4e53f..dea57bd1d 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -1,7 +1,7 @@ -use std::cmp; use std::convert::TryInto; use std::ops::Mul; use std::time::Duration; +use std::{cmp, thread}; use async_trait::async_trait; use axelar_wasm_std::FnExt; @@ -10,32 +10,34 @@ use cosmrs::proto::cosmos::auth::v1beta1::{ }; use cosmrs::proto::cosmos::bank::v1beta1::QueryBalanceRequest; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmrs::proto::cosmos::tx::v1beta1::{BroadcastMode, BroadcastTxRequest, SimulateRequest}; +use cosmrs::proto::cosmos::tx::v1beta1::{ + BroadcastMode, BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, +}; use cosmrs::proto::traits::MessageExt; use cosmrs::tendermint::chain::Id; use cosmrs::tx::Fee; use cosmrs::{Amount, Coin, Denom, Gas}; use dec_coin::DecCoin; -use error_stack::{ensure, report, FutureExt, Result, ResultExt}; +use error_stack::{ensure, report, FutureExt, Report, Result, ResultExt}; use futures::TryFutureExt; use k256::sha2::{Digest, Sha256}; use mockall::automock; use num_traits::{cast, Zero}; use prost::Message; use prost_types::Any; -use report::ResultCompatExt; +use report::{LoggableError, ResultCompatExt}; use serde::{Deserialize, Serialize}; use thiserror::Error; use tonic::{Code, Status}; -use tracing::info; +use tracing::{debug, info}; use tx::Tx; use typed_builder::TypedBuilder; +use valuable::Valuable; use crate::tofnd; use crate::tofnd::grpc::Multisig; use crate::types::{PublicKey, TMAddress}; -pub mod confirm_tx; mod cosmos; mod dec_coin; mod tx; @@ -50,6 +52,10 @@ pub enum Error { FeeEstimation, #[error("broadcast failed")] Broadcast, + #[error("failed to confirm inclusion in block for tx with hash '{tx_hash}'")] + TxConfirmation { tx_hash: String }, + #[error("failed to execute tx")] + Execution, #[error("failed to query balance for address '{address}' and denomination '{denom}'")] QueryBalance { address: TMAddress, denom: Denom }, #[error("failed to query account for address '{address}'")] @@ -96,7 +102,6 @@ impl Default for Config { #[automock] #[async_trait] pub trait Broadcaster { - fn sender_address(&self) -> TMAddress; async fn broadcast(&mut self, msgs: Vec) -> Result; async fn estimate_fee(&mut self, msgs: Vec) -> Result; } @@ -210,10 +215,6 @@ where S: Multisig + Send + Sync, Q: cosmos::AccountQueryClient + Send, { - fn sender_address(&self) -> TMAddress { - self.address.clone() - } - async fn broadcast(&mut self, msgs: Vec) -> Result { let (acc_number, acc_sequence) = self.acc_number_and_sequence().await?; let tx = Tx::builder() @@ -258,6 +259,10 @@ where info!(tx_hash, "broadcasted transaction"); + self.confirm_tx(tx_hash).await?; + + info!(tx_hash, "confirmed transaction"); + self.acc_sequence.replace( acc_sequence .checked_add(1) @@ -347,6 +352,48 @@ where }) .await } + + async fn confirm_tx(&mut self, tx_hash: &str) -> Result<(), Error> { + let mut result: Result<(), Status> = Ok(()); + + for i in 0..self.config.tx_fetch_max_retries.saturating_add(1) { + if i > 0 { + thread::sleep(self.config.tx_fetch_interval) + } + + let response = self + .client + .get_tx(GetTxRequest { + hash: tx_hash.to_string(), + }) + .await; + + match evaluate_tx_response(response) { + ConfirmationResult::Success => { + if let Err(report) = result { + debug!( + err = LoggableError::from(&report).as_value(), + "tx confirmed after {} retries", i + ) + } + + return Ok(()); + } + ConfirmationResult::Critical(err) => return Err(err), + ConfirmationResult::Retriable(err) => { + if let Err(result) = result.as_mut() { + result.extend_one(err); + } else { + result = Err(err); + } + } + }; + } + + result.change_context(Error::TxConfirmation { + tx_hash: tx_hash.to_string(), + }) + } } fn decode_base_account(account: Any) -> Result { @@ -357,6 +404,27 @@ fn decode_base_account(account: Any) -> Result { .attach_printable_lazy(|| format!("{{ value = {:?} }}", account.value)) } +fn evaluate_tx_response( + response: core::result::Result, +) -> ConfirmationResult { + match response { + Err(err) => ConfirmationResult::Retriable(report!(err)), + Ok(GetTxResponse { + tx_response: None, .. + }) => ConfirmationResult::Retriable(Report::new(Status::not_found("tx not found"))), + Ok(GetTxResponse { + tx_response: Some(response), + .. + }) => match response { + TxResponse { code: 0, .. } => ConfirmationResult::Success, + _ => ConfirmationResult::Critical( + report!(Error::Execution) + .attach_printable(format!("{{ response = {response:?} }}")), + ), + }, + } +} + fn remap_account_not_found_error( response: core::result::Result, ) -> core::result::Result { @@ -367,6 +435,12 @@ fn remap_account_not_found_error( } } +enum ConfirmationResult { + Success, + Retriable(Report), + Critical(Report), +} + #[cfg(test)] mod tests { use cosmrs::bank::MsgSend; @@ -490,6 +564,72 @@ mod tests { )); } + #[test] + async fn tx_confirmation_failed() { + let mut client = MockBroadcastClient::new(); + client.expect_simulate().returning(|_| { + Ok(SimulateResponse { + gas_info: Some(GasInfo { + gas_wanted: 0, + gas_used: 0, + }), + result: None, + }) + }); + client + .expect_broadcast_tx() + .returning(|_| Ok(TxResponse::default())); + client + .expect_get_tx() + .times((Config::default().tx_fetch_max_retries + 1) as usize) + .returning(|_| Err(Status::deadline_exceeded("time out"))); + + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; + let msgs = vec![dummy_msg()]; + + assert!(matches!( + broadcaster + .broadcast(msgs) + .await + .unwrap_err() + .current_context(), + Error::TxConfirmation { .. } + )); + } + + #[test] + async fn tx_execution_failed() { + let mut client = MockBroadcastClient::new(); + client.expect_simulate().returning(|_| { + Ok(SimulateResponse { + gas_info: Some(GasInfo { + gas_wanted: 0, + gas_used: 0, + }), + result: None, + }) + }); + client + .expect_broadcast_tx() + .returning(|_| Ok(TxResponse::default())); + client.expect_get_tx().times(1).returning(|_| { + Ok(GetTxResponse { + tx_response: Some(TxResponse { + code: 32, + ..TxResponse::default() + }), + ..GetTxResponse::default() + }) + }); + + let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; + let msgs = vec![dummy_msg()]; + + let report = broadcaster.broadcast(msgs).await.unwrap_err(); + + assert!(matches!(report.current_context(), Error::Execution)); + } + #[test] async fn broadcast_confirmed() { let mut broadcaster = init_validated_broadcaster(None, None, None).await; diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index a134c2fae..08804d5fb 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -2,7 +2,6 @@ use std::time::Duration; use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; use block_height_monitor::BlockHeightMonitor; -use broadcaster::confirm_tx::TxConfirmer; use broadcaster::Broadcaster; use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient as AuthQueryClient; use cosmrs::proto::cosmos::bank::v1beta1::query_client::QueryClient as BankQueryClient; @@ -17,10 +16,8 @@ use router_api::ChainName; use thiserror::Error; use tofnd::grpc::{Multisig, MultisigClient}; use tokio::signal::unix::{signal, SignalKind}; -use tokio::sync::mpsc; use tokio::time::interval; use tokio_util::sync::CancellationToken; -use tonic::transport::Channel; use tracing::info; use types::TMAddress; @@ -95,7 +92,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { .auth_query_client(auth_query_client) .bank_query_client(bank_query_client) .address_prefix(PREFIX.to_string()) - .client(service_client.clone()) + .client(service_client) .signer(multisig_client.clone()) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast.clone()) @@ -114,7 +111,6 @@ async fn prepare_app(cfg: Config) -> Result, Error> { App::new( tm_client, broadcaster, - service_client, multisig_client, broadcast, event_processor.stream_buffer_size, @@ -149,7 +145,6 @@ where event_subscriber: event_sub::EventSubscriber, event_processor: TaskGroup, broadcaster: QueuedBroadcaster, - tx_confirmer: TxConfirmer>, multisig_client: MultisigClient, block_height_monitor: BlockHeightMonitor, health_check_server: health_check::Server, @@ -164,7 +159,6 @@ where fn new( tm_client: tendermint_rpc::HttpClient, broadcaster: T, - service_client: ServiceClient, multisig_client: MultisigClient, broadcast_cfg: broadcaster::Config, event_buffer_cap: usize, @@ -176,24 +170,12 @@ where let (event_publisher, event_subscriber) = event_sub::EventPublisher::new(tm_client, event_buffer_cap); - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); - let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); - let event_processor = TaskGroup::new(); let broadcaster = QueuedBroadcaster::new( broadcaster, broadcast_cfg.batch_gas_limit, broadcast_cfg.queue_cap, interval(broadcast_cfg.broadcast_interval), - tx_confirmer_sender, - tx_res_receiver, - ); - let tx_confirmer = TxConfirmer::new( - service_client, - broadcast_cfg.tx_fetch_interval, - broadcast_cfg.tx_fetch_max_retries.saturating_add(1), - tx_confirmer_receiver, - tx_res_sender, ); Self { @@ -201,7 +183,6 @@ where event_subscriber, event_processor, broadcaster, - tx_confirmer, multisig_client, block_height_monitor, health_check_server, @@ -366,7 +347,6 @@ where event_publisher, event_processor, broadcaster, - tx_confirmer, block_height_monitor, health_check_server, token, @@ -409,9 +389,6 @@ where .run(token) .change_context(Error::EventProcessor) })) - .add_task(CancellableTask::create(|_| { - tx_confirmer.run().change_context(Error::TxConfirmer) - })) .add_task(CancellableTask::create(|_| { broadcaster.run().change_context(Error::Broadcaster) })) @@ -428,8 +405,6 @@ pub enum Error { EventProcessor, #[error("broadcaster failed")] Broadcaster, - #[error("tx confirmer failed")] - TxConfirmer, #[error("tofnd failed")] Tofnd, #[error("connection failed")] diff --git a/ampd/src/queue/mod.rs b/ampd/src/queue/mod.rs index d7568b662..2a6ce0415 100644 --- a/ampd/src/queue/mod.rs +++ b/ampd/src/queue/mod.rs @@ -1,3 +1,2 @@ mod msg_queue; -mod proto; pub mod queued_broadcaster; diff --git a/ampd/src/queue/proto.rs b/ampd/src/queue/proto.rs deleted file mode 100644 index 322f2ab62..000000000 --- a/ampd/src/queue/proto.rs +++ /dev/null @@ -1,42 +0,0 @@ -use cosmrs::proto::traits::TypeUrl; - -pub mod axelar { - pub mod auxiliary { - pub mod v1beta1 { - tonic::include_proto!("axelar.auxiliary.v1beta1"); - } - } -} - -mod cosmos { - pub mod base { - pub mod abci { - pub mod v1beta1 { - tonic::include_proto!("cosmos.base.abci.v1beta1"); - } - } - } -} - -mod tendermint { - #[allow(clippy::large_enum_variant)] - pub mod abci { - tonic::include_proto!("tendermint.abci"); - } - - pub mod crypto { - tonic::include_proto!("tendermint.crypto"); - } - - pub mod types { - tonic::include_proto!("tendermint.types"); - } - - pub mod version { - tonic::include_proto!("tendermint.version"); - } -} - -impl TypeUrl for axelar::auxiliary::v1beta1::BatchRequest { - const TYPE_URL: &'static str = "/axelar.auxiliary.v1beta1.BatchRequest"; -} diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index 836325acb..cd3feb4ae 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -1,5 +1,4 @@ use async_trait::async_trait; -use cosmrs::tx::MessageExt; use cosmrs::{Any, Gas}; use error_stack::{self, Report, ResultExt}; use mockall::automock; @@ -10,8 +9,6 @@ use tokio::time::Interval; use tracing::{info, warn}; use super::msg_queue::MsgQueue; -use super::proto; -use crate::broadcaster::confirm_tx::{TxResponse, TxStatus}; use crate::broadcaster::Broadcaster; type Result = error_stack::Result; @@ -27,10 +24,6 @@ pub enum Error { Client, #[error("failed to queue message")] Queue, - #[error("failed to confirm transaction")] - TxConfirmation, - #[error("failed to decode tx response")] - DecodeTxResponse(#[from] prost::DecodeError), } #[automock] @@ -65,8 +58,6 @@ where batch_gas_limit: Gas, channel: Option<(mpsc::Sender, mpsc::Receiver)>, broadcast_interval: Interval, - tx_confirmer_sender: mpsc::Sender, - tx_confirmer_receiver: mpsc::Receiver, } impl QueuedBroadcaster @@ -78,8 +69,6 @@ where batch_gas_limit: Gas, capacity: usize, broadcast_interval: Interval, - tx_confirmer_sender: mpsc::Sender, - tx_res_receiver: mpsc::Receiver, ) -> Self { Self { broadcaster, @@ -87,8 +76,6 @@ where batch_gas_limit, channel: Some(mpsc::channel(capacity)), broadcast_interval, - tx_confirmer_sender, - tx_confirmer_receiver: tx_res_receiver, } } @@ -108,18 +95,10 @@ where self.broadcast_all().await?; self.broadcast_interval.reset(); }, - Some(tx_res) = self.tx_confirmer_receiver.recv() => self.handle_tx_res(tx_res).await?, } } - self.clean_up().await - } - - async fn clean_up(mut self) -> Result { self.broadcast_all().await?; - while let Some(tx_res) = self.tx_confirmer_receiver.recv().await { - self.handle_tx_res(tx_res).await?; - } Ok(()) } @@ -135,30 +114,6 @@ where } } - async fn handle_tx_res(&self, tx_res: TxResponse) -> Result { - let tx_hash = tx_res.response.txhash; - - match tx_res.status { - TxStatus::Success => { - tx_res.response.logs.iter().for_each(|log| { - let msg_index = log.msg_index; - - log.events - .iter() - .enumerate() - .for_each(|(event_index, event)| { - info!(tx_hash, msg_index, event_index, "tx event {:?}", event); - }); - }); - } - TxStatus::Failure => { - warn!(tx_hash, "tx failed"); - } - } - - Ok(()) - } - async fn broadcast_all(&mut self) -> Result { let msgs = self.queue.pop_all(); @@ -167,25 +122,11 @@ where n => { info!(message_count = n, "ready to broadcast messages"); - let batch_req = proto::axelar::auxiliary::v1beta1::BatchRequest { - sender: self.broadcaster.sender_address().as_ref().to_bytes(), - messages: msgs, - } - .to_any() - .expect("failed to serialize proto message for batch request"); - - let tx_hash = self - .broadcaster - .broadcast(vec![batch_req]) - .await - .change_context(Error::Broadcast)? - .txhash; - self.tx_confirmer_sender - .send(tx_hash) + self.broadcaster + .broadcast(msgs) .await - .change_context(Error::TxConfirmation)?; - - Ok(()) + .map(|_| ()) + .change_context(Error::Broadcast) } } } @@ -232,20 +173,16 @@ where mod test { use cosmrs::bank::MsgSend; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; - use cosmrs::tx::{Fee, MessageExt, Msg}; + use cosmrs::tx::{Fee, Msg}; use cosmrs::{AccountId, Any}; use error_stack::Report; - use futures::StreamExt; use tokio::sync::mpsc; use tokio::test; use tokio::time::{interval, timeout, Duration, Instant}; - use tokio_stream::wrappers::ReceiverStream; use super::{Error, QueuedBroadcaster}; use crate::broadcaster::{self, MockBroadcaster}; - use crate::queue::proto; use crate::queue::queued_broadcaster::BroadcasterClient; - use crate::PREFIX; #[test] async fn should_ignore_msg_when_fee_estimation_fails() { @@ -254,17 +191,8 @@ mod test { .expect_estimate_fee() .return_once(|_| Err(Report::new(broadcaster::Error::FeeEstimation))); - let (tx_confirmer_sender, _tx_confirmer_receiver) = mpsc::channel(1000); - let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let broadcast_interval = interval(Duration::from_secs(5)); - let queued_broadcaster = QueuedBroadcaster::new( - broadcaster, - 100, - 10, - broadcast_interval, - tx_confirmer_sender, - tx_res_receiver, - ); + let queued_broadcaster = QueuedBroadcaster::new(broadcaster, 100, 10, broadcast_interval); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); @@ -277,7 +205,6 @@ mod test { Error::EstimateFee )); drop(client); - drop(tx_res_sender); assert!(handle.await.unwrap().is_ok()); } @@ -303,39 +230,24 @@ mod test { payer: None, }) }); - broadcaster - .expect_sender_address() - .once() - .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); + broadcaster .expect_broadcast() - .once() + .times(1) .returning(move |msgs| { - assert_eq!(msgs.len(), 1); - let msg = msgs.first().unwrap(); - let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); - assert_eq!(msg.messages.len(), tx_count); - + assert_eq!(msgs.len(), tx_count); tx.try_send(()) .expect("Failed to send broadcast completion signal"); - Ok(TxResponse::default()) }); - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); - let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(interval_duration); broadcast_interval.tick().await; - let queued_broadcaster = QueuedBroadcaster::new( - broadcaster, - batch_gas_limit, - tx_count, - broadcast_interval, - tx_confirmer_sender, - tx_res_receiver, - ); + + let queued_broadcaster = + QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); let client = queued_broadcaster.client(); - let handle = tokio::spawn(queued_broadcaster.run()); + let _handle = tokio::spawn(queued_broadcaster.run()); let start_time = Instant::now(); @@ -352,14 +264,8 @@ mod test { assert!(elapsed > interval_duration); assert!(elapsed < interval_duration * 2); } - Err(_) => panic!("broadcast did not occur within the expected timeframe"), + Err(_) => panic!("Broadcast did not occur within the expected timeframe"), } - - drop(client); - drop(tx_res_sender); - - assert!(handle.await.unwrap().is_ok()); - assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 1); } #[test(start_paused = true)] @@ -371,73 +277,52 @@ mod test { let interval_duration = Duration::from_secs(5); let mut broadcaster = MockBroadcaster::new(); + broadcaster.expect_estimate_fee().returning(move |_| { + Ok(Fee { + gas_limit, + amount: vec![], + granter: None, + payer: None, + }) + }); broadcaster - .expect_estimate_fee() - .times(tx_count) - .returning(move |_| { - Ok(Fee { - gas_limit, - amount: vec![], - granter: None, - payer: None, - }) + .expect_broadcast() + .once() + .returning(move |msgs| { + assert_eq!(msgs.len(), 9); + + Ok(TxResponse::default()) }); - broadcaster - .expect_sender_address() - .times(3) - .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); - let mut call_count = 0; broadcaster .expect_broadcast() - .times(3) + .once() .returning(move |msgs| { - call_count += 1; - - assert_eq!(msgs.len(), 1); - let msg = msgs.first().unwrap(); - let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); - - if call_count < 3 { - assert_eq!(msg.messages.len(), 9); - } else { - assert_eq!(msg.messages.len(), 2); - } + assert_eq!(msgs.len(), 9); Ok(TxResponse::default()) }); - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); - let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); + let mut broadcast_interval = interval(interval_duration); - // get rid of tick on startup broadcast_interval.tick().await; - let queued_broadcaster = QueuedBroadcaster::new( - broadcaster, - batch_gas_limit, - batch_size, - broadcast_interval, - tx_confirmer_sender, - tx_res_receiver, - ); + + let queued_broadcaster = + QueuedBroadcaster::new(broadcaster, batch_gas_limit, batch_size, broadcast_interval); let client = queued_broadcaster.client(); - let handle = tokio::spawn(queued_broadcaster.run()); + let _handle = tokio::spawn(queued_broadcaster.run()); let start_time = Instant::now(); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } + // Advance time by a small amount to allow processing tokio::time::advance(Duration::from_millis(100)).await; let elapsed = start_time.elapsed(); + // Assert that broadcasts happened faster than the interval assert!(elapsed < interval_duration); - - drop(client); - drop(tx_res_sender); - - assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 3); - assert!(handle.await.unwrap().is_ok()); } #[test(start_paused = true)] @@ -458,52 +343,36 @@ mod test { payer: None, }) }); - broadcaster - .expect_sender_address() - .times(2) - .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); - let mut broadcast_count = 0; broadcaster .expect_broadcast() - .times(2) + .once() .returning(move |msgs| { - broadcast_count += 1; + assert_eq!(msgs.len(), tx_count - 1); + Ok(TxResponse::default()) + }); + broadcaster + .expect_broadcast() + .once() + .returning(move |msgs| { assert_eq!(msgs.len(), 1); - let msg = msgs.first().unwrap(); - let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); - - if broadcast_count == 1 { - assert_eq!(msg.messages.len(), tx_count - 1); - } else { - assert_eq!(msg.messages.len(), 1); - } - Ok(TxResponse::default()) }); - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); - let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(Duration::from_secs(5)); // get rid of tick on startup broadcast_interval.tick().await; - let queued_broadcaster = QueuedBroadcaster::new( - broadcaster, - batch_gas_limit, - tx_count, - broadcast_interval, - tx_confirmer_sender, - tx_res_receiver, - ); + + let queued_broadcaster = + QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } + drop(client); - drop(tx_res_sender); - assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 2); assert!(handle.await.unwrap().is_ok()); } From e4ef3073f8e7d461265479955feb51d9f2e1abc7 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 24 Jul 2024 12:19:13 -0400 Subject: [PATCH 099/168] refactor(minor): make the main flow msgs consistent (#539) --- contracts/gateway/src/contract.rs | 2 +- contracts/gateway/tests/contract.rs | 7 +- contracts/gateway/tests/test_verify.json | 14 +- contracts/multisig-prover/src/contract.rs | 6 +- .../multisig-prover/src/contract/execute.rs | 6 +- contracts/multisig-prover/src/msg.rs | 2 +- contracts/voting-verifier/src/client.rs | 10 +- contracts/voting-verifier/src/contract.rs | 154 ++++++------------ contracts/voting-verifier/src/msg.rs | 6 +- integration-tests/tests/test_utils/mod.rs | 10 +- packages/gateway-api/src/msg.rs | 2 +- 11 files changed, 80 insertions(+), 139 deletions(-) diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 91b5fe956..2d750ec47 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -140,7 +140,7 @@ mod internal { pub(crate) fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::GetOutgoingMessages { message_ids } => { + QueryMsg::GetOutgoingMessages(message_ids) => { let msgs = contract::query::get_outgoing_messages(deps.storage, message_ids)?; to_json_binary(&msgs).change_context(Error::SerializeResponse) } diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index 541e8eb63..a2bc314fc 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -138,9 +138,8 @@ fn successful_route_outgoing() { let router = "router"; instantiate_contract(deps.as_mut(), "verifier", router); - let query_msg = QueryMsg::GetOutgoingMessages { - message_ids: msgs.iter().map(|msg| msg.cc_id.clone()).collect(), - }; + let query_msg = + QueryMsg::GetOutgoingMessages(msgs.iter().map(|msg| msg.cc_id.clone()).collect()); // check no messages are outgoing let query_response = query(deps.as_ref(), mock_env(), query_msg.clone()); @@ -398,7 +397,7 @@ fn correctly_working_verifier_handler( { move |msg: voting_verifier::msg::QueryMsg| -> Result, ContractError> { match msg { - voting_verifier::msg::QueryMsg::GetMessagesStatus { messages } => Ok(messages + voting_verifier::msg::QueryMsg::GetMessagesStatus(messages) => Ok(messages .into_iter() .map(|msg| { MessageStatus::new( diff --git a/contracts/gateway/tests/test_verify.json b/contracts/gateway/tests/test_verify.json index d335c7a1f..3bd7657cb 100644 --- a/contracts/gateway/tests/test_verify.json +++ b/contracts/gateway/tests/test_verify.json @@ -85,7 +85,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifV19fQ==", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifV19", "funds": [] } } @@ -136,7 +136,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9XX19", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9XX0=", "funds": [] } } @@ -223,7 +223,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn1dfX0=", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn1dfQ==", "funds": [] } } @@ -868,7 +868,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19fQ==", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", "funds": [] } } @@ -1180,7 +1180,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9XX19", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9XX0=", "funds": [] } } @@ -1789,7 +1789,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd24xIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjMifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd240In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjYifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd243In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjkifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5In1dfX0=", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd24xIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjMifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd240In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjYifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd243In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjkifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5In1dfQ==", "funds": [] } } @@ -2101,7 +2101,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOnsibWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd24yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd241In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd244In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19fQ==", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd24yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd241In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd244In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", "funds": [] } } diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 1a01ce10e..2bd5949ca 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -61,9 +61,7 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg.ensure_permissions(deps.storage, &info.sender)? { - ExecuteMsg::ConstructProof { message_ids } => { - Ok(execute::construct_proof(deps, message_ids)?) - } + ExecuteMsg::ConstructProof(message_ids) => Ok(execute::construct_proof(deps, message_ids)?), ExecuteMsg::UpdateVerifierSet {} => Ok(execute::update_verifier_set(deps, env)?), ExecuteMsg::ConfirmVerifierSet {} => Ok(execute::confirm_verifier_set(deps, info.sender)?), ExecuteMsg::UpdateSigningThreshold { @@ -229,7 +227,7 @@ mod tests { .collect::>() }); - let msg = ExecuteMsg::ConstructProof { message_ids }; + let msg = ExecuteMsg::ConstructProof(message_ids); execute(deps, mock_env(), mock_info(RELAYER, &[]), msg) } diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index 677ec8d55..08689eb7b 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -82,7 +82,7 @@ fn get_messages( ) -> Result, ContractError> { let length = message_ids.len(); - let query = gateway_api::msg::QueryMsg::GetOutgoingMessages { message_ids }; + let query = gateway_api::msg::QueryMsg::GetOutgoingMessages(message_ids); let messages: Vec = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: gateway.into(), msg: to_json_binary(&query)?, @@ -288,9 +288,7 @@ fn ensure_verifier_set_verification( config: &Config, deps: &DepsMut, ) -> Result<(), ContractError> { - let query = voting_verifier::msg::QueryMsg::GetVerifierSetStatus { - new_verifier_set: verifier_set.clone(), - }; + let query = voting_verifier::msg::QueryMsg::GetVerifierSetStatus(verifier_set.clone()); let status: VerificationStatus = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.voting_verifier.to_string(), diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index 5a7f7001a..0b0e23d54 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -63,7 +63,7 @@ pub enum ExecuteMsg { // Start building a proof that includes specified messages // Queries the gateway for actual message contents #[permission(Any)] - ConstructProof { message_ids: Vec }, + ConstructProof(Vec), #[permission(Elevated)] UpdateVerifierSet, diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index e2a9c3538..5363e4dfc 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -27,10 +27,8 @@ pub struct Client<'a> { impl<'a> Client<'a> { pub fn verify_messages(&self, messages: Vec) -> Option { - ignore_empty(messages).map(|messages| { - self.client - .execute(&ExecuteMsg::VerifyMessages { messages }) - }) + ignore_empty(messages) + .map(|messages| self.client.execute(&ExecuteMsg::VerifyMessages(messages))) } pub fn vote(&self, poll_id: PollId, votes: Vec) -> WasmMsg { @@ -69,14 +67,14 @@ impl<'a> Client<'a> { [] => Ok(vec![]), _ => self .client - .query(&QueryMsg::GetMessagesStatus { messages }) + .query(&QueryMsg::GetMessagesStatus(messages)) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())), } } pub fn verifier_set_status(&self, new_verifier_set: VerifierSet) -> Result { self.client - .query(&QueryMsg::GetVerifierSetStatus { new_verifier_set }) + .query(&QueryMsg::GetVerifierSetStatus(new_verifier_set)) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())) } diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 135a79854..216b220ab 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -54,7 +54,7 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg.ensure_permissions(deps.storage, &info.sender)? { - ExecuteMsg::VerifyMessages { messages } => execute::verify_messages(deps, env, messages), + ExecuteMsg::VerifyMessages(messages) => execute::verify_messages(deps, env, messages), ExecuteMsg::Vote { poll_id, votes } => execute::vote(deps, env, info, poll_id, votes), ExecuteMsg::EndPoll { poll_id } => execute::end_poll(deps, env, poll_id), ExecuteMsg::VerifyVerifierSet { @@ -75,10 +75,10 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { to_json_binary(&query::poll_response(deps, env.block.height, poll_id)?) } - QueryMsg::GetMessagesStatus { messages } => { + QueryMsg::GetMessagesStatus(messages) => { to_json_binary(&query::messages_status(deps, &messages, env.block.height)?) } - QueryMsg::GetVerifierSetStatus { new_verifier_set } => to_json_binary( + QueryMsg::GetVerifierSetStatus(new_verifier_set) => to_json_binary( &query::verifier_set_status(deps, &new_verifier_set, env.block.height)?, ), QueryMsg::GetCurrentThreshold => to_json_binary(&query::voting_threshold(deps)?), @@ -265,26 +265,24 @@ mod test { let verifiers = verifiers(2); let mut deps = setup(verifiers.clone(), &msg_id_format); - let msg = ExecuteMsg::VerifyMessages { - messages: vec![ - Message { - cc_id: CrossChainId::new(source_chain(), message_id("id", 1, &msg_id_format)) - .unwrap(), - source_address: "source_address1".parse().unwrap(), - destination_chain: "destination-chain1".parse().unwrap(), - destination_address: "destination_address1".parse().unwrap(), - payload_hash: [0; 32], - }, - Message { - cc_id: CrossChainId::new("other-chain", message_id("id", 2, &msg_id_format)) - .unwrap(), - source_address: "source_address2".parse().unwrap(), - destination_chain: "destination-chain2".parse().unwrap(), - destination_address: "destination_address2".parse().unwrap(), - payload_hash: [0; 32], - }, - ], - }; + let msg = ExecuteMsg::VerifyMessages(vec![ + Message { + cc_id: CrossChainId::new(source_chain(), message_id("id", 1, &msg_id_format)) + .unwrap(), + source_address: "source_address1".parse().unwrap(), + destination_chain: "destination-chain1".parse().unwrap(), + destination_address: "destination_address1".parse().unwrap(), + payload_hash: [0; 32], + }, + Message { + cc_id: CrossChainId::new("other-chain", message_id("id", 2, &msg_id_format)) + .unwrap(), + source_address: "source_address2".parse().unwrap(), + destination_chain: "destination-chain2".parse().unwrap(), + destination_address: "destination_address2".parse().unwrap(), + payload_hash: [0; 32], + }, + ]); let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); assert_contract_err_strings_equal(err, ContractError::SourceChainMismatch(source_chain())); } @@ -298,7 +296,7 @@ mod test { let mut messages = messages(1, &MessageIdFormat::HexTxHashAndEventIndex); messages[0].cc_id = CrossChainId::new(source_chain(), "foobar").unwrap(); - let msg = ExecuteMsg::VerifyMessages { messages }; + let msg = ExecuteMsg::VerifyMessages(messages); let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); assert_contract_err_strings_equal( @@ -314,9 +312,7 @@ mod test { let mut deps = setup(verifiers.clone(), &msg_id_format); let messages = messages(1, &MessageIdFormat::Base58TxDigestAndEventIndex); - let msg = ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }; + let msg = ExecuteMsg::VerifyMessages(messages.clone()); let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); assert_contract_err_strings_equal( @@ -332,9 +328,7 @@ mod test { let mut deps = setup(verifiers.clone(), &msg_id_format); let messages = messages(1, &MessageIdFormat::HexTxHashAndEventIndex); - let msg = ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }; + let msg = ExecuteMsg::VerifyMessages(messages.clone()); let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); assert_contract_err_strings_equal( @@ -356,9 +350,9 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages[0..messages_in_progress].to_vec(), // verify a subset of the messages - }, + ExecuteMsg::VerifyMessages( + messages[0..messages_in_progress].to_vec(), // verify a subset of the messages + ), ) .unwrap(); @@ -366,9 +360,9 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages.clone(), // verify all messages including the ones from previous execution - }, + ExecuteMsg::VerifyMessages( + messages.clone(), // verify all messages including the ones from previous execution + ), ) .unwrap(); @@ -414,9 +408,7 @@ mod test { let mut deps = setup(verifiers.clone(), &msg_id_format); let messages = messages(5, &msg_id_format); - let msg = ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }; + let msg = ExecuteMsg::VerifyMessages(messages.clone()); execute( deps.as_mut(), mock_env(), @@ -430,9 +422,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -494,9 +484,7 @@ mod test { // 1. First verification - let msg_verify = ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }; + let msg_verify = ExecuteMsg::VerifyMessages(messages.clone()); let res = execute( deps.as_mut(), @@ -551,9 +539,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -589,9 +575,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -622,9 +606,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -648,9 +630,7 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }, + ExecuteMsg::VerifyMessages(messages.clone()), ) .unwrap(); @@ -658,9 +638,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -684,9 +662,7 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }, + ExecuteMsg::VerifyMessages(messages.clone()), ) .unwrap(); @@ -694,9 +670,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -737,9 +711,7 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }, + ExecuteMsg::VerifyMessages(messages.clone()), ) .unwrap(); @@ -774,9 +746,7 @@ mod test { &query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -803,9 +773,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus { - new_verifier_set: verifier_set.clone(), - }, + QueryMsg::GetVerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -855,9 +823,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus { - new_verifier_set: verifier_set.clone(), - }, + QueryMsg::GetVerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -910,9 +876,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus { - new_verifier_set: verifier_set.clone(), - }, + QueryMsg::GetVerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -965,9 +929,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus { - new_verifier_set: verifier_set.clone(), - }, + QueryMsg::GetVerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -1012,9 +974,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus { - new_verifier_set: verifier_set.clone(), - }, + QueryMsg::GetVerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -1122,9 +1082,7 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }, + ExecuteMsg::VerifyMessages(messages.clone()), ) .unwrap(); @@ -1179,9 +1137,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -1229,9 +1185,7 @@ mod test { deps.as_mut(), mock_env(), mock_info(SENDER, &[]), - ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }, + ExecuteMsg::VerifyMessages(messages.clone()), ) .unwrap(); @@ -1270,9 +1224,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus { - messages: messages.clone(), - }, + QueryMsg::GetMessagesStatus(messages.clone()), ) .unwrap(), ) @@ -1302,9 +1254,7 @@ mod test { // 1. First verification - let msg_verify = ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }; + let msg_verify = ExecuteMsg::VerifyMessages(messages.clone()); let res = execute( deps.as_mut(), diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index 8aa480e37..f7c61af2a 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -47,7 +47,7 @@ pub enum ExecuteMsg { // returns a vector of true/false values, indicating current verification status for each message // starts a poll for any not yet verified messages #[permission(Any)] - VerifyMessages { messages: Vec }, + VerifyMessages(Vec), // Starts a poll to confirm a verifier set update on the external gateway #[permission(Any)] @@ -82,10 +82,10 @@ pub enum QueryMsg { GetPoll { poll_id: PollId }, #[returns(Vec)] - GetMessagesStatus { messages: Vec }, + GetMessagesStatus(Vec), #[returns(VerificationStatus)] - GetVerifierSetStatus { new_verifier_set: VerifierSet }, + GetVerifierSetStatus(VerifierSet), #[returns(MajorityThreshold)] GetCurrentThreshold, diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index fee9f9194..b963db21d 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -197,9 +197,9 @@ pub fn construct_proof_and_sign( let response = multisig_prover.execute( &mut protocol.app, Addr::unchecked("relayer"), - &multisig_prover::msg::ExecuteMsg::ConstructProof { - message_ids: messages.iter().map(|msg| msg.cc_id.clone()).collect(), - }, + &multisig_prover::msg::ExecuteMsg::ConstructProof( + messages.iter().map(|msg| msg.cc_id.clone()).collect(), + ), ); assert!(response.is_ok()); @@ -278,9 +278,7 @@ pub fn get_messages_from_gateway( ) -> Vec { let query_response: Result, StdError> = gateway.query( app, - &gateway_api::msg::QueryMsg::GetOutgoingMessages { - message_ids: message_ids.to_owned(), - }, + &gateway_api::msg::QueryMsg::GetOutgoingMessages(message_ids.to_owned()), ); assert!(query_response.is_ok()); diff --git a/packages/gateway-api/src/msg.rs b/packages/gateway-api/src/msg.rs index 2911c2e3d..ae642d748 100644 --- a/packages/gateway-api/src/msg.rs +++ b/packages/gateway-api/src/msg.rs @@ -21,5 +21,5 @@ pub enum ExecuteMsg { pub enum QueryMsg { // messages that can be relayed to the chain corresponding to this gateway #[returns(Vec)] - GetOutgoingMessages { message_ids: Vec }, + GetOutgoingMessages(Vec), } From 216f15394858a7e97719235d759cd89e09bf5e24 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 24 Jul 2024 13:32:13 -0400 Subject: [PATCH 100/168] refactor(minor): remove "get" from function names (#537) --- ampd/proto/ampd.proto | 14 ++--- ampd/src/broadcaster/confirm_tx.rs | 0 ampd/src/broadcaster/cosmos.rs | 4 +- ampd/src/broadcaster/mod.rs | 8 +-- ampd/src/commands/register_public_key.rs | 4 +- ampd/src/evm/verifier.rs | 33 +++++----- ampd/src/grpc/client.rs | 8 +-- ampd/src/grpc/server/crypto.rs | 26 ++++---- ampd/src/handlers/evm_verify_msg.rs | 20 +++---- ampd/src/handlers/evm_verify_verifier_set.rs | 6 +- ampd/src/handlers/mod.rs | 5 +- ampd/src/handlers/multisig.rs | 14 ++--- ampd/src/handlers/sui_verify_msg.rs | 16 ++--- ampd/src/handlers/sui_verify_verifier_set.rs | 6 +- ampd/src/sui/verifier.rs | 40 ++++++------- contracts/gateway/src/contract.rs | 4 +- contracts/gateway/src/contract/query.rs | 14 ++--- contracts/gateway/tests/contract.rs | 4 +- contracts/multisig-prover/src/contract.rs | 34 +++++------ .../multisig-prover/src/contract/execute.rs | 24 ++++---- .../multisig-prover/src/contract/query.rs | 11 ++-- contracts/multisig-prover/src/msg.rs | 6 +- .../multisig-prover/src/test/test_utils.rs | 12 ++-- contracts/multisig/src/contract.rs | 42 +++++++------ contracts/multisig/src/contract/execute.rs | 4 +- contracts/multisig/src/contract/query.rs | 6 +- contracts/multisig/src/msg.rs | 6 +- contracts/multisig/src/state.rs | 2 +- contracts/multisig/src/verifier_set.rs | 2 +- contracts/router/src/contract.rs | 4 +- contracts/router/src/contract/query.rs | 14 ++--- contracts/service-registry/src/contract.rs | 60 +++++++++---------- .../service-registry/src/contract/query.rs | 6 +- contracts/service-registry/src/msg.rs | 6 +- contracts/voting-verifier/src/client.rs | 8 +-- contracts/voting-verifier/src/contract.rs | 38 ++++++------ .../voting-verifier/src/contract/execute.rs | 12 ++-- contracts/voting-verifier/src/msg.rs | 8 +-- .../tests/chain_freeze_unfreeze.rs | 2 +- integration-tests/tests/message_routing.rs | 4 +- integration-tests/tests/test_utils/mod.rs | 38 ++++++------ integration-tests/tests/update_worker_set.rs | 30 +++++----- packages/axelar-wasm-std/src/counter.rs | 2 +- packages/axelar-wasm-std/src/snapshot.rs | 4 +- packages/gateway-api/src/msg.rs | 2 +- packages/router-api/src/msg.rs | 2 +- 46 files changed, 302 insertions(+), 313 deletions(-) create mode 100644 ampd/src/broadcaster/confirm_tx.rs diff --git a/ampd/proto/ampd.proto b/ampd/proto/ampd.proto index 59bb0ebe6..fa477adda 100644 --- a/ampd/proto/ampd.proto +++ b/ampd/proto/ampd.proto @@ -15,9 +15,9 @@ message SubscribeRequest { bool include_block_begin_end = 2; } -message EventBlockBegin { uint64 height = 1; } +message EventBlockBegin {uint64 height = 1;} -message EventBlockEnd { uint64 height = 1; } +message EventBlockEnd {uint64 height = 1;} message Event { string event_type = 1; @@ -32,7 +32,7 @@ message SubscribeResponse { } } -message BroadcastRequest { google.protobuf.Any msg = 1; } +message BroadcastRequest {google.protobuf.Any msg = 1;} message BroadcastResponse {} @@ -47,16 +47,16 @@ message SignRequest { Algorithm algorithm = 3; } -message SignResponse { bytes signature = 1; } +message SignResponse {bytes signature = 1;} -message GetKeyRequest { +message KeyRequest { string key_id = 1; Algorithm algorithm = 2; } -message GetKeyResponse { bytes pub_key = 1; } +message KeyResponse {bytes pub_key = 1;} service Crypto { rpc Sign(SignRequest) returns (SignResponse) {} - rpc GetKey(GetKeyRequest) returns (GetKeyResponse) {} + rpc Key(KeyRequest) returns (KeyResponse) {} } diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs new file mode 100644 index 000000000..e69de29bb diff --git a/ampd/src/broadcaster/cosmos.rs b/ampd/src/broadcaster/cosmos.rs index f77134e4b..5f0dabeb9 100644 --- a/ampd/src/broadcaster/cosmos.rs +++ b/ampd/src/broadcaster/cosmos.rs @@ -24,7 +24,7 @@ use tonic::{Response, Status}; pub trait BroadcastClient { async fn broadcast_tx(&mut self, request: BroadcastTxRequest) -> Result; async fn simulate(&mut self, request: SimulateRequest) -> Result; - async fn get_tx(&mut self, request: GetTxRequest) -> Result; + async fn tx(&mut self, request: GetTxRequest) -> Result; } #[async_trait] @@ -42,7 +42,7 @@ impl BroadcastClient for ServiceClient { self.simulate(request).await.map(Response::into_inner) } - async fn get_tx(&mut self, request: GetTxRequest) -> Result { + async fn tx(&mut self, request: GetTxRequest) -> Result { self.get_tx(request).await.map(Response::into_inner) } } diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index dea57bd1d..91a78fe60 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -363,7 +363,7 @@ where let response = self .client - .get_tx(GetTxRequest { + .tx(GetTxRequest { hash: tx_hash.to_string(), }) .await; @@ -580,7 +580,7 @@ mod tests { .expect_broadcast_tx() .returning(|_| Ok(TxResponse::default())); client - .expect_get_tx() + .expect_tx() .times((Config::default().tx_fetch_max_retries + 1) as usize) .returning(|_| Err(Status::deadline_exceeded("time out"))); @@ -612,7 +612,7 @@ mod tests { client .expect_broadcast_tx() .returning(|_| Ok(TxResponse::default())); - client.expect_get_tx().times(1).returning(|_| { + client.expect_tx().times(1).returning(|_| { Ok(GetTxResponse { tx_response: Some(TxResponse { code: 32, @@ -808,7 +808,7 @@ mod tests { client .expect_broadcast_tx() .returning(|_| Ok(TxResponse::default())); - client.expect_get_tx().returning(|_| { + client.expect_tx().returning(|_| { Ok(GetTxResponse { tx_response: Some(TxResponse { code: 0, diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index e0e8d0c7a..b31f45f1a 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -49,7 +49,7 @@ pub struct Args { pub async fn run(config: Config, args: Args) -> Result, Error> { let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; - let multisig_address = get_multisig_address(&config)?; + let multisig_address = multisig_address(&config)?; let tofnd_config = config.tofnd_config.clone(); @@ -105,7 +105,7 @@ pub async fn run(config: Config, args: Args) -> Result, Error> { ))) } -fn get_multisig_address(config: &Config) -> Result { +fn multisig_address(config: &Config) -> Result { config .handlers .iter() diff --git a/ampd/src/evm/verifier.rs b/ampd/src/evm/verifier.rs index 120d4313c..b29c702f0 100644 --- a/ampd/src/evm/verifier.rs +++ b/ampd/src/evm/verifier.rs @@ -50,7 +50,7 @@ fn has_failed(tx_receipt: &TransactionReceipt) -> bool { tx_receipt.status == Some(0u64.into()) } -fn get_event<'a>( +fn event<'a>( gateway_address: &EVMAddress, tx_receipt: &'a TransactionReceipt, log_index: u32, @@ -83,7 +83,7 @@ where return Vote::FailedOnChain; } - match get_event(gateway_address, tx_receipt, expected_event_index) { + match event(gateway_address, tx_receipt, expected_event_index) { Some(event) if tx_receipt.transaction_hash == expected_transaction_hash && to_verify == event => { @@ -135,7 +135,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_tx_id_does_not_match() { let (gateway_address, tx_receipt, mut verifier_set) = - get_matching_verifier_set_and_tx_receipt(); + matching_verifier_set_and_tx_receipt(); verifier_set.tx_id = Hash::random(); assert_eq!( @@ -147,7 +147,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_tx_failed() { let (gateway_address, mut tx_receipt, verifier_set) = - get_matching_verifier_set_and_tx_receipt(); + matching_verifier_set_and_tx_receipt(); tx_receipt.status = Some(0u64.into()); assert_eq!( @@ -158,7 +158,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_gateway_address_does_not_match() { - let (_, tx_receipt, verifier_set) = get_matching_verifier_set_and_tx_receipt(); + let (_, tx_receipt, verifier_set) = matching_verifier_set_and_tx_receipt(); let gateway_address = EVMAddress::random(); assert_eq!( @@ -170,7 +170,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_log_index_does_not_match() { let (gateway_address, tx_receipt, mut verifier_set) = - get_matching_verifier_set_and_tx_receipt(); + matching_verifier_set_and_tx_receipt(); verifier_set.event_index = 0; assert_eq!( @@ -192,7 +192,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_verifier_set_does_not_match() { let (gateway_address, tx_receipt, mut verifier_set) = - get_matching_verifier_set_and_tx_receipt(); + matching_verifier_set_and_tx_receipt(); verifier_set.verifier_set.threshold = Uint128::from(50u64); assert_eq!( @@ -203,8 +203,7 @@ mod tests { #[test] fn should_verify_verifier_set_if_correct() { - let (gateway_address, tx_receipt, verifier_set) = - get_matching_verifier_set_and_tx_receipt(); + let (gateway_address, tx_receipt, verifier_set) = matching_verifier_set_and_tx_receipt(); assert_eq!( verify_verifier_set(&gateway_address, &tx_receipt, &verifier_set), @@ -214,7 +213,7 @@ mod tests { #[test] fn should_not_verify_msg_if_tx_id_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_receipt(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_receipt(); msg.tx_id = Hash::random(); assert_eq!( @@ -225,7 +224,7 @@ mod tests { #[test] fn should_not_verify_msg_if_tx_failed() { - let (gateway_address, mut tx_receipt, msg) = get_matching_msg_and_tx_receipt(); + let (gateway_address, mut tx_receipt, msg) = matching_msg_and_tx_receipt(); tx_receipt.status = Some(0u64.into()); assert_eq!( @@ -236,7 +235,7 @@ mod tests { #[test] fn should_not_verify_msg_if_gateway_address_does_not_match() { - let (_, tx_receipt, msg) = get_matching_msg_and_tx_receipt(); + let (_, tx_receipt, msg) = matching_msg_and_tx_receipt(); let gateway_address = EVMAddress::random(); assert_eq!( @@ -247,7 +246,7 @@ mod tests { #[test] fn should_not_verify_msg_if_log_index_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_receipt(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_receipt(); msg.event_index = 0; assert_eq!( @@ -268,7 +267,7 @@ mod tests { #[test] fn should_not_verify_msg_if_msg_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_receipt(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_receipt(); msg.source_address = EVMAddress::random(); assert_eq!( @@ -279,7 +278,7 @@ mod tests { #[test] fn should_verify_msg_if_correct() { - let (gateway_address, tx_receipt, msg) = get_matching_msg_and_tx_receipt(); + let (gateway_address, tx_receipt, msg) = matching_msg_and_tx_receipt(); assert_eq!( verify_message(&gateway_address, &tx_receipt, &msg), @@ -287,7 +286,7 @@ mod tests { ); } - fn get_matching_verifier_set_and_tx_receipt( + fn matching_verifier_set_and_tx_receipt( ) -> (EVMAddress, TransactionReceipt, VerifierSetConfirmation) { let tx_id = Hash::random(); let log_index = 1; @@ -326,7 +325,7 @@ mod tests { (gateway_address, tx_receipt, verifier_set) } - fn get_matching_msg_and_tx_receipt() -> (EVMAddress, TransactionReceipt, Message) { + fn matching_msg_and_tx_receipt() -> (EVMAddress, TransactionReceipt, Message) { let tx_id = Hash::random(); let log_index = 1; let gateway_address = EVMAddress::random(); diff --git a/ampd/src/grpc/client.rs b/ampd/src/grpc/client.rs index 4ea5b8f13..44822fbc9 100644 --- a/ampd/src/grpc/client.rs +++ b/ampd/src/grpc/client.rs @@ -51,7 +51,7 @@ mod tests { use crate::event_sub::MockEventSub; use crate::grpc; use crate::proto::{ - Algorithm, BroadcastRequest, BroadcastResponse, GetKeyRequest, GetKeyResponse, SignRequest, + Algorithm, BroadcastRequest, BroadcastResponse, KeyRequest, KeyResponse, SignRequest, SignResponse, SubscribeRequest, }; use crate::queue::queued_broadcaster::MockBroadcasterClient; @@ -80,7 +80,7 @@ mod tests { } #[test] - async fn get_key_should_work() { + async fn key_should_work() { let key_id = "key_id"; let key: PublicKey = SigningKey::random(&mut OsRng).verifying_key().into(); let algorithm = Algorithm::Ed25519; @@ -105,14 +105,14 @@ mod tests { .await .unwrap() .crypto - .get_key(GetKeyRequest { + .key(KeyRequest { key_id: key_id.to_string(), algorithm: algorithm.into(), }) .await .unwrap() .into_inner(), - GetKeyResponse { + KeyResponse { pub_key: key.to_bytes() } ); diff --git a/ampd/src/grpc/server/crypto.rs b/ampd/src/grpc/server/crypto.rs index 690988c0e..48e912616 100644 --- a/ampd/src/grpc/server/crypto.rs +++ b/ampd/src/grpc/server/crypto.rs @@ -67,17 +67,17 @@ where Ok(Response::new(proto::SignResponse { signature })) } - async fn get_key( + async fn key( &self, - req: Request, - ) -> Result, Status> { + req: Request, + ) -> Result, Status> { let req = req.into_inner(); let algorithm = proto::Algorithm::from_i32(req.algorithm) .ok_or(Status::invalid_argument("invalid algorithm"))?; let key = self.key(&req.key_id, algorithm).await?; - Ok(Response::new(proto::GetKeyResponse { + Ok(Response::new(proto::KeyResponse { pub_key: key.to_bytes(), })) } @@ -92,9 +92,10 @@ mod tests { use tokio::test; use tonic::Code; - use super::proto::crypto_server::Crypto; use super::proto::{self}; use super::Server; + use crate::proto::crypto_server; + use crate::proto::crypto_server::Crypto; use crate::tofnd; use crate::tofnd::grpc::MockMultisig; use crate::types::PublicKey; @@ -158,7 +159,7 @@ mod tests { } #[test] - async fn get_key_should_return_correct_key() { + async fn key_should_return_correct_key() { let key_id = "key_id"; let algorithm = proto::Algorithm::Ecdsa; let key: PublicKey = SigningKey::random(&mut OsRng).verifying_key().into(); @@ -173,27 +174,30 @@ mod tests { .return_once(move |_, _| Ok(key)); let server = Server::new(multisig_client); - let req = tonic::Request::new(proto::GetKeyRequest { + let req = tonic::Request::new(proto::KeyRequest { key_id: key_id.to_string(), algorithm: algorithm.into(), }); - let res = server.get_key(req).await.unwrap().into_inner(); + let res = crypto_server::Crypto::key(&server, req) + .await + .unwrap() + .into_inner(); assert_eq!(res.pub_key, key.to_bytes()); } #[test] - async fn get_key_should_return_error_when_algorithm_is_invalid() { + async fn key_should_return_error_when_algorithm_is_invalid() { let key_id = "key_id"; let multisig_client = MockMultisig::default(); let server = Server::new(multisig_client); - let req = tonic::Request::new(proto::GetKeyRequest { + let req = tonic::Request::new(proto::KeyRequest { key_id: key_id.to_string(), algorithm: 2, }); - let res = server.get_key(req).await.unwrap_err(); + let res = crypto_server::Crypto::key(&server, req).await.unwrap_err(); assert_eq!(res.code(), Code::InvalidArgument); } diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 9133e4c8a..7abb4cc1d 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -246,7 +246,7 @@ mod tests { use crate::types::{EVMAddress, Hash, TMAddress}; use crate::PREFIX; - fn get_poll_started_event(participants: Vec, expires_at: u64) -> PollStarted { + fn poll_started_event(participants: Vec, expires_at: u64) -> PollStarted { PollStarted::Messages { metadata: PollMetadata { poll_id: "100".parse().unwrap(), @@ -293,8 +293,8 @@ mod tests { #[test] fn should_not_deserialize_incorrect_event() { // incorrect event type - let mut event: Event = get_event( - get_poll_started_event(participants(5, None), 100), + let mut event: Event = to_event( + poll_started_event(participants(5, None), 100), &TMAddress::random(PREFIX), ); match event { @@ -313,8 +313,8 @@ mod tests { )); // invalid field - let mut event: Event = get_event( - get_poll_started_event(participants(5, None), 100), + let mut event: Event = to_event( + poll_started_event(participants(5, None), 100), &TMAddress::random(PREFIX), ); match event { @@ -336,8 +336,8 @@ mod tests { #[test] fn should_deserialize_correct_event() { - let event: Event = get_event( - get_poll_started_event(participants(5, None), 100), + let event: Event = to_event( + poll_started_event(participants(5, None), 100), &TMAddress::random(PREFIX), ); let event: Result = event.try_into(); @@ -357,8 +357,8 @@ mod tests { let voting_verifier_contract = TMAddress::random(PREFIX); let verifier = TMAddress::random(PREFIX); let expiration = 100u64; - let event: Event = get_event( - get_poll_started_event(participants(5, Some(verifier.clone())), expiration), + let event: Event = to_event( + poll_started_event(participants(5, Some(verifier.clone())), expiration), &voting_verifier_contract, ); @@ -382,7 +382,7 @@ mod tests { assert_eq!(handler.handle(&event).await.unwrap(), vec![]); } - fn get_event(event: impl Into, contract_address: &TMAddress) -> Event { + fn to_event(event: impl Into, contract_address: &TMAddress) -> Event { let mut event: cosmwasm_std::Event = event.into(); event.ty = format!("wasm-{}", event.ty); diff --git a/ampd/src/handlers/evm_verify_verifier_set.rs b/ampd/src/handlers/evm_verify_verifier_set.rs index 9e936f248..7b7179c6c 100644 --- a/ampd/src/handlers/evm_verify_verifier_set.rs +++ b/ampd/src/handlers/evm_verify_verifier_set.rs @@ -223,7 +223,7 @@ mod tests { #[test] fn should_deserialize_correct_event() { - let event: Event = get_event( + let event: Event = to_event( poll_started_event(participants(5, None), 100), &TMAddress::random(PREFIX), ); @@ -245,7 +245,7 @@ mod tests { let voting_verifier = TMAddress::random(PREFIX); let verifier = TMAddress::random(PREFIX); let expiration = 100u64; - let event: Event = get_event( + let event: Event = to_event( poll_started_event(participants(5, Some(verifier.clone())), expiration), &voting_verifier, ); @@ -293,7 +293,7 @@ mod tests { } } - fn get_event(event: impl Into, contract_address: &TMAddress) -> Event { + fn to_event(event: impl Into, contract_address: &TMAddress) -> Event { let mut event: cosmwasm_std::Event = event.into(); event.ty = format!("wasm-{}", event.ty); diff --git a/ampd/src/handlers/mod.rs b/ampd/src/handlers/mod.rs index 026238768..8a15b92fd 100644 --- a/ampd/src/handlers/mod.rs +++ b/ampd/src/handlers/mod.rs @@ -18,7 +18,10 @@ mod tests { use crate::types::TMAddress; /// Convert a CosmWasm event into an ABCI event - pub fn get_event(event: impl Into, contract_address: &TMAddress) -> Event { + pub fn into_structured_event( + event: impl Into, + contract_address: &TMAddress, + ) -> Event { let mut event: cosmwasm_std::Event = event.into(); event.ty = format!("wasm-{}", event.ty); diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index c05936889..978ee4bdb 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -301,7 +301,7 @@ mod test { .unwrap() } - fn get_handler( + fn handler( verifier: TMAddress, multisig: TMAddress, signer: MockMultisig, @@ -376,7 +376,7 @@ mod test { async fn should_not_handle_event_with_missing_fields_if_multisig_address_does_not_match() { let client = MockMultisig::default(); - let handler = get_handler( + let handler = handler( rand_account(), TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), client, @@ -398,7 +398,7 @@ mod test { async fn should_error_on_event_with_missing_fields_if_multisig_address_does_match() { let client = MockMultisig::default(); - let handler = get_handler( + let handler = handler( rand_account(), TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), client, @@ -415,7 +415,7 @@ mod test { async fn should_not_handle_event_if_multisig_address_does_not_match() { let client = MockMultisig::default(); - let handler = get_handler(rand_account(), rand_account(), client, 100u64); + let handler = handler(rand_account(), rand_account(), client, 100u64); assert_eq!( handler.handle(&signing_started_event()).await.unwrap(), @@ -430,7 +430,7 @@ mod test { .expect_sign() .returning(move |_, _, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); - let handler = get_handler( + let handler = handler( rand_account(), TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), client, @@ -453,7 +453,7 @@ mod test { let event = signing_started_event(); let signing_started: SigningStartedEvent = ((&event).try_into() as Result<_, _>).unwrap(); let verifier = signing_started.pub_keys.keys().next().unwrap().clone(); - let handler = get_handler( + let handler = handler( verifier, TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), client, @@ -476,7 +476,7 @@ mod test { let event = signing_started_event(); let signing_started: SigningStartedEvent = ((&event).try_into() as Result<_, _>).unwrap(); let verifier = signing_started.pub_keys.keys().next().unwrap().clone(); - let handler = get_handler( + let handler = handler( verifier, TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), client, diff --git a/ampd/src/handlers/sui_verify_msg.rs b/ampd/src/handlers/sui_verify_msg.rs index 53dcbfdcf..3d60cb2b0 100644 --- a/ampd/src/handlers/sui_verify_msg.rs +++ b/ampd/src/handlers/sui_verify_msg.rs @@ -166,7 +166,7 @@ mod tests { use super::PollStartedEvent; use crate::event_processor::EventHandler; use crate::handlers::errors::Error; - use crate::handlers::tests::get_event; + use crate::handlers::tests::into_structured_event; use crate::sui::json_rpc::MockSuiClient; use crate::types::{EVMAddress, Hash, TMAddress}; @@ -174,7 +174,7 @@ mod tests { #[test] fn should_deserialize_poll_started_event() { - let event: Result = get_event( + let event: Result = into_structured_event( poll_started_event(participants(5, None), 100), &TMAddress::random(PREFIX), ) @@ -186,7 +186,7 @@ mod tests { // Should not handle event if it is not a poll started event #[async_test] async fn not_poll_started_event() { - let event = get_event( + let event = into_structured_event( cosmwasm_std::Event::new("transfer"), &TMAddress::random(PREFIX), ); @@ -204,7 +204,7 @@ mod tests { // Should not handle event if it is not emitted from voting verifier #[async_test] async fn contract_is_not_voting_verifier() { - let event = get_event( + let event = into_structured_event( poll_started_event(participants(5, None), 100), &TMAddress::random(PREFIX), ); @@ -223,7 +223,7 @@ mod tests { #[async_test] async fn verifier_is_not_a_participant() { let voting_verifier = TMAddress::random(PREFIX); - let event = get_event( + let event = into_structured_event( poll_started_event(participants(5, None), 100), &voting_verifier, ); @@ -252,7 +252,7 @@ mod tests { let voting_verifier = TMAddress::random(PREFIX); let verifier = TMAddress::random(PREFIX); - let event = get_event( + let event = into_structured_event( poll_started_event(participants(5, Some(verifier.clone())), 100), &voting_verifier, ); @@ -275,7 +275,7 @@ mod tests { let voting_verifier = TMAddress::random(PREFIX); let verifier = TMAddress::random(PREFIX); - let event = get_event( + let event = into_structured_event( poll_started_event(participants(5, Some(verifier.clone())), 100), &voting_verifier, ); @@ -303,7 +303,7 @@ mod tests { let voting_verifier = TMAddress::random(PREFIX); let verifier = TMAddress::random(PREFIX); let expiration = 100u64; - let event: Event = get_event( + let event: Event = into_structured_event( poll_started_event(participants(5, Some(verifier.clone())), expiration), &voting_verifier, ); diff --git a/ampd/src/handlers/sui_verify_verifier_set.rs b/ampd/src/handlers/sui_verify_verifier_set.rs index 8b12a701b..4a159c916 100644 --- a/ampd/src/handlers/sui_verify_verifier_set.rs +++ b/ampd/src/handlers/sui_verify_verifier_set.rs @@ -167,7 +167,7 @@ mod tests { use super::PollStartedEvent; use crate::event_processor::EventHandler; - use crate::handlers::tests::get_event; + use crate::handlers::tests::into_structured_event; use crate::sui::json_rpc::MockSuiClient; use crate::types::TMAddress; use crate::PREFIX; @@ -176,7 +176,7 @@ mod tests { fn should_deserialize_verifier_set_poll_started_event() { let participants = (0..5).map(|_| TMAddress::random(PREFIX)).collect(); - let event: Result = get_event( + let event: Result = into_structured_event( verifier_set_poll_started_event(participants, 100), &TMAddress::random(PREFIX), ) @@ -200,7 +200,7 @@ mod tests { let voting_verifier = TMAddress::random(PREFIX); let verifier = TMAddress::random(PREFIX); let expiration = 100u64; - let event: Event = get_event( + let event: Event = into_structured_event( verifier_set_poll_started_event( vec![verifier.clone()].into_iter().collect(), expiration, diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index 7dcf603e0..d49efb5bb 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -226,7 +226,7 @@ mod tests { #[test] fn should_not_verify_msg_if_tx_id_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_block(); msg.tx_id = TransactionDigest::random(); assert_eq!( @@ -237,7 +237,7 @@ mod tests { #[test] fn should_not_verify_msg_if_event_index_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_block(); msg.event_index = rand::random::(); assert_eq!( @@ -248,7 +248,7 @@ mod tests { #[test] fn should_not_verify_msg_if_source_address_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_block(); msg.source_address = SuiAddress::random_for_testing_only(); assert_eq!( @@ -259,7 +259,7 @@ mod tests { #[test] fn should_not_verify_msg_if_destination_chain_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_block(); msg.destination_chain = rand_chain_name(); assert_eq!( @@ -270,7 +270,7 @@ mod tests { #[test] fn should_not_verify_msg_if_destination_address_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_block(); msg.destination_address = EVMAddress::random().to_string(); assert_eq!( @@ -281,7 +281,7 @@ mod tests { #[test] fn should_not_verify_msg_if_payload_hash_does_not_match() { - let (gateway_address, tx_receipt, mut msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_receipt, mut msg) = matching_msg_and_tx_block(); msg.payload_hash = Hash::random(); assert_eq!( @@ -292,7 +292,7 @@ mod tests { #[test] fn should_verify_msg_if_correct() { - let (gateway_address, tx_block, msg) = get_matching_msg_and_tx_block(); + let (gateway_address, tx_block, msg) = matching_msg_and_tx_block(); assert_eq!( verify_message(&gateway_address, &tx_block, &msg), Vote::SucceededOnChain @@ -301,7 +301,7 @@ mod tests { #[test] fn should_verify_verifier_set_if_correct() { - let (gateway_address, tx_block, verifier_set) = get_matching_verifier_set_and_tx_block(); + let (gateway_address, tx_block, verifier_set) = matching_verifier_set_and_tx_block(); assert_eq!( verify_verifier_set(&gateway_address, &tx_block, &verifier_set), @@ -311,7 +311,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_gateway_address_mismatch() { - let (_, tx_block, verifier_set) = get_matching_verifier_set_and_tx_block(); + let (_, tx_block, verifier_set) = matching_verifier_set_and_tx_block(); assert_eq!( verify_verifier_set( @@ -325,8 +325,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_tx_digest_mismatch() { - let (gateway_address, mut tx_block, verifier_set) = - get_matching_verifier_set_and_tx_block(); + let (gateway_address, mut tx_block, verifier_set) = matching_verifier_set_and_tx_block(); tx_block.digest = TransactionDigest::random(); assert_eq!( @@ -337,8 +336,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_event_seq_mismatch() { - let (gateway_address, tx_block, mut verifier_set) = - get_matching_verifier_set_and_tx_block(); + let (gateway_address, tx_block, mut verifier_set) = matching_verifier_set_and_tx_block(); verifier_set.event_index = rand::random(); assert_eq!( @@ -349,8 +347,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_struct_tag_mismatch() { - let (gateway_address, mut tx_block, verifier_set) = - get_matching_verifier_set_and_tx_block(); + let (gateway_address, mut tx_block, verifier_set) = matching_verifier_set_and_tx_block(); tx_block .events .as_mut() @@ -373,8 +370,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_threshold_mismatch() { - let (gateway_address, tx_block, mut verifier_set) = - get_matching_verifier_set_and_tx_block(); + let (gateway_address, tx_block, mut verifier_set) = matching_verifier_set_and_tx_block(); verifier_set.verifier_set.threshold = Uint128::new(2); assert_eq!( @@ -385,8 +381,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_nonce_mismatch() { - let (gateway_address, tx_block, mut verifier_set) = - get_matching_verifier_set_and_tx_block(); + let (gateway_address, tx_block, mut verifier_set) = matching_verifier_set_and_tx_block(); verifier_set.verifier_set.created_at = rand::random(); assert_eq!( @@ -397,8 +392,7 @@ mod tests { #[test] fn should_not_verify_verifier_set_if_signers_mismatch() { - let (gateway_address, tx_block, mut verifier_set) = - get_matching_verifier_set_and_tx_block(); + let (gateway_address, tx_block, mut verifier_set) = matching_verifier_set_and_tx_block(); let signer = random_signer(); verifier_set .verifier_set @@ -411,7 +405,7 @@ mod tests { ); } - fn get_matching_msg_and_tx_block() -> (SuiAddress, SuiTransactionBlockResponse, Message) { + fn matching_msg_and_tx_block() -> (SuiAddress, SuiTransactionBlockResponse, Message) { let gateway_address = SuiAddress::random_for_testing_only(); let msg = Message { @@ -476,7 +470,7 @@ mod tests { } } - fn get_matching_verifier_set_and_tx_block() -> ( + fn matching_verifier_set_and_tx_block() -> ( SuiAddress, SuiTransactionBlockResponse, VerifierSetConfirmation, diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 2d750ec47..ebde2b2fe 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -140,8 +140,8 @@ mod internal { pub(crate) fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::GetOutgoingMessages(message_ids) => { - let msgs = contract::query::get_outgoing_messages(deps.storage, message_ids)?; + QueryMsg::OutgoingMessages(message_ids) => { + let msgs = contract::query::outgoing_messages(deps.storage, message_ids)?; to_json_binary(&msgs).change_context(Error::SerializeResponse) } } diff --git a/contracts/gateway/src/contract/query.rs b/contracts/gateway/src/contract/query.rs index c6b1a632d..62835b162 100644 --- a/contracts/gateway/src/contract/query.rs +++ b/contracts/gateway/src/contract/query.rs @@ -6,7 +6,7 @@ use router_api::{CrossChainId, Message}; use crate::contract::Error; use crate::state; -pub fn get_outgoing_messages( +pub fn outgoing_messages( storage: &dyn Storage, cross_chain_ids: Vec, ) -> Result, Error> { @@ -45,7 +45,7 @@ mod test { use crate::state; #[test] - fn get_outgoing_messages_all_messages_present_returns_all() { + fn outgoing_messages_all_messages_present_returns_all() { let mut deps = mock_dependencies(); let messages = generate_messages(); @@ -56,25 +56,25 @@ mod test { let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); - let res = super::get_outgoing_messages(&deps.storage, ids).unwrap(); + let res = super::outgoing_messages(&deps.storage, ids).unwrap(); assert_eq!(res, messages); } #[test] - fn get_outgoing_messages_nothing_stored_returns_not_found_error() { + fn outgoing_messages_nothing_stored_returns_not_found_error() { let deps = mock_dependencies(); let messages = generate_messages(); let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); - let res = super::get_outgoing_messages(&deps.storage, ids); + let res = super::outgoing_messages(&deps.storage, ids); assert!(res.is_err()); assert_eq!(res.unwrap_err().current_frames().len(), messages.len()); } #[test] - fn get_outgoing_messages_only_partially_found_returns_not_found_error() { + fn outgoing_messages_only_partially_found_returns_not_found_error() { let mut deps = mock_dependencies(); let messages = generate_messages(); @@ -83,7 +83,7 @@ mod test { let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); - let res = super::get_outgoing_messages(&deps.storage, ids); + let res = super::outgoing_messages(&deps.storage, ids); assert!(res.is_err()); assert_eq!(res.unwrap_err().current_frames().len(), messages.len() - 1); diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index a2bc314fc..ef8541942 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -139,7 +139,7 @@ fn successful_route_outgoing() { instantiate_contract(deps.as_mut(), "verifier", router); let query_msg = - QueryMsg::GetOutgoingMessages(msgs.iter().map(|msg| msg.cc_id.clone()).collect()); + QueryMsg::OutgoingMessages(msgs.iter().map(|msg| msg.cc_id.clone()).collect()); // check no messages are outgoing let query_response = query(deps.as_ref(), mock_env(), query_msg.clone()); @@ -397,7 +397,7 @@ fn correctly_working_verifier_handler( { move |msg: voting_verifier::msg::QueryMsg| -> Result, ContractError> { match msg { - voting_verifier::msg::QueryMsg::GetMessagesStatus(messages) => Ok(messages + voting_verifier::msg::QueryMsg::MessagesStatus(messages) => Ok(messages .into_iter() .map(|msg| { MessageStatus::new( diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 2bd5949ca..9bde0dad4 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -96,9 +96,9 @@ pub fn query( msg: QueryMsg, ) -> Result { match msg { - QueryMsg::GetProof { + QueryMsg::Proof { multisig_session_id, - } => to_json_binary(&query::get_proof(deps, multisig_session_id)?), + } => to_json_binary(&query::proof(deps, multisig_session_id)?), QueryMsg::CurrentVerifierSet {} => to_json_binary(&query::current_verifier_set(deps)?), QueryMsg::NextVerifierSet {} => to_json_binary(&query::next_verifier_set(deps)?), } @@ -137,7 +137,7 @@ mod tests { use super::*; use crate::contract::execute::should_update_verifier_set; use crate::encoding::Encoder; - use crate::msg::{GetProofResponse, ProofStatus, VerifierSetResponse}; + use crate::msg::{ProofResponse, ProofStatus, VerifierSetResponse}; use crate::test::test_data::{self, TestOperator}; use crate::test::test_utils::{ mock_querier_handler, ADMIN, COORDINATOR_ADDRESS, GATEWAY_ADDRESS, GOVERNANCE, @@ -256,10 +256,10 @@ mod tests { ) } - fn query_get_proof( + fn query_proof( deps: Deps, multisig_session_id: Option, - ) -> Result { + ) -> Result { let multisig_session_id = match multisig_session_id { Some(id) => id, None => MULTISIG_SESSION_ID, @@ -268,14 +268,14 @@ mod tests { query( deps, mock_env(), - QueryMsg::GetProof { + QueryMsg::Proof { multisig_session_id, }, ) .map(|res| from_json(res).unwrap()) } - fn query_get_verifier_set( + fn query_verifier_set( deps: Deps, ) -> Result, axelar_wasm_std::error::ContractError> { query(deps, mock_env(), QueryMsg::CurrentVerifierSet {}).map(|res| from_json(res).unwrap()) @@ -385,14 +385,14 @@ mod tests { #[test] fn test_update_verifier_set_fresh() { let mut deps = setup_test_case(); - let verifier_set = query_get_verifier_set(deps.as_ref()); + let verifier_set = query_verifier_set(deps.as_ref()); assert!(verifier_set.is_ok()); assert!(verifier_set.unwrap().is_none()); let res = execute_update_verifier_set(deps.as_mut()); assert!(res.is_ok()); - let verifier_set = query_get_verifier_set(deps.as_ref()); + let verifier_set = query_verifier_set(deps.as_ref()); assert!(verifier_set.is_ok()); let verifier_set = verifier_set.unwrap().unwrap(); @@ -468,7 +468,7 @@ mod tests { assert!(res.is_ok()); - let verifier_set = query_get_verifier_set(deps.as_ref()); + let verifier_set = query_verifier_set(deps.as_ref()); assert!(verifier_set.is_ok()); let verifier_set = verifier_set.unwrap().unwrap(); @@ -502,7 +502,7 @@ mod tests { let res = execute_update_verifier_set(deps.as_mut()); assert!(res.is_ok()); - let verifier_set = query_get_verifier_set(deps.as_ref()); + let verifier_set = query_verifier_set(deps.as_ref()); assert!(verifier_set.is_ok()); let verifier_set = verifier_set.unwrap().unwrap(); @@ -536,7 +536,7 @@ mod tests { assert!(res.is_ok()); - let verifier_set = query_get_verifier_set(deps.as_ref()); + let verifier_set = query_verifier_set(deps.as_ref()); assert!(verifier_set.is_ok()); let verifier_set = verifier_set.unwrap().unwrap(); @@ -653,7 +653,7 @@ mod tests { execute_construct_proof(deps.as_mut(), None).unwrap(); reply_construct_proof(deps.as_mut()).unwrap(); // simulate reply from multisig - let res = query_get_proof(deps.as_ref(), None).unwrap(); + let res = query_proof(deps.as_ref(), None).unwrap(); assert_eq!(res.multisig_session_id, MULTISIG_SESSION_ID); assert_eq!(res.message_ids.len(), 1); @@ -702,7 +702,7 @@ mod tests { /// Calls update_signing_threshold, increasing the threshold by one. /// Returns (initial threshold, new threshold) fn update_signing_threshold_increase_by_one(deps: DepsMut) -> (Uint128, Uint128) { - let verifier_set = query_get_verifier_set(deps.as_ref()) + let verifier_set = query_verifier_set(deps.as_ref()) .unwrap() .unwrap() .verifier_set; @@ -740,7 +740,7 @@ mod tests { update_signing_threshold_increase_by_one(deps.as_mut()); assert_ne!(initial_threshold, new_threshold); - let verifier_set = query_get_verifier_set(deps.as_ref()) + let verifier_set = query_verifier_set(deps.as_ref()) .unwrap() .unwrap() .verifier_set; @@ -761,7 +761,7 @@ mod tests { let governance = Addr::unchecked(GOVERNANCE); confirm_verifier_set(deps.as_mut(), governance).unwrap(); - let verifier_set = query_get_verifier_set(deps.as_ref()) + let verifier_set = query_verifier_set(deps.as_ref()) .unwrap() .unwrap() .verifier_set; @@ -782,7 +782,7 @@ mod tests { let res = confirm_verifier_set(deps.as_mut(), Addr::unchecked("relayer")); assert!(res.is_ok()); - let verifier_set = query_get_verifier_set(deps.as_ref()) + let verifier_set = query_verifier_set(deps.as_ref()) .unwrap() .unwrap() .verifier_set; diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index 08689eb7b..40452f796 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -27,7 +27,7 @@ pub fn construct_proof( let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; let payload_id = message_ids.as_slice().into(); - let messages = get_messages( + let messages = messages( deps.querier, message_ids, config.gateway.clone(), @@ -74,7 +74,7 @@ pub fn construct_proof( Ok(Response::new().add_submessage(SubMsg::reply_on_success(wasm_msg, START_MULTISIG_REPLY_ID))) } -fn get_messages( +fn messages( querier: QuerierWrapper, message_ids: Vec, gateway: Addr, @@ -82,7 +82,7 @@ fn get_messages( ) -> Result, ContractError> { let length = message_ids.len(); - let query = gateway_api::msg::QueryMsg::GetOutgoingMessages(message_ids); + let query = gateway_api::msg::QueryMsg::OutgoingMessages(message_ids); let messages: Vec = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: gateway.into(), msg: to_json_binary(&query)?, @@ -109,7 +109,7 @@ fn make_verifier_set( env: &Env, config: &Config, ) -> Result { - let active_verifiers_query = service_registry::msg::QueryMsg::GetActiveVerifiers { + let active_verifiers_query = service_registry::msg::QueryMsg::ActiveVerifiers { service_name: config.service_name.clone(), chain_name: config.chain_name.clone(), }; @@ -124,7 +124,7 @@ fn make_verifier_set( .querier .query::(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.service_registry.to_string(), - msg: to_json_binary(&service_registry::msg::QueryMsg::GetService { + msg: to_json_binary(&service_registry::msg::QueryMsg::Service { service_name: config.service_name.clone(), })?, }))? @@ -133,7 +133,7 @@ fn make_verifier_set( let participants_with_pubkeys = verifiers .into_iter() .filter_map(|verifier| { - let pub_key_query = multisig::msg::QueryMsg::GetPublicKey { + let pub_key_query = multisig::msg::QueryMsg::PublicKey { verifier_address: verifier.verifier_info.address.to_string(), key_type: config.key_type, }; @@ -168,7 +168,7 @@ fn make_verifier_set( )) } -fn get_next_verifier_set( +fn next_verifier_set( deps: &DepsMut, env: &Env, config: &Config, @@ -237,7 +237,7 @@ pub fn update_verifier_set( )) } Some(cur_verifier_set) => { - let new_verifier_set = get_next_verifier_set(&deps, &env, &config)? + let new_verifier_set = next_verifier_set(&deps, &env, &config)? .ok_or(ContractError::VerifierSetUnchanged)?; save_next_verifier_set(deps.storage, &new_verifier_set)?; @@ -288,7 +288,7 @@ fn ensure_verifier_set_verification( config: &Config, deps: &DepsMut, ) -> Result<(), ContractError> { - let query = voting_verifier::msg::QueryMsg::GetVerifierSetStatus(verifier_set.clone()); + let query = voting_verifier::msg::QueryMsg::VerifierSetStatus(verifier_set.clone()); let status: VerificationStatus = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.voting_verifier.to_string(), @@ -413,7 +413,7 @@ mod tests { use cosmwasm_std::Addr; use router_api::ChainName; - use super::{different_set_in_progress, get_next_verifier_set, should_update_verifier_set}; + use super::{different_set_in_progress, next_verifier_set, should_update_verifier_set}; use crate::state::{Config, NEXT_VERIFIER_SET}; use crate::test::test_data; @@ -521,14 +521,14 @@ mod tests { } #[test] - fn get_next_verifier_set_should_return_pending() { + fn next_verifier_set_should_return_pending() { let mut deps = mock_dependencies(); let env = mock_env(); let new_verifier_set = test_data::new_verifier_set(); NEXT_VERIFIER_SET .save(deps.as_mut().storage, &new_verifier_set) .unwrap(); - let ret_verifier_set = get_next_verifier_set(&deps.as_mut(), &env, &mock_config()); + let ret_verifier_set = next_verifier_set(&deps.as_mut(), &env, &mock_config()); assert_eq!(ret_verifier_set.unwrap().unwrap(), new_verifier_set); } diff --git a/contracts/multisig-prover/src/contract/query.rs b/contracts/multisig-prover/src/contract/query.rs index 82f620f47..14c35a102 100644 --- a/contracts/multisig-prover/src/contract/query.rs +++ b/contracts/multisig-prover/src/contract/query.rs @@ -4,22 +4,19 @@ use multisig::multisig::Multisig; use multisig::types::MultisigState; use crate::error::ContractError; -use crate::msg::{GetProofResponse, ProofStatus, VerifierSetResponse}; +use crate::msg::{ProofResponse, ProofStatus, VerifierSetResponse}; use crate::state::{ CONFIG, CURRENT_VERIFIER_SET, MULTISIG_SESSION_PAYLOAD, NEXT_VERIFIER_SET, PAYLOAD, }; -pub fn get_proof( - deps: Deps, - multisig_session_id: Uint64, -) -> Result { +pub fn proof(deps: Deps, multisig_session_id: Uint64) -> Result { let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; let payload_id = MULTISIG_SESSION_PAYLOAD .load(deps.storage, multisig_session_id.u64()) .map_err(ContractError::from)?; - let query_msg = multisig::msg::QueryMsg::GetMultisig { + let query_msg = multisig::msg::QueryMsg::Multisig { session_id: multisig_session_id, }; @@ -49,7 +46,7 @@ pub fn get_proof( } }; - Ok(GetProofResponse { + Ok(ProofResponse { multisig_session_id, message_ids: payload.message_ids().unwrap_or_default(), payload, diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index 0b0e23d54..69b50beaf 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -82,8 +82,8 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(GetProofResponse)] - GetProof { multisig_session_id: Uint64 }, + #[returns(ProofResponse)] + Proof { multisig_session_id: Uint64 }, /// Returns a `VerifierSetResponse` with the current verifier set id and the verifier set itself. #[returns(Option)] @@ -101,7 +101,7 @@ pub enum ProofStatus { } #[cw_serde] -pub struct GetProofResponse { +pub struct ProofResponse { pub multisig_session_id: Uint64, pub message_ids: Vec, pub payload: Payload, diff --git a/contracts/multisig-prover/src/test/test_utils.rs b/contracts/multisig-prover/src/test/test_utils.rs index 5db7060f8..1553a98a4 100644 --- a/contracts/multisig-prover/src/test/test_utils.rs +++ b/contracts/multisig-prover/src/test/test_utils.rs @@ -49,10 +49,10 @@ fn multisig_mock_querier_handler( operators: Vec, ) -> QuerierResult { let result = match msg { - multisig::msg::QueryMsg::GetMultisig { session_id: _ } => { - to_json_binary(&mock_get_multisig(operators)) + multisig::msg::QueryMsg::Multisig { session_id: _ } => { + to_json_binary(&mock_multisig(operators)) } - multisig::msg::QueryMsg::GetPublicKey { + multisig::msg::QueryMsg::PublicKey { verifier_address, key_type: _, } => to_json_binary( @@ -68,7 +68,7 @@ fn multisig_mock_querier_handler( Ok(result.into()).into() } -fn mock_get_multisig(operators: Vec) -> Multisig { +fn mock_multisig(operators: Vec) -> Multisig { let quorum = test_data::quorum(); let signers = operators @@ -117,7 +117,7 @@ fn service_registry_mock_querier_handler( operators: Vec, ) -> QuerierResult { let result = match msg { - service_registry::msg::QueryMsg::GetService { service_name } => { + service_registry::msg::QueryMsg::Service { service_name } => { to_json_binary(&service_registry::state::Service { name: service_name.to_string(), coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), @@ -129,7 +129,7 @@ fn service_registry_mock_querier_handler( description: "verifiers".to_string(), }) } - service_registry::msg::QueryMsg::GetActiveVerifiers { + service_registry::msg::QueryMsg::ActiveVerifiers { service_name: _, chain_name: _, } => to_json_binary( diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 4f0ea8120..b9116cf07 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -14,7 +14,7 @@ use router_api::ChainName; use crate::events::Event; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrationMsg, QueryMsg}; use crate::state::{ - get_verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, + verifier_set, Config, CONFIG, SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS, }; use crate::types::{MsgToSign, MultisigState}; use crate::ContractError; @@ -167,16 +167,14 @@ fn can_start_signing_session( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetMultisig { session_id } => { - to_json_binary(&query::get_multisig(deps, session_id)?) + QueryMsg::Multisig { session_id } => to_json_binary(&query::multisig(deps, session_id)?), + QueryMsg::VerifierSet { verifier_set_id } => { + to_json_binary(&query::verifier_set(deps, verifier_set_id)?) } - QueryMsg::GetVerifierSet { verifier_set_id } => { - to_json_binary(&query::get_verifier_set(deps, verifier_set_id)?) - } - QueryMsg::GetPublicKey { + QueryMsg::PublicKey { verifier_address, key_type, - } => to_json_binary(&query::get_public_key( + } => to_json_binary(&query::public_key( deps, deps.api.addr_validate(&verifier_address)?, key_type, @@ -261,7 +259,7 @@ mod tests { query( deps, env, - QueryMsg::GetVerifierSet { + QueryMsg::VerifierSet { verifier_set_id: verifier_set_id.to_string(), }, ) @@ -375,7 +373,7 @@ mod tests { query( deps, env, - QueryMsg::GetPublicKey { + QueryMsg::PublicKey { verifier_address: verifier.to_string(), key_type, }, @@ -402,7 +400,7 @@ mod tests { } // TODO: move to external crate? - fn get_event_attribute<'a>( + fn event_attribute<'a>( event: &'a cosmwasm_std::Event, attribute_name: &'a str, ) -> Option<&'a str> { @@ -514,7 +512,7 @@ mod tests { .unwrap(); let verifier_set_id = subkey.to_string(); - let verifier_set = get_verifier_set(deps.as_ref().storage, &verifier_set_id).unwrap(); + let verifier_set = verifier_set(deps.as_ref().storage, &verifier_set_id).unwrap(); let message = match subkey { _ if subkey == ecdsa_subkey => ecdsa_test_data::message(), _ if subkey == ed25519_subkey => ed25519_test_data::message(), @@ -536,18 +534,18 @@ mod tests { let event = res.events.first().unwrap(); assert_eq!(event.ty, "signing_started".to_string()); assert_eq!( - get_event_attribute(event, "session_id").unwrap(), + event_attribute(event, "session_id").unwrap(), session.id.to_string() ); assert_eq!( - get_event_attribute(event, "verifier_set_id").unwrap(), + event_attribute(event, "verifier_set_id").unwrap(), session.verifier_set_id ); assert_eq!( - verifier_set.get_pub_keys(), - from_str(get_event_attribute(event, "pub_keys").unwrap()).unwrap() + verifier_set.pub_keys(), + from_str(event_attribute(event, "pub_keys").unwrap()).unwrap() ); - assert_eq!(get_event_attribute(event, "msg").unwrap(), message.to_hex()); + assert_eq!(event_attribute(event, "msg").unwrap(), message.to_hex()); } } @@ -635,15 +633,15 @@ mod tests { let event = res.events.first().unwrap(); assert_eq!(event.ty, "signature_submitted".to_string()); assert_eq!( - get_event_attribute(event, "session_id").unwrap(), + event_attribute(event, "session_id").unwrap(), session_id.to_string() ); assert_eq!( - get_event_attribute(event, "participant").unwrap(), + event_attribute(event, "participant").unwrap(), signer.address.into_string() ); assert_eq!( - get_event_attribute(event, "signature").unwrap(), + event_attribute(event, "signature").unwrap(), signer.signature.to_hex() ); } @@ -700,7 +698,7 @@ mod tests { let event = res.events.get(1).unwrap(); assert_eq!(event.ty, "signing_completed".to_string()); assert_eq!( - get_event_attribute(event, "session_id").unwrap(), + event_attribute(event, "session_id").unwrap(), session_id.to_string() ); } @@ -846,7 +844,7 @@ mod tests { let expected_completed_at = env.block.height; do_sign(deps.as_mut(), env, session_id, signers.get(1).unwrap()).unwrap(); - let msg = QueryMsg::GetMultisig { session_id }; + let msg = QueryMsg::Multisig { session_id }; let res = query(deps.as_ref(), mock_env(), msg); assert!(res.is_ok()); diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index 81cea039c..00c0c302f 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -26,7 +26,7 @@ pub fn start_signing_session( let config = CONFIG.load(deps.storage)?; - let verifier_set = get_verifier_set(deps.storage, &verifier_set_id)?; + let verifier_set = verifier_set(deps.storage, &verifier_set_id)?; let session_id = SIGNING_SESSION_COUNTER.update( deps.storage, @@ -64,7 +64,7 @@ pub fn start_signing_session( let event = Event::SigningStarted { session_id, verifier_set_id, - pub_keys: verifier_set.get_pub_keys(), + pub_keys: verifier_set.pub_keys(), msg, chain_name, expires_at, diff --git a/contracts/multisig/src/contract/query.rs b/contracts/multisig/src/contract/query.rs index 6d34cc0e6..8279883ee 100644 --- a/contracts/multisig/src/contract/query.rs +++ b/contracts/multisig/src/contract/query.rs @@ -6,7 +6,7 @@ use crate::multisig::Multisig; use crate::state::{load_pub_key, load_session_signatures, AUTHORIZED_CALLERS}; use crate::verifier_set::VerifierSet; -pub fn get_multisig(deps: Deps, session_id: Uint64) -> StdResult { +pub fn multisig(deps: Deps, session_id: Uint64) -> StdResult { let session = SIGNING_SESSIONS.load(deps.storage, session_id.into())?; let verifier_set = VERIFIER_SETS.load(deps.storage, &session.verifier_set_id)?; @@ -19,11 +19,11 @@ pub fn get_multisig(deps: Deps, session_id: Uint64) -> StdResult { }) } -pub fn get_verifier_set(deps: Deps, verifier_set_id: String) -> StdResult { +pub fn verifier_set(deps: Deps, verifier_set_id: String) -> StdResult { VERIFIER_SETS.load(deps.storage, &verifier_set_id) } -pub fn get_public_key(deps: Deps, verifier: Addr, key_type: KeyType) -> StdResult { +pub fn public_key(deps: Deps, verifier: Addr, key_type: KeyType) -> StdResult { let raw = load_pub_key(deps.storage, verifier, key_type)?; Ok(PublicKey::try_from((key_type, raw)).expect("could not decode pub key")) } diff --git a/contracts/multisig/src/msg.rs b/contracts/multisig/src/msg.rs index 6a88d696c..213d76c81 100644 --- a/contracts/multisig/src/msg.rs +++ b/contracts/multisig/src/msg.rs @@ -82,13 +82,13 @@ pub enum ExecuteMsg { #[derive(QueryResponses)] pub enum QueryMsg { #[returns(Multisig)] - GetMultisig { session_id: Uint64 }, + Multisig { session_id: Uint64 }, #[returns(VerifierSet)] - GetVerifierSet { verifier_set_id: String }, + VerifierSet { verifier_set_id: String }, #[returns(PublicKey)] - GetPublicKey { + PublicKey { verifier_address: String, key_type: KeyType, }, diff --git a/contracts/multisig/src/state.rs b/contracts/multisig/src/state.rs index 0ead03953..43979c058 100644 --- a/contracts/multisig/src/state.rs +++ b/contracts/multisig/src/state.rs @@ -57,7 +57,7 @@ pub fn save_signature( type VerifierSetId = str; pub const VERIFIER_SETS: Map<&VerifierSetId, VerifierSet> = Map::new("verifier_sets"); -pub fn get_verifier_set( +pub fn verifier_set( store: &dyn Storage, verifier_set_id: &str, ) -> Result { diff --git a/contracts/multisig/src/verifier_set.rs b/contracts/multisig/src/verifier_set.rs index 634a63dde..637859165 100644 --- a/contracts/multisig/src/verifier_set.rs +++ b/contracts/multisig/src/verifier_set.rs @@ -65,7 +65,7 @@ impl VerifierSet { HexBinary::from(self.hash()).to_hex() } - pub fn get_pub_keys(&self) -> HashMap { + pub fn pub_keys(&self) -> HashMap { self.signers .iter() .map(|(address, signer)| (address.clone(), signer.pub_key.clone())) diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 205bcee8e..2180858c3 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -128,9 +128,7 @@ pub fn query( msg: QueryMsg, ) -> Result { match msg { - QueryMsg::GetChainInfo(chain) => { - to_json_binary(&query::get_chain_info(deps.storage, chain)?) - } + QueryMsg::ChainInfo(chain) => to_json_binary(&query::chain_info(deps.storage, chain)?), QueryMsg::Chains { start_after, limit } => { to_json_binary(&query::chains(deps, start_after, limit)?) } diff --git a/contracts/router/src/contract/query.rs b/contracts/router/src/contract/query.rs index 28a3f70aa..d10f23aae 100644 --- a/contracts/router/src/contract/query.rs +++ b/contracts/router/src/contract/query.rs @@ -9,7 +9,7 @@ use crate::state::chain_endpoints; // Pagination limits const DEFAULT_LIMIT: u32 = u32::MAX; -pub fn get_chain_info(storage: &dyn Storage, chain: ChainName) -> Result { +pub fn chain_info(storage: &dyn Storage, chain: ChainName) -> Result { chain_endpoints() .may_load(storage, chain) .change_context(Error::StoreFailure)? @@ -42,14 +42,14 @@ mod test { use router_api::error::Error; use router_api::{ChainEndpoint, ChainName, Gateway, GatewayDirection}; - use super::get_chain_info; + use super::chain_info; use crate::state::chain_endpoints; #[test] fn should_get_chain_info() { let mut deps = mock_dependencies(); let chain_name: ChainName = "Ethereum".try_into().unwrap(); - let chain_info = ChainEndpoint { + let endpoint = ChainEndpoint { name: chain_name.clone(), gateway: Gateway { address: Addr::unchecked("some gateway"), @@ -59,18 +59,18 @@ mod test { }; assert!(chain_endpoints() - .save(deps.as_mut().storage, chain_name.clone(), &chain_info) + .save(deps.as_mut().storage, chain_name.clone(), &endpoint) .is_ok()); - let result = get_chain_info(deps.as_ref().storage, chain_name); + let result = chain_info(deps.as_ref().storage, chain_name); assert!(result.is_ok()); - assert_eq!(result.unwrap(), chain_info); + assert_eq!(result.unwrap(), endpoint); } #[test] fn get_non_existent_chain_info() { let deps = mock_dependencies(); let chain_name: ChainName = "Ethereum".try_into().unwrap(); - let result = get_chain_info(deps.as_ref().storage, chain_name); + let result = chain_info(deps.as_ref().storage, chain_name); assert!(result.is_err()); assert_eq!(result.unwrap_err().current_context(), &Error::ChainNotFound); } diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 98f4bf970..04899b415 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -147,22 +147,18 @@ fn match_verifier( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name, chain_name, - } => to_json_binary(&query::get_active_verifiers( - deps, - service_name, - chain_name, - )?) - .map_err(|err| err.into()), - QueryMsg::GetVerifier { + } => to_json_binary(&query::active_verifiers(deps, service_name, chain_name)?) + .map_err(|err| err.into()), + QueryMsg::Verifier { service_name, verifier, - } => to_json_binary(&query::get_verifier(deps, service_name, verifier)?) + } => to_json_binary(&query::verifier(deps, service_name, verifier)?) .map_err(|err| err.into()), - QueryMsg::GetService { service_name } => { - to_json_binary(&query::get_service(deps, service_name)?).map_err(|err| err.into()) + QueryMsg::Service { service_name } => { + to_json_binary(&query::service(deps, service_name)?).map_err(|err| err.into()) } } } @@ -428,7 +424,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -455,7 +451,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: ChainName::from_str("random chain").unwrap(), }, @@ -543,7 +539,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -635,7 +631,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: chain, }, @@ -731,7 +727,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: deregistered_chain, }, @@ -747,7 +743,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: chain.clone(), }, @@ -850,7 +846,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -962,7 +958,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1051,7 +1047,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1125,7 +1121,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1183,7 +1179,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1293,7 +1289,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1399,7 +1395,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1473,7 +1469,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1547,7 +1543,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1654,7 +1650,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name, }, @@ -1800,7 +1796,7 @@ mod test { #[test] #[allow(clippy::cast_possible_truncation)] - fn get_active_verifiers_should_not_return_less_than_min() { + fn active_verifiers_should_not_return_less_than_min() { let mut deps = setup(); let verifiers = vec![Addr::unchecked("verifier1"), Addr::unchecked("verifier2")]; @@ -1843,7 +1839,7 @@ mod test { let res = query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: chain_name.clone(), }, @@ -1880,7 +1876,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: chain_name.clone(), }, @@ -1903,7 +1899,7 @@ mod test { let res = query( deps.as_ref(), mock_env(), - QueryMsg::GetActiveVerifiers { + QueryMsg::ActiveVerifiers { service_name: service_name.into(), chain_name: chain_name.clone(), }, @@ -2013,7 +2009,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifier { + QueryMsg::Verifier { service_name: service_name.into(), verifier: verifier2.to_string(), }, diff --git a/contracts/service-registry/src/contract/query.rs b/contracts/service-registry/src/contract/query.rs index 7748cb027..241bfce10 100644 --- a/contracts/service-registry/src/contract/query.rs +++ b/contracts/service-registry/src/contract/query.rs @@ -3,7 +3,7 @@ use router_api::ChainName; use super::*; use crate::state::{WeightedVerifier, VERIFIERS, VERIFIERS_PER_CHAIN, VERIFIER_WEIGHT}; -pub fn get_active_verifiers( +pub fn active_verifiers( deps: Deps, service_name: String, chain_name: ChainName, @@ -36,7 +36,7 @@ pub fn get_active_verifiers( } } -pub fn get_verifier( +pub fn verifier( deps: Deps, service_name: String, verifier: String, @@ -49,7 +49,7 @@ pub fn get_verifier( .ok_or(ContractError::VerifierNotFound) } -pub fn get_service(deps: Deps, service_name: String) -> Result { +pub fn service(deps: Deps, service_name: String) -> Result { SERVICES .may_load(deps.storage, &service_name)? .ok_or(ContractError::ServiceNotFound) diff --git a/contracts/service-registry/src/msg.rs b/contracts/service-registry/src/msg.rs index ca30c421a..934e07bab 100644 --- a/contracts/service-registry/src/msg.rs +++ b/contracts/service-registry/src/msg.rs @@ -70,16 +70,16 @@ pub enum ExecuteMsg { #[derive(QueryResponses)] pub enum QueryMsg { #[returns(Vec)] - GetActiveVerifiers { + ActiveVerifiers { service_name: String, chain_name: ChainName, }, #[returns(crate::state::Service)] - GetService { service_name: String }, + Service { service_name: String }, #[returns(crate::state::Verifier)] - GetVerifier { + Verifier { service_name: String, verifier: String, }, diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index 5363e4dfc..a98d4de21 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -58,7 +58,7 @@ impl<'a> Client<'a> { pub fn poll(&self, poll_id: PollId) -> Result { self.client - .query(&QueryMsg::GetPoll { poll_id }) + .query(&QueryMsg::Poll { poll_id }) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())) } @@ -67,20 +67,20 @@ impl<'a> Client<'a> { [] => Ok(vec![]), _ => self .client - .query(&QueryMsg::GetMessagesStatus(messages)) + .query(&QueryMsg::MessagesStatus(messages)) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())), } } pub fn verifier_set_status(&self, new_verifier_set: VerifierSet) -> Result { self.client - .query(&QueryMsg::GetVerifierSetStatus(new_verifier_set)) + .query(&QueryMsg::VerifierSetStatus(new_verifier_set)) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())) } pub fn current_threshold(&self) -> Result { self.client - .query(&QueryMsg::GetCurrentThreshold) + .query(&QueryMsg::CurrentThreshold) .change_context_lazy(|| Error::QueryVotingVerifier(self.client.address.clone())) } } diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 216b220ab..8c6602450 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -71,17 +71,17 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetPoll { poll_id } => { + QueryMsg::Poll { poll_id } => { to_json_binary(&query::poll_response(deps, env.block.height, poll_id)?) } - QueryMsg::GetMessagesStatus(messages) => { + QueryMsg::MessagesStatus(messages) => { to_json_binary(&query::messages_status(deps, &messages, env.block.height)?) } - QueryMsg::GetVerifierSetStatus(new_verifier_set) => to_json_binary( + QueryMsg::VerifierSetStatus(new_verifier_set) => to_json_binary( &query::verifier_set_status(deps, &new_verifier_set, env.block.height)?, ), - QueryMsg::GetCurrentThreshold => to_json_binary(&query::voting_threshold(deps)?), + QueryMsg::CurrentThreshold => to_json_binary(&query::voting_threshold(deps)?), } } @@ -422,7 +422,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -539,7 +539,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -575,7 +575,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -606,7 +606,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -638,7 +638,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -670,7 +670,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -746,7 +746,7 @@ mod test { &query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -773,7 +773,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus(verifier_set.clone()), + QueryMsg::VerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -823,7 +823,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus(verifier_set.clone()), + QueryMsg::VerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -876,7 +876,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus(verifier_set.clone()), + QueryMsg::VerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -929,7 +929,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus(verifier_set.clone()), + QueryMsg::VerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -974,7 +974,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetVerifierSetStatus(verifier_set.clone()), + QueryMsg::VerifierSetStatus(verifier_set.clone()), ) .unwrap(), ) @@ -1060,7 +1060,7 @@ mod test { ) .unwrap(); - let res = query(deps.as_ref(), mock_env(), QueryMsg::GetCurrentThreshold).unwrap(); + let res = query(deps.as_ref(), mock_env(), QueryMsg::CurrentThreshold).unwrap(); let threshold: MajorityThreshold = from_json(res).unwrap(); assert_eq!(threshold, new_voting_threshold); @@ -1137,7 +1137,7 @@ mod test { query( deps.as_ref(), mock_env(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) @@ -1224,7 +1224,7 @@ mod test { query( deps.as_ref(), mock_env_expired(), - QueryMsg::GetMessagesStatus(messages.clone()), + QueryMsg::MessagesStatus(messages.clone()), ) .unwrap(), ) diff --git a/contracts/voting-verifier/src/contract/execute.rs b/contracts/voting-verifier/src/contract/execute.rs index e5a6cc991..41c76dc85 100644 --- a/contracts/voting-verifier/src/contract/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -46,7 +46,7 @@ pub fn verify_verifier_set( let config = CONFIG.load(deps.storage)?; let snapshot = take_snapshot(deps.as_ref(), &config.source_chain)?; - let participants = snapshot.get_participants(); + let participants = snapshot.participants(); let expires_at = calculate_expiration(env.block.height, config.block_expiry.into())?; let poll_id = create_verifier_set_poll(deps.storage, expires_at, snapshot)?; @@ -122,7 +122,7 @@ pub fn verify_messages( } let snapshot = take_snapshot(deps.as_ref(), &source_chain)?; - let participants = snapshot.get_participants(); + let participants = snapshot.participants(); let expires_at = calculate_expiration(env.block.height, config.block_expiry.into())?; let id = create_messages_poll(deps.storage, expires_at, snapshot, msgs_to_verify.len())?; @@ -156,7 +156,7 @@ pub fn verify_messages( )) } -fn get_poll_results(poll: &Poll) -> PollResults { +fn poll_results(poll: &Poll) -> PollResults { match poll { Poll::Messages(weighted_poll) => weighted_poll.results(), Poll::ConfirmVerifierSet(weighted_poll) => weighted_poll.results(), @@ -221,7 +221,7 @@ pub fn vote( .may_load(deps.storage, poll_id)? .ok_or(ContractError::PollNotFound)?; - let results_before_voting = get_poll_results(&poll); + let results_before_voting = poll_results(&poll); let poll = poll.try_map(|poll| { poll.cast_vote(env.block.height, &info.sender, votes.clone()) @@ -229,7 +229,7 @@ pub fn vote( })?; POLLS.save(deps.storage, poll_id, &poll)?; - let results_after_voting = get_poll_results(&poll); + let results_after_voting = poll_results(&poll); let quorum_events = results_after_voting .difference(results_before_voting) @@ -311,7 +311,7 @@ fn take_snapshot(deps: Deps, chain: &ChainName) -> Result)] - GetMessagesStatus(Vec), + MessagesStatus(Vec), #[returns(VerificationStatus)] - GetVerifierSetStatus(VerifierSet), + VerifierSetStatus(VerifierSet), #[returns(MajorityThreshold)] - GetCurrentThreshold, + CurrentThreshold, } #[cw_serde] diff --git a/integration-tests/tests/chain_freeze_unfreeze.rs b/integration-tests/tests/chain_freeze_unfreeze.rs index 91fb5cc77..1886c5f9f 100644 --- a/integration-tests/tests/chain_freeze_unfreeze.rs +++ b/integration-tests/tests/chain_freeze_unfreeze.rs @@ -88,7 +88,7 @@ fn chain_can_be_freezed_unfreezed() { // routed message should have been preserved let found_msgs = - test_utils::get_messages_from_gateway(&mut protocol.app, &chain2.gateway, &msg_ids); + test_utils::messages_from_gateway(&mut protocol.app, &chain2.gateway, &msg_ids); assert_eq!(found_msgs, msgs); // can route again diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index 98447c62c..1c41efbc6 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -64,7 +64,7 @@ fn single_message_can_be_verified_and_routed_and_proven_and_rewards_are_distribu // check that the message can be found at the outgoing gateway let found_msgs = - test_utils::get_messages_from_gateway(&mut protocol.app, &chain2.gateway, &msg_ids); + test_utils::messages_from_gateway(&mut protocol.app, &chain2.gateway, &msg_ids); assert_eq!(found_msgs, msgs); // trigger signing and submit all necessary signatures @@ -75,7 +75,7 @@ fn single_message_can_be_verified_and_routed_and_proven_and_rewards_are_distribu &verifiers, ); - let proof = test_utils::get_proof(&mut protocol.app, &chain2.multisig_prover, &session_id); + let proof = test_utils::proof(&mut protocol.app, &chain2.multisig_prover, &session_id); // proof should be complete by now assert!(matches!( diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index b963db21d..0a94de2a4 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -32,7 +32,7 @@ pub const AXL_DENOMINATION: &str = "uaxl"; pub const SIGNATURE_BLOCK_EXPIRY: u64 = 100; -fn get_event_attribute<'a>( +fn find_event_attribute<'a>( events: &'a [Event], event_type: &str, attribute_name: &str, @@ -61,10 +61,10 @@ pub fn verify_messages( let response = response.unwrap(); - let poll_id = get_event_attribute(&response.events, "wasm-messages_poll_started", "poll_id") + let poll_id = find_event_attribute(&response.events, "wasm-messages_poll_started", "poll_id") .map(|attr| serde_json::from_str(&attr.value).unwrap()) .expect("couldn't get poll_id"); - let expiry = get_event_attribute(&response.events, "wasm-messages_poll_started", "expires_at") + let expiry = find_event_attribute(&response.events, "wasm-messages_poll_started", "expires_at") .map(|attr| attr.value.as_str().parse().unwrap()) .expect("couldn't get poll expiry"); (poll_id, expiry) @@ -206,8 +206,8 @@ pub fn construct_proof_and_sign( sign_proof(protocol, verifiers, response.unwrap()) } -pub fn get_multisig_session_id(response: AppResponse) -> Uint64 { - get_event_attribute(&response.events, "wasm-signing_started", "session_id") +pub fn multisig_session_id(response: AppResponse) -> Uint64 { + find_event_attribute(&response.events, "wasm-signing_started", "session_id") .map(|attr| attr.value.as_str().try_into().unwrap()) .expect("couldn't get session_id") } @@ -217,10 +217,10 @@ pub fn sign_proof( verifiers: &Vec, response: AppResponse, ) -> Uint64 { - let msg_to_sign = get_event_attribute(&response.events, "wasm-signing_started", "msg") + let msg_to_sign = find_event_attribute(&response.events, "wasm-signing_started", "msg") .map(|attr| attr.value.clone()) .expect("couldn't find message to sign"); - let session_id = get_multisig_session_id(response); + let session_id = multisig_session_id(response); for verifier in verifiers { let signature = tofn::ecdsa::sign( @@ -271,29 +271,29 @@ pub fn register_service( assert!(response.is_ok()); } -pub fn get_messages_from_gateway( +pub fn messages_from_gateway( app: &mut App, gateway: &GatewayContract, message_ids: &[CrossChainId], ) -> Vec { let query_response: Result, StdError> = gateway.query( app, - &gateway_api::msg::QueryMsg::GetOutgoingMessages(message_ids.to_owned()), + &gateway_api::msg::QueryMsg::OutgoingMessages(message_ids.to_owned()), ); assert!(query_response.is_ok()); query_response.unwrap() } -pub fn get_proof( +pub fn proof( app: &mut App, multisig_prover: &MultisigProverContract, multisig_session_id: &Uint64, -) -> multisig_prover::msg::GetProofResponse { - let query_response: Result = multisig_prover +) -> multisig_prover::msg::ProofResponse { + let query_response: Result = multisig_prover .query( app, - &multisig_prover::msg::QueryMsg::GetProof { + &multisig_prover::msg::QueryMsg::Proof { multisig_session_id: *multisig_session_id, }, ); @@ -302,7 +302,7 @@ pub fn get_proof( query_response.unwrap() } -pub fn get_verifier_set_from_prover( +pub fn verifier_set_from_prover( app: &mut App, multisig_prover_contract: &MultisigProverContract, ) -> VerifierSet { @@ -491,15 +491,15 @@ pub fn confirm_verifier_set( assert!(response.is_ok()); } -fn get_verifier_set_poll_id_and_expiry(response: AppResponse) -> (PollId, PollExpiryBlock) { - let poll_id = get_event_attribute( +fn verifier_set_poll_id_and_expiry(response: AppResponse) -> (PollId, PollExpiryBlock) { + let poll_id = find_event_attribute( &response.events, "wasm-verifier_set_poll_started", "poll_id", ) .map(|attr| serde_json::from_str(&attr.value).unwrap()) .expect("couldn't get poll_id"); - let expiry = get_event_attribute( + let expiry = find_event_attribute( &response.events, "wasm-verifier_set_poll_started", "expires_at", @@ -531,7 +531,7 @@ pub fn create_verifier_set_poll( ); assert!(response.is_ok()); - get_verifier_set_poll_id_and_expiry(response.unwrap()) + verifier_set_poll_id_and_expiry(response.unwrap()) } pub fn verifiers_to_verifier_set( @@ -782,7 +782,7 @@ pub fn rotate_active_verifier_set( let session_id = sign_proof(protocol, previous_verifiers, response.unwrap()); - let proof = get_proof(&mut protocol.app, &chain.multisig_prover, &session_id); + let proof = proof(&mut protocol.app, &chain.multisig_prover, &session_id); assert!(matches!( proof.status, multisig_prover::msg::ProofStatus::Completed { .. } diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index 190f71981..ba5cf3b86 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -5,7 +5,7 @@ use multisig_prover::msg::ExecuteMsg; use service_registry::msg::QueryMsg as ServiceRegistryQueryMsg; use service_registry::state::WeightedVerifier; use test_utils::{ - create_new_verifiers_vec, get_multisig_session_id, register_in_service_registry, + create_new_verifiers_vec, multisig_session_id, register_in_service_registry, register_verifiers, rotate_active_verifier_set, Verifier, }; @@ -30,7 +30,7 @@ fn verifier_set_can_be_initialized_and_then_manually_updated() { test_utils::verifiers_to_verifier_set(&mut protocol, &initial_verifiers); let verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(verifier_set, simulated_verifier_set); @@ -70,7 +70,7 @@ fn verifier_set_can_be_initialized_and_then_manually_updated() { // sign with old verifiers let session_id = test_utils::sign_proof(&mut protocol, &initial_verifiers, response); - let proof = test_utils::get_proof(&mut protocol.app, ðereum.multisig_prover, &session_id); + let proof = test_utils::proof(&mut protocol.app, ðereum.multisig_prover, &session_id); assert!(matches!( proof.status, multisig_prover::msg::ProofStatus::Completed { .. } @@ -104,7 +104,7 @@ fn verifier_set_can_be_initialized_and_then_manually_updated() { ); let new_verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(new_verifier_set, expected_new_verifier_set); } @@ -126,7 +126,7 @@ fn verifier_set_cannot_be_updated_again_while_pending_verifier_is_not_yet_confir test_utils::verifiers_to_verifier_set(&mut protocol, &initial_verifiers); let verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(verifier_set, simulated_verifier_set); @@ -160,7 +160,7 @@ fn verifier_set_cannot_be_updated_again_while_pending_verifier_is_not_yet_confir let session_id = test_utils::sign_proof(&mut protocol, &initial_verifiers, response); - let proof = test_utils::get_proof(&mut protocol.app, ðereum.multisig_prover, &session_id); + let proof = test_utils::proof(&mut protocol.app, ðereum.multisig_prover, &session_id); // proof must be completed assert!(matches!( @@ -206,7 +206,7 @@ fn verifier_set_cannot_be_updated_again_while_pending_verifier_is_not_yet_confir ); let new_verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(new_verifier_set, expected_new_verifier_set); @@ -246,7 +246,7 @@ fn verifier_set_update_can_be_resigned() { test_utils::verifiers_to_verifier_set(&mut protocol, &initial_verifiers); let verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(verifier_set, simulated_verifier_set); @@ -275,7 +275,7 @@ fn verifier_set_update_can_be_resigned() { ) .unwrap(); - let first_session_id = get_multisig_session_id(response.clone()); + let first_session_id = multisig_session_id(response.clone()); // signing didn't occur, trigger signing again let response = protocol @@ -288,7 +288,7 @@ fn verifier_set_update_can_be_resigned() { ) .unwrap(); - let second_session_id = get_multisig_session_id(response.clone()); + let second_session_id = multisig_session_id(response.clone()); assert_ne!(first_session_id, second_session_id); test_utils::sign_proof(&mut protocol, &initial_verifiers, response); @@ -304,13 +304,13 @@ fn verifier_set_update_can_be_resigned() { ) .unwrap(); - let third_session_id = get_multisig_session_id(response.clone()); + let third_session_id = multisig_session_id(response.clone()); assert_ne!(first_session_id, second_session_id); assert_ne!(second_session_id, third_session_id); test_utils::sign_proof(&mut protocol, &initial_verifiers, response); - let proof = test_utils::get_proof( + let proof = test_utils::proof( &mut protocol.app, ðereum.multisig_prover, &second_session_id, @@ -367,7 +367,7 @@ fn governance_should_confirm_new_verifier_set_without_verification() { ); let new_verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, ðereum.multisig_prover); assert_eq!(new_verifier_set, expected_new_verifier_set); } @@ -415,7 +415,7 @@ fn rotate_signers_should_filter_out_signers_without_pubkey() { .service_registry .query( &protocol.app, - &ServiceRegistryQueryMsg::GetActiveVerifiers { + &ServiceRegistryQueryMsg::ActiveVerifiers { service_name: protocol.service_name.to_string(), chain_name: chains[0].clone(), }, @@ -436,7 +436,7 @@ fn rotate_signers_should_filter_out_signers_without_pubkey() { ); let verifier_set = - test_utils::get_verifier_set_from_prover(&mut protocol.app, &chain1.multisig_prover); + test_utils::verifier_set_from_prover(&mut protocol.app, &chain1.multisig_prover); assert_eq!(verifier_set, expected_verifier_set); } diff --git a/packages/axelar-wasm-std/src/counter.rs b/packages/axelar-wasm-std/src/counter.rs index 05a709663..90ff709e8 100644 --- a/packages/axelar-wasm-std/src/counter.rs +++ b/packages/axelar-wasm-std/src/counter.rs @@ -38,7 +38,7 @@ mod tests { use super::*; #[test] - fn test_get_and_incr() { + fn test_cur_and_incr() { let mut store = MockStorage::new(); let counter: Counter = Counter::new("counter"); diff --git a/packages/axelar-wasm-std/src/snapshot.rs b/packages/axelar-wasm-std/src/snapshot.rs index 1487a42d6..165966f6b 100644 --- a/packages/axelar-wasm-std/src/snapshot.rs +++ b/packages/axelar-wasm-std/src/snapshot.rs @@ -45,7 +45,7 @@ impl Snapshot { } } - pub fn get_participants(&self) -> Vec { + pub fn participants(&self) -> Vec { self.participants .keys() .cloned() @@ -53,7 +53,7 @@ impl Snapshot { .collect() } - pub fn get_participant(&self, participant: &Addr) -> Option<&Participant> { + pub fn find(&self, participant: &Addr) -> Option<&Participant> { self.participants.get(&participant.to_string()) } } diff --git a/packages/gateway-api/src/msg.rs b/packages/gateway-api/src/msg.rs index ae642d748..40c0bc590 100644 --- a/packages/gateway-api/src/msg.rs +++ b/packages/gateway-api/src/msg.rs @@ -21,5 +21,5 @@ pub enum ExecuteMsg { pub enum QueryMsg { // messages that can be relayed to the chain corresponding to this gateway #[returns(Vec)] - GetOutgoingMessages(Vec), + OutgoingMessages(Vec), } diff --git a/packages/router-api/src/msg.rs b/packages/router-api/src/msg.rs index 57c43f7af..05cbe8bce 100644 --- a/packages/router-api/src/msg.rs +++ b/packages/router-api/src/msg.rs @@ -51,7 +51,7 @@ pub enum ExecuteMsg { #[derive(QueryResponses)] pub enum QueryMsg { #[returns(ChainEndpoint)] - GetChainInfo(ChainName), + ChainInfo(ChainName), // Returns a list of chains registered with the router // The list is paginated by: From 7e27cb71f31675b3accb3cef8d987544af4dcc50 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Wed, 24 Jul 2024 14:19:03 -0400 Subject: [PATCH 101/168] ci: use cosmwasm-check v1.3.x for consistency with wasmvm version (#534) Co-authored-by: Christian Gorenflo --- .github/workflows/basic.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index e6b6d3d09..3ee6e136b 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -59,8 +59,18 @@ jobs: profile: minimal toolchain: 1.78.0 target: wasm32-unknown-unknown + default: true override: true + - name: Install cosmwasm-check compatible toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.75.0 + target: wasm32-unknown-unknown + default: false + override: false + - name: Cache build artifacts id: cache uses: useblacksmith/rust-cache@v3.0.1 @@ -79,11 +89,14 @@ jobs: (cd $C && cargo build --release --lib --target wasm32-unknown-unknown --locked) done + # cosmwasm-check v1.3.x is used to check for compatibility with wasmvm v1.3.x used by Axelar + # Older rust toolchain is required to install cosmwasm-check v1.3.x - name: Install cosmwasm-check uses: actions-rs/cargo@v1 with: command: install - args: --version 1.5.5 --locked cosmwasm-check + toolchain: 1.75.0 + args: --version 1.3.4 --locked cosmwasm-check - name: Check wasm contracts run: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm From 3359fc3afbb95cbe9ad31e4e282a3708d3b4386d Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Wed, 24 Jul 2024 14:40:02 -0400 Subject: [PATCH 102/168] ci(ampd): build ampd in gh actions (#533) --- .github/workflows/basic.yaml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index 3ee6e136b..e15914b38 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -101,6 +101,39 @@ jobs: - name: Check wasm contracts run: cosmwasm-check ./target/wasm32-unknown-unknown/release/*.wasm + ampd-compilation: + name: Ampd Release Compilation + runs-on: blacksmith-16vcpu-ubuntu-2204 + steps: + - uses: actions/checkout@v4 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.78.0 + target: wasm32-unknown-unknown + override: true + + - name: Install protoc + uses: arduino/setup-protoc@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Cache build artifacts + id: cache + uses: useblacksmith/rust-cache@v3.0.1 + with: + shared-key: "cache-ampd-compilation" + + - name: Log crates.toml + if: steps.cache.outputs.cache-hit == 'true' + run: cat /home/runner/.cargo/.crates.toml + + - name: Build ampd + working-directory: ./ampd + run: cargo build --release --locked + lints: name: Lints runs-on: blacksmith-16vcpu-ubuntu-2204 From 852e68b52dbe137308916f0b9104ccfc0c76d7ef Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 25 Jul 2024 15:09:43 -0400 Subject: [PATCH 103/168] fix(minor-router): unambiguous message hash computation (#542) --- contracts/gateway/src/state.rs | 4 +- contracts/router/src/contract.rs | 8 +- contracts/voting-verifier/src/contract.rs | 12 +- .../voting-verifier/src/contract/query.rs | 4 +- contracts/voting-verifier/src/events.rs | 2 +- packages/router-api/src/primitives.rs | 119 ++++++++++++++++-- 6 files changed, 126 insertions(+), 23 deletions(-) diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index 1c1af0cb7..161ebc1a3 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -84,9 +84,9 @@ mod test { let message = Message { cc_id: CrossChainId::new("chain", "id").unwrap(), - source_address: "source_address".parse().unwrap(), + source_address: "source-address".parse().unwrap(), destination_chain: "destination".parse().unwrap(), - destination_address: "destination_address".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), payload_hash: [1; 32], }; diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 2180858c3..0f7156795 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -152,7 +152,7 @@ mod test { use permission_control::Permission; use router_api::error::Error; use router_api::{ - ChainEndpoint, ChainName, CrossChainId, GatewayDirection, Message, CHAIN_NAME_DELIMITER, + ChainEndpoint, ChainName, CrossChainId, GatewayDirection, Message, FIELD_DELIMITER, }; use super::*; @@ -638,7 +638,7 @@ mod test { register_chain(deps.as_mut(), ð); register_chain(deps.as_mut(), &polygon); - let new_gateway = Addr::unchecked("new_gateway"); + let new_gateway = Addr::unchecked("new-gateway"); let _ = execute( deps.as_mut(), @@ -676,7 +676,7 @@ mod test { register_chain(deps.as_mut(), ð); register_chain(deps.as_mut(), &polygon); - let new_gateway = Addr::unchecked("new_gateway"); + let new_gateway = Addr::unchecked("new-gateway"); let _ = execute( deps.as_mut(), @@ -791,7 +791,7 @@ mod test { #[test] fn invalid_chain_name() { assert_contract_err_string_contains( - ChainName::from_str(format!("bad{}", CHAIN_NAME_DELIMITER).as_str()).unwrap_err(), + ChainName::from_str(format!("bad{}", FIELD_DELIMITER).as_str()).unwrap_err(), Error::InvalidChainName, ); diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 8c6602450..8259e10f7 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -237,9 +237,9 @@ mod test { .map(|i| Message { cc_id: CrossChainId::new(source_chain(), message_id("id", i, msg_id_format)) .unwrap(), - source_address: format!("source_address{i}").parse().unwrap(), + source_address: format!("source-address{i}").parse().unwrap(), destination_chain: format!("destination-chain{i}").parse().unwrap(), - destination_address: format!("destination_address{i}").parse().unwrap(), + destination_address: format!("destination-address{i}").parse().unwrap(), payload_hash: [0; 32], }) .collect() @@ -269,17 +269,17 @@ mod test { Message { cc_id: CrossChainId::new(source_chain(), message_id("id", 1, &msg_id_format)) .unwrap(), - source_address: "source_address1".parse().unwrap(), + source_address: "source-address1".parse().unwrap(), destination_chain: "destination-chain1".parse().unwrap(), - destination_address: "destination_address1".parse().unwrap(), + destination_address: "destination-address1".parse().unwrap(), payload_hash: [0; 32], }, Message { cc_id: CrossChainId::new("other-chain", message_id("id", 2, &msg_id_format)) .unwrap(), - source_address: "source_address2".parse().unwrap(), + source_address: "source-address2".parse().unwrap(), destination_chain: "destination-chain2".parse().unwrap(), - destination_address: "destination_address2".parse().unwrap(), + destination_address: "destination-address2".parse().unwrap(), payload_hash: [0; 32], }, ]); diff --git a/contracts/voting-verifier/src/contract/query.rs b/contracts/voting-verifier/src/contract/query.rs index 6bf2f7d66..c21cdacff 100644 --- a/contracts/voting-verifier/src/contract/query.rs +++ b/contracts/voting-verifier/src/contract/query.rs @@ -319,9 +319,9 @@ mod tests { .as_str(), ) .unwrap(), - source_address: format!("source_address{id}").parse().unwrap(), + source_address: format!("source-address{id}").parse().unwrap(), destination_chain: format!("destination-chain{id}").parse().unwrap(), - destination_address: format!("destination_address{id}").parse().unwrap(), + destination_address: format!("destination-address{id}").parse().unwrap(), payload_hash: [0; 32], } } diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 7755b2c51..26215bf1e 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -301,7 +301,7 @@ mod test { fn generate_msg(msg_id: nonempty::String) -> Message { Message { cc_id: CrossChainId::new("source-chain", msg_id).unwrap(), - source_address: "source_address".parse().unwrap(), + source_address: "source-address".parse().unwrap(), destination_chain: "destination-chain".parse().unwrap(), destination_address: "destination-address".parse().unwrap(), payload_hash: [0; 32], diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index a8894b6ee..f9f55e0bf 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -22,7 +22,9 @@ use valuable::Valuable; use crate::error::*; -pub const CHAIN_NAME_DELIMITER: char = '_'; +/// Delimiter used when concatenating fields to prevent ambiguous encodings. +/// The delimiter must be prevented from being contained in values that are used as fields. +pub const FIELD_DELIMITER: char = '_'; #[cw_serde] #[derive(Eq, Hash)] @@ -41,11 +43,18 @@ pub struct Message { impl Message { pub fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); + let delimiter_bytes = &[FIELD_DELIMITER as u8]; + hasher.update(self.cc_id.to_string()); + hasher.update(delimiter_bytes); hasher.update(self.source_address.as_str()); + hasher.update(delimiter_bytes); hasher.update(self.destination_chain.as_ref()); + hasher.update(delimiter_bytes); hasher.update(self.destination_address.as_str()); + hasher.update(delimiter_bytes); hasher.update(self.payload_hash); + hasher.finalize().into() } } @@ -68,6 +77,7 @@ impl From for Vec { } #[cw_serde] +#[serde(try_from = "String")] #[derive(Eq, Hash)] pub struct Address(nonempty::String); @@ -91,6 +101,10 @@ impl TryFrom for Address { type Error = Report; fn try_from(value: String) -> Result { + if value.contains(FIELD_DELIMITER) { + return Err(Report::new(Error::InvalidAddress)); + } + Ok(Address( value .parse::() @@ -150,7 +164,7 @@ impl KeyDeserialize for CrossChainId { } impl Display for CrossChainId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}{}{}", self.chain, CHAIN_NAME_DELIMITER, *self.id) + write!(f, "{}{}{}", self.chain, FIELD_DELIMITER, *self.id) } } @@ -274,7 +288,7 @@ impl FromStr for ChainNameRaw { type Err = Error; fn from_str(s: &str) -> Result { - if s.contains(CHAIN_NAME_DELIMITER) || s.is_empty() { + if s.contains(FIELD_DELIMITER) || s.is_empty() { return Err(Error::InvalidChainName); } @@ -430,7 +444,7 @@ mod tests { // will cause this test to fail, indicating that a migration is needed. fn test_message_struct_unchanged() { let expected_message_hash = - "e8052da3a89c90468cc6e4e242a827f8579fb0ea8e298b1650d73a0f7e81abc3"; + "b0c6ee811cf4c205b08e36dbbad956212c4e291aedae44ab700265477bfea526"; let msg = dummy_message(); @@ -444,7 +458,7 @@ mod tests { #[test] fn hash_id_unchanged() { let expected_message_hash = - "d30a374a795454706b43259998aafa741267ecbc8b6d5771be8d7b8c9a9db263"; + "e6b9cc9b6962c997b44ded605ebfb4f861e2db2ddff7e8be84a7a79728cea61e"; let msg = dummy_message(); @@ -462,7 +476,7 @@ mod tests { assert_eq!( "chain name is invalid", - serde_json::from_str::(format!("\"chain{CHAIN_NAME_DELIMITER}\"").as_str()) + serde_json::from_str::(format!("\"chain{FIELD_DELIMITER}\"").as_str()) .unwrap_err() .to_string() ); @@ -561,6 +575,87 @@ mod tests { } } + #[test] + fn should_not_deserialize_invalid_address() { + assert_eq!( + "address is invalid", + serde_json::from_str::

("\"\"") + .unwrap_err() + .to_string() + ); + + assert_eq!( + "address is invalid", + serde_json::from_str::
(format!("\"address{FIELD_DELIMITER}\"").as_str()) + .unwrap_err() + .to_string() + ); + } + + #[test] + fn ensure_address_parsing_respect_restrictions() { + struct TestCase<'a> { + input: &'a str, + can_parse: bool, + } + let random_lower = random_address().to_lowercase(); + let random_upper = random_address().to_uppercase(); + + let test_cases = [ + TestCase { + input: "", + can_parse: false, + }, + TestCase { + input: "address_with_prohibited_symbols", + can_parse: false, + }, + TestCase { + input: "!@#$%^&*()+=-1234567890", + can_parse: true, + }, + TestCase { + input: "0x4F4495243837681061C4743b74B3eEdf548D56A5", + can_parse: true, + }, + TestCase { + input: "0x4f4495243837681061c4743b74b3eedf548d56a5", + can_parse: true, + }, + TestCase { + input: "GARRAOPAA5MNY3Y5V2OOYXUMBC54UDHHJTUMLRQBY2DIZKT62G5WSJP4Copy", + can_parse: true, + }, + TestCase { + input: "ETHEREUM-1", + can_parse: true, + }, + TestCase { + input: random_lower.as_str(), + can_parse: true, + }, + TestCase { + input: random_upper.as_str(), + can_parse: true, + }, + ]; + + let conversions: [fn(&str) -> Result; 2] = [ + |input: &str| Address::from_str(input), + |input: &str| Address::try_from(input.to_string()), + ]; + + for case in test_cases.into_iter() { + for conversion in conversions.into_iter() { + let result = conversion(case.input); + assert_eq!(result.is_ok(), case.can_parse, "input: {}", case.input); + if case.can_parse { + assert_eq!(result.unwrap().to_string(), case.input); + } + } + } + } + #[test] fn json_schema_for_gateway_direction_flag_set_does_not_panic() { let gen = &mut SchemaGenerator::default(); @@ -574,9 +669,9 @@ mod tests { fn dummy_message() -> Message { Message { cc_id: CrossChainId::new("chain", "hash-index").unwrap(), - source_address: "source_address".parse().unwrap(), + source_address: "source-address".parse().unwrap(), destination_chain: "destination-chain".parse().unwrap(), - destination_address: "destination_address".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), payload_hash: [1; 32], } } @@ -588,4 +683,12 @@ mod tests { .map(char::from) .collect() } + + fn random_address() -> String { + thread_rng() + .sample_iter(&Alphanumeric) + .take(10) + .map(char::from) + .collect() + } } From 0ac9bdef4a5785701a9c7f67546aac5a5354d037 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:05:28 -0600 Subject: [PATCH 104/168] feat(ampd): retry fetching block height (#543) --- ampd/src/event_sub.rs | 22 +++++++--------------- ampd/src/tm_client.rs | 26 ++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/ampd/src/event_sub.rs b/ampd/src/event_sub.rs index d7393ab9e..512b0ee4c 100644 --- a/ampd/src/event_sub.rs +++ b/ampd/src/event_sub.rs @@ -15,7 +15,6 @@ use tokio_stream::Stream; use tokio_util::sync::CancellationToken; use tracing::info; -use crate::asyncutil::future::{self, RetryPolicy}; use crate::tm_client::TmClient; #[automock] @@ -125,20 +124,13 @@ impl EventPublisher { } async fn events(&self, block_height: block::Height) -> Result, EventSubError> { - let block_results = future::with_retry( - || { - self.tm_client.block_results(block_height).change_context( - EventSubError::EventQuery { - block: block_height, - }, - ) - }, - RetryPolicy::RepeatConstant { - sleep: Duration::from_secs(1), - max_attempts: 15, - }, - ) - .await?; + let block_results = self + .tm_client + .block_results(block_height) + .change_context(EventSubError::EventQuery { + block: block_height, + }) + .await?; let begin_block_events = block_results.begin_block_events.into_iter().flatten(); let tx_events = block_results diff --git a/ampd/src/tm_client.rs b/ampd/src/tm_client.rs index 44f91b475..fddf7feca 100644 --- a/ampd/src/tm_client.rs +++ b/ampd/src/tm_client.rs @@ -1,9 +1,13 @@ +use std::time::Duration; + use async_trait::async_trait; use error_stack::{Report, Result}; use mockall::automock; use tendermint::block::Height; use tendermint_rpc::{Client, HttpClient}; +use crate::asyncutil::future::{self, RetryPolicy}; + pub type BlockResultsResponse = tendermint_rpc::endpoint::block_results::Response; pub type BlockResponse = tendermint_rpc::endpoint::block::Response; pub type Error = tendermint_rpc::Error; @@ -18,12 +22,26 @@ pub trait TmClient { #[async_trait] impl TmClient for HttpClient { async fn latest_block(&self) -> Result { - Client::latest_block(self).await.map_err(Report::from) + future::with_retry( + || Client::latest_block(self), + RetryPolicy::RepeatConstant { + sleep: Duration::from_secs(1), + max_attempts: 15, + }, + ) + .await + .map_err(Report::from) } async fn block_results(&self, height: Height) -> Result { - Client::block_results(self, height) - .await - .map_err(Report::from) + future::with_retry( + || Client::block_results(self, height), + RetryPolicy::RepeatConstant { + sleep: Duration::from_secs(1), + max_attempts: 15, + }, + ) + .await + .map_err(Report::from) } } From 562aff57f88b511f3c12e36773324e46a32f20fb Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Thu, 25 Jul 2024 18:22:25 -0400 Subject: [PATCH 105/168] ci(amplifier): add r2 support for releases (#541) --- .../build-contracts-and-push-to-r2.yaml | 106 ++++++++++++++++-- release.toml | 2 +- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-contracts-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml index 0067c8f8d..51d87aa49 100644 --- a/.github/workflows/build-contracts-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -4,6 +4,8 @@ on: push: branches: - main + tags: + - '*-v[0-9]+.[0-9]+.[0-9]+' workflow_dispatch: inputs: branch: @@ -22,15 +24,53 @@ jobs: packages: write id-token: write steps: - - name: Determine branch - id: get-branch-name + - name: Get tag + id: get-tag run: | - if [ "${{ github.event_name }}" == "push" ]; then - branch="main" + echo "github_ref=$GITHUB_REF" + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo "tag=${GITHUB_REF#refs/tags/}" + echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT else - branch="${{ inputs.branch }}" + echo "tag=" >> $GITHUB_OUTPUT fi - echo "branch=$branch" >> $GITHUB_OUTPUT + + - name: Check for release information from tag + id: check-release + run: | + tag="${{ steps.get-tag.outputs.tag }}" + is_release="false" + + if [[ $tag =~ ^([a-zA-Z-]+)-v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then + is_release="true" + crate_name="${BASH_REMATCH[1]}" + crate_version="${BASH_REMATCH[2]}" + + echo "Is release: $is_release" + echo "Crate Name: $crate_name" + echo "Crate Version: $crate_version" + + echo "is-release=$is_release" >> $GITHUB_OUTPUT + echo "crate-name=$crate_name" >> $GITHUB_OUTPUT + echo "crate-version=$crate_version" >> $GITHUB_OUTPUT + else + echo "Is release: $is_release" + echo "Not a release tag. Skipping crate name and version extraction." + echo "is-release=$is_release" >> $GITHUB_OUTPUT + fi + + + - name: Determine checkout ref + id: get-checkout-ref + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo "ref=$GITHUB_REF" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" == "push" ]; then + echo "ref=main" >> $GITHUB_OUTPUT + else + echo "ref=${{ inputs.branch }}" >> $GITHUB_OUTPUT + fi + - name: Checkout code uses: actions/checkout@v4 @@ -38,9 +78,18 @@ jobs: fetch-depth: "0" path: axelar-amplifier submodules: recursive - ref: ${{ steps.get-branch-name.outputs.branch }} + ref: ${{ steps.get-checkout-ref.outputs.ref }} + - - name: Compile amplifier contracts + - name: Import GPG key + id: import_gpg + uses: crazy-max/ghaction-import-gpg@v4 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + + + - name: Compile all amplifier contracts id: compile-contracts run: | cd axelar-amplifier @@ -48,14 +97,53 @@ jobs: --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ cosmwasm/optimizer:0.16.0 - + commit_hash=$(git rev-parse --short HEAD) cd .. mkdir -p ./artifacts/$commit_hash/ cp -R axelar-amplifier/artifacts/* ./artifacts/$commit_hash/ echo "wasm-directory=./artifacts" >> $GITHUB_OUTPUT + + - name: Prepare and sign release artifacts + if: steps.check-release.outputs.is-release == 'true' + id: prepare-release + run: | + cd ${{ steps.compile-contracts.outputs.wasm-directory }} + crate_name="${{ steps.check-release.outputs.crate-name }}" + crate_version="${{ steps.check-release.outputs.crate-version }}" + wasm_file=$(find . -name "${crate_name//-/_}.wasm") + checksum_file=$(find . -name "checksums.txt") + + if [ -z "$wasm_file" ]; then + echo "Error: Could not find .wasm file for $crate_name" + exit 1 + fi + + mkdir -p "../release-artifacts" + cp "$wasm_file" "../release-artifacts/${crate_name}.wasm" + cp "$checksum_file" "../release-artifacts/" + + gpg --armor --detach-sign ../release-artifacts/${crate_name}.wasm + gpg --armor --detach-sign ../release-artifacts/checksums.txt + + echo "release-artifacts-dir=./release-artifacts" >> $GITHUB_OUTPUT + echo "r2-destination-dir=./releases/amplifier/${crate_name}/${crate_version}" >> $GITHUB_OUTPUT + + + - uses: ryand56/r2-upload-action@latest + if: steps.check-release.outputs.is-release == 'true' + with: + r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} + r2-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CF }} + r2-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CF }} + r2-bucket: ${{ secrets.R2_BUCKET }} + source-dir: ${{ steps.prepare-release.outputs.release-artifacts-dir }} + destination-dir: ${{ steps.prepare-release.outputs.r2-destination-dir }} + + - uses: ryand56/r2-upload-action@latest + if: steps.check-release.outputs.is-release != 'true' with: r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CF }} diff --git a/release.toml b/release.toml index da7a87a48..7259e24f6 100644 --- a/release.toml +++ b/release.toml @@ -1,4 +1,4 @@ -pre-release-commit-message = "chore: release {{crate_name}} {{version}} [skip ci]" +pre-release-commit-message = "chore: release {{crate_name}} {{version}}" consolidate-commits = false release = true publish = false From 770a4888caaef154064f1145e0cfd1fa1774be4b Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 25 Jul 2024 22:45:53 -0400 Subject: [PATCH 106/168] refactor(minor): rename id field in CrosschainId to message_id (#538) --- contracts/gateway/src/contract.rs | 25 +- contracts/gateway/src/contract/execute.rs | 3 +- .../gateway/src/contract/migrations/mod.rs | 1 + .../gateway/src/contract/migrations/v0_2_3.rs | 185 ++++++++++++ contracts/gateway/src/contract/query.rs | 11 +- contracts/gateway/src/state.rs | 43 +-- .../gateway/tests/test_route_incoming.json | 258 ++++++++--------- .../gateway/tests/test_route_outgoing.json | 252 ++++++++--------- contracts/gateway/tests/test_verify.json | 266 +++++++++--------- contracts/multisig-prover/src/contract.rs | 1 - .../src/contract/migrations/v0_6_0.rs | 83 +++++- contracts/nexus-gateway/src/contract.rs | 8 +- contracts/nexus-gateway/src/nexus.rs | 28 +- contracts/router/src/contract.rs | 6 +- contracts/router/src/contract/execute.rs | 7 +- contracts/voting-verifier/src/contract.rs | 4 +- .../voting-verifier/src/contract/execute.rs | 2 +- .../src/contract/migrations/v0_5_0.rs | 22 ++ contracts/voting-verifier/src/events.rs | 2 +- packages/evm-gateway/src/lib.rs | 4 +- packages/router-api/src/primitives.rs | 30 +- 21 files changed, 752 insertions(+), 489 deletions(-) create mode 100644 contracts/gateway/src/contract/migrations/mod.rs create mode 100644 contracts/gateway/src/contract/migrations/v0_2_3.rs diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index ebde2b2fe..e40799767 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -6,9 +6,11 @@ use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; use gateway_api::msg::{ExecuteMsg, QueryMsg}; use router_api::CrossChainId; +use crate::contract::migrations::v0_2_3; use crate::msg::InstantiateMsg; mod execute; +mod migrations; mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); @@ -20,10 +22,7 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - // any version checks should be done before here - - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - + v0_2_3::migrate(deps.storage)?; Ok(Response::default()) } @@ -147,21 +146,3 @@ mod internal { } } } - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env}; - - use super::*; - - #[test] - fn migrate_sets_contract_version() { - let mut deps = mock_dependencies(); - - migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); - - let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, "gateway"); - assert_eq!(contract_version.version, CONTRACT_VERSION); - } -} diff --git a/contracts/gateway/src/contract/execute.rs b/contracts/gateway/src/contract/execute.rs index 78586a14e..d50b8aa40 100644 --- a/contracts/gateway/src/contract/execute.rs +++ b/contracts/gateway/src/contract/execute.rs @@ -37,7 +37,8 @@ pub(crate) fn route_outgoing_messages( let msgs = check_for_duplicates(verified)?; for msg in msgs.iter() { - state::save_outgoing_msg(store, &msg.cc_id, msg) + state::OUTGOING_MESSAGES + .save(store, &msg.cc_id, msg) .change_context(Error::InvalidStoreAccess)?; } diff --git a/contracts/gateway/src/contract/migrations/mod.rs b/contracts/gateway/src/contract/migrations/mod.rs new file mode 100644 index 000000000..3f8ffb3bd --- /dev/null +++ b/contracts/gateway/src/contract/migrations/mod.rs @@ -0,0 +1 @@ +pub mod v0_2_3; diff --git a/contracts/gateway/src/contract/migrations/v0_2_3.rs b/contracts/gateway/src/contract/migrations/v0_2_3.rs new file mode 100644 index 000000000..a05fe95ea --- /dev/null +++ b/contracts/gateway/src/contract/migrations/v0_2_3.rs @@ -0,0 +1,185 @@ +#![allow(deprecated)] + +use std::any::type_name; + +use axelar_wasm_std::error::ContractError; +use axelar_wasm_std::nonempty; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{StdError, StdResult, Storage}; +use cw_storage_plus::{Key, KeyDeserialize, Map, PrimaryKey}; +use router_api::{Address, ChainName, ChainNameRaw}; + +use crate::contract::{CONTRACT_NAME, CONTRACT_VERSION}; + +const BASE_VERSION: &str = "0.2.3"; + +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + delete_outgoing_messages(storage); + + cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(()) +} + +fn delete_outgoing_messages(storage: &mut dyn Storage) { + OUTGOING_MESSAGES.clear(storage); +} + +#[deprecated(since = "0.2.3", note = "only used during migration")] +const OUTGOING_MESSAGES_NAME: &str = "outgoing_messages"; + +#[deprecated(since = "0.2.3", note = "only used during migration")] +const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new(OUTGOING_MESSAGES_NAME); + +#[cw_serde] +#[derive(Eq, Hash)] +#[deprecated(since = "0.2.3", note = "only used during migration")] +pub struct Message { + pub cc_id: CrossChainId, + pub source_address: Address, + pub destination_chain: ChainName, + pub destination_address: Address, + /// for better user experience, the payload hash gets encoded into hex at the edges (input/output), + /// but internally, we treat it as raw bytes to enforce its format. + #[serde(with = "axelar_wasm_std::hex")] + #[schemars(with = "String")] // necessary attribute in conjunction with #[serde(with ...)] + pub payload_hash: [u8; 32], +} + +#[cw_serde] +#[derive(Eq, Hash)] +#[deprecated(since = "0.2.3", note = "only used during migration")] +pub struct CrossChainId { + pub chain: ChainNameRaw, + pub id: nonempty::String, +} + +impl PrimaryKey<'_> for CrossChainId { + type Prefix = ChainNameRaw; + type SubPrefix = (); + type Suffix = String; + type SuperSuffix = (ChainNameRaw, String); + + fn key(&self) -> Vec { + let mut keys = self.chain.key(); + keys.extend(self.id.key()); + keys + } +} + +impl KeyDeserialize for &CrossChainId { + type Output = CrossChainId; + + fn from_vec(value: Vec) -> StdResult { + let (chain, id) = <(ChainNameRaw, String)>::from_vec(value)?; + Ok(CrossChainId { + chain, + id: id + .try_into() + .map_err(|err| StdError::parse_err(type_name::(), err))?, + }) + } +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::DepsMut; + + use crate::contract::migrations::v0_2_3; + use crate::contract::{instantiate, CONTRACT_NAME, CONTRACT_VERSION}; + use crate::msg::InstantiateMsg; + use crate::state; + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v0_2_3::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_2_3::BASE_VERSION) + .unwrap(); + + assert!(v0_2_3::migrate(deps.as_mut().storage).is_ok()); + } + + #[test] + fn migrate_sets_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + v0_2_3::migrate(deps.as_mut().storage).unwrap(); + + let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); + assert_eq!(contract_version.contract, CONTRACT_NAME); + assert_eq!(contract_version.version, CONTRACT_VERSION); + } + + fn instantiate_contract(deps: DepsMut) { + instantiate( + deps, + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + verifier_address: "verifier".to_string(), + router_address: "router".to_string(), + }, + ) + .unwrap(); + } + + #[test] + fn migrate_outgoing_messages() { + let mut deps = mock_dependencies(); + + instantiate_contract(deps.as_mut()); + + let msgs = vec![ + v0_2_3::Message { + cc_id: v0_2_3::CrossChainId { + id: "id1".try_into().unwrap(), + chain: "chain1".try_into().unwrap(), + }, + source_address: "source-address".parse().unwrap(), + destination_chain: "destination".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: [1; 32], + }, + v0_2_3::Message { + cc_id: v0_2_3::CrossChainId { + id: "id2".try_into().unwrap(), + chain: "chain2".try_into().unwrap(), + }, + source_address: "source-address2".parse().unwrap(), + destination_chain: "destination2".parse().unwrap(), + destination_address: "destination-address2".parse().unwrap(), + payload_hash: [2; 32], + }, + v0_2_3::Message { + cc_id: v0_2_3::CrossChainId { + id: "id3".try_into().unwrap(), + chain: "chain3".try_into().unwrap(), + }, + source_address: "source-address3".parse().unwrap(), + destination_chain: "destination3".parse().unwrap(), + destination_address: "destination-address3".parse().unwrap(), + payload_hash: [3; 32], + }, + ]; + + for msg in msgs.iter() { + v0_2_3::OUTGOING_MESSAGES + .save(deps.as_mut().storage, &msg.cc_id, msg) + .unwrap(); + } + + assert!(v0_2_3::migrate(deps.as_mut().storage).is_ok()); + + assert!(state::OUTGOING_MESSAGES.is_empty(deps.as_ref().storage)) + } +} diff --git a/contracts/gateway/src/contract/query.rs b/contracts/gateway/src/contract/query.rs index 62835b162..d29eefa9c 100644 --- a/contracts/gateway/src/contract/query.rs +++ b/contracts/gateway/src/contract/query.rs @@ -17,7 +17,8 @@ pub fn outgoing_messages( } fn try_load_msg(storage: &dyn Storage, id: CrossChainId) -> Result { - state::may_load_outgoing_msg(storage, &id) + state::OUTGOING_MESSAGES + .may_load(storage, &id) .change_context(Error::InvalidStoreAccess) .transpose() .unwrap_or(Err(report!(Error::MessageNotFound(id)))) @@ -51,7 +52,9 @@ mod test { let messages = generate_messages(); for message in messages.iter() { - state::save_outgoing_msg(deps.as_mut().storage, &message.cc_id, message).unwrap(); + state::OUTGOING_MESSAGES + .save(deps.as_mut().storage, &message.cc_id, message) + .unwrap(); } let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); @@ -79,7 +82,9 @@ mod test { let messages = generate_messages(); - state::save_outgoing_msg(deps.as_mut().storage, &messages[1].cc_id, &messages[1]).unwrap(); + state::OUTGOING_MESSAGES + .save(deps.as_mut().storage, &messages[1].cc_id, &messages[1]) + .unwrap(); let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index 161ebc1a3..473cb7ba5 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -21,39 +21,18 @@ pub(crate) fn load_config(storage: &dyn Storage) -> Result { .change_context(Error::LoadValue(CONFIG_NAME)) } -pub(crate) fn save_outgoing_msg( - storage: &mut dyn Storage, - key: &CrossChainId, - value: &Message, -) -> Result<(), Error> { - OUTGOING_MESSAGES - .save(storage, key, value) - .change_context(Error::SaveValue(OUTGOING_MESSAGES_NAME)) -} -pub(crate) fn may_load_outgoing_msg( - storage: &dyn Storage, - id: &CrossChainId, -) -> Result, Error> { - OUTGOING_MESSAGES - .may_load(storage, id) - .change_context(Error::Parse(OUTGOING_MESSAGES_NAME)) - .attach_printable(id.to_string()) -} - #[derive(thiserror::Error, Debug)] pub(crate) enum Error { #[error("failed to save {0}")] SaveValue(&'static str), #[error("failed to load {0}")] LoadValue(&'static str), - #[error("failed to parse key for {0}")] - Parse(&'static str), } const CONFIG_NAME: &str = "config"; const CONFIG: Item = Item::new(CONFIG_NAME); const OUTGOING_MESSAGES_NAME: &str = "outgoing_messages"; -const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new(OUTGOING_MESSAGES_NAME); +pub const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new(OUTGOING_MESSAGES_NAME); #[cfg(test)] mod test { @@ -61,9 +40,7 @@ mod test { use cosmwasm_std::Addr; use router_api::{CrossChainId, Message}; - use crate::state::{ - load_config, may_load_outgoing_msg, save_config, save_outgoing_msg, Config, - }; + use crate::state::{load_config, save_config, Config, OUTGOING_MESSAGES}; #[test] fn config_storage() { @@ -90,23 +67,31 @@ mod test { payload_hash: [1; 32], }; - assert!(save_outgoing_msg(deps.as_mut().storage, &message.cc_id, &message).is_ok()); + assert!(OUTGOING_MESSAGES + .save(deps.as_mut().storage, &message.cc_id, &message) + .is_ok()); assert_eq!( - may_load_outgoing_msg(&deps.storage, &message.cc_id).unwrap(), + OUTGOING_MESSAGES + .may_load(&deps.storage, &message.cc_id) + .unwrap(), Some(message) ); let unknown_chain_id = CrossChainId::new("unknown", "id").unwrap(); assert_eq!( - may_load_outgoing_msg(&deps.storage, &unknown_chain_id).unwrap(), + OUTGOING_MESSAGES + .may_load(&deps.storage, &unknown_chain_id) + .unwrap(), None ); let unknown_id = CrossChainId::new("chain", "unkown").unwrap(); assert_eq!( - may_load_outgoing_msg(&deps.storage, &unknown_id).unwrap(), + OUTGOING_MESSAGES + .may_load(&deps.storage, &unknown_id) + .unwrap(), None ); } diff --git a/contracts/gateway/tests/test_route_incoming.json b/contracts/gateway/tests/test_route_incoming.json index b8bb48025..f0b261d23 100644 --- a/contracts/gateway/tests/test_route_incoming.json +++ b/contracts/gateway/tests/test_route_incoming.json @@ -13,7 +13,7 @@ "wasm": { "execute": { "contract_addr": "router", - "msg": "eyJyb3V0ZV9tZXNzYWdlcyI6W3siY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifV19", + "msg": "eyJyb3V0ZV9tZXNzYWdlcyI6W3siY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifV19", "funds": [] } } @@ -28,7 +28,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -64,7 +64,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -100,7 +100,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -136,7 +136,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -172,7 +172,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -208,7 +208,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -244,7 +244,7 @@ "wasm": { "execute": { "contract_addr": "router", - "msg": "eyJyb3V0ZV9tZXNzYWdlcyI6W3siY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW4yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW41In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW44In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", + "msg": "eyJyb3V0ZV9tZXNzYWdlcyI6W3siY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW4yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW41In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW44In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", "funds": [] } } @@ -259,7 +259,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -288,7 +288,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain1" }, { @@ -317,7 +317,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain2" }, { @@ -346,7 +346,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain3" }, { @@ -375,7 +375,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain4" }, { @@ -404,7 +404,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain5" }, { @@ -433,7 +433,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain6" }, { @@ -462,7 +462,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain7" }, { @@ -491,7 +491,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain8" }, { @@ -520,7 +520,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain9" }, { @@ -556,7 +556,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -585,7 +585,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain1" }, { @@ -614,7 +614,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain2" }, { @@ -643,7 +643,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain3" }, { @@ -672,7 +672,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain4" }, { @@ -701,7 +701,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain5" }, { @@ -730,7 +730,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain6" }, { @@ -759,7 +759,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain7" }, { @@ -788,7 +788,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain8" }, { @@ -817,7 +817,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain9" }, { @@ -853,7 +853,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -882,7 +882,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain1" }, { @@ -911,7 +911,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain2" }, { @@ -940,7 +940,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain3" }, { @@ -969,7 +969,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain4" }, { @@ -998,7 +998,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain5" }, { @@ -1027,7 +1027,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain6" }, { @@ -1056,7 +1056,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain7" }, { @@ -1085,7 +1085,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain8" }, { @@ -1114,7 +1114,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain9" }, { @@ -1150,7 +1150,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -1179,7 +1179,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify1" }, { @@ -1208,7 +1208,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify2" }, { @@ -1237,7 +1237,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify3" }, { @@ -1266,7 +1266,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify4" }, { @@ -1295,7 +1295,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify5" }, { @@ -1324,7 +1324,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify6" }, { @@ -1353,7 +1353,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify7" }, { @@ -1382,7 +1382,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify8" }, { @@ -1411,7 +1411,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify9" }, { @@ -1447,7 +1447,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -1476,7 +1476,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress1" }, { @@ -1505,7 +1505,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress2" }, { @@ -1534,7 +1534,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress3" }, { @@ -1563,7 +1563,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress4" }, { @@ -1592,7 +1592,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress5" }, { @@ -1621,7 +1621,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress6" }, { @@ -1650,7 +1650,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress7" }, { @@ -1679,7 +1679,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress8" }, { @@ -1708,7 +1708,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress9" }, { @@ -1744,7 +1744,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -1773,7 +1773,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown1" }, { @@ -1802,7 +1802,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown2" }, { @@ -1831,7 +1831,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown3" }, { @@ -1860,7 +1860,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown4" }, { @@ -1889,7 +1889,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown5" }, { @@ -1918,7 +1918,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown6" }, { @@ -1947,7 +1947,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown7" }, { @@ -1976,7 +1976,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown8" }, { @@ -2005,7 +2005,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown9" }, { @@ -2041,7 +2041,7 @@ "wasm": { "execute": { "contract_addr": "router", - "msg": "eyJyb3V0ZV9tZXNzYWdlcyI6W3siY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW4yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW41In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW44In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", + "msg": "eyJyb3V0ZV9tZXNzYWdlcyI6W3siY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW4yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW41In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiU3VjY2VlZGVkT25Tb3VyY2VDaGFpbjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlN1Y2NlZWRlZE9uU291cmNlQ2hhaW44In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJTdWNjZWVkZWRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", "funds": [] } } @@ -2056,7 +2056,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -2085,7 +2085,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain1" }, { @@ -2114,7 +2114,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain2" }, { @@ -2143,7 +2143,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain3" }, { @@ -2172,7 +2172,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain4" }, { @@ -2201,7 +2201,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain5" }, { @@ -2230,7 +2230,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain6" }, { @@ -2259,7 +2259,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain7" }, { @@ -2288,7 +2288,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain8" }, { @@ -2317,7 +2317,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain9" }, { @@ -2346,7 +2346,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -2375,7 +2375,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain1" }, { @@ -2404,7 +2404,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain2" }, { @@ -2433,7 +2433,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain3" }, { @@ -2462,7 +2462,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain4" }, { @@ -2491,7 +2491,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain5" }, { @@ -2520,7 +2520,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain6" }, { @@ -2549,7 +2549,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain7" }, { @@ -2578,7 +2578,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain8" }, { @@ -2607,7 +2607,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain9" }, { @@ -2636,7 +2636,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -2665,7 +2665,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain1" }, { @@ -2694,7 +2694,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain2" }, { @@ -2723,7 +2723,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain3" }, { @@ -2752,7 +2752,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain4" }, { @@ -2781,7 +2781,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain5" }, { @@ -2810,7 +2810,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain6" }, { @@ -2839,7 +2839,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain7" }, { @@ -2868,7 +2868,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain8" }, { @@ -2897,7 +2897,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain9" }, { @@ -2926,7 +2926,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -2955,7 +2955,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify1" }, { @@ -2984,7 +2984,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify2" }, { @@ -3013,7 +3013,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify3" }, { @@ -3042,7 +3042,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify4" }, { @@ -3071,7 +3071,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify5" }, { @@ -3100,7 +3100,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify6" }, { @@ -3129,7 +3129,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify7" }, { @@ -3158,7 +3158,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify8" }, { @@ -3187,7 +3187,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify9" }, { @@ -3216,7 +3216,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -3245,7 +3245,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress1" }, { @@ -3274,7 +3274,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress2" }, { @@ -3303,7 +3303,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress3" }, { @@ -3332,7 +3332,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress4" }, { @@ -3361,7 +3361,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress5" }, { @@ -3390,7 +3390,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress6" }, { @@ -3419,7 +3419,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress7" }, { @@ -3448,7 +3448,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress8" }, { @@ -3477,7 +3477,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress9" }, { @@ -3506,7 +3506,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -3535,7 +3535,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown1" }, { @@ -3564,7 +3564,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown2" }, { @@ -3593,7 +3593,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown3" }, { @@ -3622,7 +3622,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown4" }, { @@ -3651,7 +3651,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown5" }, { @@ -3680,7 +3680,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown6" }, { @@ -3709,7 +3709,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown7" }, { @@ -3738,7 +3738,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown8" }, { @@ -3767,7 +3767,7 @@ "type": "unfit_for_routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown9" }, { diff --git a/contracts/gateway/tests/test_route_outgoing.json b/contracts/gateway/tests/test_route_outgoing.json index ef0605400..6590430c4 100644 --- a/contracts/gateway/tests/test_route_outgoing.json +++ b/contracts/gateway/tests/test_route_outgoing.json @@ -13,7 +13,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -49,7 +49,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -85,7 +85,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -121,7 +121,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -157,7 +157,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -193,7 +193,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -229,7 +229,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -258,7 +258,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain1" }, { @@ -287,7 +287,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain2" }, { @@ -316,7 +316,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain3" }, { @@ -345,7 +345,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain4" }, { @@ -374,7 +374,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain5" }, { @@ -403,7 +403,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain6" }, { @@ -432,7 +432,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain7" }, { @@ -461,7 +461,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain8" }, { @@ -490,7 +490,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain9" }, { @@ -526,7 +526,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -555,7 +555,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain1" }, { @@ -584,7 +584,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain2" }, { @@ -613,7 +613,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain3" }, { @@ -642,7 +642,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain4" }, { @@ -671,7 +671,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain5" }, { @@ -700,7 +700,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain6" }, { @@ -729,7 +729,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain7" }, { @@ -758,7 +758,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain8" }, { @@ -787,7 +787,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain9" }, { @@ -823,7 +823,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -852,7 +852,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain1" }, { @@ -881,7 +881,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain2" }, { @@ -910,7 +910,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain3" }, { @@ -939,7 +939,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain4" }, { @@ -968,7 +968,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain5" }, { @@ -997,7 +997,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain6" }, { @@ -1026,7 +1026,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain7" }, { @@ -1055,7 +1055,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain8" }, { @@ -1084,7 +1084,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain9" }, { @@ -1120,7 +1120,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -1149,7 +1149,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify1" }, { @@ -1178,7 +1178,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify2" }, { @@ -1207,7 +1207,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify3" }, { @@ -1236,7 +1236,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify4" }, { @@ -1265,7 +1265,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify5" }, { @@ -1294,7 +1294,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify6" }, { @@ -1323,7 +1323,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify7" }, { @@ -1352,7 +1352,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify8" }, { @@ -1381,7 +1381,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify9" }, { @@ -1417,7 +1417,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -1446,7 +1446,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress1" }, { @@ -1475,7 +1475,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress2" }, { @@ -1504,7 +1504,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress3" }, { @@ -1533,7 +1533,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress4" }, { @@ -1562,7 +1562,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress5" }, { @@ -1591,7 +1591,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress6" }, { @@ -1620,7 +1620,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress7" }, { @@ -1649,7 +1649,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress8" }, { @@ -1678,7 +1678,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress9" }, { @@ -1714,7 +1714,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -1743,7 +1743,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown1" }, { @@ -1772,7 +1772,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown2" }, { @@ -1801,7 +1801,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown3" }, { @@ -1830,7 +1830,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown4" }, { @@ -1859,7 +1859,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown5" }, { @@ -1888,7 +1888,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown6" }, { @@ -1917,7 +1917,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown7" }, { @@ -1946,7 +1946,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown8" }, { @@ -1975,7 +1975,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown9" }, { @@ -2011,7 +2011,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -2040,7 +2040,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain1" }, { @@ -2069,7 +2069,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain2" }, { @@ -2098,7 +2098,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain3" }, { @@ -2127,7 +2127,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain4" }, { @@ -2156,7 +2156,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain5" }, { @@ -2185,7 +2185,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain6" }, { @@ -2214,7 +2214,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain7" }, { @@ -2243,7 +2243,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain8" }, { @@ -2272,7 +2272,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain9" }, { @@ -2301,7 +2301,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -2330,7 +2330,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain1" }, { @@ -2359,7 +2359,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain2" }, { @@ -2388,7 +2388,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain3" }, { @@ -2417,7 +2417,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain4" }, { @@ -2446,7 +2446,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain5" }, { @@ -2475,7 +2475,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain6" }, { @@ -2504,7 +2504,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain7" }, { @@ -2533,7 +2533,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain8" }, { @@ -2562,7 +2562,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain9" }, { @@ -2591,7 +2591,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -2620,7 +2620,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain1" }, { @@ -2649,7 +2649,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain2" }, { @@ -2678,7 +2678,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain3" }, { @@ -2707,7 +2707,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain4" }, { @@ -2736,7 +2736,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain5" }, { @@ -2765,7 +2765,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain6" }, { @@ -2794,7 +2794,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain7" }, { @@ -2823,7 +2823,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain8" }, { @@ -2852,7 +2852,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain9" }, { @@ -2881,7 +2881,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -2910,7 +2910,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify1" }, { @@ -2939,7 +2939,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify2" }, { @@ -2968,7 +2968,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify3" }, { @@ -2997,7 +2997,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify4" }, { @@ -3026,7 +3026,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify5" }, { @@ -3055,7 +3055,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify6" }, { @@ -3084,7 +3084,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify7" }, { @@ -3113,7 +3113,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify8" }, { @@ -3142,7 +3142,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify9" }, { @@ -3171,7 +3171,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -3200,7 +3200,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress1" }, { @@ -3229,7 +3229,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress2" }, { @@ -3258,7 +3258,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress3" }, { @@ -3287,7 +3287,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress4" }, { @@ -3316,7 +3316,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress5" }, { @@ -3345,7 +3345,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress6" }, { @@ -3374,7 +3374,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress7" }, { @@ -3403,7 +3403,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress8" }, { @@ -3432,7 +3432,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress9" }, { @@ -3461,7 +3461,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -3490,7 +3490,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown1" }, { @@ -3519,7 +3519,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown2" }, { @@ -3548,7 +3548,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown3" }, { @@ -3577,7 +3577,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown4" }, { @@ -3606,7 +3606,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown5" }, { @@ -3635,7 +3635,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown6" }, { @@ -3664,7 +3664,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown7" }, { @@ -3693,7 +3693,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown8" }, { @@ -3722,7 +3722,7 @@ "type": "routing", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown9" }, { diff --git a/contracts/gateway/tests/test_verify.json b/contracts/gateway/tests/test_verify.json index 3bd7657cb..1cf376c00 100644 --- a/contracts/gateway/tests/test_verify.json +++ b/contracts/gateway/tests/test_verify.json @@ -13,7 +13,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -49,7 +49,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -85,7 +85,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifV19", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifV19", "funds": [] } } @@ -100,7 +100,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -136,7 +136,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9XX0=", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9XX0=", "funds": [] } } @@ -151,7 +151,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -187,7 +187,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -223,7 +223,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn1dfQ==", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn1dfQ==", "funds": [] } } @@ -238,7 +238,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -274,7 +274,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -303,7 +303,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain1" }, { @@ -332,7 +332,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain2" }, { @@ -361,7 +361,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain3" }, { @@ -390,7 +390,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain4" }, { @@ -419,7 +419,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain5" }, { @@ -448,7 +448,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain6" }, { @@ -477,7 +477,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain7" }, { @@ -506,7 +506,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain8" }, { @@ -535,7 +535,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain9" }, { @@ -571,7 +571,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -600,7 +600,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain1" }, { @@ -629,7 +629,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain2" }, { @@ -658,7 +658,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain3" }, { @@ -687,7 +687,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain4" }, { @@ -716,7 +716,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain5" }, { @@ -745,7 +745,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain6" }, { @@ -774,7 +774,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain7" }, { @@ -803,7 +803,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain8" }, { @@ -832,7 +832,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain9" }, { @@ -868,7 +868,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", "funds": [] } } @@ -883,7 +883,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -912,7 +912,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain1" }, { @@ -941,7 +941,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain2" }, { @@ -970,7 +970,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain3" }, { @@ -999,7 +999,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain4" }, { @@ -1028,7 +1028,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain5" }, { @@ -1057,7 +1057,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain6" }, { @@ -1086,7 +1086,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain7" }, { @@ -1115,7 +1115,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain8" }, { @@ -1144,7 +1144,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain9" }, { @@ -1180,7 +1180,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9XX0=", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9XX0=", "funds": [] } } @@ -1195,7 +1195,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -1224,7 +1224,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify1" }, { @@ -1253,7 +1253,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify2" }, { @@ -1282,7 +1282,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify3" }, { @@ -1311,7 +1311,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify4" }, { @@ -1340,7 +1340,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify5" }, { @@ -1369,7 +1369,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify6" }, { @@ -1398,7 +1398,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify7" }, { @@ -1427,7 +1427,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify8" }, { @@ -1456,7 +1456,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify9" }, { @@ -1492,7 +1492,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -1521,7 +1521,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress1" }, { @@ -1550,7 +1550,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress2" }, { @@ -1579,7 +1579,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress3" }, { @@ -1608,7 +1608,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress4" }, { @@ -1637,7 +1637,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress5" }, { @@ -1666,7 +1666,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress6" }, { @@ -1695,7 +1695,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress7" }, { @@ -1724,7 +1724,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress8" }, { @@ -1753,7 +1753,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress9" }, { @@ -1789,7 +1789,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd24xIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjMifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd240In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjYifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd243In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjkifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5In1dfQ==", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjAifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlVua25vd24xIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMSJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjMifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlVua25vd240In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNCJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjYifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlVua25vd243In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNyJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjkifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5In1dfQ==", "funds": [] } } @@ -1804,7 +1804,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -1833,7 +1833,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown1" }, { @@ -1862,7 +1862,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown2" }, { @@ -1891,7 +1891,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown3" }, { @@ -1920,7 +1920,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown4" }, { @@ -1949,7 +1949,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown5" }, { @@ -1978,7 +1978,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown6" }, { @@ -2007,7 +2007,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown7" }, { @@ -2036,7 +2036,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown8" }, { @@ -2065,7 +2065,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown9" }, { @@ -2101,7 +2101,7 @@ "wasm": { "execute": { "contract_addr": "verifier", - "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd24yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd241In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7ImNoYWluIjoibW9jay1jaGFpbiIsImlkIjoiVW5rbm93bjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJjaGFpbiI6Im1vY2stY2hhaW4iLCJpZCI6IlVua25vd244In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsiY2hhaW4iOiJtb2NrLWNoYWluIiwiaWQiOiJVbmtub3duOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", + "msg": "eyJ2ZXJpZnlfbWVzc2FnZXMiOlt7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluNyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiTm90Rm91bmRPblNvdXJjZUNoYWluOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnkwIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJGYWlsZWRUb1ZlcmlmeTEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IkZhaWxlZFRvVmVyaWZ5MiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnkzIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMyJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJGYWlsZWRUb1ZlcmlmeTQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IkZhaWxlZFRvVmVyaWZ5NSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnk2In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNiJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJGYWlsZWRUb1ZlcmlmeTcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IkZhaWxlZFRvVmVyaWZ5OCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiRmFpbGVkVG9WZXJpZnk5In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOSJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duMCJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjEifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxIn0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlVua25vd24yIn0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMiJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duMyJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMwMzAzMDMifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjQifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlVua25vd241In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNSJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duNiJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYwNjA2MDYifSx7ImNjX2lkIjp7InNvdXJjZV9jaGFpbiI6Im1vY2stY2hhaW4iLCJtZXNzYWdlX2lkIjoiVW5rbm93bjcifSwic291cmNlX2FkZHJlc3MiOiJpZGMiLCJkZXN0aW5hdGlvbl9jaGFpbiI6Im1vY2stY2hhaW4tMiIsImRlc3RpbmF0aW9uX2FkZHJlc3MiOiJpZGMiLCJwYXlsb2FkX2hhc2giOiIwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3MDcwNzA3In0seyJjY19pZCI6eyJzb3VyY2VfY2hhaW4iOiJtb2NrLWNoYWluIiwibWVzc2FnZV9pZCI6IlVua25vd244In0sInNvdXJjZV9hZGRyZXNzIjoiaWRjIiwiZGVzdGluYXRpb25fY2hhaW4iOiJtb2NrLWNoYWluLTIiLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoiaWRjIiwicGF5bG9hZF9oYXNoIjoiMDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwOCJ9LHsiY2NfaWQiOnsic291cmNlX2NoYWluIjoibW9jay1jaGFpbiIsIm1lc3NhZ2VfaWQiOiJVbmtub3duOSJ9LCJzb3VyY2VfYWRkcmVzcyI6ImlkYyIsImRlc3RpbmF0aW9uX2NoYWluIjoibW9jay1jaGFpbi0yIiwiZGVzdGluYXRpb25fYWRkcmVzcyI6ImlkYyIsInBheWxvYWRfaGFzaCI6IjA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkwOTA5MDkifV19", "funds": [] } } @@ -2116,7 +2116,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain0" }, { @@ -2145,7 +2145,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain1" }, { @@ -2174,7 +2174,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain2" }, { @@ -2203,7 +2203,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain3" }, { @@ -2232,7 +2232,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain4" }, { @@ -2261,7 +2261,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain5" }, { @@ -2290,7 +2290,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain6" }, { @@ -2319,7 +2319,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain7" }, { @@ -2348,7 +2348,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain8" }, { @@ -2377,7 +2377,7 @@ "type": "already_verified", "attributes": [ { - "key": "id", + "key": "message_id", "value": "SucceededOnSourceChain9" }, { @@ -2406,7 +2406,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain0" }, { @@ -2435,7 +2435,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain1" }, { @@ -2464,7 +2464,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain2" }, { @@ -2493,7 +2493,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain3" }, { @@ -2522,7 +2522,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain4" }, { @@ -2551,7 +2551,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain5" }, { @@ -2580,7 +2580,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain6" }, { @@ -2609,7 +2609,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain7" }, { @@ -2638,7 +2638,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain8" }, { @@ -2667,7 +2667,7 @@ "type": "already_rejected", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedOnSourceChain9" }, { @@ -2696,7 +2696,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain0" }, { @@ -2725,7 +2725,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain1" }, { @@ -2754,7 +2754,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain2" }, { @@ -2783,7 +2783,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain3" }, { @@ -2812,7 +2812,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain4" }, { @@ -2841,7 +2841,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain5" }, { @@ -2870,7 +2870,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain6" }, { @@ -2899,7 +2899,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain7" }, { @@ -2928,7 +2928,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain8" }, { @@ -2957,7 +2957,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "NotFoundOnSourceChain9" }, { @@ -2986,7 +2986,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify0" }, { @@ -3015,7 +3015,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify1" }, { @@ -3044,7 +3044,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify2" }, { @@ -3073,7 +3073,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify3" }, { @@ -3102,7 +3102,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify4" }, { @@ -3131,7 +3131,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify5" }, { @@ -3160,7 +3160,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify6" }, { @@ -3189,7 +3189,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify7" }, { @@ -3218,7 +3218,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify8" }, { @@ -3247,7 +3247,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "FailedToVerify9" }, { @@ -3276,7 +3276,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress0" }, { @@ -3305,7 +3305,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress1" }, { @@ -3334,7 +3334,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress2" }, { @@ -3363,7 +3363,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress3" }, { @@ -3392,7 +3392,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress4" }, { @@ -3421,7 +3421,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress5" }, { @@ -3450,7 +3450,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress6" }, { @@ -3479,7 +3479,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress7" }, { @@ -3508,7 +3508,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress8" }, { @@ -3537,7 +3537,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "InProgress9" }, { @@ -3566,7 +3566,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown0" }, { @@ -3595,7 +3595,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown1" }, { @@ -3624,7 +3624,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown2" }, { @@ -3653,7 +3653,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown3" }, { @@ -3682,7 +3682,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown4" }, { @@ -3711,7 +3711,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown5" }, { @@ -3740,7 +3740,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown6" }, { @@ -3769,7 +3769,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown7" }, { @@ -3798,7 +3798,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown8" }, { @@ -3827,7 +3827,7 @@ "type": "verifying", "attributes": [ { - "key": "id", + "key": "message_id", "value": "Unknown9" }, { diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 9bde0dad4..270a2a15d 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -114,7 +114,6 @@ pub fn migrate( ) -> Result { migrations::v0_6_0::migrate(deps.storage)?; - cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(Response::default()) } diff --git a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs index b872d0aa1..316fab18a 100644 --- a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs +++ b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs @@ -9,7 +9,7 @@ use cw_storage_plus::Item; use multisig::key::KeyType; use router_api::ChainName; -use crate::contract::CONTRACT_NAME; +use crate::contract::{CONTRACT_NAME, CONTRACT_VERSION}; use crate::encoding::Encoder; use crate::state; @@ -21,11 +21,19 @@ pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { let config = CONFIG.load(storage)?; migrate_permission_control(storage, &config)?; - migrate_config(storage, config)?; + delete_payloads(storage); + + cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(()) } +fn delete_payloads(storage: &mut dyn Storage) { + state::PAYLOAD.clear(storage); + state::MULTISIG_SESSION_PAYLOAD.clear(storage); + state::REPLY_TRACKER.remove(storage); +} + fn migrate_permission_control( storage: &mut dyn Storage, config: &Config, @@ -58,7 +66,7 @@ fn migrate_config(storage: &mut dyn Storage, config: Config) -> Result<(), Contr #[cw_serde] #[deprecated(since = "0.6.0", note = "only used during migration")] -pub struct Config { +struct Config { pub admin: Addr, pub governance: Addr, pub gateway: Addr, @@ -75,7 +83,7 @@ pub struct Config { pub domain_separator: Hash, } #[deprecated(since = "0.6.0", note = "only used during migration")] -pub const CONFIG: Item = Item::new("config"); +const CONFIG: Item = Item::new("config"); #[cfg(test)] mod tests { @@ -84,13 +92,14 @@ mod tests { use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response}; use multisig::key::KeyType; + use router_api::{CrossChainId, Message}; use crate::contract::migrations::v0_6_0; - use crate::contract::CONTRACT_NAME; + use crate::contract::{CONTRACT_NAME, CONTRACT_VERSION}; use crate::encoding::Encoder; use crate::error::ContractError; use crate::msg::InstantiateMsg; - use crate::state; + use crate::{payload, state}; #[test] fn migrate_checks_contract_version() { @@ -106,6 +115,68 @@ mod tests { assert!(v0_6_0::migrate(deps.as_mut().storage).is_ok()); } + #[test] + fn migrate_sets_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + v0_6_0::migrate(deps.as_mut().storage).unwrap(); + + let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); + assert_eq!(contract_version.contract, CONTRACT_NAME); + assert_eq!(contract_version.version, CONTRACT_VERSION); + } + + #[test] + fn migrate_payload() { + let mut deps = mock_dependencies(); + + instantiate_contract(deps.as_mut()); + + let msgs = vec![ + Message { + cc_id: CrossChainId { + message_id: "id1".try_into().unwrap(), + source_chain: "chain1".try_into().unwrap(), + }, + source_address: "source-address".parse().unwrap(), + destination_chain: "destination".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: [1; 32], + }, + Message { + cc_id: CrossChainId { + message_id: "id2".try_into().unwrap(), + source_chain: "chain2".try_into().unwrap(), + }, + source_address: "source-address2".parse().unwrap(), + destination_chain: "destination2".parse().unwrap(), + destination_address: "destination-address2".parse().unwrap(), + payload_hash: [2; 32], + }, + Message { + cc_id: CrossChainId { + message_id: "id3".try_into().unwrap(), + source_chain: "chain3".try_into().unwrap(), + }, + source_address: "source-address3".parse().unwrap(), + destination_chain: "destination3".parse().unwrap(), + destination_address: "destination-address3".parse().unwrap(), + payload_hash: [3; 32], + }, + ]; + + let payload = payload::Payload::Messages(msgs); + + state::PAYLOAD + .save(deps.as_mut().storage, &payload.id(), &payload) + .unwrap(); + + assert!(v0_6_0::migrate(deps.as_mut().storage).is_ok()); + + assert!(state::PAYLOAD.is_empty(deps.as_ref().storage)); + } + #[test] fn migrate_permission_control() { let mut deps = mock_dependencies(); diff --git a/contracts/nexus-gateway/src/contract.rs b/contracts/nexus-gateway/src/contract.rs index 2da129fc4..622d2efa2 100644 --- a/contracts/nexus-gateway/src/contract.rs +++ b/contracts/nexus-gateway/src/contract.rs @@ -275,8 +275,8 @@ mod tests { let msgs = vec![ router_api::Message { cc_id: CrossChainId { - chain: "sourceChain".parse().unwrap(), - id: "0x2fe4:0".parse().unwrap(), + source_chain: "sourceChain".parse().unwrap(), + message_id: "0x2fe4:0".parse().unwrap(), }, source_address: "0xb860".parse().unwrap(), destination_address: "0xD419".parse().unwrap(), @@ -290,8 +290,8 @@ mod tests { }, router_api::Message { cc_id: CrossChainId { - chain: "sourceChain".parse().unwrap(), - id: "0x6b33:10".parse().unwrap(), + source_chain: "sourceChain".parse().unwrap(), + message_id: "0x6b33:10".parse().unwrap(), }, source_address: "0x70725".parse().unwrap(), destination_address: "0x7FAD".parse().unwrap(), diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 6f6fb7c1b..32f509f8e 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -41,17 +41,17 @@ impl From for Message { fn from(msg: router_api::Message) -> Self { // fallback to using all 0's as the tx ID if it's not in the expected format let (source_tx_id, source_tx_index) = - parse_message_id(&msg.cc_id.id).unwrap_or((vec![0; 32].try_into().unwrap(), 0)); + parse_message_id(&msg.cc_id.message_id).unwrap_or((vec![0; 32].try_into().unwrap(), 0)); Self { - source_chain: msg.cc_id.chain, + source_chain: msg.cc_id.source_chain, source_address: msg.source_address, destination_chain: msg.destination_chain, destination_address: msg.destination_address, payload_hash: msg.payload_hash, source_tx_id, source_tx_index, - id: msg.cc_id.id.into(), + id: msg.cc_id.message_id.into(), } } } @@ -62,8 +62,8 @@ impl TryFrom for router_api::Message { fn try_from(msg: Message) -> Result { Ok(Self { cc_id: CrossChainId { - chain: msg.source_chain, - id: nonempty::String::try_from(msg.id.as_str()) + source_chain: msg.source_chain, + message_id: nonempty::String::try_from(msg.id.as_str()) .change_context(ContractError::InvalidMessageId(msg.id))?, }, source_address: msg.source_address, @@ -110,8 +110,8 @@ mod test { assert!(router_msg.is_ok()); let router_msg = router_msg.unwrap(); let router_msg_cc_id = router_msg.cc_id; - assert_eq!(router_msg_cc_id.chain, msg.source_chain); - assert_eq!(router_msg_cc_id.id.to_string(), msg.id); + assert_eq!(router_msg_cc_id.source_chain, msg.source_chain); + assert_eq!(router_msg_cc_id.message_id.to_string(), msg.id); } #[test] @@ -137,11 +137,14 @@ mod test { let router_msg_cc_id = msg.cc_id; - assert_eq!(nexus_msg.id, *router_msg_cc_id.id); + assert_eq!(nexus_msg.id, *router_msg_cc_id.message_id); assert_eq!(nexus_msg.destination_address, msg.destination_address); assert_eq!(nexus_msg.destination_chain, msg.destination_chain); assert_eq!(nexus_msg.source_address, msg.source_address); - assert_eq!(nexus_msg.source_chain, router_msg_cc_id.chain.clone()); + assert_eq!( + nexus_msg.source_chain, + router_msg_cc_id.source_chain.clone() + ); assert_eq!(nexus_msg.source_tx_id, vec![2; 32].try_into().unwrap()); assert_eq!(nexus_msg.source_tx_index, 1); } @@ -169,13 +172,16 @@ mod test { let router_msg_cc_id = msg.cc_id; - assert_eq!(nexus_msg.id, *router_msg_cc_id.id); + assert_eq!(nexus_msg.id, *router_msg_cc_id.message_id); assert_eq!(nexus_msg.source_tx_id, vec![0; 32].try_into().unwrap()); assert_eq!(nexus_msg.source_tx_index, 0); assert_eq!(nexus_msg.destination_address, msg.destination_address); assert_eq!(nexus_msg.destination_chain, msg.destination_chain); assert_eq!(nexus_msg.source_address, msg.source_address); - assert_eq!(nexus_msg.source_chain, router_msg_cc_id.chain.clone()); + assert_eq!( + nexus_msg.source_chain, + router_msg_cc_id.source_chain.clone() + ); } } diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index 0f7156795..c4b139055 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -331,7 +331,7 @@ mod test { let mut messages = generate_messages(ð, &polygon, &mut 0, 1); messages .iter_mut() - .for_each(|msg| msg.cc_id.chain = "Ethereum".parse().unwrap()); + .for_each(|msg| msg.cc_id.source_chain = "Ethereum".parse().unwrap()); let result = execute( deps.as_mut(), @@ -354,7 +354,7 @@ mod test { let mut messages = generate_messages(ð, &polygon, &mut 0, 1); messages .iter_mut() - .for_each(|msg| msg.cc_id.chain = "Ethereum".parse().unwrap()); + .for_each(|msg| msg.cc_id.source_chain = "Ethereum".parse().unwrap()); let result = execute( deps.as_mut(), @@ -426,7 +426,7 @@ mod test { .unwrap() .clone() .into_iter() - .filter(|m| m.cc_id.chain == s.chain_name) + .filter(|m| m.cc_id.source_chain == s.chain_name) .collect::>(), &res.messages[i].msg, ); diff --git a/contracts/router/src/contract/execute.rs b/contracts/router/src/contract/execute.rs index 4ca2b9bbf..c31016b57 100644 --- a/contracts/router/src/contract/execute.rs +++ b/contracts/router/src/contract/execute.rs @@ -153,7 +153,7 @@ fn verify_msg_ids( expected_format: &MessageIdFormat, ) -> Result<(), error_stack::Report> { msgs.iter() - .try_for_each(|msg| msg_id::verify_msg_id(&msg.cc_id.id, expected_format)) + .try_for_each(|msg| msg_id::verify_msg_id(&msg.cc_id.message_id, expected_format)) .change_context(Error::InvalidMessageId) } @@ -179,7 +179,10 @@ fn validate_msgs( })); } - if msgs.iter().any(|msg| msg.cc_id.chain != source_chain.name) { + if msgs + .iter() + .any(|msg| msg.cc_id.source_chain != source_chain.name) + { return Err(report!(Error::WrongSourceChain)); } diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 8259e10f7..bfe20eb50 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -317,7 +317,7 @@ mod test { let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); assert_contract_err_strings_equal( err, - ContractError::InvalidMessageID(messages[0].cc_id.id.to_string()), + ContractError::InvalidMessageID(messages[0].cc_id.message_id.to_string()), ); } @@ -333,7 +333,7 @@ mod test { let err = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap_err(); assert_contract_err_strings_equal( err, - ContractError::InvalidMessageID(messages[0].cc_id.id.to_string()), + ContractError::InvalidMessageID(messages[0].cc_id.message_id.to_string()), ); } diff --git a/contracts/voting-verifier/src/contract/execute.rs b/contracts/voting-verifier/src/contract/execute.rs index 41c76dc85..e2e2155bf 100644 --- a/contracts/voting-verifier/src/contract/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -90,7 +90,7 @@ pub fn verify_messages( if messages .iter() - .any(|message| message.cc_id.chain != source_chain) + .any(|message| message.cc_id.source_chain != source_chain) { Err(ContractError::SourceChainMismatch(source_chain.clone()))?; } diff --git a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs index 1cee2ac84..0a7a90651 100644 --- a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs +++ b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs @@ -20,6 +20,8 @@ pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { migrate_permission_control(storage, &config.governance)?; migrate_config(storage, config)?; + delete_polls(storage); + cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(()) @@ -50,6 +52,13 @@ fn migrate_permission_control(storage: &mut dyn Storage, governance: &Addr) -> S permission_control::set_governance(storage, governance) } +fn delete_polls(storage: &mut dyn Storage) { + state::POLLS.clear(storage); + state::VOTES.clear(storage); + state::poll_messages().clear(storage); + state::poll_messages().clear(storage); +} + #[cw_serde] #[deprecated(since = "0.5.0", note = "only used during migration")] pub struct Config { @@ -163,6 +172,19 @@ mod tests { .contains(Permission::Governance)); } + #[test] + fn state_is_cleared_after_migration() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + assert!(v0_5_0::migrate(deps.as_mut().storage).is_ok()); + + assert!(state::VOTES.is_empty(deps.as_ref().storage)); + assert!(state::POLLS.is_empty(deps.as_ref().storage)); + assert!(state::poll_messages().is_empty(deps.as_ref().storage)); + assert!(state::poll_verifier_sets().is_empty(deps.as_ref().storage)); + } + fn instantiate_contract(deps: DepsMut) { instantiate( deps, diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 26215bf1e..a82fc5a0c 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -195,7 +195,7 @@ pub struct TxEventConfirmation { impl TryFrom<(Message, &MessageIdFormat)> for TxEventConfirmation { type Error = ContractError; fn try_from((msg, msg_id_format): (Message, &MessageIdFormat)) -> Result { - let (tx_id, event_index) = parse_message_id(&msg.cc_id.id, msg_id_format)?; + let (tx_id, event_index) = parse_message_id(&msg.cc_id.message_id, msg_id_format)?; Ok(TxEventConfirmation { tx_id, diff --git a/packages/evm-gateway/src/lib.rs b/packages/evm-gateway/src/lib.rs index b022e9f72..5354a7c6c 100644 --- a/packages/evm-gateway/src/lib.rs +++ b/packages/evm-gateway/src/lib.rs @@ -82,8 +82,8 @@ impl TryFrom<&RouterMessage> for Message { .change_context(Error::InvalidAddress)?; Ok(Message { - source_chain: msg.cc_id.chain.to_string(), - message_id: msg.cc_id.id.to_string(), + source_chain: msg.cc_id.source_chain.to_string(), + message_id: msg.cc_id.message_id.to_string(), source_address: msg.source_address.to_string(), contract_address, payload_hash: msg.payload_hash, diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index f9f55e0bf..6014d5759 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -62,8 +62,8 @@ impl Message { impl From for Vec { fn from(other: Message) -> Self { vec![ - ("id", other.cc_id.id).into(), - ("source_chain", other.cc_id.chain).into(), + ("message_id", other.cc_id.message_id).into(), + ("source_chain", other.cc_id.source_chain).into(), ("source_address", other.source_address.deref()).into(), ("destination_chain", other.destination_chain).into(), ("destination_address", other.destination_address.deref()).into(), @@ -116,8 +116,8 @@ impl TryFrom for Address { #[cw_serde] #[derive(Eq, Hash)] pub struct CrossChainId { - pub chain: ChainNameRaw, - pub id: nonempty::String, + pub source_chain: ChainNameRaw, + pub message_id: nonempty::String, } impl CrossChainId { @@ -130,8 +130,8 @@ impl CrossChainId { T: Context, { Ok(CrossChainId { - chain: chain.try_into().change_context(Error::InvalidChainName)?, - id: id.try_into().change_context(Error::InvalidMessageId)?, + source_chain: chain.try_into().change_context(Error::InvalidChainName)?, + message_id: id.try_into().change_context(Error::InvalidMessageId)?, }) } } @@ -143,8 +143,8 @@ impl PrimaryKey<'_> for CrossChainId { type SuperSuffix = (ChainNameRaw, String); fn key(&self) -> Vec { - let mut keys = self.chain.key(); - keys.extend(self.id.key()); + let mut keys = self.source_chain.key(); + keys.extend(self.message_id.key()); keys } } @@ -153,10 +153,10 @@ impl KeyDeserialize for CrossChainId { type Output = Self; fn from_vec(value: Vec) -> StdResult { - let (chain, id) = <(ChainNameRaw, String)>::from_vec(value)?; + let (source_chain, id) = <(ChainNameRaw, String)>::from_vec(value)?; Ok(CrossChainId { - chain, - id: id + source_chain, + message_id: id .try_into() .map_err(|err| StdError::parse_err(type_name::(), err))?, }) @@ -164,7 +164,11 @@ impl KeyDeserialize for CrossChainId { } impl Display for CrossChainId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}{}{}", self.chain, FIELD_DELIMITER, *self.id) + write!( + f, + "{}{}{}", + self.source_chain, FIELD_DELIMITER, *self.message_id + ) } } @@ -444,7 +448,7 @@ mod tests { // will cause this test to fail, indicating that a migration is needed. fn test_message_struct_unchanged() { let expected_message_hash = - "b0c6ee811cf4c205b08e36dbbad956212c4e291aedae44ab700265477bfea526"; + "3a0edbeb590d12cf9f71864469d9e7afd52cccf2798db09c55def296af3a8e89"; let msg = dummy_message(); From 862449362e0a4d005f0d14e948c999ed727dd679 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 26 Jul 2024 20:45:56 -0400 Subject: [PATCH 107/168] feat: add interchain token service encoding/decoding api (#482) Co-authored-by: Christian Gorenflo Co-authored-by: haiyizxx Co-authored-by: Houmaan Chamani Co-authored-by: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> --- .github/workflows/basic.yaml | 4 + Cargo.lock | 418 +++++++++++-- Cargo.toml | 6 +- interchain-token-service/Cargo.toml | 27 + interchain-token-service/release.toml | 1 + interchain-token-service/src/abi.rs | 579 ++++++++++++++++++ interchain-token-service/src/error.rs | 14 + interchain-token-service/src/lib.rs | 5 + interchain-token-service/src/primitives.rs | 89 +++ ...ploy_interchain_token_encode_decode.golden | 8 + .../deploy_token_manager_encode_decode.golden | 6 + .../interchain_transfer_encode_decode.golden | 6 + packages/axelar-wasm-std/Cargo.toml | 2 +- 13 files changed, 1117 insertions(+), 48 deletions(-) create mode 100644 interchain-token-service/Cargo.toml create mode 100644 interchain-token-service/release.toml create mode 100644 interchain-token-service/src/abi.rs create mode 100644 interchain-token-service/src/error.rs create mode 100644 interchain-token-service/src/lib.rs create mode 100644 interchain-token-service/src/primitives.rs create mode 100644 interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden create mode 100644 interchain-token-service/src/testdata/deploy_token_manager_encode_decode.golden create mode 100644 interchain-token-service/src/testdata/interchain_transfer_encode_decode.golden diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index e15914b38..d0df1cd1d 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -89,6 +89,10 @@ jobs: (cd $C && cargo build --release --lib --target wasm32-unknown-unknown --locked) done + - name: Build ITS release + working-directory: ./interchain-token-service + run: cargo build --release --target wasm32-unknown-unknown --locked + # cosmwasm-check v1.3.x is used to check for compatibility with wasmvm v1.3.x used by Axelar # Older rust toolchain is required to install cosmwasm-check v1.3.x - name: Install cosmwasm-check diff --git a/Cargo.lock b/Cargo.lock index d320b4719..5c4bfe81e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,6 +126,97 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "alloy-primitives" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "k256", + "keccak-asm", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d58d9f5da7b40e9bfff0b7e7816700be4019db97d4b6359fe7f94a9e22e42ac" +dependencies = [ + "arrayvec", + "bytes", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.68", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck 0.5.0", + "indexmap 2.2.6", + "proc-macro-error", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.68", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" +dependencies = [ + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.68", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-types" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "ampd" version = "0.6.0" @@ -308,9 +399,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -320,8 +411,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -331,11 +422,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-relations", - "ark-serialize", + "ark-serialize 0.4.2", "ark-snark", - "ark-std", + "ark-std 0.4.0", "blake2", "derivative", "digest 0.10.7", @@ -348,10 +439,10 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", "itertools 0.10.5", @@ -359,26 +450,54 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.5", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + [[package]] name = "ark-ff" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "digest 0.10.7", "itertools 0.10.5", "num-bigint 0.4.5", "num-traits", "paste", - "rustc_version", + "rustc_version 0.4.0", "zeroize", ] +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote 1.0.36", + "syn 1.0.109", +] + [[package]] name = "ark-ff-asm" version = "0.4.2" @@ -389,6 +508,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint 0.4.5", + "num-traits", + "quote 1.0.36", + "syn 1.0.109", +] + [[package]] name = "ark-ff-macros" version = "0.4.2" @@ -410,11 +541,11 @@ checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" dependencies = [ "ark-crypto-primitives", "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", "ark-relations", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -423,9 +554,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", ] @@ -436,8 +567,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" dependencies = [ - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", "tracing", ] @@ -448,8 +579,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3975a01b0a6e3eae0f72ec7ca8598a6620fc72fa5981f6f5cca33b7cd788f633" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", ] [[package]] @@ -459,7 +600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-serialize-derive", - "ark-std", + "ark-std 0.4.0", "digest 0.10.7", "num-bigint 0.4.5", ] @@ -481,10 +622,20 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" dependencies = [ - "ark-ff", + "ark-ff 0.4.2", "ark-relations", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", ] [[package]] @@ -612,7 +763,7 @@ checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ "futures", "pharos", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -1212,7 +1363,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1672,7 +1823,7 @@ dependencies = [ "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "rustc_version", + "rustc_version 0.4.0", "subtle", "zeroize", ] @@ -1762,7 +1913,7 @@ dependencies = [ "cosmwasm-std", "cw2 0.15.1", "schemars", - "semver", + "semver 1.0.23", "serde", "thiserror", ] @@ -1777,7 +1928,7 @@ dependencies = [ "cosmwasm-std", "cw2 1.1.2", "schemars", - "semver", + "semver 1.0.23", "serde", "thiserror", ] @@ -1805,7 +1956,7 @@ dependencies = [ "cosmwasm-std", "cw-storage-plus 1.2.0", "schemars", - "semver", + "semver 1.0.23", "serde", "thiserror", ] @@ -2008,10 +2159,16 @@ dependencies = [ "convert_case", "proc-macro2 1.0.85", "quote 1.0.36", - "rustc_version", + "rustc_version 0.4.0", "syn 2.0.68", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "difference" version = "2.0.0" @@ -2315,7 +2472,7 @@ checksum = "27a72baa257b5e0e2de241967bc5ee8f855d6072351042688621081d66b2a76b" dependencies = [ "anyhow", "eyre", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -2560,9 +2717,9 @@ dependencies = [ "aes", "aes-gcm", "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-secp256r1", - "ark-serialize", + "ark-serialize 0.4.2", "auto_ops", "base64ct", "bech32", @@ -2641,10 +2798,10 @@ dependencies = [ "ark-bls12-381", "ark-bn254", "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-groth16", "ark-relations", - "ark-serialize", + "ark-serialize 0.4.2", "ark-snark", "blst", "byte-slice-cast", @@ -2679,6 +2836,17 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "ff" version = "0.13.0" @@ -3042,6 +3210,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "goldie" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa70c42797cac60e6182e00f33f629212e02ba80d67e8a976f6168b57568d78e" +dependencies = [ + "anyhow", + "once_cell", + "pretty_assertions", + "serde", + "serde_json", + "upon", + "yansi 1.0.1", +] + [[package]] name = "group" version = "0.13.0" @@ -3746,6 +3929,27 @@ dependencies = [ "voting-verifier", ] +[[package]] +name = "interchain-token-service" +version = "0.1.0" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "axelar-wasm-std", + "axelar-wasm-std-derive", + "cosmwasm-schema", + "cosmwasm-std", + "error-stack", + "goldie", + "report", + "router-api", + "schemars", + "serde", + "serde_json", + "strum 0.25.0", + "thiserror", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -4002,6 +4206,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a3633291834c4fbebf8673acbc1b04ec9d151418ff9b8e26dcd79129928758" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -5400,7 +5614,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ "futures", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -5573,6 +5787,16 @@ dependencies = [ "termtree", ] +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi 0.5.1", +] + [[package]] name = "prettyplease" version = "0.1.25" @@ -6335,6 +6559,36 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ruint" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint 0.4.5", + "num-traits", + "parity-scale-codec 3.6.12", + "primitive-types 0.12.2", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rust-ini" version = "0.18.0" @@ -6363,13 +6617,22 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.23", ] [[package]] @@ -6648,6 +6911,15 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.23" @@ -6657,6 +6929,15 @@ dependencies = [ "serde", ] +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "send_wrapper" version = "0.4.0" @@ -6953,6 +7234,16 @@ dependencies = [ "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9b57fd861253bff08bb1919e995f90ba8f4889de2726091c8876f3a4e823b40" +dependencies = [ + "cc", + "cfg-if", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -7490,6 +7781,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" +dependencies = [ + "paste", + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.68", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -7711,7 +8014,7 @@ dependencies = [ "hyper-rustls 0.22.1", "peg", "pin-project", - "semver", + "semver 1.0.23", "serde", "serde_bytes", "serde_json", @@ -8431,6 +8734,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "upon" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe29601d1624f104fa9a35ea71a5f523dd8bd1cfc8c31f8124ad2b829f013c0" +dependencies = [ + "serde", + "unicode-ident", + "unicode-width", +] + [[package]] name = "url" version = "2.5.1" @@ -8957,7 +9271,7 @@ dependencies = [ "js-sys", "log", "pharos", - "rustc_version", + "rustc_version 0.4.0", "send_wrapper 0.6.0", "thiserror", "wasm-bindgen", @@ -9007,6 +9321,18 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yasna" version = "0.5.2" diff --git a/Cargo.toml b/Cargo.toml index 83a1c828c..a0d1e13b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["ampd", "contracts/*", "integration-tests", "packages/*"] +members = ["ampd", "contracts/*", "integration-tests", "interchain-token-service", "packages/*"] resolver = "2" [workspace.package] @@ -48,6 +48,10 @@ tokio = "1.38.0" tokio-stream = "0.1.11" tokio-util = "0.7.11" tofn = { version = "1.1" } +alloy-primitives = { version = "0.7.6", default-features = false, features = ["std"] } +alloy-sol-types = { version = "0.7.6", default-features = false, features = ["std"] } +strum = { version = "0.25", default-features = false, features = ["derive"] } +interchain-token-service = { version = "^0.1.0", path = "interchain-token-service" } [workspace.lints.clippy] arithmetic_side_effects = "deny" diff --git a/interchain-token-service/Cargo.toml b/interchain-token-service/Cargo.toml new file mode 100644 index 000000000..6a91f4d51 --- /dev/null +++ b/interchain-token-service/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "interchain-token-service" +version = "0.1.0" +rust-version = { workspace = true } +edition = "2021" + +[dependencies] +alloy-primitives = { workspace = true } +alloy-sol-types = { workspace = true } +axelar-wasm-std = { workspace = true } +axelar-wasm-std-derive = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +error-stack = { workspace = true } +report = { workspace = true } +router-api = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +strum = { workspace = true } +thiserror = { workspace = true } + +[dev-dependencies] +goldie = { version = "0.5" } + +[lints] +workspace = true diff --git a/interchain-token-service/release.toml b/interchain-token-service/release.toml new file mode 100644 index 000000000..954564097 --- /dev/null +++ b/interchain-token-service/release.toml @@ -0,0 +1 @@ +release = false diff --git a/interchain-token-service/src/abi.rs b/interchain-token-service/src/abi.rs new file mode 100644 index 000000000..a0cb0ac31 --- /dev/null +++ b/interchain-token-service/src/abi.rs @@ -0,0 +1,579 @@ +use alloy_primitives::{FixedBytes, U256}; +use alloy_sol_types::{sol, SolValue}; +use axelar_wasm_std::FnExt; +use cosmwasm_std::{HexBinary, Uint256}; +use error_stack::{Report, ResultExt}; +use router_api::ChainName; + +use crate::error::Error; +use crate::primitives::{ItsHubMessage, ItsMessage}; +use crate::{TokenId, TokenManagerType}; + +// ITS Message payload types +// Reference: https://github.com/axelarnetwork/interchain-token-service/blob/v1.2.4/DESIGN.md#interchain-communication-spec +// `abi_encode_params` is used to encode the struct fields as ABI params as required by the spec. +// E.g. `DeployTokenManager::abi_encode_params` encodes as `abi.encode([uint256, bytes32, uint256, bytes], [...])`. +sol! { + enum MessageType { + InterchainTransfer, + DeployInterchainToken, + DeployTokenManager, + SendToHub, + ReceiveFromHub, + } + + struct InterchainTransfer { + uint256 messageType; + bytes32 tokenId; + bytes sourceAddress; + bytes destinationAddress; + uint256 amount; + bytes data; + } + + struct DeployInterchainToken { + uint256 messageType; + bytes32 tokenId; + string name; + string symbol; + uint8 decimals; + bytes minter; + } + + struct DeployTokenManager { + uint256 messageType; + bytes32 tokenId; + uint256 tokenManagerType; + bytes params; + } + + struct SendToHub { + uint256 messageType; + /// True destination chain name when sending a message from ITS edge source contract -> ITS Hub + string destination_chain; + bytes message; + } + + struct ReceiveFromHub { + uint256 messageType; + /// True source chain name when receiving a message from ITS Hub -> ITS edge destination contract + string source_chain; + bytes message; + } +} + +impl ItsMessage { + pub fn abi_encode(self) -> HexBinary { + match self { + ItsMessage::InterchainTransfer { + token_id, + source_address, + destination_address, + amount, + data, + } => InterchainTransfer { + messageType: MessageType::InterchainTransfer.into(), + tokenId: FixedBytes::<32>::new(token_id.into()), + sourceAddress: Vec::::from(source_address).into(), + destinationAddress: Vec::::from(destination_address).into(), + amount: U256::from_le_bytes(amount.to_le_bytes()), + data: Vec::::from(data).into(), + } + .abi_encode_params(), + ItsMessage::DeployInterchainToken { + token_id, + name, + symbol, + decimals, + minter, + } => DeployInterchainToken { + messageType: MessageType::DeployInterchainToken.into(), + tokenId: FixedBytes::<32>::new(token_id.into()), + name, + symbol, + decimals, + minter: Vec::::from(minter).into(), + } + .abi_encode_params(), + ItsMessage::DeployTokenManager { + token_id, + token_manager_type, + params, + } => DeployTokenManager { + messageType: MessageType::DeployTokenManager.into(), + tokenId: FixedBytes::<32>::new(token_id.into()), + tokenManagerType: token_manager_type.into(), + params: Vec::::from(params).into(), + } + .abi_encode_params(), + } + .into() + } + + pub fn abi_decode(payload: &[u8]) -> Result> { + if payload.len() < 32 { + return Err(Report::new(Error::InvalidMessage)); + } + + let message_type = MessageType::abi_decode(&payload[0..32], true) + .change_context(Error::InvalidMessageType)?; + + let message = match message_type { + MessageType::InterchainTransfer => { + let decoded = InterchainTransfer::abi_decode_params(payload, true) + .change_context(Error::InvalidMessage)?; + + Ok(ItsMessage::InterchainTransfer { + token_id: TokenId::new(decoded.tokenId.into()), + source_address: HexBinary::from(decoded.sourceAddress.to_vec()), + destination_address: HexBinary::from(decoded.destinationAddress.as_ref()), + amount: Uint256::from_le_bytes(decoded.amount.to_le_bytes()), + data: HexBinary::from(decoded.data.as_ref()), + }) + } + MessageType::DeployInterchainToken => { + let decoded = DeployInterchainToken::abi_decode_params(payload, true) + .change_context(Error::InvalidMessage)?; + + Ok(ItsMessage::DeployInterchainToken { + token_id: TokenId::new(decoded.tokenId.into()), + name: decoded.name, + symbol: decoded.symbol, + decimals: decoded.decimals, + minter: HexBinary::from(decoded.minter.as_ref()), + }) + } + MessageType::DeployTokenManager => { + let decoded = DeployTokenManager::abi_decode_params(payload, true) + .change_context(Error::InvalidMessage)?; + + let token_manager_type = u8::try_from(decoded.tokenManagerType) + .change_context(Error::InvalidTokenManagerType)? + .then(TokenManagerType::from_repr) + .ok_or_else(|| Report::new(Error::InvalidTokenManagerType))?; + + Ok(ItsMessage::DeployTokenManager { + token_id: TokenId::new(decoded.tokenId.into()), + token_manager_type, + params: HexBinary::from(decoded.params.as_ref()), + }) + } + _ => Err(Report::new(Error::InvalidMessageType)), + }?; + + Ok(message) + } +} + +impl ItsHubMessage { + pub fn abi_encode(self) -> HexBinary { + match self { + ItsHubMessage::SendToHub { + destination_chain, + message, + } => SendToHub { + messageType: MessageType::SendToHub.into(), + destination_chain: destination_chain.into(), + message: Vec::::from(message.abi_encode()).into(), + } + .abi_encode_params() + .into(), + ItsHubMessage::ReceiveFromHub { + source_chain, + message, + } => ReceiveFromHub { + messageType: MessageType::ReceiveFromHub.into(), + source_chain: source_chain.into(), + message: Vec::::from(message.abi_encode()).into(), + } + .abi_encode_params() + .into(), + } + } + + pub fn abi_decode(payload: &[u8]) -> Result> { + if payload.len() < 32 { + return Err(Report::new(Error::InvalidMessage)); + } + + let message_type = MessageType::abi_decode(&payload[0..32], true) + .change_context(Error::InvalidMessageType)?; + + let hub_message = match message_type { + MessageType::SendToHub => { + let decoded = SendToHub::abi_decode_params(payload, true) + .change_context(Error::InvalidMessage)?; + + ItsHubMessage::SendToHub { + destination_chain: ChainName::try_from(decoded.destination_chain) + .change_context(Error::InvalidChainName)?, + message: ItsMessage::abi_decode(&decoded.message)?, + } + } + MessageType::ReceiveFromHub => { + let decoded = ReceiveFromHub::abi_decode_params(payload, true) + .change_context(Error::InvalidMessage)?; + + ItsHubMessage::ReceiveFromHub { + source_chain: ChainName::try_from(decoded.source_chain) + .change_context(Error::InvalidChainName)?, + message: ItsMessage::abi_decode(&decoded.message)?, + } + } + _ => return Err(Report::new(Error::InvalidMessageType)), + }; + + Ok(hub_message) + } +} + +impl From for U256 { + fn from(value: MessageType) -> Self { + U256::from(value as u8) + } +} + +impl From for U256 { + fn from(value: TokenManagerType) -> Self { + U256::from(value as u8) + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use alloy_primitives::{FixedBytes, U256}; + use alloy_sol_types::SolValue; + use cosmwasm_std::{HexBinary, Uint256}; + use router_api::ChainName; + + use crate::abi::{DeployTokenManager, MessageType, SendToHub}; + use crate::error::Error; + use crate::{ItsHubMessage, ItsMessage, TokenManagerType}; + + #[test] + fn interchain_transfer_encode_decode() { + let remote_chain = ChainName::from_str("chain").unwrap(); + + let cases = vec![ + ItsHubMessage::SendToHub { + destination_chain: remote_chain.clone(), + message: ItsMessage::InterchainTransfer { + token_id: [0u8; 32].into(), + source_address: HexBinary::from_hex("").unwrap(), + destination_address: HexBinary::from_hex("").unwrap(), + amount: Uint256::zero(), + data: HexBinary::from_hex("").unwrap(), + }, + }, + ItsHubMessage::SendToHub { + destination_chain: remote_chain.clone(), + message: ItsMessage::InterchainTransfer { + token_id: [255u8; 32].into(), + source_address: HexBinary::from_hex("4F4495243837681061C4743b74B3eEdf548D56A5") + .unwrap(), + destination_address: HexBinary::from_hex( + "4F4495243837681061C4743b74B3eEdf548D56A5", + ) + .unwrap(), + amount: Uint256::MAX, + data: HexBinary::from_hex("abcd").unwrap(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: remote_chain.clone(), + message: ItsMessage::InterchainTransfer { + token_id: [0u8; 32].into(), + source_address: HexBinary::from_hex("").unwrap(), + destination_address: HexBinary::from_hex("").unwrap(), + amount: Uint256::zero(), + data: HexBinary::from_hex("").unwrap(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: remote_chain.clone(), + message: ItsMessage::InterchainTransfer { + token_id: [255u8; 32].into(), + source_address: HexBinary::from_hex("4F4495243837681061C4743b74B3eEdf548D56A5") + .unwrap(), + destination_address: HexBinary::from_hex( + "4F4495243837681061C4743b74B3eEdf548D56A5", + ) + .unwrap(), + amount: Uint256::MAX, + data: HexBinary::from_hex("abcd").unwrap(), + }, + }, + ]; + + let encoded: Vec<_> = cases + .iter() + .map(|original| original.clone().abi_encode().to_hex()) + .collect(); + + goldie::assert_json!(encoded); + + for original in cases { + let encoded = original.clone().abi_encode(); + let decoded = ItsHubMessage::abi_decode(&encoded).unwrap(); + assert_eq!(original, decoded); + } + } + + #[test] + fn deploy_interchain_token_encode_decode() { + let remote_chain = ChainName::from_str("chain").unwrap(); + + let cases = vec![ + ItsHubMessage::SendToHub { + destination_chain: remote_chain.clone(), + message: ItsMessage::DeployInterchainToken { + token_id: [0u8; 32].into(), + name: "".into(), + symbol: "".into(), + decimals: 0, + minter: HexBinary::from_hex("").unwrap(), + }, + }, + ItsHubMessage::SendToHub { + destination_chain: remote_chain.clone(), + message: ItsMessage::DeployInterchainToken { + token_id: [1u8; 32].into(), + name: "Test Token".into(), + symbol: "TST".into(), + decimals: 18, + minter: HexBinary::from_hex("1234").unwrap(), + }, + }, + ItsHubMessage::SendToHub { + destination_chain: ChainName::from_str("unicode-chain-🌍").unwrap(), + message: ItsMessage::DeployInterchainToken { + token_id: [0u8; 32].into(), + name: "Unicode Token 🪙".into(), + symbol: "UNI🔣".into(), + decimals: 255, + minter: HexBinary::from_hex("abcd").unwrap(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: remote_chain.clone(), + message: ItsMessage::DeployInterchainToken { + token_id: [0u8; 32].into(), + name: "".into(), + symbol: "".into(), + decimals: 0, + minter: HexBinary::from_hex("").unwrap(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: remote_chain.clone(), + message: ItsMessage::DeployInterchainToken { + token_id: [1u8; 32].into(), + name: "Test Token".into(), + symbol: "TST".into(), + decimals: 18, + minter: HexBinary::from_hex("1234").unwrap(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: ChainName::from_str("unicode-chain-🌍").unwrap(), + message: ItsMessage::DeployInterchainToken { + token_id: [0u8; 32].into(), + name: "Unicode Token 🪙".into(), + symbol: "UNI🔣".into(), + decimals: 255, + minter: HexBinary::from_hex("abcd").unwrap(), + }, + }, + ]; + + let encoded: Vec<_> = cases + .iter() + .map(|original| original.clone().abi_encode().to_hex()) + .collect(); + + goldie::assert_json!(encoded); + + for original in cases { + let encoded = original.clone().abi_encode(); + let decoded = ItsHubMessage::abi_decode(&encoded).unwrap(); + assert_eq!(original, decoded); + } + } + + #[test] + fn deploy_token_manager_encode_decode() { + let remote_chain = ChainName::from_str("chain").unwrap(); + + let cases = vec![ + ItsHubMessage::SendToHub { + destination_chain: remote_chain.clone(), + message: ItsMessage::DeployTokenManager { + token_id: [0u8; 32].into(), + token_manager_type: TokenManagerType::NativeInterchainToken, + params: HexBinary::default(), + }, + }, + ItsHubMessage::SendToHub { + destination_chain: remote_chain.clone(), + message: ItsMessage::DeployTokenManager { + token_id: [1u8; 32].into(), + token_manager_type: TokenManagerType::Gateway, + params: HexBinary::from_hex("1234").unwrap(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: remote_chain.clone(), + message: ItsMessage::DeployTokenManager { + token_id: [0u8; 32].into(), + token_manager_type: TokenManagerType::NativeInterchainToken, + params: HexBinary::default(), + }, + }, + ItsHubMessage::ReceiveFromHub { + source_chain: remote_chain.clone(), + message: ItsMessage::DeployTokenManager { + token_id: [1u8; 32].into(), + token_manager_type: TokenManagerType::Gateway, + params: HexBinary::from_hex("1234").unwrap(), + }, + }, + ]; + + let encoded: Vec<_> = cases + .iter() + .map(|original| original.clone().abi_encode().to_hex()) + .collect(); + + goldie::assert_json!(encoded); + + for original in cases { + let encoded = original.clone().abi_encode(); + let decoded = ItsHubMessage::abi_decode(&encoded).unwrap(); + assert_eq!(original, decoded); + } + } + + #[test] + fn invalid_its_hub_message_type() { + let invalid_payload = SendToHub { + messageType: U256::from(MessageType::ReceiveFromHub as u8 + 1), + destination_chain: "remote-chain".into(), + message: vec![].into(), + } + .abi_encode_params(); + + let result = ItsHubMessage::abi_decode(&invalid_payload); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().current_context().to_string(), + Error::InvalidMessageType.to_string() + ); + } + + #[test] + fn invalid_its_message_type() { + let mut message = MessageType::DeployTokenManager.abi_encode(); + message[31] = 3; + + let invalid_payload = SendToHub { + messageType: MessageType::SendToHub.into(), + destination_chain: "remote-chain".into(), + message: message.into(), + } + .abi_encode_params(); + + let result = ItsHubMessage::abi_decode(&invalid_payload); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().current_context().to_string(), + Error::InvalidMessageType.to_string() + ); + } + + #[test] + fn invalid_destination_chain() { + let message = DeployTokenManager { + messageType: MessageType::DeployTokenManager.into(), + tokenId: FixedBytes::<32>::new([0u8; 32]), + tokenManagerType: TokenManagerType::NativeInterchainToken.into(), + params: vec![].into(), + }; + + let payload = SendToHub { + messageType: MessageType::SendToHub.into(), + destination_chain: "".into(), + message: message.abi_encode_params().into(), + } + .abi_encode_params(); + + let result = ItsHubMessage::abi_decode(&payload); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().current_context().to_string(), + Error::InvalidChainName.to_string() + ); + } + + #[test] + fn invalid_token_manager_type() { + let message = DeployTokenManager { + messageType: MessageType::DeployTokenManager.into(), + tokenId: FixedBytes::<32>::new([0u8; 32]), + tokenManagerType: U256::from(TokenManagerType::Gateway as u8 + 1), + params: vec![].into(), + }; + + let payload = SendToHub { + messageType: MessageType::SendToHub.into(), + destination_chain: "chain".into(), + message: message.abi_encode_params().into(), + } + .abi_encode_params(); + + let result = ItsHubMessage::abi_decode(&payload); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().current_context().to_string(), + Error::InvalidTokenManagerType.to_string() + ); + } + + #[test] + fn encode_decode_large_data() { + let large_data = vec![0u8; 1024 * 1024]; // 1MB of data + let original = ItsHubMessage::SendToHub { + destination_chain: ChainName::from_str("large-data-chain").unwrap(), + message: ItsMessage::InterchainTransfer { + token_id: [0u8; 32].into(), + source_address: HexBinary::from_hex("1234").unwrap(), + destination_address: HexBinary::from_hex("5678").unwrap(), + amount: Uint256::from(1u128), + data: HexBinary::from(large_data), + }, + }; + + let encoded = original.clone().abi_encode(); + let decoded = ItsHubMessage::abi_decode(&encoded).unwrap(); + assert_eq!(original, decoded); + } + + #[test] + fn encode_decode_unicode_strings() { + let original = ItsHubMessage::SendToHub { + destination_chain: ChainName::from_str("unicode-chain-🌍").unwrap(), + message: ItsMessage::DeployInterchainToken { + token_id: [0u8; 32].into(), + name: "Unicode Token 🪙".into(), + symbol: "UNI🔣".into(), + decimals: 18, + minter: HexBinary::from_hex("abcd").unwrap(), + }, + }; + + let encoded = original.clone().abi_encode(); + let decoded = ItsHubMessage::abi_decode(&encoded).unwrap(); + assert_eq!(original, decoded); + } +} diff --git a/interchain-token-service/src/error.rs b/interchain-token-service/src/error.rs new file mode 100644 index 000000000..5ae15cd1c --- /dev/null +++ b/interchain-token-service/src/error.rs @@ -0,0 +1,14 @@ +use axelar_wasm_std_derive::IntoContractError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq, IntoContractError)] +pub enum Error { + #[error("failed to decode ITS message")] + InvalidMessage, + #[error("invalid message type")] + InvalidMessageType, + #[error("invalid chain name")] + InvalidChainName, + #[error("invalid token manager type")] + InvalidTokenManagerType, +} diff --git a/interchain-token-service/src/lib.rs b/interchain-token-service/src/lib.rs new file mode 100644 index 000000000..d4f5ac941 --- /dev/null +++ b/interchain-token-service/src/lib.rs @@ -0,0 +1,5 @@ +mod primitives; + +pub mod error; +pub use primitives::*; +pub mod abi; diff --git a/interchain-token-service/src/primitives.rs b/interchain-token-service/src/primitives.rs new file mode 100644 index 000000000..4970d294e --- /dev/null +++ b/interchain-token-service/src/primitives.rs @@ -0,0 +1,89 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{HexBinary, Uint256}; +use router_api::ChainName; +use strum::FromRepr; + +#[cw_serde] +#[derive(Eq)] +pub struct TokenId( + #[serde(with = "axelar_wasm_std::hex")] + #[schemars(with = "String")] + [u8; 32], +); + +#[cw_serde] +#[derive(Eq, Copy, FromRepr)] +#[repr(u8)] +pub enum TokenManagerType { + NativeInterchainToken, + MintBurnFrom, + LockUnlock, + LockUnlockFee, + MintBurn, + Gateway, +} + +/// ITS message type that can be sent between ITS contracts for transfers/token deployments +/// `ItsMessage` that are routed via the ITS hub get wrapped inside `ItsHubMessage` +#[cw_serde] +#[derive(Eq)] +pub enum ItsMessage { + InterchainTransfer { + token_id: TokenId, + source_address: HexBinary, + destination_address: HexBinary, + amount: Uint256, + data: HexBinary, + }, + DeployInterchainToken { + token_id: TokenId, + name: String, + symbol: String, + decimals: u8, + minter: HexBinary, + }, + DeployTokenManager { + token_id: TokenId, + token_manager_type: TokenManagerType, + params: HexBinary, + }, +} + +/// ITS message type that can be sent between ITS edge contracts and the ITS Hub +#[cw_serde] +#[derive(Eq)] +pub enum ItsHubMessage { + /// ITS edge source contract -> ITS Hub + SendToHub { + /// True destination chain of the ITS message + destination_chain: ChainName, + message: ItsMessage, + }, + /// ITS Hub -> ITS edge destination contract + ReceiveFromHub { + /// True source chain of the ITS message + source_chain: ChainName, + message: ItsMessage, + }, +} + +impl TokenId { + #[inline(always)] + pub fn new(id: [u8; 32]) -> Self { + id.into() + } +} + +impl From<[u8; 32]> for TokenId { + #[inline(always)] + fn from(id: [u8; 32]) -> Self { + Self(id) + } +} + +impl From for [u8; 32] { + #[inline(always)] + fn from(id: TokenId) -> Self { + id.0 + } +} diff --git a/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden b/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden new file mode 100644 index 000000000..87ccfbfd9 --- /dev/null +++ b/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden @@ -0,0 +1,8 @@ +[ + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000a5465737420546f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003545354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012756e69636f64652d636861696e2df09f8c8d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000012556e69636f646520546f6b656e20f09faa9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e49f09f94a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000a5465737420546f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003545354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012756e69636f64652d636861696e2df09f8c8d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000012556e69636f646520546f6b656e20f09faa9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e49f09f94a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000" +] \ No newline at end of file diff --git a/interchain-token-service/src/testdata/deploy_token_manager_encode_decode.golden b/interchain-token-service/src/testdata/deploy_token_manager_encode_decode.golden new file mode 100644 index 000000000..9bd957c4a --- /dev/null +++ b/interchain-token-service/src/testdata/deploy_token_manager_encode_decode.golden @@ -0,0 +1,6 @@ +[ + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000201010101010101010101010101010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000201010101010101010101010101010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000" +] \ No newline at end of file diff --git a/interchain-token-service/src/testdata/interchain_transfer_encode_decode.golden b/interchain-token-service/src/testdata/interchain_transfer_encode_decode.golden new file mode 100644 index 000000000..eb9766e8a --- /dev/null +++ b/interchain-token-service/src/testdata/interchain_transfer_encode_decode.golden @@ -0,0 +1,6 @@ +[ + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000144f4495243837681061c4743b74b3eedf548d56a500000000000000000000000000000000000000000000000000000000000000000000000000000000000000144f4495243837681061c4743b74b3eedf548d56a50000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000144f4495243837681061c4743b74b3eedf548d56a500000000000000000000000000000000000000000000000000000000000000000000000000000000000000144f4495243837681061c4743b74b3eedf548d56a50000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000" +] \ No newline at end of file diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index 0df4ed24a..61147911e 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -45,7 +45,7 @@ schemars = "0.8.10" serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" sha3 = { workspace = true } -strum = { version = "0.25", default-features = false, features = ["derive"] } +strum = { workspace = true } thiserror = { workspace = true } valuable = { version = "0.1.0", features = ["derive"] } From 5def6f390a4409736e5b6730ec1793228c801cf9 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Mon, 29 Jul 2024 11:05:14 -0400 Subject: [PATCH 108/168] fix(ampd): copy ITS folder to docker image for ampd build (#546) --- ampd/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/ampd/Dockerfile b/ampd/Dockerfile index dfada706b..2adea51e4 100644 --- a/ampd/Dockerfile +++ b/ampd/Dockerfile @@ -7,6 +7,7 @@ COPY ./Cargo.lock ./Cargo.lock COPY ./ampd/Cargo.toml ./ampd/Cargo.toml COPY ./packages ./packages COPY ./contracts ./contracts +COPY ./interchain-token-service ./interchain-token-service COPY ./integration-tests ./integration-tests COPY ./.cargo ./.cargo From aba343356c6d8fffd8279da0fa2d766221013f8d Mon Sep 17 00:00:00 2001 From: Talal Ashraf Date: Mon, 29 Jul 2024 14:50:27 -0400 Subject: [PATCH 109/168] ci: update description for contract build action to include tags (#547) --- .github/workflows/build-contracts-and-push-to-r2.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-contracts-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml index 51d87aa49..4ae1f3983 100644 --- a/.github/workflows/build-contracts-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -9,7 +9,7 @@ on: workflow_dispatch: inputs: branch: - description: Github branch to checkout for compilation + description: Github branch or tag to checkout for compilation required: true default: main type: string @@ -40,16 +40,16 @@ jobs: run: | tag="${{ steps.get-tag.outputs.tag }}" is_release="false" - + if [[ $tag =~ ^([a-zA-Z-]+)-v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then is_release="true" crate_name="${BASH_REMATCH[1]}" crate_version="${BASH_REMATCH[2]}" - + echo "Is release: $is_release" echo "Crate Name: $crate_name" echo "Crate Version: $crate_version" - + echo "is-release=$is_release" >> $GITHUB_OUTPUT echo "crate-name=$crate_name" >> $GITHUB_OUTPUT echo "crate-version=$crate_version" >> $GITHUB_OUTPUT From 3a64ad6a3a2d67c368775d70a70dc83722756b99 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Mon, 29 Jul 2024 15:51:43 -0400 Subject: [PATCH 110/168] feat(minor-voting-verifier): validate source address (#545) --- Cargo.lock | 3 + contracts/voting-verifier/Cargo.toml | 1 + contracts/voting-verifier/src/client.rs | 1 + contracts/voting-verifier/src/contract.rs | 85 ++++++++++++++++--- .../voting-verifier/src/contract/execute.rs | 69 +++++++++------ .../src/contract/migrations/v0_5_0.rs | 2 + contracts/voting-verifier/src/error.rs | 3 + contracts/voting-verifier/src/events.rs | 5 ++ contracts/voting-verifier/src/msg.rs | 2 + contracts/voting-verifier/src/state.rs | 2 + .../src/voting_verifier_contract.rs | 1 + .../tests/chain_freeze_unfreeze.rs | 2 +- integration-tests/tests/message_routing.rs | 2 +- packages/axelar-wasm-std/Cargo.toml | 1 + .../axelar-wasm-std/src/address_format.rs | 23 +++++ packages/axelar-wasm-std/src/lib.rs | 1 + 16 files changed, 166 insertions(+), 37 deletions(-) create mode 100644 packages/axelar-wasm-std/src/address_format.rs diff --git a/Cargo.lock b/Cargo.lock index 5c4bfe81e..75e735cdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,6 +137,7 @@ dependencies = [ "cfg-if", "const-hex", "derive_more", + "getrandom", "hex-literal", "itoa", "k256", @@ -793,6 +794,7 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" name = "axelar-wasm-std" version = "0.1.0" dependencies = [ + "alloy-primitives", "bs58 0.5.1", "cosmwasm-schema", "cosmwasm-std", @@ -8852,6 +8854,7 @@ checksum = "2e4fe92cfc1bad19c19925d5eee4b30584dbbdee4ff10183b261acccbef74e2d" name = "voting-verifier" version = "0.5.0" dependencies = [ + "alloy-primitives", "axelar-wasm-std", "axelar-wasm-std-derive", "client", diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index d4f031a56..db7e0948b 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -52,6 +52,7 @@ service-registry = { workspace = true, features = ["library"] } thiserror = { workspace = true } [dev-dependencies] +alloy-primitives = { version = "0.7.7", features = ["getrandom"] } cw-multi-test = "0.15.1" integration-tests = { workspace = true } multisig = { workspace = true, features = ["test", "library"] } diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index a98d4de21..f0c107a01 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -222,6 +222,7 @@ mod test { source_chain: "source-chain".parse().unwrap(), rewards_address: "rewards".try_into().unwrap(), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, + address_format: axelar_wasm_std::address_format::AddressFormat::Eip55, }; instantiate(deps, env, info.clone(), msg.clone()).unwrap(); diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index bfe20eb50..7ae5b495c 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::{permission_control, FnExt}; +use axelar_wasm_std::permission_control; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -39,6 +39,7 @@ pub fn instantiate( source_chain: msg.source_chain, rewards_contract: deps.api.addr_validate(&msg.rewards_address)?, msg_id_format: msg.msg_id_format, + address_format: msg.address_format, }; CONFIG.save(deps.storage, &config)?; @@ -54,18 +55,25 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg.ensure_permissions(deps.storage, &info.sender)? { - ExecuteMsg::VerifyMessages(messages) => execute::verify_messages(deps, env, messages), - ExecuteMsg::Vote { poll_id, votes } => execute::vote(deps, env, info, poll_id, votes), - ExecuteMsg::EndPoll { poll_id } => execute::end_poll(deps, env, poll_id), + ExecuteMsg::VerifyMessages(messages) => Ok(execute::verify_messages(deps, env, messages)?), + ExecuteMsg::Vote { poll_id, votes } => Ok(execute::vote(deps, env, info, poll_id, votes)?), + ExecuteMsg::EndPoll { poll_id } => Ok(execute::end_poll(deps, env, poll_id)?), ExecuteMsg::VerifyVerifierSet { message_id, new_verifier_set, - } => execute::verify_verifier_set(deps, env, &message_id, new_verifier_set), + } => Ok(execute::verify_verifier_set( + deps, + env, + &message_id, + new_verifier_set, + )?), ExecuteMsg::UpdateVotingThreshold { new_voting_threshold, - } => execute::update_voting_threshold(deps, new_voting_threshold), - }? - .then(Ok) + } => Ok(execute::update_voting_threshold( + deps, + new_voting_threshold, + )?), + } } #[cfg_attr(not(feature = "library"), entry_point)] @@ -98,12 +106,15 @@ pub fn migrate( #[cfg(test)] mod test { + use axelar_wasm_std::address_format::AddressFormat; use axelar_wasm_std::msg_id::{ Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat, }; use axelar_wasm_std::voting::Vote; - use axelar_wasm_std::{nonempty, MajorityThreshold, Threshold, VerificationStatus}; + use axelar_wasm_std::{ + err_contains, nonempty, MajorityThreshold, Threshold, VerificationStatus, + }; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; @@ -179,6 +190,7 @@ mod test { source_chain: source_chain(), rewards_address: REWARDS_ADDRESS.parse().unwrap(), msg_id_format: msg_id_format.clone(), + address_format: AddressFormat::Eip55, }, ) .unwrap(); @@ -237,7 +249,10 @@ mod test { .map(|i| Message { cc_id: CrossChainId::new(source_chain(), message_id("id", i, msg_id_format)) .unwrap(), - source_address: format!("source-address{i}").parse().unwrap(), + source_address: alloy_primitives::Address::random() + .to_string() + .try_into() + .unwrap(), destination_chain: format!("destination-chain{i}").parse().unwrap(), destination_address: format!("destination-address{i}").parse().unwrap(), payload_hash: [0; 32], @@ -269,7 +284,10 @@ mod test { Message { cc_id: CrossChainId::new(source_chain(), message_id("id", 1, &msg_id_format)) .unwrap(), - source_address: "source-address1".parse().unwrap(), + source_address: alloy_primitives::Address::random() + .to_string() + .parse() + .unwrap(), destination_chain: "destination-chain1".parse().unwrap(), destination_address: "destination-address1".parse().unwrap(), payload_hash: [0; 32], @@ -1350,4 +1368,49 @@ mod test { } }); } + + #[test] + fn should_fail_if_messages_have_invalid_source_address() { + let msg_id_format = MessageIdFormat::HexTxHashAndEventIndex; + let verifiers = verifiers(2); + let mut deps = setup(verifiers.clone(), &msg_id_format); + + let eip55_address = alloy_primitives::Address::random().to_string(); + + let cases = vec![ + eip55_address.to_lowercase(), + eip55_address.to_uppercase(), + // mix + eip55_address + .chars() + .enumerate() + .map(|(i, c)| { + if i % 2 == 0 { + c.to_uppercase().next().unwrap() + } else { + c.to_lowercase().next().unwrap() + } + }) + .collect::(), + ]; + + for case in cases { + let mut messages = messages(1, &MessageIdFormat::HexTxHashAndEventIndex); + messages[0].source_address = case.parse().unwrap(); + let msg = ExecuteMsg::VerifyMessages(messages); + let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg); + assert!(res.is_err_and(|err| err_contains!( + err.report, + ContractError, + ContractError::InvalidSourceAddress { .. } + ))); + } + + // should not fail if address is valid + let mut messages = messages(1, &MessageIdFormat::HexTxHashAndEventIndex); + messages[0].source_address = eip55_address.parse().unwrap(); + let msg = ExecuteMsg::VerifyMessages(messages); + let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg); + assert!(res.is_ok()); + } } diff --git a/contracts/voting-verifier/src/contract/execute.rs b/contracts/voting-verifier/src/contract/execute.rs index e2e2155bf..00dafdbbc 100644 --- a/contracts/voting-verifier/src/contract/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -1,11 +1,14 @@ use std::collections::HashMap; +use axelar_wasm_std::address_format::{validate_address, AddressFormat}; +use axelar_wasm_std::utils::TryMapExt; use axelar_wasm_std::voting::{PollId, PollResults, Vote, WeightedPoll}; use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ to_json_binary, Deps, DepsMut, Env, Event, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, }; +use error_stack::{report, Report, ResultExt}; use itertools::Itertools; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; @@ -81,29 +84,22 @@ pub fn verify_messages( deps: DepsMut, env: Env, messages: Vec, -) -> Result { +) -> Result> { if messages.is_empty() { Err(ContractError::EmptyMessages)?; } - let source_chain = CONFIG.load(deps.storage)?.source_chain; + let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; - if messages - .iter() - .any(|message| message.cc_id.source_chain != source_chain) - { - Err(ContractError::SourceChainMismatch(source_chain.clone()))?; - } - - let config = CONFIG.load(deps.storage)?; - - let messages = messages - .into_iter() - .map(|message| { - message_status(deps.as_ref(), &message, env.block.height) - .map(|status| (status, message)) - }) - .collect::, _>>()?; + let messages = messages.try_map(|message| { + validate_source_chain(message, &config.source_chain) + .and_then(|message| validate_source_address(message, &config.address_format)) + .and_then(|message| { + message_status(deps.as_ref(), &message, env.block.height) + .map(|status| (status, message)) + .map_err(Report::from) + }) + })?; let msgs_to_verify: Vec = messages .into_iter() @@ -121,18 +117,20 @@ pub fn verify_messages( return Ok(Response::new()); } - let snapshot = take_snapshot(deps.as_ref(), &source_chain)?; + let snapshot = take_snapshot(deps.as_ref(), &config.source_chain)?; let participants = snapshot.participants(); let expires_at = calculate_expiration(env.block.height, config.block_expiry.into())?; let id = create_messages_poll(deps.storage, expires_at, snapshot, msgs_to_verify.len())?; for (idx, message) in msgs_to_verify.iter().enumerate() { - poll_messages().save( - deps.storage, - &message.hash(), - &state::PollContent::::new(message.clone(), id, idx), - )?; + poll_messages() + .save( + deps.storage, + &message.hash(), + &state::PollContent::::new(message.clone(), id, idx), + ) + .map_err(ContractError::from)?; } let messages = msgs_to_verify @@ -366,3 +364,26 @@ fn calculate_expiration(block_height: u64, block_expiry: u64) -> Result Result> { + if message.cc_id.source_chain != *source_chain { + Err(report!(ContractError::SourceChainMismatch( + source_chain.clone() + ))) + } else { + Ok(message) + } +} + +fn validate_source_address( + message: Message, + address_format: &AddressFormat, +) -> Result> { + validate_address(&message.source_address, address_format) + .change_context(ContractError::InvalidSourceAddress)?; + + Ok(message) +} diff --git a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs index 0a7a90651..06085bdcc 100644 --- a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs +++ b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs @@ -1,5 +1,6 @@ #![allow(deprecated)] +use axelar_wasm_std::address_format::AddressFormat; use axelar_wasm_std::error::ContractError; use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::{nonempty, permission_control, MajorityThreshold}; @@ -43,6 +44,7 @@ fn migrate_config(storage: &mut dyn Storage, config: Config) -> StdResult<()> { msg_id_format: config.msg_id_format, source_gateway_address: config.source_gateway_address, voting_threshold: config.voting_threshold, + address_format: AddressFormat::Eip55, }; state::CONFIG.save(storage, &config) diff --git a/contracts/voting-verifier/src/error.rs b/contracts/voting-verifier/src/error.rs index 1aec7e088..f9995ca37 100644 --- a/contracts/voting-verifier/src/error.rs +++ b/contracts/voting-verifier/src/error.rs @@ -42,6 +42,9 @@ pub enum ContractError { #[error("poll results have different length")] PollResultsLengthUnequal, + + #[error("invalid source address")] + InvalidSourceAddress, } impl From for StdError { diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index a82fc5a0c..484171597 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -28,6 +28,7 @@ impl From for Vec { source_chain, rewards_contract, msg_id_format, + address_format, } = other; vec![ @@ -50,6 +51,10 @@ impl From for Vec { "msg_id_format", serde_json::to_string(&msg_id_format).expect("failed to serialize msg_id_format"), ), + ( + "address_format", + serde_json::to_string(&address_format).expect("failed to serialize address_format"), + ), ] .into_iter() .map(Attribute::from) diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index f0f75b078..dc6d79455 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::address_format::AddressFormat; use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::voting::{PollId, PollStatus, Vote, WeightedPoll}; use axelar_wasm_std::{nonempty, MajorityThreshold, VerificationStatus}; @@ -30,6 +31,7 @@ pub struct InstantiateMsg { pub rewards_address: nonempty::String, /// Format that incoming messages should use for the id field of CrossChainId pub msg_id_format: MessageIdFormat, + pub address_format: AddressFormat, } #[cw_serde] diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index 1d687d5ee..471dc0ab0 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::address_format::AddressFormat; use axelar_wasm_std::hash::Hash; use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::voting::{PollId, Vote, WeightedPoll}; @@ -21,6 +22,7 @@ pub struct Config { pub source_chain: ChainName, pub rewards_contract: Addr, pub msg_id_format: MessageIdFormat, + pub address_format: AddressFormat, } #[cw_serde] diff --git a/integration-tests/src/voting_verifier_contract.rs b/integration-tests/src/voting_verifier_contract.rs index b3342355d..43d4a2b60 100644 --- a/integration-tests/src/voting_verifier_contract.rs +++ b/integration-tests/src/voting_verifier_contract.rs @@ -51,6 +51,7 @@ impl VotingVerifierContract { .try_into() .unwrap(), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, + address_format: axelar_wasm_std::address_format::AddressFormat::Eip55, }, &[], "voting_verifier", diff --git a/integration-tests/tests/chain_freeze_unfreeze.rs b/integration-tests/tests/chain_freeze_unfreeze.rs index 1886c5f9f..f1f46d0a8 100644 --- a/integration-tests/tests/chain_freeze_unfreeze.rs +++ b/integration-tests/tests/chain_freeze_unfreeze.rs @@ -21,7 +21,7 @@ fn chain_can_be_freezed_unfreezed() { "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3", ) .unwrap(), - source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" + source_address: "0xBf12773B490e1Deb57039061AAcFA2A87DEaC9b9" .to_string() .try_into() .unwrap(), diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index 1c41efbc6..6ed73be9b 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -24,7 +24,7 @@ fn single_message_can_be_verified_and_routed_and_proven_and_rewards_are_distribu "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3", ) .unwrap(), - source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" + source_address: "0xBf12773B490e1Deb57039061AAcFA2A87DEaC9b9" .to_string() .try_into() .unwrap(), diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index 61147911e..0adc3e5e6 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -29,6 +29,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] +alloy-primitives = { workspace = true } bs58 = "0.5.1" cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/packages/axelar-wasm-std/src/address_format.rs b/packages/axelar-wasm-std/src/address_format.rs new file mode 100644 index 000000000..b0de28b68 --- /dev/null +++ b/packages/axelar-wasm-std/src/address_format.rs @@ -0,0 +1,23 @@ +use alloy_primitives::Address; +use cosmwasm_schema::cw_serde; +use error_stack::{Report, ResultExt}; + +#[derive(thiserror::Error)] +#[cw_serde] +pub enum Error { + #[error("invalid address '{0}'")] + InvalidAddress(String), +} + +#[cw_serde] +pub enum AddressFormat { + Eip55, +} + +pub fn validate_address(address: &str, format: &AddressFormat) -> Result<(), Report> { + match format { + AddressFormat::Eip55 => Address::parse_checksummed(address, None) + .change_context(Error::InvalidAddress(address.to_string())) + .map(|_| ()), + } +} diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 5ddcb9a68..3de4988a8 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -3,6 +3,7 @@ pub use crate::snapshot::{Participant, Snapshot}; pub use crate::threshold::{MajorityThreshold, Threshold}; pub use crate::verification::VerificationStatus; +pub mod address_format; pub mod counter; pub mod error; pub mod flagset; From 957099c2c8852a7fd26f367ce89f1ee221cd9575 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Mon, 29 Jul 2024 16:41:45 -0400 Subject: [PATCH 111/168] fix(ci): add extra condition for get-tag step to also check input branch (#549) --- .../workflows/build-contracts-and-push-to-r2.yaml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-contracts-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml index 4ae1f3983..91d155afa 100644 --- a/.github/workflows/build-contracts-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -8,7 +8,7 @@ on: - '*-v[0-9]+.[0-9]+.[0-9]+' workflow_dispatch: inputs: - branch: + ref: description: Github branch or tag to checkout for compilation required: true default: main @@ -31,7 +31,17 @@ jobs: if [[ $GITHUB_REF == refs/tags/* ]]; then echo "tag=${GITHUB_REF#refs/tags/}" echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + input_ref="${{ github.event.inputs.ref }}" + if [[ $input_ref =~ ^([a-zA-Z-]+)-v([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then + echo "tag=$input_ref" + echo "tag=$input_ref" >> $GITHUB_OUTPUT + else + echo "tag=" + echo "tag=" >> $GITHUB_OUTPUT + fi else + echo "tag=" echo "tag=" >> $GITHUB_OUTPUT fi @@ -68,7 +78,7 @@ jobs: elif [ "${{ github.event_name }}" == "push" ]; then echo "ref=main" >> $GITHUB_OUTPUT else - echo "ref=${{ inputs.branch }}" >> $GITHUB_OUTPUT + echo "ref=${{ inputs.ref }}" >> $GITHUB_OUTPUT fi From cb73476fdd6264a88101ece66da70de1e1ba8ae9 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Mon, 29 Jul 2024 18:09:32 -0400 Subject: [PATCH 112/168] fix(minor-gateway): do not override outgoing messages (#550) --- Cargo.lock | 1 + contracts/gateway/Cargo.toml | 1 + contracts/gateway/src/contract.rs | 2 ++ contracts/gateway/src/contract/execute.rs | 15 +++++++-- contracts/gateway/tests/contract.rs | 40 ++++++++++++++++++++++- 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75e735cdd..a1b0024e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3120,6 +3120,7 @@ dependencies = [ "error-stack", "gateway-api", "itertools 0.11.0", + "rand", "report", "router-api", "serde", diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index f822930ac..d9cfd8830 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -54,6 +54,7 @@ voting-verifier = { workspace = true, features = ["library"] } [dev-dependencies] cw-multi-test = "0.15.1" +rand = "0.8.5" [lints] workspace = true diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index e40799767..9fea40be5 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -74,6 +74,8 @@ pub enum Error { MessageStatus, #[error("message with ID {0} not found")] MessageNotFound(CrossChainId), + #[error("message with id {0} mismatches with the stored one")] + MessageMismatch(CrossChainId), } mod internal { diff --git a/contracts/gateway/src/contract/execute.rs b/contracts/gateway/src/contract/execute.rs index d50b8aa40..a355a7f2a 100644 --- a/contracts/gateway/src/contract/execute.rs +++ b/contracts/gateway/src/contract/execute.rs @@ -1,6 +1,6 @@ use axelar_wasm_std::{FnExt, VerificationStatus}; use cosmwasm_std::{Event, Response, Storage, WasmMsg}; -use error_stack::{Result, ResultExt}; +use error_stack::{report, Result, ResultExt}; use itertools::Itertools; use router_api::client::Router; use router_api::Message; @@ -38,8 +38,17 @@ pub(crate) fn route_outgoing_messages( for msg in msgs.iter() { state::OUTGOING_MESSAGES - .save(store, &msg.cc_id, msg) - .change_context(Error::InvalidStoreAccess)?; + .may_load(store, &msg.cc_id) + .change_context(Error::InvalidStoreAccess) + .and_then(|stored_msg| match stored_msg { + Some(stored_msg) if msg.hash() != stored_msg.hash() => { + Err(report!(Error::MessageMismatch(msg.cc_id.clone()))) + } + Some(_) => Ok(()), // message already exists + None => state::OUTGOING_MESSAGES + .save(store, &msg.cc_id, msg) + .change_context(Error::InvalidStoreAccess), + })?; } Ok(Response::new().add_events( diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index ef8541942..10c3ab27c 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -4,7 +4,7 @@ use std::fs::File; use std::iter; use axelar_wasm_std::error::ContractError; -use axelar_wasm_std::VerificationStatus; +use axelar_wasm_std::{err_contains, VerificationStatus}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier}; #[cfg(not(feature = "generate_golden_files"))] use cosmwasm_std::Response; @@ -15,6 +15,7 @@ use gateway::contract::*; use gateway::msg::InstantiateMsg; use gateway_api::msg::{ExecuteMsg, QueryMsg}; use itertools::Itertools; +use rand::{thread_rng, Rng}; use router_api::{CrossChainId, Message}; use serde::Serialize; use voting_verifier::msg::MessageStatus; @@ -280,6 +281,43 @@ fn route_duplicate_ids_should_fail() { } } +#[test] +fn reject_reroute_outgoing_message_with_different_contents() { + let mut msgs = generate_msgs(VerificationStatus::SucceededOnSourceChain, 10); + + let mut deps = mock_dependencies(); + + let router = "router"; + instantiate_contract(deps.as_mut(), "verifier", router); + + let response = execute( + deps.as_mut(), + mock_env(), + mock_info(router, &[]), + ExecuteMsg::RouteMessages(msgs.clone()), + ); + assert!(response.is_ok()); + + // re-route with different payload + msgs.iter_mut().for_each(|msg| { + let mut rng = thread_rng(); + msg.payload_hash.iter_mut().for_each(|byte| { + *byte = rng.gen(); + }); + }); + let response = execute( + deps.as_mut(), + mock_env(), + mock_info(router, &[]), + ExecuteMsg::RouteMessages(msgs.clone()), + ); + assert!(response.is_err_and(|err| err_contains!( + err.report, + Error, + Error::MessageMismatch { .. } + ))); +} + fn test_cases_for_correct_verifier() -> ( Vec>, impl Fn(voting_verifier::msg::QueryMsg) -> Result, ContractError> + Clone, From 52e3c52307d31333770486ae86c786fd34cfb042 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Tue, 30 Jul 2024 12:03:01 -0400 Subject: [PATCH 113/168] fix(multisig-prover): better error message on chain name mismatch (#544) --- contracts/multisig-prover/src/contract/execute.rs | 13 ++++++++----- contracts/multisig-prover/src/error.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index 40452f796..3181bbb4a 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -94,14 +94,17 @@ fn messages( "violated invariant: returned gateway messages count mismatch" ); - if messages + if let Some(wrong_destination) = messages .iter() - .any(|msg| msg.destination_chain != chain_name) + .find(|msg| msg.destination_chain != chain_name) { - panic!("violated invariant: messages from different chain found"); + Err(ContractError::InvalidDestinationChain { + expected: chain_name, + actual: wrong_destination.destination_chain.clone(), + }) + } else { + Ok(messages) } - - Ok(messages) } fn make_verifier_set( diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index 0e7c90113..f5eb9382e 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -1,6 +1,7 @@ use axelar_wasm_std::nonempty; use axelar_wasm_std_derive::IntoContractError; use cosmwasm_std::StdError; +use router_api::ChainName; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] @@ -18,6 +19,7 @@ pub enum ContractError { InvalidSignature { reason: String }, #[error("chain name is invalid")] + #[deprecated(since = "0.6.0")] InvalidChainName, #[error("invalid participants: {reason}")] @@ -61,4 +63,10 @@ pub enum ContractError { #[error("not enough verifiers")] NotEnoughVerifiers, + + #[error("invalid destination chain '{actual}', expected '{expected}'")] + InvalidDestinationChain { + actual: ChainName, + expected: ChainName, + }, } From d6a727dc3463a51c6d38bfb2c5efe5ab56adf15c Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Tue, 30 Jul 2024 12:31:04 -0400 Subject: [PATCH 114/168] fix(minor-voting-verifier): length prefix verifier set when hashing (#551) --- Cargo.lock | 2 ++ Cargo.toml | 1 + contracts/multisig/Cargo.toml | 2 ++ .../verifier_set_hash_unchanged.golden | 1 + .../testdata/verifier_set_id_unchanged.golden | 1 + contracts/multisig/src/verifier_set.rs | 27 +++++++++++++++++++ interchain-token-service/Cargo.toml | 2 +- 7 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 contracts/multisig/src/testdata/verifier_set_hash_unchanged.golden create mode 100644 contracts/multisig/src/testdata/verifier_set_id_unchanged.golden diff --git a/Cargo.lock b/Cargo.lock index a1b0024e0..c7abf14c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4835,6 +4835,8 @@ dependencies = [ "enum-display-derive", "error-stack", "getrandom", + "goldie", + "hex", "itertools 0.11.0", "k256", "msgs-derive", diff --git a/Cargo.toml b/Cargo.toml index a0d1e13b2..a10fdf763 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ alloy-primitives = { version = "0.7.6", default-features = false, features = ["s alloy-sol-types = { version = "0.7.6", default-features = false, features = ["std"] } strum = { version = "0.25", default-features = false, features = ["derive"] } interchain-token-service = { version = "^0.1.0", path = "interchain-token-service" } +goldie = { version = "0.5" } [workspace.lints.clippy] arithmetic_side_effects = "deny" diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index d25b44bf8..535a1de6a 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -67,6 +67,8 @@ thiserror = { workspace = true } [dev-dependencies] curve25519-dalek = "4.1.1" cw-multi-test = "0.15.1" +goldie = { workspace = true } +hex = "0.4" [lints] workspace = true diff --git a/contracts/multisig/src/testdata/verifier_set_hash_unchanged.golden b/contracts/multisig/src/testdata/verifier_set_hash_unchanged.golden new file mode 100644 index 000000000..4c871bd0e --- /dev/null +++ b/contracts/multisig/src/testdata/verifier_set_hash_unchanged.golden @@ -0,0 +1 @@ +"1dbf312c423dd70771c471c71d18e3d756aaab6d5b313b41289e002017610e84" \ No newline at end of file diff --git a/contracts/multisig/src/testdata/verifier_set_id_unchanged.golden b/contracts/multisig/src/testdata/verifier_set_id_unchanged.golden new file mode 100644 index 000000000..4c871bd0e --- /dev/null +++ b/contracts/multisig/src/testdata/verifier_set_id_unchanged.golden @@ -0,0 +1 @@ +"1dbf312c423dd70771c471c71d18e3d756aaab6d5b313b41289e002017610e84" \ No newline at end of file diff --git a/contracts/multisig/src/verifier_set.rs b/contracts/multisig/src/verifier_set.rs index 637859165..1e3881ef6 100644 --- a/contracts/multisig/src/verifier_set.rs +++ b/contracts/multisig/src/verifier_set.rs @@ -49,6 +49,9 @@ impl VerifierSet { pub fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); + // Length prefix the bytes to be hashed to prevent hash collisions + hasher.update(self.signers.len().to_be_bytes()); + self.signers.values().for_each(|signer| { hasher.update(signer.address.as_bytes()); hasher.update(signer.pub_key.as_ref()); @@ -76,3 +79,27 @@ impl VerifierSet { self.signers.contains_key(signer.as_str()) } } + +#[cfg(test)] +mod tests { + use crate::key::KeyType; + use crate::test::common::{build_verifier_set, ecdsa_test_data}; + + // If this test fails, it means the verifier set hash has changed and therefore a migration is needed. + #[test] + fn verifier_set_hash_unchanged() { + let signers = ecdsa_test_data::signers(); + let verifier_set = build_verifier_set(KeyType::Ecdsa, &signers); + + goldie::assert_json!(hex::encode(verifier_set.hash())); + } + + // If this test fails, it means the verifier set hash has changed and therefore a migration is needed. + #[test] + fn verifier_set_id_unchanged() { + let signers = ecdsa_test_data::signers(); + let verifier_set = build_verifier_set(KeyType::Ecdsa, &signers); + + goldie::assert_json!(verifier_set.id()); + } +} diff --git a/interchain-token-service/Cargo.toml b/interchain-token-service/Cargo.toml index 6a91f4d51..ccfb56069 100644 --- a/interchain-token-service/Cargo.toml +++ b/interchain-token-service/Cargo.toml @@ -21,7 +21,7 @@ strum = { workspace = true } thiserror = { workspace = true } [dev-dependencies] -goldie = { version = "0.5" } +goldie = { workspace = true } [lints] workspace = true From d21ad0ff20b80652507983b78330cb2f194ff8cd Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Tue, 30 Jul 2024 16:04:24 -0400 Subject: [PATCH 115/168] feat(multisig): add chain name to signing_completed event (#548) --- contracts/multisig/src/contract/execute.rs | 3 ++- contracts/multisig/src/events.rs | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index 00c0c302f..9993622e7 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -250,7 +250,7 @@ fn signing_response( let rewards_msg = WasmMsg::Execute { contract_addr: rewards_contract, msg: to_json_binary(&rewards::msg::ExecuteMsg::RecordParticipation { - chain_name: session.chain_name, + chain_name: session.chain_name.clone(), event_id: session .id .to_string() @@ -278,6 +278,7 @@ fn signing_response( Event::SigningCompleted { session_id: session.id, completed_at, + chain_name: session.chain_name, } .into(), ) diff --git a/contracts/multisig/src/events.rs b/contracts/multisig/src/events.rs index ed8e7cca0..916735d4e 100644 --- a/contracts/multisig/src/events.rs +++ b/contracts/multisig/src/events.rs @@ -27,6 +27,7 @@ pub enum Event { SigningCompleted { session_id: Uint64, completed_at: u64, + chain_name: ChainName, }, PublicKeyRegistered { verifier: Addr, @@ -76,9 +77,11 @@ impl From for cosmwasm_std::Event { Event::SigningCompleted { session_id, completed_at, + chain_name, } => cosmwasm_std::Event::new("signing_completed") .add_attribute("session_id", session_id) - .add_attribute("completed_at", completed_at.to_string()), + .add_attribute("completed_at", completed_at.to_string()) + .add_attribute("chain", chain_name), Event::PublicKeyRegistered { verifier, public_key, From 5230961b54002a60dfa99fddabe841bdaea2d553 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:54:04 -0400 Subject: [PATCH 116/168] feat(minor-multisig)!: migrate verifier set hashes in multisig (#552) --- .../src/contract/migrations/v0_4_1.rs | 99 ++++++++++++++++++- 1 file changed, 94 insertions(+), 5 deletions(-) diff --git a/contracts/multisig/src/contract/migrations/v0_4_1.rs b/contracts/multisig/src/contract/migrations/v0_4_1.rs index 087697151..24570ab1e 100644 --- a/contracts/multisig/src/contract/migrations/v0_4_1.rs +++ b/contracts/multisig/src/contract/migrations/v0_4_1.rs @@ -3,14 +3,15 @@ use axelar_wasm_std::killswitch::State; use axelar_wasm_std::{killswitch, nonempty, permission_control}; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, StdError, Storage}; +use cosmwasm_std::{Addr, Order, StdError, Storage}; use cw2::VersionError; use cw_storage_plus::Item; use itertools::Itertools; use router_api::ChainName; use crate::contract::CONTRACT_NAME; -use crate::state::AUTHORIZED_CALLERS; +use crate::signing::SigningSession; +use crate::state::{AUTHORIZED_CALLERS, SIGNING_SESSIONS, VERIFIER_SETS}; const BASE_VERSION: &str = "0.4.1"; @@ -38,6 +39,8 @@ pub fn migrate( permission_control::set_admin(storage, &admin)?; migrate_config(storage, config)?; migrate_authorized_callers(storage, authorized_callers)?; + migrate_signing_sessions(storage)?; + migrate_verifier_set_ids(storage)?; Ok(()) } @@ -55,6 +58,36 @@ fn migrate_authorized_callers( Ok(()) } +pub fn migrate_signing_sessions(storage: &mut dyn Storage) -> Result<(), Error> { + let all: Vec<_> = SIGNING_SESSIONS + .range(storage, None, None, Order::Ascending) + .collect::, _>>()?; + + for (session_id, session) in all { + let verifier_set = VERIFIER_SETS.load(storage, &session.verifier_set_id)?; + let new_session = SigningSession { + verifier_set_id: verifier_set.id(), + ..session + }; + SIGNING_SESSIONS.save(storage, session_id, &new_session)?; + } + + Ok(()) +} + +pub fn migrate_verifier_set_ids(storage: &mut dyn Storage) -> Result<(), Error> { + let all: Vec<_> = VERIFIER_SETS + .range(storage, None, None, Order::Ascending) + .collect::, _>>()?; + + for v in all { + VERIFIER_SETS.remove(storage, &v.0); + VERIFIER_SETS.save(storage, &v.1.id(), &v.1)?; + } + + Ok(()) +} + fn ensure_expiry_height_is_not_zero(storage: &mut dyn Storage) -> Result { CONFIG.update(storage, |mut config| { if config.block_expiry == 0 { @@ -94,11 +127,13 @@ mod tests { use cosmwasm_std::{Addr, DepsMut, Env, HexBinary, MessageInfo, Response, Uint64}; use router_api::ChainName; - use crate::contract::migrations::v0_4_1; - use crate::contract::migrations::v0_4_1::BASE_VERSION; + use crate::contract::migrations::v0_4_1::{self, BASE_VERSION}; use crate::contract::{execute, query, CONTRACT_NAME}; use crate::msg::ExecuteMsg::{DisableSigning, SubmitSignature}; - use crate::state::SIGNING_SESSION_COUNTER; + use crate::signing::SigningSession; + use crate::state::{SIGNING_SESSIONS, SIGNING_SESSION_COUNTER, VERIFIER_SETS}; + use crate::test::common::build_verifier_set; + use crate::test::common::ecdsa_test_data::signers; use crate::ContractError; #[test] @@ -247,6 +282,60 @@ mod tests { assert!(query::caller_authorized(deps.as_ref(), prover, chain_name).unwrap()); } + #[test] + fn should_be_able_to_migrate_verifier_set_ids() { + let mut deps = mock_dependencies(); + + instantiate( + deps.as_mut(), + mock_env(), + mock_info("admin", &[]), + InstantiateMsg { + governance_address: "governance".to_string(), + rewards_address: "rewards".to_string(), + block_expiry: 100, + }, + ) + .unwrap(); + let signers = signers(); + let verifier_set = build_verifier_set(crate::key::KeyType::Ecdsa, &signers); + VERIFIER_SETS + .save(&mut deps.storage, "foobar", &verifier_set) + .unwrap(); + let signing_session = SigningSession { + id: Uint64::one(), + verifier_set_id: "foobar".to_string(), + chain_name: "ethereum".parse().unwrap(), + msg: HexBinary::from([2; 32]).try_into().unwrap(), + state: crate::types::MultisigState::Pending, + expires_at: 100, + sig_verifier: None, + }; + SIGNING_SESSIONS + .save( + &mut deps.storage, + signing_session.id.u64(), + &signing_session, + ) + .unwrap(); + + v0_4_1::migrate(deps.as_mut().storage, Addr::unchecked("admin"), vec![]).unwrap(); + + let new_verifier_set = VERIFIER_SETS + .load(&deps.storage, &verifier_set.id()) + .unwrap(); + assert_eq!(new_verifier_set, verifier_set); + + let expected_signing_session = SigningSession { + verifier_set_id: verifier_set.id(), + ..signing_session + }; + let new_signing_session = SIGNING_SESSIONS + .load(&deps.storage, expected_signing_session.id.u64()) + .unwrap(); + assert_eq!(new_signing_session, expected_signing_session); + } + #[deprecated(since = "0.4.1", note = "only used to test the migration")] fn instantiate( deps: DepsMut, From 32b6b39c7db859b6ba12751b217b9bace1abbe9b Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Wed, 31 Jul 2024 15:58:37 -0400 Subject: [PATCH 117/168] fix(minor-multisig-prover): generate payload id uniquely (#553) --- Cargo.lock | 1 + contracts/multisig-prover/Cargo.toml | 1 + .../multisig-prover/src/contract/execute.rs | 17 ++++-- contracts/multisig-prover/src/error.rs | 3 + contracts/multisig-prover/src/events.rs | 26 ++++++-- contracts/multisig-prover/src/payload.rs | 60 ++++++++++--------- .../payload_messages_id_unchanged.golden | 1 + .../payload_verifier_set_id_unchanged.golden | 1 + 8 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 contracts/multisig-prover/src/testdata/payload_messages_id_unchanged.golden create mode 100644 contracts/multisig-prover/src/testdata/payload_verifier_set_id_unchanged.golden diff --git a/Cargo.lock b/Cargo.lock index c7abf14c6..fbf3262cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4873,6 +4873,7 @@ dependencies = [ "gateway", "gateway-api", "generic-array", + "goldie", "hex", "itertools 0.11.0", "k256", diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 5d10e1833..6bc166fc4 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -66,6 +66,7 @@ anyhow = "1.0" cw-multi-test = "0.15.1" elliptic-curve = "0.13.5" generic-array = "0.14.7" +goldie = { workspace = true } prost = "0.12.4" [lints] diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index 3181bbb4a..27c29d3f9 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -7,6 +7,7 @@ use cosmwasm_std::{ to_json_binary, wasm_execute, Addr, DepsMut, Env, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, WasmQuery, }; +use error_stack::{report, ResultExt}; use itertools::Itertools; use multisig::msg::Signer; use multisig::verifier_set::VerifierSet; @@ -25,7 +26,6 @@ pub fn construct_proof( message_ids: Vec, ) -> error_stack::Result { let config = CONFIG.load(deps.storage).map_err(ContractError::from)?; - let payload_id = message_ids.as_slice().into(); let messages = messages( deps.querier, @@ -34,18 +34,23 @@ pub fn construct_proof( config.chain_name.clone(), )?; - let payload = match PAYLOAD + let payload = Payload::Messages(messages); + let payload_id = payload.id(); + + match PAYLOAD .may_load(deps.storage, &payload_id) .map_err(ContractError::from)? { - Some(payload) => payload, + Some(stored_payload) => { + if stored_payload != payload { + return Err(report!(ContractError::PayloadMismatch)) + .attach_printable_lazy(|| format!("{:?}", stored_payload)); + } + } None => { - let payload = Payload::Messages(messages); PAYLOAD .save(deps.storage, &payload_id, &payload) .map_err(ContractError::from)?; - - payload } }; diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index f5eb9382e..c11363074 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -69,4 +69,7 @@ pub enum ContractError { actual: ChainName, expected: ChainName, }, + + #[error("payload does not match the stored value")] + PayloadMismatch, } diff --git a/contracts/multisig-prover/src/events.rs b/contracts/multisig-prover/src/events.rs index ec7687536..0992a7637 100644 --- a/contracts/multisig-prover/src/events.rs +++ b/contracts/multisig-prover/src/events.rs @@ -47,22 +47,36 @@ impl From for cosmwasm_std::Event { #[cfg(test)] mod tests { + use router_api::Message; use serde_json::to_string; use super::*; + use crate::payload::Payload; #[test] fn proof_under_construction_is_serializable() { - let msg_ids = vec![ - CrossChainId::new("ethereum", "some_id").unwrap(), - CrossChainId::new("fantom", "some_other_id").unwrap(), - ]; + let payload = Payload::Messages(vec![ + Message { + cc_id: CrossChainId::new("ethereum", "some-id").unwrap(), + source_address: "0x1234".parse().unwrap(), + destination_chain: "avalanche".parse().unwrap(), + destination_address: "0x5678".parse().unwrap(), + payload_hash: [0; 32], + }, + Message { + cc_id: CrossChainId::new("fantom", "some-other-id").unwrap(), + source_address: "0x1234".parse().unwrap(), + destination_chain: "avalanche".parse().unwrap(), + destination_address: "0x5678".parse().unwrap(), + payload_hash: [0; 32], + }, + ]); let event = Event::ProofUnderConstruction { destination_chain: "avalanche".parse().unwrap(), - payload_id: msg_ids.as_slice().into(), + payload_id: payload.id(), multisig_session_id: Uint64::new(2), - msg_ids, + msg_ids: payload.message_ids().unwrap(), }; assert!(to_string(&cosmwasm_std::Event::from(event)).is_ok()); diff --git a/contracts/multisig-prover/src/payload.rs b/contracts/multisig-prover/src/payload.rs index 94521f8e5..b757e4ad4 100644 --- a/contracts/multisig-prover/src/payload.rs +++ b/contracts/multisig-prover/src/payload.rs @@ -5,7 +5,7 @@ use cw_storage_plus::{Key, KeyDeserialize, PrimaryKey}; use error_stack::Result; use multisig::msg::SignerWithSig; use multisig::verifier_set::VerifierSet; -use router_api::{CrossChainId, Message}; +use router_api::{CrossChainId, Message, FIELD_DELIMITER}; use sha3::{Digest, Keccak256}; use crate::encoding::{abi, Encoder}; @@ -19,16 +19,29 @@ pub enum Payload { impl Payload { /// id returns the unique identifier for the payload, which can be either - /// - the hash of comma separated sorted message ids - /// - the hash of the verifier set + /// - Hash of 0 followed by '_' separated message ids + /// - Hash of 1 followed by the verifier set hash pub fn id(&self) -> PayloadId { - match self { + let hash = match self { Payload::Messages(msgs) => { - let message_ids: Vec<_> = msgs.iter().map(|msg| msg.cc_id.clone()).collect(); + let message_ids: Vec = + msgs.iter().map(|msg| msg.cc_id.to_string()).collect(); - message_ids.as_slice().into() + message_ids.join(&FIELD_DELIMITER.to_string()).into() } - Payload::VerifierSet(verifier_set) => verifier_set.hash().as_slice().into(), + Payload::VerifierSet(verifier_set) => verifier_set.hash().to_vec(), + }; + + let mut id = vec![self.variant_to_u8()]; + id.extend(hash); + + Keccak256::digest(id).to_vec().into() + } + + fn variant_to_u8(&self) -> u8 { + match self { + Payload::Messages(_) => 0, + Payload::VerifierSet(_) => 1, } } @@ -73,8 +86,8 @@ impl Payload { #[cw_serde] pub struct PayloadId(HexBinary); -impl From<&[u8]> for PayloadId { - fn from(id: &[u8]) -> Self { +impl From> for PayloadId { + fn from(id: Vec) -> Self { Self(id.into()) } } @@ -98,33 +111,22 @@ impl KeyDeserialize for PayloadId { } } -impl From<&[CrossChainId]> for PayloadId { - fn from(ids: &[CrossChainId]) -> Self { - let mut message_ids = ids.iter().map(|id| id.to_string()).collect::>(); - message_ids.sort(); - - Keccak256::digest(message_ids.join(",")).as_slice().into() - } -} - #[cfg(test)] mod test { - use router_api::CrossChainId; - - use crate::payload::PayloadId; + use crate::payload::Payload; use crate::test::test_data; #[test] - fn test_payload_id() { - let messages = test_data::messages(); - let mut message_ids: Vec = - messages.into_iter().map(|msg| msg.cc_id).collect(); + fn payload_messages_id_unchanged() { + let payload = Payload::Messages(test_data::messages()); - let res: PayloadId = message_ids.as_slice().into(); + goldie::assert_json!(payload.id()); + } - message_ids.reverse(); - let res2: PayloadId = message_ids.as_slice().into(); + #[test] + fn payload_verifier_set_id_unchanged() { + let payload = Payload::VerifierSet(test_data::curr_verifier_set()); - assert_eq!(res, res2); + goldie::assert_json!(payload.id()); } } diff --git a/contracts/multisig-prover/src/testdata/payload_messages_id_unchanged.golden b/contracts/multisig-prover/src/testdata/payload_messages_id_unchanged.golden new file mode 100644 index 000000000..7b45c5ed4 --- /dev/null +++ b/contracts/multisig-prover/src/testdata/payload_messages_id_unchanged.golden @@ -0,0 +1 @@ +"068d17b0fe521c092561cd0fcf63928fc148b6fb9000fa1558030c1e55590a49" \ No newline at end of file diff --git a/contracts/multisig-prover/src/testdata/payload_verifier_set_id_unchanged.golden b/contracts/multisig-prover/src/testdata/payload_verifier_set_id_unchanged.golden new file mode 100644 index 000000000..9fcd783ad --- /dev/null +++ b/contracts/multisig-prover/src/testdata/payload_verifier_set_id_unchanged.golden @@ -0,0 +1 @@ +"76dc1094e9f8dbb6a98c077e3a67c889d49820e98e8560f0a91e3531d41d4168" \ No newline at end of file From 063c85f4beec4370ac43d1c5a1c90418d452c173 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:17:42 -0400 Subject: [PATCH 118/168] feat(minor-multisig-prover)!: better error message for confirm_verifier_set (#556) --- contracts/multisig-prover/src/contract.rs | 13 +++++++++++++ contracts/multisig-prover/src/contract/execute.rs | 4 +++- contracts/multisig-prover/src/error.rs | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 270a2a15d..2f95218e3 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -619,6 +619,19 @@ mod tests { ); } + #[test] + fn confirm_verifier_no_update_in_progress_should_fail() { + let mut deps = setup_test_case(); + + let res = confirm_verifier_set(deps.as_mut(), Addr::unchecked("relayer")); + assert!(res.is_err()); + assert_eq!( + res.unwrap_err().to_string(), + axelar_wasm_std::error::ContractError::from(ContractError::NoVerifierSetToConfirm) + .to_string() + ); + } + #[test] fn test_construct_proof() { let mut deps = setup_test_case(); diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index 27c29d3f9..b29947ab5 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -313,7 +313,9 @@ fn ensure_verifier_set_verification( pub fn confirm_verifier_set(deps: DepsMut, sender: Addr) -> Result { let config = CONFIG.load(deps.storage)?; - let verifier_set = NEXT_VERIFIER_SET.load(deps.storage)?; + let verifier_set = NEXT_VERIFIER_SET + .may_load(deps.storage)? + .ok_or(ContractError::NoVerifierSetToConfirm)?; let sender_role = permission_control::sender_role(deps.storage, &sender)?; if !sender_role.contains(Permission::Governance) { diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index c11363074..6fac47f6b 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -49,6 +49,9 @@ pub enum ContractError { #[error("a verifier set confirmation already in progress")] VerifierSetConfirmationInProgress, + #[error("no verifier set to confirm")] + NoVerifierSetToConfirm, + #[error("no verifier set stored")] NoVerifierSet, From f86528e0f5992602d142cabf485d4cda079ca9f1 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 31 Jul 2024 16:42:51 -0400 Subject: [PATCH 119/168] feat(major): signifier for v1 release (#557) From c03a9b62d7c33e411530896f63c16e77c495234f Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 31 Jul 2024 17:07:54 -0400 Subject: [PATCH 120/168] feat(major): upgrade all packages to v1.0.0 (#558) --- Cargo.lock | 24 +++++++++++----------- Cargo.toml | 24 +++++++++++----------- integration-tests/Cargo.toml | 2 +- packages/axelar-wasm-std-derive/Cargo.toml | 2 +- packages/axelar-wasm-std/Cargo.toml | 2 +- packages/client/Cargo.toml | 2 +- packages/events-derive/Cargo.toml | 2 +- packages/events/Cargo.toml | 2 +- packages/evm-gateway/Cargo.toml | 2 +- packages/gateway-api/Cargo.toml | 2 +- packages/msgs-derive/Cargo.toml | 2 +- packages/report/Cargo.toml | 2 +- packages/router-api/Cargo.toml | 2 +- packages/signature-verifier-api/Cargo.toml | 2 +- 14 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbf3262cd..244df312e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -792,7 +792,7 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axelar-wasm-std" -version = "0.1.0" +version = "1.0.0" dependencies = [ "alloy-primitives", "bs58 0.5.1", @@ -821,7 +821,7 @@ dependencies = [ [[package]] name = "axelar-wasm-std-derive" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "error-stack", @@ -1460,7 +1460,7 @@ checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "client" -version = "0.1.0" +version = "1.0.0" dependencies = [ "cosmwasm-std", "error-stack", @@ -2662,7 +2662,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "events" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "base64 0.21.7", @@ -2675,7 +2675,7 @@ dependencies = [ [[package]] name = "events-derive" -version = "0.1.0" +version = "1.0.0" dependencies = [ "error-stack", "events", @@ -2687,7 +2687,7 @@ dependencies = [ [[package]] name = "evm-gateway" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "cosmwasm-std", @@ -3131,7 +3131,7 @@ dependencies = [ [[package]] name = "gateway-api" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "cosmwasm-schema", @@ -3907,7 +3907,7 @@ dependencies = [ [[package]] name = "integration-tests" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "coordinator", @@ -4734,7 +4734,7 @@ dependencies = [ [[package]] name = "msgs-derive" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "cosmwasm-std", @@ -6334,7 +6334,7 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "report" -version = "0.1.0" +version = "1.0.0" dependencies = [ "error-stack", "eyre", @@ -6523,7 +6523,7 @@ dependencies = [ [[package]] name = "router-api" -version = "0.1.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", @@ -7298,7 +7298,7 @@ dependencies = [ [[package]] name = "signature-verifier-api" -version = "0.1.0" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/Cargo.toml b/Cargo.toml index a10fdf763..e0b093a44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,25 +13,25 @@ cw-storage-plus = { version = "1.2.0", features = ["iterator", "macro"] } cw2 = "1.1.0" ed25519-dalek = { version = "2.1.1", default-features = false } error-stack = { version = "0.4.0", features = ["eyre"] } -events = { version = "^0.1.0", path = "packages/events" } -events-derive = { version = "^0.1.0", path = "packages/events-derive" } -evm-gateway = { version = "^0.1.0", path = "packages/evm-gateway" } -axelar-wasm-std = { version = "^0.1.0", path = "packages/axelar-wasm-std" } -axelar-wasm-std-derive = { version = "^0.1.0", path = "packages/axelar-wasm-std-derive" } -integration-tests = { version = "^0.1.0", path = "integration-tests" } +events = { version = "^1.0.0", path = "packages/events" } +events-derive = { version = "^1.0.0", path = "packages/events-derive" } +evm-gateway = { version = "^1.0.0", path = "packages/evm-gateway" } +axelar-wasm-std = { version = "^1.0.0", path = "packages/axelar-wasm-std" } +axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std-derive" } +integration-tests = { version = "^1.0.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.2.0", path = "contracts/coordinator" } multisig = { version = "^0.4.1", path = "contracts/multisig" } -msgs-derive = { version = "^0.1.0", path = "packages/msgs-derive" } +msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^0.4.1", path = "contracts/service-registry" } gateway = { version = "^0.2.3", path = "contracts/gateway" } -gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } -router-api = { version = "^0.1.0", path = "packages/router-api" } -report = { version = "^0.1.0", path = "packages/report" } -client = { version = "^0.1.0", path = "packages/client" } +gateway-api = { version = "^1.0.0", path = "packages/gateway-api" } +router-api = { version = "^1.0.0", path = "packages/router-api" } +report = { version = "^1.0.0", path = "packages/report" } +client = { version = "^1.0.0", path = "packages/client" } quote = "1.0.36" rewards = { version = "^0.4.0", path = "contracts/rewards" } thiserror = "1.0.61" @@ -40,7 +40,7 @@ serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" schemars = "0.8.10" sha3 = { version = "0.10.8", default-features = false, features = [] } -signature-verifier-api = { version = "^0.1.0", path = "packages/signature-verifier-api" } +signature-verifier-api = { version = "^1.0.0", path = "packages/signature-verifier-api" } syn = "2.0.68" ethers-contract = { version = "2.0.14", default-features = false, features = ["abigen"] } ethers-core = "2.0.14" diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index aa4c018a5..09ca8a18a 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "integration-tests" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Amplifier Integration Tests" diff --git a/packages/axelar-wasm-std-derive/Cargo.toml b/packages/axelar-wasm-std-derive/Cargo.toml index 1639c75e7..6a6acc7b4 100644 --- a/packages/axelar-wasm-std-derive/Cargo.toml +++ b/packages/axelar-wasm-std-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "axelar-wasm-std-derive" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index 0adc3e5e6..2e36aef62 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "axelar-wasm-std" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Axelar cosmwasm standard library crate" diff --git a/packages/client/Cargo.toml b/packages/client/Cargo.toml index 8cd9ca5c1..e00f7f6f3 100644 --- a/packages/client/Cargo.toml +++ b/packages/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "client" -version = "0.1.0" +version = "1.0.0" edition = "2021" rust-version = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/events-derive/Cargo.toml b/packages/events-derive/Cargo.toml index 630f8b3d1..a6e91c5bf 100644 --- a/packages/events-derive/Cargo.toml +++ b/packages/events-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "events-derive" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/events/Cargo.toml b/packages/events/Cargo.toml index 91ca72d8f..5b354577e 100644 --- a/packages/events/Cargo.toml +++ b/packages/events/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "events" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/evm-gateway/Cargo.toml b/packages/evm-gateway/Cargo.toml index 6d3916050..7a1a48721 100644 --- a/packages/evm-gateway/Cargo.toml +++ b/packages/evm-gateway/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "evm-gateway" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/gateway-api/Cargo.toml b/packages/gateway-api/Cargo.toml index ba7fdbec0..874db1ac5 100644 --- a/packages/gateway-api/Cargo.toml +++ b/packages/gateway-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gateway-api" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/msgs-derive/Cargo.toml b/packages/msgs-derive/Cargo.toml index cca7aef88..495c17ef6 100644 --- a/packages/msgs-derive/Cargo.toml +++ b/packages/msgs-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "msgs-derive" -version = "0.1.0" +version = "1.0.0" edition = "2021" rust-version = { workspace = true } diff --git a/packages/report/Cargo.toml b/packages/report/Cargo.toml index 65f56e40b..b491bd58b 100644 --- a/packages/report/Cargo.toml +++ b/packages/report/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "report" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/router-api/Cargo.toml b/packages/router-api/Cargo.toml index 22edbaa45..25e1340bd 100644 --- a/packages/router-api/Cargo.toml +++ b/packages/router-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "router-api" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/signature-verifier-api/Cargo.toml b/packages/signature-verifier-api/Cargo.toml index 1602a84e2..813633a23 100644 --- a/packages/signature-verifier-api/Cargo.toml +++ b/packages/signature-verifier-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature-verifier-api" -version = "0.1.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" From e515aed72cd713891ac8591a9d50769e3e2a88e5 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 31 Jul 2024 17:21:21 -0400 Subject: [PATCH 121/168] chore: add major/minor commit message signifiers for release action (#559) --- .github/workflows/release.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c70bb6248..941444712 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -37,16 +37,16 @@ jobs: run: | binary="${{ github.event.inputs.binary-to-release }}" declare -A binaries_data=( - ["ampd"]="ampd,major-ampd,minor-ampd," - ["router"]="router,/(major-router)|(major-contracts)|(major-connection-router)/,/(minor-router)|(minor-contracts)|(minor-connection-router)/,contracts/router packages" - ["gateway"]="gateway,/(major-gateway)|(major-contracts)/,/(minor-gateway)|(minor-contracts)/,contracts/gateway packages" - ["multisig"]="multisig,/(major-multisig)|(major-contracts)/,/(minor-multisig)|(minor-contracts)/,contracts/multisig packages" - ["multisig-prover"]="multisig-prover,/(major-multisig-prover)|(major-contracts)/,/(minor-multisig-prover)|(minor-contracts)/,contracts/multisig-prover packages" - ["nexus-gateway"]="nexus-gateway,/(major-nexus-gateway)|(major-contracts)/,/(minor-nexus-gateway)|(minor-contracts)/,contracts/nexus-gateway packages" - ["rewards"]="rewards,/(major-rewards)|(major-contracts)/,/(minor-rewards)|(minor-contracts)/,contracts/rewards packages" - ["service-registry"]="service-registry,/(major-service-registry)|(major-contracts)/,/(minor-service-registry)|(minor-contracts)/,contracts/service-registry packages" - ["voting-verifier"]="voting-verifier,/(major-voting-verifier)|(major-contracts)/,/(minor-voting-verifier)|(minor-contracts)/,contracts/voting-verifier packages" - ["coordinator"]="coordinator,/(major-coordinator)|(major-contracts)/,/(minor-coordinator)|(minor-contracts)/,contracts/coordinator packages" + ["ampd"]="ampd,/(major)|(major-ampd)/,/(minor)|(minor-ampd)/,ampd packages" + ["router"]="router,/(major)|(major-router)|(major-contracts)|(major-connection-router)/,/(minor)|(minor-router)|(minor-contracts)|(minor-connection-router)/,contracts/router packages" + ["gateway"]="gateway,/(major)|(major-gateway)|(major-contracts)/,/(minor)|(minor-gateway)|(minor-contracts)/,contracts/gateway packages" + ["multisig"]="multisig,/(major)|(major-multisig)|(major-contracts)/,/(minor)|(minor-multisig)|(minor-contracts)/,contracts/multisig packages" + ["multisig-prover"]="multisig-prover,/(major)|(major-multisig-prover)|(major-contracts)/,/(minor)|(minor-multisig-prover)|(minor-contracts)/,contracts/multisig-prover packages" + ["nexus-gateway"]="nexus-gateway,/(major)|(major-nexus-gateway)|(major-contracts)/,/(minor)|(minor-nexus-gateway)|(minor-contracts)/,contracts/nexus-gateway packages" + ["rewards"]="rewards,/(major)|(major-rewards)|(major-contracts)/,/(minor)|(minor-rewards)|(minor-contracts)/,contracts/rewards packages" + ["service-registry"]="service-registry,/(major)|(major-service-registry)|(major-contracts)/,/(minor)|(minor-service-registry)|(minor-contracts)/,contracts/service-registry packages" + ["voting-verifier"]="voting-verifier,/(major)|(major-voting-verifier)|(major-contracts)/,/(minor)|(minor-voting-verifier)|(minor-contracts)/,contracts/voting-verifier packages" + ["coordinator"]="coordinator,/(major)|(major-coordinator)|(major-contracts)/,/(minor)|(minor-coordinator)|(minor-contracts)/,contracts/coordinator packages" ) if [[ -n "${binaries_data[$binary]}" ]]; then From e5d7ef128e9b582bc00b2abfe1bcce5f81c2a3e7 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 21:52:41 +0000 Subject: [PATCH 122/168] chore: release router 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/router/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 244df312e..cdec10ec5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6497,7 +6497,7 @@ dependencies = [ [[package]] name = "router" -version = "0.4.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index e0b093a44..e68dfc44c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ resolver = "2" rust-version = "1.78.0" # be sure there is an optimizer release supporting this version before updating. See https://github.com/CosmWasm/optimizer [workspace.dependencies] -router = { version = "^0.4.0", path = "contracts/router" } +router = { version = "^1.0.0", path = "contracts/router" } cosmwasm-std = "1.5.5" cosmwasm-schema = "1.5.5" cw-storage-plus = { version = "1.2.0", features = ["iterator", "macro"] } diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 4184fe32d..70bbe6d02 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "router" -version = "0.4.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Router contract" From ff195ca77d154458a7ba9e4eda42158da4060457 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 21:55:39 +0000 Subject: [PATCH 123/168] chore: release rewards 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/rewards/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cdec10ec5..3515428db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6386,7 +6386,7 @@ dependencies = [ [[package]] name = "rewards" -version = "0.4.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index e68dfc44c..77f8d31ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ router-api = { version = "^1.0.0", path = "packages/router-api" } report = { version = "^1.0.0", path = "packages/report" } client = { version = "^1.0.0", path = "packages/client" } quote = "1.0.36" -rewards = { version = "^0.4.0", path = "contracts/rewards" } +rewards = { version = "^1.0.0", path = "contracts/rewards" } thiserror = "1.0.61" mockall = "0.12.1" serde = { version = "1.0.145", default-features = false, features = ["derive"] } diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index 2e14aa297..75e56964b 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rewards" -version = "0.4.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Validator rewards contract" From d0badad29b4d4a90c20b8967b8780a2434d52000 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 21:58:08 +0000 Subject: [PATCH 124/168] chore: release multisig 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/multisig/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3515428db..c28bc335b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4819,7 +4819,7 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multisig" -version = "0.4.1" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 77f8d31ad..56ac4773a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ integration-tests = { version = "^1.0.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } coordinator = { version = "^0.2.0", path = "contracts/coordinator" } -multisig = { version = "^0.4.1", path = "contracts/multisig" } +multisig = { version = "^1.0.0", path = "contracts/multisig" } msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 535a1de6a..753db7151 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multisig" -version = "0.4.1" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Multisig contract" From ec12cd39f6433fba6fd7a5a3a3f18f40540c4e0e Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:01:36 +0000 Subject: [PATCH 125/168] chore: release coordinator 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/coordinator/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c28bc335b..cd8c665c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1581,7 +1581,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "coordinator" -version = "0.2.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 56ac4773a..3473a5891 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std- integration-tests = { version = "^1.0.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } -coordinator = { version = "^0.2.0", path = "contracts/coordinator" } +coordinator = { version = "^1.0.0", path = "contracts/coordinator" } multisig = { version = "^1.0.0", path = "contracts/multisig" } msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index eca1f0e77..ba948f33e 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "coordinator" -version = "0.2.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Amplifier info aggregation for external use, alongside contract management, instantiation and migration" From acfccc007c4185e0be56a1e89a63363687f05616 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:05:24 +0000 Subject: [PATCH 126/168] chore: release service-registry 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/service-registry/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd8c665c0..d754fc906 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7152,7 +7152,7 @@ dependencies = [ [[package]] name = "service-registry" -version = "0.4.1" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index 3473a5891..079cb8d62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ multisig = { version = "^1.0.0", path = "contracts/multisig" } msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } -service-registry = { version = "^0.4.1", path = "contracts/service-registry" } +service-registry = { version = "^1.0.0", path = "contracts/service-registry" } gateway = { version = "^0.2.3", path = "contracts/gateway" } gateway-api = { version = "^1.0.0", path = "packages/gateway-api" } router-api = { version = "^1.0.0", path = "packages/router-api" } diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index 2437847de..fd9541d43 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "service-registry" -version = "0.4.1" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Contract handling the service registrations" From e4d651faf608bb10c705ce5a64dec9f15dde76d8 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:09:35 +0000 Subject: [PATCH 127/168] chore: release voting-verifier 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/voting-verifier/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d754fc906..4420f260f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8856,7 +8856,7 @@ checksum = "2e4fe92cfc1bad19c19925d5eee4b30584dbbdee4ff10183b261acccbef74e2d" [[package]] name = "voting-verifier" -version = "0.5.0" +version = "1.0.0" dependencies = [ "alloy-primitives", "axelar-wasm-std", diff --git a/Cargo.toml b/Cargo.toml index 079cb8d62..d9ee71a8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ axelar-wasm-std = { version = "^1.0.0", path = "packages/axelar-wasm-std" } axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std-derive" } integration-tests = { version = "^1.0.0", path = "integration-tests" } itertools = "0.11.0" -voting-verifier = { version = "^0.5.0", path = "contracts/voting-verifier" } +voting-verifier = { version = "^1.0.0", path = "contracts/voting-verifier" } coordinator = { version = "^1.0.0", path = "contracts/coordinator" } multisig = { version = "^1.0.0", path = "contracts/multisig" } msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index db7e0948b..6ed22889e 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "voting-verifier" -version = "0.5.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Voting verifier contract" From 81cd54dfb89e7dc277ef1cbae6d89e0a1e8de903 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:12:34 +0000 Subject: [PATCH 128/168] chore: release nexus-gateway 1.0.0 --- Cargo.lock | 2 +- contracts/nexus-gateway/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4420f260f..5be630c49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5011,7 +5011,7 @@ dependencies = [ [[package]] name = "nexus-gateway" -version = "0.3.0" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index fcf181460..94ef1aa43 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nexus-gateway" -version = "0.3.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 2c00c62f45cbf0a9895c05aa3c51bb9a17509b9a Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:18:32 +0000 Subject: [PATCH 129/168] chore: release gateway 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/gateway/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5be630c49..034992204 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3107,7 +3107,7 @@ dependencies = [ [[package]] name = "gateway" -version = "0.2.3" +version = "1.0.0" dependencies = [ "axelar-wasm-std", "axelar-wasm-std-derive", diff --git a/Cargo.toml b/Cargo.toml index d9ee71a8a..cd9560443 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^1.0.0", path = "contracts/service-registry" } -gateway = { version = "^0.2.3", path = "contracts/gateway" } +gateway = { version = "^1.0.0", path = "contracts/gateway" } gateway-api = { version = "^1.0.0", path = "packages/gateway-api" } router-api = { version = "^1.0.0", path = "packages/router-api" } report = { version = "^1.0.0", path = "packages/report" } diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index d9cfd8830..06c1b86ef 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gateway" -version = "0.2.3" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Gateway contract" From ca9da13a534332cd226a4fbc80495e74bff89a4e Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:21:30 +0000 Subject: [PATCH 130/168] chore: release multisig-prover 1.0.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- contracts/multisig-prover/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 034992204..2f11b5c55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4852,7 +4852,7 @@ dependencies = [ [[package]] name = "multisig-prover" -version = "0.6.0" +version = "1.0.0" dependencies = [ "anyhow", "axelar-wasm-std", diff --git a/Cargo.toml b/Cargo.toml index cd9560443..037a615e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ voting-verifier = { version = "^1.0.0", path = "contracts/voting-verifier" } coordinator = { version = "^1.0.0", path = "contracts/coordinator" } multisig = { version = "^1.0.0", path = "contracts/multisig" } msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } -multisig-prover = { version = "^0.6.0", path = "contracts/multisig-prover" } +multisig-prover = { version = "^1.0.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^1.0.0", path = "contracts/service-registry" } gateway = { version = "^1.0.0", path = "contracts/gateway" } diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 6bc166fc4..2d92f397a 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multisig-prover" -version = "0.6.0" +version = "1.0.0" rust-version = { workspace = true } edition = "2021" description = "Multisig prover contract" From bb58d241ccb4757fdbbf96cb33246d3634667449 Mon Sep 17 00:00:00 2001 From: Axelar DevOps Date: Wed, 31 Jul 2024 22:24:07 +0000 Subject: [PATCH 131/168] chore: release ampd 1.0.0 --- Cargo.lock | 2 +- ampd/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f11b5c55..5bd99db29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,7 +220,7 @@ dependencies = [ [[package]] name = "ampd" -version = "0.6.0" +version = "1.0.0" dependencies = [ "async-trait", "axelar-wasm-std", diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index cd8b7d5aa..f8b633856 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "ampd" -version = "0.6.0" +version = "1.0.0" rust-version = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From f7acd1b40829e5625b80021aea61cee455954526 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 1 Aug 2024 13:43:14 -0400 Subject: [PATCH 132/168] fix(gateway): copy instantiate function to migration to keep contract version fixed (#561) --- .../gateway/src/contract/migrations/v0_2_3.rs | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/contracts/gateway/src/contract/migrations/v0_2_3.rs b/contracts/gateway/src/contract/migrations/v0_2_3.rs index a05fe95ea..7b96edcb8 100644 --- a/contracts/gateway/src/contract/migrations/v0_2_3.rs +++ b/contracts/gateway/src/contract/migrations/v0_2_3.rs @@ -86,12 +86,14 @@ impl KeyDeserialize for &CrossChainId { #[cfg(test)] mod tests { use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::DepsMut; + use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; + use error_stack::ResultExt; use crate::contract::migrations::v0_2_3; - use crate::contract::{instantiate, CONTRACT_NAME, CONTRACT_VERSION}; + use crate::contract::{Error, CONTRACT_NAME, CONTRACT_VERSION}; use crate::msg::InstantiateMsg; use crate::state; + use crate::state::Config; #[test] fn migrate_checks_contract_version() { @@ -182,4 +184,31 @@ mod tests { assert!(state::OUTGOING_MESSAGES.is_empty(deps.as_ref().storage)) } + + #[deprecated(since = "0.2.3", note = "only used to test the migration")] + pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_2_3::BASE_VERSION)?; + + let router = deps + .api + .addr_validate(&msg.router_address) + .change_context(Error::InvalidAddress) + .attach_printable(msg.router_address)?; + + let verifier = deps + .api + .addr_validate(&msg.verifier_address) + .change_context(Error::InvalidAddress) + .attach_printable(msg.verifier_address)?; + + state::save_config(deps.storage, &Config { verifier, router }) + .change_context(Error::InvalidStoreAccess)?; + + Ok(Response::new()) + } } From 12937f5d6b3ba5ced474d386382dfe7056b2de38 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 1 Aug 2024 13:49:41 -0400 Subject: [PATCH 133/168] refactor: minor improvements to code quality (#560) --- README.md | 31 ++++++++++--------- ampd/src/broadcaster/confirm_tx.rs | 0 ampd/src/broadcaster/mod.rs | 2 +- ampd/src/handlers/evm_verify_msg.rs | 4 +-- ampd/src/handlers/evm_verify_verifier_set.rs | 2 +- ampd/src/handlers/multisig.rs | 23 ++++++++------ ampd/src/sui/verifier.rs | 8 ++--- contracts/multisig-prover/src/contract.rs | 2 +- .../multisig-prover/src/test/test_data.rs | 14 ++++----- contracts/multisig/src/contract.rs | 4 +-- contracts/multisig/src/key.rs | 4 +-- contracts/rewards/src/contract/execute.rs | 4 +-- contracts/rewards/src/state.rs | 8 ++--- contracts/router/src/contract.rs | 4 +-- contracts/voting-verifier/src/contract.rs | 10 ++---- .../voting-verifier/src/contract/execute.rs | 4 +-- .../voting-verifier/src/contract/query.rs | 14 ++++----- integration-tests/tests/update_worker_set.rs | 28 +++++++---------- packages/axelar-wasm-std/src/killswitch.rs | 9 ++---- packages/axelar-wasm-std/src/voting.rs | 6 ++-- packages/events/src/event.rs | 3 +- 21 files changed, 87 insertions(+), 97 deletions(-) delete mode 100644 ampd/src/broadcaster/confirm_tx.rs diff --git a/README.md b/README.md index a445c43be..75d0ac4db 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,21 @@ The basic rules are as follows: ### Compatibility -For the amplifier preview with version numbers < 1.0.0, please refer to the following compatibility table to select versions of +For the amplifier preview with version numbers < 1.0.0, please refer to the following compatibility table to select +versions of contracts and `ampd` that work well together. -| Binary | Version | -|-------------|---------| -| ampd | 0.6.0 | -| coordinator | 0.2.0 | -| gateway | 0.2.3 | -| multisig-prover | 0.6.0 | -| multisig | 0.4.1 | -| nexus-gateway | 0.3.0 | -| rewards | 0.4.0 | -| router | 0.4.0 | -| service-registry | 0.4.1 | -| voting-verifier | 0.5.0 | -| [tofnd](https://github.com/axelarnetwork/tofnd) | v1.0.1 | -| [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | +| Binary | Version | +|--------------------------------------------------------------------------------|---------| +| ampd | 0.6.0 | +| coordinator | 0.2.0 | +| gateway | 0.2.3 | +| multisig-prover | 0.6.0 | +| multisig | 0.4.1 | +| nexus-gateway | 0.3.0 | +| rewards | 0.4.0 | +| router | 0.4.0 | +| service-registry | 0.4.1 | +| voting-verifier | 0.5.0 | +| [tofnd](https://github.com/axelarnetwork/tofnd) | 1.0.1 | +| [solidity-contracts](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity) | 5.9.0 | diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index 91a78fe60..27c493fd7 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -330,7 +330,7 @@ where Ok(Fee::from_amount_and_gas( Coin { - amount: cast((gas_adj.mul(self.config.gas_price.amount)).ceil()) + amount: cast(gas_adj.mul(self.config.gas_price.amount).ceil()) .ok_or(Error::FeeEstimation)?, denom: self.config.gas_price.denom.clone().into(), }, diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 7abb4cc1d..6fe8ca131 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -35,7 +35,7 @@ pub struct Message { pub tx_id: Hash, pub event_index: u32, pub destination_address: String, - pub destination_chain: router_api::ChainName, + pub destination_chain: ChainName, pub source_address: EVMAddress, pub payload_hash: Hash, } @@ -44,7 +44,7 @@ pub struct Message { #[try_from("wasm-messages_poll_started")] struct PollStartedEvent { poll_id: PollId, - source_chain: router_api::ChainName, + source_chain: ChainName, source_gateway_address: EVMAddress, confirmation_height: u64, expires_at: u64, diff --git a/ampd/src/handlers/evm_verify_verifier_set.rs b/ampd/src/handlers/evm_verify_verifier_set.rs index 7b7179c6c..6097f85b9 100644 --- a/ampd/src/handlers/evm_verify_verifier_set.rs +++ b/ampd/src/handlers/evm_verify_verifier_set.rs @@ -40,7 +40,7 @@ pub struct VerifierSetConfirmation { struct PollStartedEvent { verifier_set: VerifierSetConfirmation, poll_id: PollId, - source_chain: router_api::ChainName, + source_chain: ChainName, source_gateway_address: EVMAddress, expires_at: u64, confirmation_height: u64, diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 978ee4bdb..86211bce6 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -8,7 +8,6 @@ use cosmrs::Any; use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::VerifyingKey; use error_stack::{Report, ResultExt}; -use events::Error::EventTypeMismatch; use events_derive; use events_derive::try_from; use hex::encode; @@ -126,7 +125,12 @@ where msg, expires_at, } = match event.try_into() as error_stack::Result<_, _> { - Err(report) if matches!(report.current_context(), EventTypeMismatch(_)) => { + Err(report) + if matches!( + report.current_context(), + events::Error::EventTypeMismatch(_) + ) => + { return Ok(vec![]); } result => result.change_context(DeserializeEvent)?, @@ -194,8 +198,7 @@ mod test { use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::SigningKey; use error_stack::{Report, Result}; - use multisig::events::Event::SigningStarted; - use multisig::key::PublicKey; + use multisig::events::Event; use multisig::types::MsgToSign; use rand::distributions::Alphanumeric; use rand::rngs::OsRng; @@ -242,9 +245,9 @@ mod test { fn signing_started_event() -> events::Event { let pub_keys = (0..10) .map(|_| (rand_account().to_string(), rand_public_key())) - .collect::>(); + .collect::>(); - let poll_started = SigningStarted { + let poll_started = Event::SigningStarted { session_id: Uint64::one(), verifier_set_id: "verifier_set_id".to_string(), pub_keys, @@ -273,9 +276,9 @@ mod test { fn signing_started_event_with_missing_fields(contract_address: &str) -> events::Event { let pub_keys = (0..10) .map(|_| (rand_account().to_string(), rand_public_key())) - .collect::>(); + .collect::>(); - let poll_started = SigningStarted { + let poll_started = Event::SigningStarted { session_id: Uint64::one(), verifier_set_id: "verifier_set_id".to_string(), pub_keys, @@ -342,10 +345,10 @@ mod test { let mut event = signing_started_event(); let invalid_pub_key: [u8; 32] = rand::random(); - let mut map: HashMap = HashMap::new(); + let mut map: HashMap = HashMap::new(); map.insert( rand_account().to_string(), - PublicKey::Ecdsa(HexBinary::from(invalid_pub_key.as_slice())), + multisig::key::PublicKey::Ecdsa(HexBinary::from(invalid_pub_key.as_slice())), ); match event { events::Event::Abci { diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index d49efb5bb..d088b2125 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -21,7 +21,7 @@ where { let string: String = Deserialize::deserialize(deserializer)?; - R::from_str(&string).map_err(D::Error::custom) + R::from_str(&string).map_err(Error::custom) } fn deserialize_sui_bytes<'de, D, const LENGTH: usize>( @@ -33,13 +33,13 @@ where let bytes: HashMap = Deserialize::deserialize(deserializer)?; let hex = bytes .get("bytes") - .ok_or_else(|| D::Error::custom("missing bytes"))? + .ok_or_else(|| Error::custom("missing bytes"))? .trim_start_matches("0x"); hex::decode(hex) - .map_err(D::Error::custom)? + .map_err(Error::custom)? .try_into() - .map_err(|_| D::Error::custom(format!("failed deserialize into [u8; {}]", LENGTH))) + .map_err(|_| Error::custom(format!("failed deserialize into [u8; {}]", LENGTH))) } #[derive(Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)] diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 2f95218e3..068d7d41b 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -170,7 +170,7 @@ mod tests { service_name: SERVICE_NAME.to_string(), chain_name: "ganache-0".to_string(), verifier_set_diff_threshold: 0, - encoder: crate::encoding::Encoder::Abi, + encoder: Encoder::Abi, key_type: multisig::key::KeyType::Ecdsa, domain_separator: [0; 32], }, diff --git a/contracts/multisig-prover/src/test/test_data.rs b/contracts/multisig-prover/src/test/test_data.rs index d8dc6351d..efd0eb1e6 100644 --- a/contracts/multisig-prover/src/test/test_data.rs +++ b/contracts/multisig-prover/src/test/test_data.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use axelar_wasm_std::{nonempty, MajorityThreshold, Participant, Threshold}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, HexBinary, Uint128, Uint64}; -use multisig::key::{KeyType, PublicKey, Signature}; +use multisig::key::{KeyType, Signature}; use multisig::msg::Signer; use multisig::verifier_set::VerifierSet; use router_api::{CrossChainId, Message}; @@ -13,7 +13,7 @@ pub fn new_verifier_set() -> VerifierSet { Signer { address: Addr::unchecked("axelarvaloper1x86a8prx97ekkqej2x636utrdu23y8wupp9gk5"), weight: Uint128::from(10u128), - pub_key: PublicKey::Ecdsa( + pub_key: multisig::key::PublicKey::Ecdsa( HexBinary::from_hex( "03d123ce370b163acd576be0e32e436bb7e63262769881d35fa3573943bf6c6f81", ) @@ -23,7 +23,7 @@ pub fn new_verifier_set() -> VerifierSet { Signer { address: Addr::unchecked("axelarvaloper1ff675m593vve8yh82lzhdnqfpu7m23cxstr6h4"), weight: Uint128::from(10u128), - pub_key: PublicKey::Ecdsa( + pub_key: multisig::key::PublicKey::Ecdsa( HexBinary::from_hex( "03c6ddb0fcee7b528da1ef3c9eed8d51eeacd7cc28a8baa25c33037c5562faa6e4", ) @@ -33,7 +33,7 @@ pub fn new_verifier_set() -> VerifierSet { Signer { address: Addr::unchecked("axelarvaloper12cwre2gdhyytc3p97z9autzg27hmu4gfzz4rxc"), weight: Uint128::from(10u128), - pub_key: PublicKey::Ecdsa( + pub_key: multisig::key::PublicKey::Ecdsa( HexBinary::from_hex( "0274b5d2a4c55d7edbbf9cc210c4d25adbb6194d6b444816235c82984bee518255", ) @@ -43,7 +43,7 @@ pub fn new_verifier_set() -> VerifierSet { Signer { address: Addr::unchecked("axelarvaloper1vs9rdplntrf7ceqdkznjmanrr59qcpjq6le0yw"), weight: Uint128::from(10u128), - pub_key: PublicKey::Ecdsa( + pub_key: multisig::key::PublicKey::Ecdsa( HexBinary::from_hex( "02a670f57de55b8b39b4cb051e178ca8fb3fe3a78cdde7f8238baf5e6ce1893185", ) @@ -53,7 +53,7 @@ pub fn new_verifier_set() -> VerifierSet { Signer { address: Addr::unchecked("axelarvaloper1hz0slkejw96dukw87fztjkvwjdpcu20jewg6mw"), weight: Uint128::from(10u128), - pub_key: PublicKey::Ecdsa( + pub_key: multisig::key::PublicKey::Ecdsa( HexBinary::from_hex( "028584592624e742ba154c02df4c0b06e4e8a957ba081083ea9fe5309492aa6c7b", ) @@ -201,7 +201,7 @@ pub fn verifier_set_from_pub_keys(pub_keys: Vec<&str>) -> VerifierSet { address: Addr::unchecked(format!("verifier{i}")), weight: nonempty::Uint128::one(), }, - PublicKey::Ecdsa(HexBinary::from_hex(pub_keys[i]).unwrap()), + multisig::key::PublicKey::Ecdsa(HexBinary::from_hex(pub_keys[i]).unwrap()), ) }) .collect(); diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index b9116cf07..02c70059a 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1200,7 +1200,7 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::permission_control::Error::PermissionDenied { + permission_control::Error::PermissionDenied { expected: Permission::Governance.into(), actual: Permission::NoPrivilege.into() } @@ -1222,7 +1222,7 @@ mod tests { assert_eq!( res.unwrap_err().to_string(), - axelar_wasm_std::permission_control::Error::PermissionDenied { + permission_control::Error::PermissionDenied { expected: Permission::Elevated.into(), actual: Permission::NoPrivilege.into() } diff --git a/contracts/multisig/src/key.rs b/contracts/multisig/src/key.rs index 2192684ee..fb73bfc80 100644 --- a/contracts/multisig/src/key.rs +++ b/contracts/multisig/src/key.rs @@ -131,7 +131,7 @@ where { let pk: HexBinary = Deserialize::deserialize(deserializer)?; PublicKey::try_from((KeyType::Ecdsa, pk.clone())) - .map_err(|err| D::Error::custom(format!("failed to deserialize public key: {}", err)))?; + .map_err(|err| Error::custom(format!("failed to deserialize public key: {}", err)))?; Ok(pk) } @@ -141,7 +141,7 @@ where { let pk: HexBinary = Deserialize::deserialize(deserializer)?; PublicKey::try_from((KeyType::Ed25519, pk.clone())) - .map_err(|e| D::Error::custom(format!("failed to deserialize public key: {}", e)))?; + .map_err(|e| Error::custom(format!("failed to deserialize public key: {}", e)))?; Ok(pk) } diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index dcffd963f..08eef8eed 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -65,7 +65,7 @@ pub(crate) fn distribute_rewards( .map_or(0, |last_processed| last_processed.saturating_add(1)); let to = std::cmp::min( - (from.saturating_add(epoch_process_limit)).saturating_sub(1), // for process limit =1 "from" and "to" must be equal + from.saturating_add(epoch_process_limit).saturating_sub(1), // for process limit =1 "from" and "to" must be equal cur_epoch.epoch_num.saturating_sub(EPOCH_PAYOUT_DELAY), ); @@ -553,7 +553,7 @@ mod test { let new_epoch_duration = initial_epoch_duration * 2; let new_params = Params { - epoch_duration: (new_epoch_duration).try_into().unwrap(), + epoch_duration: new_epoch_duration.try_into().unwrap(), ..initial_params_snapshot.params // keep everything besides epoch duration the same }; diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index 937885e38..e09816885 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -207,10 +207,10 @@ impl Epoch { if cur_block_height < last_updated_epoch.block_height_started { Err(ContractError::BlockHeightInPast.into()) } else { - let epochs_elapsed = (cur_block_height - .saturating_sub(last_updated_epoch.block_height_started)) - .checked_div(epoch_duration) - .expect("invalid invariant: epoch duration is zero"); + let epochs_elapsed = cur_block_height + .saturating_sub(last_updated_epoch.block_height_started) + .checked_div(epoch_duration) + .expect("invalid invariant: epoch duration is zero"); Ok(Epoch { epoch_num: last_updated_epoch .epoch_num diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index c4b139055..ac911eb2d 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -234,8 +234,8 @@ mod test { } pub fn assert_contract_err_string_contains( - actual: impl Into, - expected: impl Into, + actual: impl Into, + expected: impl Into, ) { assert!(actual .into() diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 7ae5b495c..b9acc44fd 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -407,10 +407,7 @@ mod test { .iter() .cloned() .map(|e| { - ( - e, - &axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, - ) + (e, &MessageIdFormat::HexTxHashAndEventIndex) .try_into() .unwrap() }) @@ -480,10 +477,7 @@ mod test { let expected = messages .into_iter() .map(|e| { - ( - e, - &axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, - ) + (e, &MessageIdFormat::HexTxHashAndEventIndex) .try_into() .unwrap() }) diff --git a/contracts/voting-verifier/src/contract/execute.rs b/contracts/voting-verifier/src/contract/execute.rs index 00dafdbbc..83152fd69 100644 --- a/contracts/voting-verifier/src/contract/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -339,7 +339,7 @@ fn create_verifier_set_poll( let id = POLL_ID.incr(store)?; let poll = WeightedPoll::new(id, snapshot, expires_at, 1); - POLLS.save(store, id, &state::Poll::ConfirmVerifierSet(poll))?; + POLLS.save(store, id, &Poll::ConfirmVerifierSet(poll))?; Ok(id) } @@ -353,7 +353,7 @@ fn create_messages_poll( let id = POLL_ID.incr(store)?; let poll = WeightedPoll::new(id, snapshot, expires_at, poll_size); - POLLS.save(store, id, &state::Poll::Messages(poll))?; + POLLS.save(store, id, &Poll::Messages(poll))?; Ok(id) } diff --git a/contracts/voting-verifier/src/contract/query.rs b/contracts/voting-verifier/src/contract/query.rs index c21cdacff..4e477503b 100644 --- a/contracts/voting-verifier/src/contract/query.rs +++ b/contracts/voting-verifier/src/contract/query.rs @@ -6,7 +6,7 @@ use router_api::Message; use crate::error::ContractError; use crate::msg::{MessageStatus, PollData, PollResponse}; -use crate::state::{self, poll_messages, poll_verifier_sets, Poll, PollContent, CONFIG, POLLS}; +use crate::state::{poll_messages, poll_verifier_sets, Poll, PollContent, CONFIG, POLLS}; pub fn voting_threshold(deps: Deps) -> Result { Ok(CONFIG.load(deps.storage)?.voting_threshold) @@ -132,9 +132,9 @@ fn verification_status( } } -fn voting_completed(poll: &state::Poll, cur_block_height: u64) -> bool { +fn voting_completed(poll: &Poll, cur_block_height: u64) -> bool { match poll { - state::Poll::Messages(poll) | state::Poll::ConfirmVerifierSet(poll) => { + Poll::Messages(poll) | Poll::ConfirmVerifierSet(poll) => { matches!( poll.status(cur_block_height), PollStatus::Expired | PollStatus::Finished @@ -167,7 +167,7 @@ mod tests { .save( deps.as_mut().storage, poll.poll_id, - &state::Poll::Messages(poll.clone()), + &Poll::Messages(poll.clone()), ) .unwrap(); @@ -203,7 +203,7 @@ mod tests { .save( deps.as_mut().storage, poll.poll_id, - &state::Poll::Messages(poll.clone()), + &Poll::Messages(poll.clone()), ) .unwrap(); @@ -239,7 +239,7 @@ mod tests { .save( deps.as_mut().storage, poll.poll_id, - &state::Poll::Messages(poll.clone()), + &Poll::Messages(poll.clone()), ) .unwrap(); @@ -282,7 +282,7 @@ mod tests { .save( deps.as_mut().storage, poll.poll_id, - &state::Poll::Messages(poll.clone()), + &Poll::Messages(poll.clone()), ) .unwrap(); diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index ba5cf3b86..4bbdcfe8e 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -4,10 +4,6 @@ use integration_tests::contract::Contract; use multisig_prover::msg::ExecuteMsg; use service_registry::msg::QueryMsg as ServiceRegistryQueryMsg; use service_registry::state::WeightedVerifier; -use test_utils::{ - create_new_verifiers_vec, multisig_session_id, register_in_service_registry, - register_verifiers, rotate_active_verifier_set, Verifier, -}; pub mod test_utils; @@ -36,13 +32,13 @@ fn verifier_set_can_be_initialized_and_then_manually_updated() { // add third and fourth verifier let mut new_verifiers = Vec::new(); - let new_verifier = Verifier { + let new_verifier = test_utils::Verifier { addr: Addr::unchecked("verifier3"), supported_chains: chains.clone(), key_pair: test_utils::generate_key(2), }; new_verifiers.push(new_verifier); - let new_verifier = Verifier { + let new_verifier = test_utils::Verifier { addr: Addr::unchecked("verifier4"), supported_chains: chains.clone(), key_pair: test_utils::generate_key(3), @@ -275,7 +271,7 @@ fn verifier_set_update_can_be_resigned() { ) .unwrap(); - let first_session_id = multisig_session_id(response.clone()); + let first_session_id = test_utils::multisig_session_id(response.clone()); // signing didn't occur, trigger signing again let response = protocol @@ -288,7 +284,7 @@ fn verifier_set_update_can_be_resigned() { ) .unwrap(); - let second_session_id = multisig_session_id(response.clone()); + let second_session_id = test_utils::multisig_session_id(response.clone()); assert_ne!(first_session_id, second_session_id); test_utils::sign_proof(&mut protocol, &initial_verifiers, response); @@ -304,7 +300,7 @@ fn verifier_set_update_can_be_resigned() { ) .unwrap(); - let third_session_id = multisig_session_id(response.clone()); + let third_session_id = test_utils::multisig_session_id(response.clone()); assert_ne!(first_session_id, second_session_id); assert_ne!(second_session_id, third_session_id); @@ -336,7 +332,7 @@ fn governance_should_confirm_new_verifier_set_without_verification() { // add third verifier let mut new_verifiers = Vec::new(); - let new_verifier = Verifier { + let new_verifier = test_utils::Verifier { addr: Addr::unchecked("verifier3"), supported_chains: chains.clone(), key_pair: test_utils::generate_key(2), @@ -385,21 +381,21 @@ fn rotate_signers_should_filter_out_signers_without_pubkey() { let chains: Vec = vec![chain1.chain_name.clone()]; // add a third verifier to satisfy min verifier change threshold - register_verifiers( + test_utils::register_verifiers( &mut protocol, - &create_new_verifiers_vec(chains.clone(), vec![("verifier3".to_string(), 2)]), + &test_utils::create_new_verifiers_vec(chains.clone(), vec![("verifier3".to_string(), 2)]), min_verifier_bond, ); // add a fourth verifier in service registry but does not submit a pubkey to multisig - register_in_service_registry( + test_utils::register_in_service_registry( &mut protocol, - &create_new_verifiers_vec(chains.clone(), vec![("verifier4".to_string(), 3)]), + &test_utils::create_new_verifiers_vec(chains.clone(), vec![("verifier4".to_string(), 3)]), min_verifier_bond, ); // the fourth verifier should be filtered out in prover because it does not have a pubkey - let expect_new_verifiers = create_new_verifiers_vec( + let expect_new_verifiers = test_utils::create_new_verifiers_vec( chains.clone(), vec![ ("verifier1".to_string(), 0), @@ -428,7 +424,7 @@ fn rotate_signers_should_filter_out_signers_without_pubkey() { ); // rotate signers - rotate_active_verifier_set( + test_utils::rotate_active_verifier_set( &mut protocol, chain1.clone(), &initial_verifiers, diff --git a/packages/axelar-wasm-std/src/killswitch.rs b/packages/axelar-wasm-std/src/killswitch.rs index dffb53a6d..b2342d5a8 100644 --- a/packages/axelar-wasm-std/src/killswitch.rs +++ b/packages/axelar-wasm-std/src/killswitch.rs @@ -15,17 +15,14 @@ pub enum State { } /// Sets the initial state of the killswitch. Should be called during contract instantiation -pub fn init(storage: &mut dyn cosmwasm_std::Storage, initial_state: State) -> StdResult<()> { +pub fn init(storage: &mut dyn Storage, initial_state: State) -> StdResult<()> { STATE.save(storage, &initial_state) } /// Sets the killswitch state to `Engaged`. If the state was previously `Disengaged`, /// adds the on_state_changed event to the response. Returns an error if the killswitch /// was not initialized via `init` -pub fn engage( - storage: &mut dyn cosmwasm_std::Storage, - on_state_change: impl Into, -) -> StdResult { +pub fn engage(storage: &mut dyn Storage, on_state_change: impl Into) -> StdResult { let state = STATE.update(storage, |state| match state { State::Disengaged => Ok(State::Engaged), State::Engaged => Err(KillSwitchUpdateError::SameState), @@ -38,7 +35,7 @@ pub fn engage( /// adds the on_state_changed event to the response. Returns an error if the killswitch /// was not initialized via `init` pub fn disengage( - storage: &mut dyn cosmwasm_std::Storage, + storage: &mut dyn Storage, on_state_change: impl Into, ) -> StdResult { let state = STATE.update(storage, |state| match state { diff --git a/packages/axelar-wasm-std/src/voting.rs b/packages/axelar-wasm-std/src/voting.rs index 3c38feffc..e3eae4f97 100644 --- a/packages/axelar-wasm-std/src/voting.rs +++ b/packages/axelar-wasm-std/src/voting.rs @@ -411,7 +411,7 @@ impl WeightedPoll { mod tests { use cosmwasm_std::{Addr, Uint64}; use rand::distributions::Alphanumeric; - use rand::{thread_rng, Rng}; + use rand::Rng; use super::*; use crate::{nonempty, Participant, Threshold}; @@ -444,7 +444,7 @@ mod tests { #[test] fn voter_not_a_participant() { - let mut rng = thread_rng(); + let mut rng = rand::thread_rng(); let poll = new_poll( rng.gen::(), rng.gen_range(1..50), @@ -452,7 +452,7 @@ mod tests { ); let votes = vec![Vote::SucceededOnChain, Vote::SucceededOnChain]; - let rand_addr: String = thread_rng() + let rand_addr: String = rand::thread_rng() .sample_iter(&Alphanumeric) .take(5) .map(char::from) diff --git a/packages/events/src/event.rs b/packages/events/src/event.rs index 17e179519..ab7fcd1b4 100644 --- a/packages/events/src/event.rs +++ b/packages/events/src/event.rs @@ -5,7 +5,6 @@ use base64::engine::general_purpose::STANDARD; use base64::Engine; use cosmrs::AccountId; use error_stack::{Report, Result, ResultExt}; -use serde_json::Value; use tendermint::abci::EventAttribute; use tendermint::{abci, block}; @@ -90,7 +89,7 @@ impl TryFrom for Event { } } -fn try_into_kv_pair(attr: &EventAttribute) -> Result<(String, Value), Error> { +fn try_into_kv_pair(attr: &EventAttribute) -> Result<(String, serde_json::Value), Error> { decode_event_attribute(attr) .change_context(Error::DecodingAttributesFailed) .map(|(key, value)| { From d434b63743cc17507581ae60eac5a7fac73aede9 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Thu, 1 Aug 2024 14:35:30 -0400 Subject: [PATCH 134/168] refactor(ci): rename r2 pre-releases and releases folder to cosmwasm (#562) --- .github/workflows/build-contracts-and-push-to-r2.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-contracts-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml index 91d155afa..aa919bc4a 100644 --- a/.github/workflows/build-contracts-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -138,7 +138,7 @@ jobs: gpg --armor --detach-sign ../release-artifacts/checksums.txt echo "release-artifacts-dir=./release-artifacts" >> $GITHUB_OUTPUT - echo "r2-destination-dir=./releases/amplifier/${crate_name}/${crate_version}" >> $GITHUB_OUTPUT + echo "r2-destination-dir=./releases/cosmwasm/${crate_name}/${crate_version}" >> $GITHUB_OUTPUT - uses: ryand56/r2-upload-action@latest @@ -160,4 +160,4 @@ jobs: r2-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CF }} r2-bucket: ${{ secrets.R2_BUCKET }} source-dir: ${{ steps.compile-contracts.outputs.wasm-directory }} - destination-dir: ./pre-releases/ampd/contracts/ + destination-dir: ./pre-releases/cosmwasm/ From f8318cd0480148a5b2865042ca010ebd48becadd Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Thu, 1 Aug 2024 17:27:03 -0400 Subject: [PATCH 135/168] refactor(ci): r2 internal path re-structure (#564) --- .../build-contracts-and-push-to-r2.yaml | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-contracts-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml index aa919bc4a..09e890dfd 100644 --- a/.github/workflows/build-contracts-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -45,6 +45,7 @@ jobs: echo "tag=" >> $GITHUB_OUTPUT fi + - name: Check for release information from tag id: check-release run: | @@ -110,9 +111,9 @@ jobs: commit_hash=$(git rev-parse --short HEAD) cd .. - mkdir -p ./artifacts/$commit_hash/ - cp -R axelar-amplifier/artifacts/* ./artifacts/$commit_hash/ - echo "wasm-directory=./artifacts" >> $GITHUB_OUTPUT + mkdir -p ./$commit_hash/ + cp -R axelar-amplifier/artifacts/* ./$commit_hash/ + echo "wasm-directory=./$commit_hash" >> $GITHUB_OUTPUT - name: Prepare and sign release artifacts @@ -130,15 +131,15 @@ jobs: exit 1 fi - mkdir -p "../release-artifacts" - cp "$wasm_file" "../release-artifacts/${crate_name}.wasm" - cp "$checksum_file" "../release-artifacts/" + mkdir -p "../${crate_version}" + cp "$wasm_file" "../${crate_version}/${crate_name}.wasm" + cp "$checksum_file" "../${crate_version}/" - gpg --armor --detach-sign ../release-artifacts/${crate_name}.wasm - gpg --armor --detach-sign ../release-artifacts/checksums.txt + gpg --armor --detach-sign ../${crate_version}/${crate_name}.wasm + gpg --armor --detach-sign ../${crate_version}/checksums.txt - echo "release-artifacts-dir=./release-artifacts" >> $GITHUB_OUTPUT - echo "r2-destination-dir=./releases/cosmwasm/${crate_name}/${crate_version}" >> $GITHUB_OUTPUT + echo "release-artifacts-dir=./${crate_version}" >> $GITHUB_OUTPUT + echo "r2-destination-dir=./releases/cosmwasm/${crate_name}" >> $GITHUB_OUTPUT - uses: ryand56/r2-upload-action@latest From 5c02b142c919aaa3e3199b6bfdcfecceae4719ce Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 1 Aug 2024 17:50:07 -0400 Subject: [PATCH 136/168] fix(router-api): restrict chain names to be short and only use ascii (#565) --- ampd/src/handlers/multisig.rs | 2 +- interchain-token-service/src/abi.rs | 6 +-- ...ploy_interchain_token_encode_decode.golden | 4 +- packages/router-api/src/primitives.rs | 41 ++++++++++++++++++- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 86211bce6..12e0ac448 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -235,7 +235,7 @@ mod test { fn rand_chain_name() -> ChainName { rand::thread_rng() .sample_iter(&Alphanumeric) - .take(32) + .take(10) .map(char::from) .collect::() .try_into() diff --git a/interchain-token-service/src/abi.rs b/interchain-token-service/src/abi.rs index a0cb0ac31..0c9f6f6dc 100644 --- a/interchain-token-service/src/abi.rs +++ b/interchain-token-service/src/abi.rs @@ -347,7 +347,7 @@ mod tests { }, }, ItsHubMessage::SendToHub { - destination_chain: ChainName::from_str("unicode-chain-🌍").unwrap(), + destination_chain: remote_chain.clone(), message: ItsMessage::DeployInterchainToken { token_id: [0u8; 32].into(), name: "Unicode Token 🪙".into(), @@ -377,7 +377,7 @@ mod tests { }, }, ItsHubMessage::ReceiveFromHub { - source_chain: ChainName::from_str("unicode-chain-🌍").unwrap(), + source_chain: remote_chain.clone(), message: ItsMessage::DeployInterchainToken { token_id: [0u8; 32].into(), name: "Unicode Token 🪙".into(), @@ -562,7 +562,7 @@ mod tests { #[test] fn encode_decode_unicode_strings() { let original = ItsHubMessage::SendToHub { - destination_chain: ChainName::from_str("unicode-chain-🌍").unwrap(), + destination_chain: ChainName::from_str("chain").unwrap(), message: ItsMessage::DeployInterchainToken { token_id: [0u8; 32].into(), name: "Unicode Token 🪙".into(), diff --git a/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden b/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden index 87ccfbfd9..e642fc6d3 100644 --- a/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden +++ b/interchain-token-service/src/testdata/deploy_interchain_token_encode_decode.golden @@ -1,8 +1,8 @@ [ "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000a5465737420546f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003545354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012756e69636f64652d636861696e2df09f8c8d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000012556e69636f646520546f6b656e20f09faa9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e49f09f94a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000012556e69636f646520546f6b656e20f09faa9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e49f09f94a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000a5465737420546f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003545354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021234000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012756e69636f64652d636861696e2df09f8c8d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000012556e69636f646520546f6b656e20f09faa9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e49f09f94a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000005636861696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000012556e69636f646520546f6b656e20f09faa9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e49f09f94a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abcd000000000000000000000000000000000000000000000000000000000000" ] \ No newline at end of file diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index 6014d5759..8bc5638b1 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -172,6 +172,13 @@ impl Display for CrossChainId { } } +/// ChainName represents the identifier used for chains in Amplifier. +/// Certain restrictions apply on the string: +/// - Must not be empty +/// - Must not exceed `ChainName::MAX_LEN` bytes +/// - Only ASCII characters are allowed +/// - Must not contain the `FIELD_DELIMITER` character +/// - The string is lowercased #[cw_serde] #[serde(try_from = "String")] #[derive(Eq, Hash, Valuable)] @@ -277,6 +284,15 @@ impl AsRef for ChainName { } } +/// ChainNameRaw represents the raw case-sensitive identifier used for source chains in Amplifier. +/// It is backwards compatible with case-sensitive chain names used in axelar-core (e.g. `Ethereum`). +/// +/// Certain restrictions apply on the string: +/// - Must not be empty +/// - Must not exceed `ChainNameRaw::MAX_LEN` bytes +/// - Only ASCII characters are allowed +/// - Must not contain the `FIELD_DELIMITER` character +/// - Case-sensitivity is preserved #[cw_serde] #[serde(try_from = "String")] #[derive(Eq, Hash)] @@ -288,11 +304,17 @@ impl From for ChainNameRaw { } } +impl ChainNameRaw { + /// Maximum length of a chain name (in bytes). + /// This MUST NOT be changed without a corresponding change to the ChainName validation in axelar-core. + const MAX_LEN: usize = 20; +} + impl FromStr for ChainNameRaw { type Err = Error; fn from_str(s: &str) -> Result { - if s.contains(FIELD_DELIMITER) || s.is_empty() { + if s.is_empty() || s.len() > Self::MAX_LEN || !s.is_ascii() || s.contains(FIELD_DELIMITER) { return Err(Error::InvalidChainName); } @@ -508,7 +530,12 @@ mod tests { is_normalized: false, }, TestCase { - input: "!@#$%^&*()+=-1234567890", + input: "!@#$%^&*()+=-", + can_parse: true, + is_normalized: true, + }, + TestCase { + input: "1234567890", can_parse: true, is_normalized: true, }, @@ -532,6 +559,16 @@ mod tests { can_parse: true, is_normalized: false, }, + TestCase { + input: "long chain name over max len", + can_parse: false, + is_normalized: false, + }, + TestCase { + input: "UTF-8 ❤", + can_parse: false, + is_normalized: false, + }, TestCase { input: random_lower.as_str(), can_parse: true, From 8bad6cd12d328b3cc556110938e609789b6461e8 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 1 Aug 2024 18:05:08 -0400 Subject: [PATCH 137/168] refactor(gateway): inline internal contract module (#563) --- contracts/gateway/src/contract.rs | 174 ++++++++---------- contracts/gateway/src/contract/execute.rs | 18 +- .../gateway/src/contract/migrations/v0_2_3.rs | 2 +- contracts/gateway/src/contract/query.rs | 59 +++--- contracts/gateway/src/lib.rs | 2 +- contracts/gateway/src/state.rs | 82 +++++---- contracts/gateway/tests/contract.rs | 5 +- 7 files changed, 158 insertions(+), 184 deletions(-) diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 9fea40be5..9787a139d 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -1,13 +1,17 @@ use std::fmt::Debug; +use axelar_wasm_std::FnExt; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; +use error_stack::ResultExt; use gateway_api::msg::{ExecuteMsg, QueryMsg}; -use router_api::CrossChainId; +use router_api::client::Router; use crate::contract::migrations::v0_2_3; use crate::msg::InstantiateMsg; +use crate::state; +use crate::state::Config; mod execute; mod migrations; @@ -16,6 +20,30 @@ mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("invalid store access")] + InvalidStoreAccess, + #[error("batch contains duplicate message ids")] + DuplicateMessageIds, + #[error("invalid address")] + InvalidAddress, + #[error("failed to query message status")] + MessageStatus, + #[error("failed to verify messages")] + VerifyMessages, + #[error("failed to route outgoing messages to gateway")] + RouteOutgoingMessages, + #[error("failed to route messages from gateway to router")] + RouteIncomingMessages, + #[error("failed to query outgoing messages")] + OutgoingMessages, + #[error("failed to save outgoing message")] + SaveOutgoingMessage, + #[error("failed to execute gateway command")] + Execute, +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( deps: DepsMut, @@ -29,122 +57,70 @@ pub fn migrate( #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - env: Env, - info: MessageInfo, + _: Env, + _: MessageInfo, msg: InstantiateMsg, ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - Ok(internal::instantiate(deps, env, info, msg)?) + let router = deps + .api + .addr_validate(&msg.router_address) + .change_context(Error::InvalidAddress) + .attach_printable(msg.router_address)?; + + let verifier = deps + .api + .addr_validate(&msg.verifier_address) + .change_context(Error::InvalidAddress) + .attach_printable(msg.verifier_address)?; + + state::save_config(deps.storage, &Config { verifier, router })?; + Ok(Response::new()) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, - env: Env, + _: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { - let msg = msg.ensure_permissions(deps.storage, &info.sender)?; - Ok(internal::execute(deps, env, info, msg)?) + let config = state::load_config(deps.storage).change_context(Error::Execute)?; + let verifier = client::Client::new(deps.querier, config.verifier).into(); + + let router = Router { + address: config.router, + }; + + match msg.ensure_permissions(deps.storage, &info.sender)? { + ExecuteMsg::VerifyMessages(msgs) => { + execute::verify_messages(&verifier, msgs).change_context(Error::VerifyMessages) + } + ExecuteMsg::RouteMessages(msgs) => { + if info.sender == router.address { + execute::route_outgoing_messages(deps.storage, msgs) + .change_context(Error::RouteOutgoingMessages) + } else { + execute::route_incoming_messages(&verifier, &router, msgs) + .change_context(Error::RouteIncomingMessages) + } + } + }? + .then(Ok) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query( deps: Deps, - env: Env, + _: Env, msg: QueryMsg, ) -> Result { - Ok(internal::query(deps, env, msg)?) -} - -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("gateway contract config is missing")] - ConfigMissing, - #[error("invalid store access")] - InvalidStoreAccess, - #[error("failed to serialize the response")] - SerializeResponse, - #[error("batch contains duplicate message ids")] - DuplicateMessageIds, - #[error("invalid address")] - InvalidAddress, - #[error("failed to query message status")] - MessageStatus, - #[error("message with ID {0} not found")] - MessageNotFound(CrossChainId), - #[error("message with id {0} mismatches with the stored one")] - MessageMismatch(CrossChainId), -} - -mod internal { - use client::Client; - use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; - use error_stack::{Result, ResultExt}; - use gateway_api::msg::{ExecuteMsg, QueryMsg}; - use router_api::client::Router; - - use crate::contract::Error; - use crate::msg::InstantiateMsg; - use crate::state::Config; - use crate::{contract, state}; - - pub(crate) fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - let router = deps - .api - .addr_validate(&msg.router_address) - .change_context(Error::InvalidAddress) - .attach_printable(msg.router_address)?; - - let verifier = deps - .api - .addr_validate(&msg.verifier_address) - .change_context(Error::InvalidAddress) - .attach_printable(msg.verifier_address)?; - - state::save_config(deps.storage, &Config { verifier, router }) - .change_context(Error::InvalidStoreAccess)?; - - Ok(Response::new()) - } - - pub(crate) fn execute( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: ExecuteMsg, - ) -> Result { - let config = state::load_config(deps.storage).change_context(Error::ConfigMissing)?; - let verifier = Client::new(deps.querier, config.verifier).into(); - - let router = Router { - address: config.router, - }; - - match msg { - ExecuteMsg::VerifyMessages(msgs) => contract::execute::verify_messages(&verifier, msgs), - ExecuteMsg::RouteMessages(msgs) => { - if info.sender == router.address { - contract::execute::route_outgoing_messages(deps.storage, msgs) - } else { - contract::execute::route_incoming_messages(&verifier, &router, msgs) - } - } - } - } - - pub(crate) fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { - match msg { - QueryMsg::OutgoingMessages(message_ids) => { - let msgs = contract::query::outgoing_messages(deps.storage, message_ids)?; - to_json_binary(&msgs).change_context(Error::SerializeResponse) - } + match msg { + QueryMsg::OutgoingMessages(message_ids) => { + query::outgoing_messages(deps.storage, message_ids.iter()) + .change_context(Error::OutgoingMessages) } - } + }? + .then(Ok) } diff --git a/contracts/gateway/src/contract/execute.rs b/contracts/gateway/src/contract/execute.rs index a355a7f2a..d72f98527 100644 --- a/contracts/gateway/src/contract/execute.rs +++ b/contracts/gateway/src/contract/execute.rs @@ -1,6 +1,6 @@ use axelar_wasm_std::{FnExt, VerificationStatus}; use cosmwasm_std::{Event, Response, Storage, WasmMsg}; -use error_stack::{report, Result, ResultExt}; +use error_stack::{Result, ResultExt}; use itertools::Itertools; use router_api::client::Router; use router_api::Message; @@ -10,7 +10,7 @@ use crate::contract::Error; use crate::events::GatewayEvent; use crate::state; -pub fn verify_messages( +pub(crate) fn verify_messages( verifier: &voting_verifier::Client, msgs: Vec, ) -> Result { @@ -37,18 +37,8 @@ pub(crate) fn route_outgoing_messages( let msgs = check_for_duplicates(verified)?; for msg in msgs.iter() { - state::OUTGOING_MESSAGES - .may_load(store, &msg.cc_id) - .change_context(Error::InvalidStoreAccess) - .and_then(|stored_msg| match stored_msg { - Some(stored_msg) if msg.hash() != stored_msg.hash() => { - Err(report!(Error::MessageMismatch(msg.cc_id.clone()))) - } - Some(_) => Ok(()), // message already exists - None => state::OUTGOING_MESSAGES - .save(store, &msg.cc_id, msg) - .change_context(Error::InvalidStoreAccess), - })?; + state::save_outgoing_message(store, &msg.cc_id, msg) + .change_context(Error::SaveOutgoingMessage)?; } Ok(Response::new().add_events( diff --git a/contracts/gateway/src/contract/migrations/v0_2_3.rs b/contracts/gateway/src/contract/migrations/v0_2_3.rs index 7b96edcb8..48ff502c6 100644 --- a/contracts/gateway/src/contract/migrations/v0_2_3.rs +++ b/contracts/gateway/src/contract/migrations/v0_2_3.rs @@ -182,7 +182,7 @@ mod tests { assert!(v0_2_3::migrate(deps.as_mut().storage).is_ok()); - assert!(state::OUTGOING_MESSAGES.is_empty(deps.as_ref().storage)) + assert!(v0_2_3::OUTGOING_MESSAGES.is_empty(deps.as_ref().storage)) } #[deprecated(since = "0.2.3", note = "only used to test the migration")] diff --git a/contracts/gateway/src/contract/query.rs b/contracts/gateway/src/contract/query.rs index d29eefa9c..59cc4c4e5 100644 --- a/contracts/gateway/src/contract/query.rs +++ b/contracts/gateway/src/contract/query.rs @@ -1,45 +1,38 @@ use axelar_wasm_std::error::extend_err; -use cosmwasm_std::Storage; -use error_stack::{report, Result, ResultExt}; +use cosmwasm_std::{to_json_binary, Binary, Storage}; +use error_stack::Result; use router_api::{CrossChainId, Message}; -use crate::contract::Error; use crate::state; -pub fn outgoing_messages( +pub fn outgoing_messages<'a>( storage: &dyn Storage, - cross_chain_ids: Vec, -) -> Result, Error> { - cross_chain_ids - .into_iter() - .map(|id| try_load_msg(storage, id)) - .fold(Ok(vec![]), accumulate_errs) -} + cross_chain_ids: impl Iterator, +) -> Result { + let msgs = cross_chain_ids + .map(|id| state::load_outgoing_message(storage, id)) + .fold(Ok(vec![]), accumulate_errs)?; -fn try_load_msg(storage: &dyn Storage, id: CrossChainId) -> Result { - state::OUTGOING_MESSAGES - .may_load(storage, &id) - .change_context(Error::InvalidStoreAccess) - .transpose() - .unwrap_or(Err(report!(Error::MessageNotFound(id)))) + Ok(to_json_binary(&msgs).map_err(state::Error::from)?) } fn accumulate_errs( - acc: Result, Error>, - msg: Result, -) -> Result, Error> { + acc: Result, state::Error>, + msg: std::result::Result, +) -> Result, state::Error> { match (acc, msg) { - (Ok(mut acc), Ok(msg)) => { - acc.push(msg); - Ok(acc) + (Ok(mut msgs), Ok(msg)) => { + msgs.push(msg); + Ok(msgs) } - (Err(acc), Ok(_)) => Err(acc), - (acc, Err(msg_err)) => extend_err(acc, msg_err), + (Err(report), Ok(_)) => Err(report), + (acc, Err(msg_err)) => extend_err(acc, msg_err.into()), } } #[cfg(test)] mod test { + use cosmwasm_std::from_json; use cosmwasm_std::testing::mock_dependencies; use router_api::{CrossChainId, Message}; @@ -52,15 +45,14 @@ mod test { let messages = generate_messages(); for message in messages.iter() { - state::OUTGOING_MESSAGES - .save(deps.as_mut().storage, &message.cc_id, message) - .unwrap(); + state::save_outgoing_message(deps.as_mut().storage, &message.cc_id, message).unwrap(); } - let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); + let ids = messages.iter().map(|msg| &msg.cc_id); let res = super::outgoing_messages(&deps.storage, ids).unwrap(); - assert_eq!(res, messages); + let actual_messages: Vec = from_json(res).unwrap(); + assert_eq!(actual_messages, messages); } #[test] @@ -68,7 +60,7 @@ mod test { let deps = mock_dependencies(); let messages = generate_messages(); - let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); + let ids = messages.iter().map(|msg| &msg.cc_id); let res = super::outgoing_messages(&deps.storage, ids); @@ -82,11 +74,10 @@ mod test { let messages = generate_messages(); - state::OUTGOING_MESSAGES - .save(deps.as_mut().storage, &messages[1].cc_id, &messages[1]) + state::save_outgoing_message(deps.as_mut().storage, &messages[1].cc_id, &messages[1]) .unwrap(); - let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); + let ids = messages.iter().map(|msg| &msg.cc_id); let res = super::outgoing_messages(&deps.storage, ids); diff --git a/contracts/gateway/src/lib.rs b/contracts/gateway/src/lib.rs index cdacc8154..5501bc9c7 100644 --- a/contracts/gateway/src/lib.rs +++ b/contracts/gateway/src/lib.rs @@ -1,4 +1,4 @@ pub mod contract; -pub mod events; +mod events; pub mod msg; pub mod state; diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index 473cb7ba5..782bce9d2 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -1,7 +1,7 @@ +use axelar_wasm_std_derive::IntoContractError; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Storage}; +use cosmwasm_std::{Addr, StdError, Storage}; use cw_storage_plus::{Item, Map}; -use error_stack::{Result, ResultExt}; use router_api::{CrossChainId, Message}; #[cw_serde] @@ -10,50 +10,66 @@ pub(crate) struct Config { pub router: Addr, } -pub(crate) fn save_config(storage: &mut dyn Storage, value: &Config) -> Result<(), Error> { - CONFIG - .save(storage, value) - .change_context(Error::SaveValue(CONFIG_NAME)) +const CONFIG: Item = Item::new("config"); +const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new("outgoing_messages"); + +#[derive(thiserror::Error, Debug, IntoContractError)] +pub enum Error { + #[error(transparent)] + Std(#[from] StdError), + #[error("gateway got into an invalid state, its config is missing")] + MissingConfig, + #[error("message with ID {0} mismatches with the stored one")] + MessageMismatch(CrossChainId), + #[error("message with ID {0} not found")] + MessageNotFound(CrossChainId), } pub(crate) fn load_config(storage: &dyn Storage) -> Result { CONFIG - .load(storage) - .change_context(Error::LoadValue(CONFIG_NAME)) + .may_load(storage) + .map_err(Error::from)? + .ok_or(Error::MissingConfig) +} + +pub(crate) fn save_config(storage: &mut dyn Storage, config: &Config) -> Result<(), Error> { + CONFIG.save(storage, config).map_err(Error::from) } -#[derive(thiserror::Error, Debug)] -pub(crate) enum Error { - #[error("failed to save {0}")] - SaveValue(&'static str), - #[error("failed to load {0}")] - LoadValue(&'static str), +pub(crate) fn load_outgoing_message( + storage: &dyn Storage, + cc_id: &CrossChainId, +) -> Result { + OUTGOING_MESSAGES + .may_load(storage, cc_id) + .map_err(Error::from)? + .ok_or_else(|| Error::MessageNotFound(cc_id.clone())) } -const CONFIG_NAME: &str = "config"; -const CONFIG: Item = Item::new(CONFIG_NAME); -const OUTGOING_MESSAGES_NAME: &str = "outgoing_messages"; -pub const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new(OUTGOING_MESSAGES_NAME); +pub(crate) fn save_outgoing_message( + storage: &mut dyn Storage, + cc_id: &CrossChainId, + msg: &Message, +) -> Result<(), Error> { + let existing = OUTGOING_MESSAGES + .may_load(storage, cc_id) + .map_err(Error::from)?; + match existing { + Some(existing) if msg.hash() != existing.hash() => { + Err(Error::MessageMismatch(msg.cc_id.clone())) + } + Some(_) => Ok(()), // new message is identical, no need to store it + None => Ok(OUTGOING_MESSAGES + .save(storage, cc_id, msg) + .map_err(Error::from)?), + } +} #[cfg(test)] mod test { use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::Addr; use router_api::{CrossChainId, Message}; - use crate::state::{load_config, save_config, Config, OUTGOING_MESSAGES}; - - #[test] - fn config_storage() { - let mut deps = mock_dependencies(); - - let config = Config { - verifier: Addr::unchecked("verifier"), - router: Addr::unchecked("router"), - }; - assert!(save_config(deps.as_mut().storage, &config).is_ok()); - - assert_eq!(load_config(&deps.storage).unwrap(), config); - } + use crate::state::OUTGOING_MESSAGES; #[test] fn outgoing_messages_storage() { diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index 10c3ab27c..deeb2af49 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -13,6 +13,7 @@ use cosmwasm_std::{ }; use gateway::contract::*; use gateway::msg::InstantiateMsg; +use gateway::state; use gateway_api::msg::{ExecuteMsg, QueryMsg}; use itertools::Itertools; use rand::{thread_rng, Rng}; @@ -313,8 +314,8 @@ fn reject_reroute_outgoing_message_with_different_contents() { ); assert!(response.is_err_and(|err| err_contains!( err.report, - Error, - Error::MessageMismatch { .. } + state::Error, + state::Error::MessageMismatch { .. } ))); } From bf11cc6594d57e72f735f3d879d97c157ecf54ee Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Thu, 1 Aug 2024 21:14:14 -0400 Subject: [PATCH 138/168] refactor: add derive feature to axelar-wasm-std (#566) --- Cargo.lock | 12 +----------- contracts/coordinator/Cargo.toml | 3 +-- contracts/coordinator/src/error.rs | 2 +- contracts/gateway/Cargo.toml | 3 +-- contracts/gateway/src/state.rs | 2 +- contracts/multisig-prover/Cargo.toml | 3 +-- contracts/multisig-prover/src/error.rs | 3 +-- contracts/multisig/Cargo.toml | 3 +-- contracts/multisig/src/error.rs | 2 +- contracts/nexus-gateway/Cargo.toml | 3 +-- contracts/nexus-gateway/src/error.rs | 2 +- contracts/rewards/Cargo.toml | 3 +-- contracts/rewards/src/error.rs | 2 +- contracts/router/Cargo.toml | 3 +-- contracts/service-registry/Cargo.toml | 3 +-- contracts/service-registry/src/error.rs | 3 +-- contracts/voting-verifier/Cargo.toml | 3 +-- contracts/voting-verifier/src/error.rs | 3 +-- interchain-token-service/Cargo.toml | 3 +-- interchain-token-service/src/error.rs | 2 +- packages/axelar-wasm-std-derive/Cargo.toml | 4 +++- packages/axelar-wasm-std-derive/tests/derive.rs | 2 +- packages/axelar-wasm-std/Cargo.toml | 4 ++-- packages/axelar-wasm-std/src/lib.rs | 3 +++ packages/router-api/Cargo.toml | 3 +-- packages/router-api/src/error.rs | 2 +- 26 files changed, 31 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bd99db29..8990712ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -795,6 +795,7 @@ name = "axelar-wasm-std" version = "1.0.0" dependencies = [ "alloy-primitives", + "axelar-wasm-std-derive", "bs58 0.5.1", "cosmwasm-schema", "cosmwasm-std", @@ -1584,7 +1585,6 @@ name = "coordinator" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", @@ -3110,7 +3110,6 @@ name = "gateway" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "client", "cosmwasm-schema", "cosmwasm-std", @@ -3939,7 +3938,6 @@ dependencies = [ "alloy-primitives", "alloy-sol-types", "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", "error-stack", @@ -4822,7 +4820,6 @@ name = "multisig" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-crypto", "cosmwasm-schema", "cosmwasm-std", @@ -4856,7 +4853,6 @@ version = "1.0.0" dependencies = [ "anyhow", "axelar-wasm-std", - "axelar-wasm-std-derive", "bcs", "coordinator", "cosmwasm-schema", @@ -5014,7 +5010,6 @@ name = "nexus-gateway" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", @@ -6389,7 +6384,6 @@ name = "rewards" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", @@ -6500,7 +6494,6 @@ name = "router" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", @@ -6526,7 +6519,6 @@ name = "router-api" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", @@ -7155,7 +7147,6 @@ name = "service-registry" version = "1.0.0" dependencies = [ "axelar-wasm-std", - "axelar-wasm-std-derive", "coordinator", "cosmwasm-schema", "cosmwasm-std", @@ -8860,7 +8851,6 @@ version = "1.0.0" dependencies = [ "alloy-primitives", "axelar-wasm-std", - "axelar-wasm-std-derive", "client", "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index ba948f33e..a653a2dd0 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -33,8 +33,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } diff --git a/contracts/coordinator/src/error.rs b/contracts/coordinator/src/error.rs index a9a986064..a60817fc5 100644 --- a/contracts/coordinator/src/error.rs +++ b/contracts/coordinator/src/error.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use cosmwasm_std::StdError; use cw2::VersionError; use thiserror::Error; diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index 06c1b86ef..a442943d0 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -35,8 +35,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } client = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index 782bce9d2..1b8712aa0 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, StdError, Storage}; use cw_storage_plus::{Item, Map}; diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 2d92f397a..98fe1fe1c 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -33,8 +33,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } bcs = "0.1.5" coordinator = { workspace = true } cosmwasm-schema = { workspace = true } diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index 6fac47f6b..4ed88fea3 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -1,5 +1,4 @@ -use axelar_wasm_std::nonempty; -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::{nonempty, IntoContractError}; use cosmwasm_std::StdError; use router_api::ChainName; use thiserror::Error; diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 753db7151..784604575 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -40,8 +40,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-crypto = "1.2.7" cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/contracts/multisig/src/error.rs b/contracts/multisig/src/error.rs index 5efa1786a..78c47cd56 100644 --- a/contracts/multisig/src/error.rs +++ b/contracts/multisig/src/error.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use cosmwasm_std::{OverflowError, StdError, Uint64}; use cw2::VersionError; use router_api::ChainName; diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index 94ef1aa43..ae172897c 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -13,8 +13,7 @@ name = "nexus-gateway-schema" path = "src/bin/schema.rs" [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } diff --git a/contracts/nexus-gateway/src/error.rs b/contracts/nexus-gateway/src/error.rs index 68f36e127..44d26d157 100644 --- a/contracts/nexus-gateway/src/error.rs +++ b/contracts/nexus-gateway/src/error.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use cosmwasm_std::HexBinary; use thiserror::Error; diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index 75e56964b..1db688d5e 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -33,8 +33,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } diff --git a/contracts/rewards/src/error.rs b/contracts/rewards/src/error.rs index 15a51ef38..169222898 100644 --- a/contracts/rewards/src/error.rs +++ b/contracts/rewards/src/error.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use cosmwasm_std::OverflowError; use thiserror::Error; diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 70bbe6d02..506e96210 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -33,8 +33,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index fd9541d43..8cc336b6d 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -33,8 +33,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } coordinator = { workspace = true, features = ["library"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/contracts/service-registry/src/error.rs b/contracts/service-registry/src/error.rs index ad86e6b44..0c45576d9 100644 --- a/contracts/service-registry/src/error.rs +++ b/contracts/service-registry/src/error.rs @@ -1,5 +1,4 @@ -use axelar_wasm_std::nonempty; -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::{nonempty, IntoContractError}; use cosmwasm_std::{OverflowError, StdError}; use thiserror::Error; diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index 6ed22889e..c43b428a7 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -33,8 +33,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } client = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/contracts/voting-verifier/src/error.rs b/contracts/voting-verifier/src/error.rs index f9995ca37..0945232f6 100644 --- a/contracts/voting-verifier/src/error.rs +++ b/contracts/voting-verifier/src/error.rs @@ -1,5 +1,4 @@ -use axelar_wasm_std::{nonempty, voting}; -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::{nonempty, voting, IntoContractError}; use cosmwasm_std::{OverflowError, StdError}; use router_api::ChainName; use service_registry; diff --git a/interchain-token-service/Cargo.toml b/interchain-token-service/Cargo.toml index ccfb56069..af554bc14 100644 --- a/interchain-token-service/Cargo.toml +++ b/interchain-token-service/Cargo.toml @@ -7,8 +7,7 @@ edition = "2021" [dependencies] alloy-primitives = { workspace = true } alloy-sol-types = { workspace = true } -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } error-stack = { workspace = true } diff --git a/interchain-token-service/src/error.rs b/interchain-token-service/src/error.rs index 5ae15cd1c..e7f8be5c5 100644 --- a/interchain-token-service/src/error.rs +++ b/interchain-token-service/src/error.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] diff --git a/packages/axelar-wasm-std-derive/Cargo.toml b/packages/axelar-wasm-std-derive/Cargo.toml index 6a6acc7b4..d6dcac8c2 100644 --- a/packages/axelar-wasm-std-derive/Cargo.toml +++ b/packages/axelar-wasm-std-derive/Cargo.toml @@ -9,12 +9,14 @@ edition = "2021" proc-macro = true [dependencies] -axelar-wasm-std = { workspace = true } error-stack = { workspace = true } quote = "1.0.33" report = { workspace = true } syn = "2.0.29" thiserror = { workspace = true } +[dev-dependencies] +axelar-wasm-std = { workspace = true } + [lints] workspace = true diff --git a/packages/axelar-wasm-std-derive/tests/derive.rs b/packages/axelar-wasm-std-derive/tests/derive.rs index 300d4403f..e5e17f8f6 100644 --- a/packages/axelar-wasm-std-derive/tests/derive.rs +++ b/packages/axelar-wasm-std-derive/tests/derive.rs @@ -1,5 +1,5 @@ use axelar_wasm_std::error::ContractError; -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use thiserror::Error; #[derive(Error, Debug, IntoContractError)] diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index 2e36aef62..7f82aa3d2 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -18,8 +18,7 @@ crate-type = ["rlib"] [features] # for more explicit tests, cargo test --features=backtraces backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] +derive = ["dep:axelar-wasm-std-derive"] [package.metadata.scripts] optimize = """docker run --rm -v "$(pwd)":/code \ @@ -30,6 +29,7 @@ optimize = """docker run --rm -v "$(pwd)":/code \ [dependencies] alloy-primitives = { workspace = true } +axelar-wasm-std-derive = { workspace = true, optional = true } bs58 = "0.5.1" cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 3de4988a8..8f6299a4f 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -19,3 +19,6 @@ pub mod threshold; pub mod utils; pub mod verification; pub mod voting; + +#[cfg(feature = "derive")] +pub use axelar_wasm_std_derive::*; diff --git a/packages/router-api/Cargo.toml b/packages/router-api/Cargo.toml index 25e1340bd..41a92c15d 100644 --- a/packages/router-api/Cargo.toml +++ b/packages/router-api/Cargo.toml @@ -6,8 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } +axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } diff --git a/packages/router-api/src/error.rs b/packages/router-api/src/error.rs index 0e04f37f8..4347cfacf 100644 --- a/packages/router-api/src/error.rs +++ b/packages/router-api/src/error.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std_derive::IntoContractError; +use axelar_wasm_std::IntoContractError; use cosmwasm_std::StdError; use thiserror::Error; From a0ee664a853b47f37c4a1226cf7c14c2e0029682 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Fri, 2 Aug 2024 16:25:04 -0400 Subject: [PATCH 139/168] refactor(service-registry): remove unused config from state file (#569) --- contracts/service-registry/src/state.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/contracts/service-registry/src/state.rs b/contracts/service-registry/src/state.rs index fdf54123f..974241b53 100644 --- a/contracts/service-registry/src/state.rs +++ b/contracts/service-registry/src/state.rs @@ -1,20 +1,12 @@ +use axelar_wasm_std::nonempty; +use axelar_wasm_std::snapshot::Participant; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Storage, Timestamp, Uint128}; -use cw_storage_plus::{Item, Map}; +use cw_storage_plus::Map; use router_api::ChainName; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -#[cw_serde] -pub struct Config { - pub governance: Addr, -} - -pub const CONFIG: Item = Item::new("config"); - -use axelar_wasm_std::nonempty; -use axelar_wasm_std::snapshot::Participant; - use crate::ContractError; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] From 0909360cfa8c1796b60d2f57b1c65ff25837e955 Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Wed, 7 Aug 2024 12:47:25 -0400 Subject: [PATCH 140/168] feat(ci): upload ampd releases to r2 (#571) --- .github/workflows/build-ampd-release.yaml | 25 ++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-ampd-release.yaml b/.github/workflows/build-ampd-release.yaml index bd5000733..d1de5e86c 100644 --- a/.github/workflows/build-ampd-release.yaml +++ b/.github/workflows/build-ampd-release.yaml @@ -14,11 +14,15 @@ jobs: name: Validate tag and extract semver outputs: semver: ${{ steps.extract_semver.outputs.semver }} + version: ${{ steps.extract_semver.outputs.version }} steps: - name: Extract semver from tag id: extract_semver run: | - echo "semver=$(echo ${{ github.event.inputs.tag }} | sed 's/ampd-//')" >> $GITHUB_OUTPUT + full_semver=$(echo ${{ github.event.inputs.tag }} | sed 's/ampd-//') + version_number=$(echo $full_semver | sed 's/^v//') + echo "semver=$full_semver" >> $GITHUB_OUTPUT + echo "version=$version_number" >> $GITHUB_OUTPUT - name: Validate tag env: @@ -176,6 +180,25 @@ jobs: run: | aws s3 cp ./ampdbin ${S3_PATH}/ --recursive + - name: Prepare source directory structure for r2 upload + id: prepare-r2-release + run: | + version="${{ needs.extract-semver.outputs.version }}" + mkdir -p "./${version}" + cp -R ./ampdbin/. "./${version}/" + echo "release-dir=./${version}" >> $GITHUB_OUTPUT + echo "r2-destination-dir=./releases/ampd/" >> $GITHUB_OUTPUT + + + - uses: ryand56/r2-upload-action@latest + with: + r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} + r2-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CF }} + r2-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CF }} + r2-bucket: ${{ secrets.R2_BUCKET }} + source-dir: ${{ steps.prepare-r2-release.outputs.release-dir }} + destination-dir: ${{ steps.prepare-r2-release.outputs.r2-destination-dir }} + release-docker: runs-on: ubuntu-22.04 needs: extract-semver From 66d73135095452d993d9a6e11ee4822e98c783fd Mon Sep 17 00:00:00 2001 From: Houmaan Chamani Date: Thu, 8 Aug 2024 12:33:23 -0400 Subject: [PATCH 141/168] fix(ci): auto trigger build action for new tags with PAT (#574) --- .github/actions/release/action.yaml | 18 ++++++++++++++++-- .../build-contracts-and-push-to-r2.yaml | 7 +++++++ .github/workflows/release.yaml | 4 +++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/actions/release/action.yaml b/.github/actions/release/action.yaml index 2796ba234..f18b10429 100644 --- a/.github/actions/release/action.yaml +++ b/.github/actions/release/action.yaml @@ -16,6 +16,9 @@ inputs: description: "minor pattern match string" change-path: description: "paths to observe for changes" + github_token: + description: "GitHub token for pushing changes" + required: true runs: using: "composite" @@ -156,9 +159,20 @@ runs: inputs.dry-run == 'false' && steps.semantic-version.outputs.changed == 'true' run: | - git config --global user.email "devops@axelar.network" - git config --global user.name "Axelar DevOps" + git config --global user.email "devops@interoplabs.io" + git config --global user.name "Interop Labs CI" cargo release -x \ --no-confirm \ + --no-push \ -p ${{ inputs.binary-to-release }} \ ${{ steps.semantic-version.outputs.version_type }} + + - name: Push changes of cargo release + if: + inputs.dry-run == 'false' && + steps.semantic-version.outputs.changed == 'true' + uses: ad-m/github-push-action@master + with: + github_token: ${{ inputs.github_token }} + branch: ${{ github.ref }} + tags: true diff --git a/.github/workflows/build-contracts-and-push-to-r2.yaml b/.github/workflows/build-contracts-and-push-to-r2.yaml index 09e890dfd..fb0e3f79c 100644 --- a/.github/workflows/build-contracts-and-push-to-r2.yaml +++ b/.github/workflows/build-contracts-and-push-to-r2.yaml @@ -4,6 +4,7 @@ on: push: branches: - main + create: tags: - '*-v[0-9]+.[0-9]+.[0-9]+' workflow_dispatch: @@ -56,6 +57,11 @@ jobs: is_release="true" crate_name="${BASH_REMATCH[1]}" crate_version="${BASH_REMATCH[2]}" + + if [[ $crate_name == "ampd" ]]; then + echo "Ampd release. Ignoring the wasm build and upload." + exit 1 + fi echo "Is release: $is_release" echo "Crate Name: $crate_name" @@ -90,6 +96,7 @@ jobs: path: axelar-amplifier submodules: recursive ref: ${{ steps.get-checkout-ref.outputs.ref }} + token: ${{ secrets.INTEROP_CI_ACTION_TOKEN }} - name: Import GPG key diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 941444712..cb59d5b44 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -28,9 +28,10 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 + token: ${{ secrets.INTEROP_CI_ACTION_TOKEN }} - name: Setup variables for sub-project to release id: setup-variables shell: bash @@ -68,3 +69,4 @@ jobs: major-pattern: ${{ steps.setup-variables.outputs.major-pattern }} minor-pattern: ${{ steps.setup-variables.outputs.minor-pattern }} change-path: ${{ steps.setup-variables.outputs.change-path }} + github_token: ${{ secrets.INTEROP_CI_ACTION_TOKEN }} From f81e26cb5a995d93915effe02e9cc0924f42cc60 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 8 Aug 2024 13:36:52 -0400 Subject: [PATCH 142/168] chore: use workspace rust edition in crates (#575) --- Cargo.toml | 1 + ampd/Cargo.toml | 2 +- contracts/coordinator/Cargo.toml | 2 +- contracts/gateway/Cargo.toml | 2 +- contracts/multisig-prover/Cargo.toml | 2 +- contracts/multisig/Cargo.toml | 2 +- contracts/nexus-gateway/Cargo.toml | 2 +- contracts/rewards/Cargo.toml | 2 +- contracts/router/Cargo.toml | 2 +- contracts/service-registry/Cargo.toml | 2 +- contracts/voting-verifier/Cargo.toml | 2 +- integration-tests/Cargo.toml | 2 +- interchain-token-service/Cargo.toml | 2 +- packages/axelar-wasm-std-derive/Cargo.toml | 2 +- packages/axelar-wasm-std/Cargo.toml | 2 +- packages/client/Cargo.toml | 2 +- packages/events-derive/Cargo.toml | 2 +- packages/events/Cargo.toml | 2 +- packages/evm-gateway/Cargo.toml | 2 +- packages/gateway-api/Cargo.toml | 2 +- packages/msgs-derive/Cargo.toml | 2 +- packages/report/Cargo.toml | 2 +- packages/router-api/Cargo.toml | 2 +- packages/signature-verifier-api/Cargo.toml | 2 +- 24 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 037a615e0..8327e3194 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "2" [workspace.package] rust-version = "1.78.0" # be sure there is an optimizer release supporting this version before updating. See https://github.com/CosmWasm/optimizer +edition = "2021" [workspace.dependencies] router = { version = "^1.0.0", path = "contracts/router" } diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index f8b633856..d70e1ef52 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -1,6 +1,6 @@ [package] -edition = "2021" name = "ampd" +edition = { workspace = true } version = "1.0.0" rust-version = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/contracts/coordinator/Cargo.toml b/contracts/coordinator/Cargo.toml index a653a2dd0..bac6a740f 100644 --- a/contracts/coordinator/Cargo.toml +++ b/contracts/coordinator/Cargo.toml @@ -2,7 +2,7 @@ name = "coordinator" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Amplifier info aggregation for external use, alongside contract management, instantiation and migration" exclude = [ diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index a442943d0..dce577e75 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -2,7 +2,7 @@ name = "gateway" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Gateway contract" exclude = [ diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 98fe1fe1c..bad6c9b62 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -2,7 +2,7 @@ name = "multisig-prover" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Multisig prover contract" exclude = [ diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 784604575..5f1d2f571 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -2,7 +2,7 @@ name = "multisig" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Multisig contract" exclude = [ diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index ae172897c..04ca59083 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -2,7 +2,7 @@ name = "nexus-gateway" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index 1db688d5e..a9248e38b 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -2,7 +2,7 @@ name = "rewards" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Validator rewards contract" exclude = [ diff --git a/contracts/router/Cargo.toml b/contracts/router/Cargo.toml index 506e96210..292820849 100644 --- a/contracts/router/Cargo.toml +++ b/contracts/router/Cargo.toml @@ -2,7 +2,7 @@ name = "router" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Router contract" exclude = [ diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index 8cc336b6d..08d40c09f 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -2,7 +2,7 @@ name = "service-registry" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Contract handling the service registrations" exclude = [ diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index c43b428a7..494ec3f18 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -2,7 +2,7 @@ name = "voting-verifier" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Voting verifier contract" exclude = [ diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 09ca8a18a..ad28b08a0 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -2,7 +2,7 @@ name = "integration-tests" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Amplifier Integration Tests" exclude = [ diff --git a/interchain-token-service/Cargo.toml b/interchain-token-service/Cargo.toml index af554bc14..738c27a49 100644 --- a/interchain-token-service/Cargo.toml +++ b/interchain-token-service/Cargo.toml @@ -2,7 +2,7 @@ name = "interchain-token-service" version = "0.1.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } [dependencies] alloy-primitives = { workspace = true } diff --git a/packages/axelar-wasm-std-derive/Cargo.toml b/packages/axelar-wasm-std-derive/Cargo.toml index d6dcac8c2..e3dee2952 100644 --- a/packages/axelar-wasm-std-derive/Cargo.toml +++ b/packages/axelar-wasm-std-derive/Cargo.toml @@ -2,7 +2,7 @@ name = "axelar-wasm-std-derive" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index 7f82aa3d2..f6d74fad5 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -2,7 +2,7 @@ name = "axelar-wasm-std" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } description = "Axelar cosmwasm standard library crate" exclude = [ diff --git a/packages/client/Cargo.toml b/packages/client/Cargo.toml index e00f7f6f3..cfefeeacb 100644 --- a/packages/client/Cargo.toml +++ b/packages/client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "client" version = "1.0.0" -edition = "2021" +edition = { workspace = true } rust-version = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/packages/events-derive/Cargo.toml b/packages/events-derive/Cargo.toml index a6e91c5bf..0d7fcb87e 100644 --- a/packages/events-derive/Cargo.toml +++ b/packages/events-derive/Cargo.toml @@ -2,7 +2,7 @@ name = "events-derive" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] diff --git a/packages/events/Cargo.toml b/packages/events/Cargo.toml index 5b354577e..1b4dd91c7 100644 --- a/packages/events/Cargo.toml +++ b/packages/events/Cargo.toml @@ -2,7 +2,7 @@ name = "events" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/packages/evm-gateway/Cargo.toml b/packages/evm-gateway/Cargo.toml index 7a1a48721..8aad6ea83 100644 --- a/packages/evm-gateway/Cargo.toml +++ b/packages/evm-gateway/Cargo.toml @@ -2,7 +2,7 @@ name = "evm-gateway" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/packages/gateway-api/Cargo.toml b/packages/gateway-api/Cargo.toml index 874db1ac5..f497011f1 100644 --- a/packages/gateway-api/Cargo.toml +++ b/packages/gateway-api/Cargo.toml @@ -2,7 +2,7 @@ name = "gateway-api" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/packages/msgs-derive/Cargo.toml b/packages/msgs-derive/Cargo.toml index 495c17ef6..fcc1171f6 100644 --- a/packages/msgs-derive/Cargo.toml +++ b/packages/msgs-derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "msgs-derive" version = "1.0.0" -edition = "2021" +edition = { workspace = true } rust-version = { workspace = true } [lib] diff --git a/packages/report/Cargo.toml b/packages/report/Cargo.toml index b491bd58b..8a1a94fbb 100644 --- a/packages/report/Cargo.toml +++ b/packages/report/Cargo.toml @@ -2,7 +2,7 @@ name = "report" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/packages/router-api/Cargo.toml b/packages/router-api/Cargo.toml index 41a92c15d..dc48843f0 100644 --- a/packages/router-api/Cargo.toml +++ b/packages/router-api/Cargo.toml @@ -2,7 +2,7 @@ name = "router-api" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/packages/signature-verifier-api/Cargo.toml b/packages/signature-verifier-api/Cargo.toml index 813633a23..61acd6e60 100644 --- a/packages/signature-verifier-api/Cargo.toml +++ b/packages/signature-verifier-api/Cargo.toml @@ -2,7 +2,7 @@ name = "signature-verifier-api" version = "1.0.0" rust-version = { workspace = true } -edition = "2021" +edition = { workspace = true } [dependencies] cosmwasm-schema = { workspace = true } From 8a3ffb33c2d30ed5b95fcdefcc85c2e90d696cf0 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 8 Aug 2024 16:09:58 -0400 Subject: [PATCH 143/168] feat(axelarnet-gateway): add axelarnet gateway (#570) --- Cargo.lock | 21 + Cargo.toml | 1 + .../axelarnet-gateway/.cargo/config.toml | 4 + contracts/axelarnet-gateway/Cargo.toml | 54 +++ contracts/axelarnet-gateway/src/bin/schema.rs | 10 + contracts/axelarnet-gateway/src/client.rs | 125 ++++++ contracts/axelarnet-gateway/src/contract.rs | 155 ++++++++ .../axelarnet-gateway/src/contract/execute.rs | 375 ++++++++++++++++++ contracts/axelarnet-gateway/src/events.rs | 37 ++ contracts/axelarnet-gateway/src/executable.rs | 88 ++++ contracts/axelarnet-gateway/src/lib.rs | 10 + contracts/axelarnet-gateway/src/msg.rs | 43 ++ contracts/axelarnet-gateway/src/state.rs | 339 ++++++++++++++++ contracts/gateway/src/state.rs | 2 + contracts/voting-verifier/src/client.rs | 13 +- packages/axelar-wasm-std/src/error.rs | 6 +- packages/axelar-wasm-std/src/lib.rs | 1 + .../src/msg_id/tx_hash_event_index.rs | 9 + packages/axelar-wasm-std/src/vec.rs | 13 + packages/router-api/src/client.rs | 13 +- 20 files changed, 1298 insertions(+), 21 deletions(-) create mode 100644 contracts/axelarnet-gateway/.cargo/config.toml create mode 100644 contracts/axelarnet-gateway/Cargo.toml create mode 100644 contracts/axelarnet-gateway/src/bin/schema.rs create mode 100644 contracts/axelarnet-gateway/src/client.rs create mode 100644 contracts/axelarnet-gateway/src/contract.rs create mode 100644 contracts/axelarnet-gateway/src/contract/execute.rs create mode 100644 contracts/axelarnet-gateway/src/events.rs create mode 100644 contracts/axelarnet-gateway/src/executable.rs create mode 100644 contracts/axelarnet-gateway/src/lib.rs create mode 100644 contracts/axelarnet-gateway/src/msg.rs create mode 100644 contracts/axelarnet-gateway/src/state.rs create mode 100644 packages/axelar-wasm-std/src/vec.rs diff --git a/Cargo.lock b/Cargo.lock index 8990712ee..b97aed73b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -832,6 +832,27 @@ dependencies = [ "thiserror", ] +[[package]] +name = "axelarnet-gateway" +version = "0.1.0" +dependencies = [ + "axelar-wasm-std", + "client", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "error-stack", + "msgs-derive", + "report", + "router-api", + "serde", + "serde_json", + "sha3", + "thiserror", +] + [[package]] name = "axum" version = "0.6.20" diff --git a/Cargo.toml b/Cargo.toml index 8327e3194..8c2fb420b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ alloy-sol-types = { version = "0.7.6", default-features = false, features = ["st strum = { version = "0.25", default-features = false, features = ["derive"] } interchain-token-service = { version = "^0.1.0", path = "interchain-token-service" } goldie = { version = "0.5" } +axelarnet-gateway = { version = "^0.1.0", path = "contracts/axelarnet-gateway" } [workspace.lints.clippy] arithmetic_side_effects = "deny" diff --git a/contracts/axelarnet-gateway/.cargo/config.toml b/contracts/axelarnet-gateway/.cargo/config.toml new file mode 100644 index 000000000..af5698e58 --- /dev/null +++ b/contracts/axelarnet-gateway/.cargo/config.toml @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" diff --git a/contracts/axelarnet-gateway/Cargo.toml b/contracts/axelarnet-gateway/Cargo.toml new file mode 100644 index 000000000..4c5499714 --- /dev/null +++ b/contracts/axelarnet-gateway/Cargo.toml @@ -0,0 +1,54 @@ +[package] +name = "axelarnet-gateway" +version = "0.1.0" +rust-version = { workspace = true } +edition = { workspace = true } +description = "The Axelarnet Gateway contract allows apps on the Axelar Network to send/receive cross-chain messages to/from other chains." + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +[lib] +crate-type = ["cdylib", "rlib"] + +[[bin]] +name = "axelarnet-gateway-schema" +path = "src/bin/schema.rs" + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[package.metadata.scripts] +optimize = """docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/optimizer:0.16.0 +""" + +[dependencies] +axelar-wasm-std = { workspace = true, features = ["derive"] } +client = { workspace = true } +cosmwasm-schema = { workspace = true } +cosmwasm-std = { workspace = true } +cw-storage-plus = { workspace = true } +cw2 = { workspace = true } +error-stack = { workspace = true } +msgs-derive = { workspace = true } +report = { workspace = true } +router-api = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sha3 = { workspace = true } +thiserror = { workspace = true } + +[dev-dependencies] +cw-multi-test = "0.15.1" + +[lints] +workspace = true diff --git a/contracts/axelarnet-gateway/src/bin/schema.rs b/contracts/axelarnet-gateway/src/bin/schema.rs new file mode 100644 index 000000000..5a060e62b --- /dev/null +++ b/contracts/axelarnet-gateway/src/bin/schema.rs @@ -0,0 +1,10 @@ +use axelarnet_gateway::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/axelarnet-gateway/src/client.rs b/contracts/axelarnet-gateway/src/client.rs new file mode 100644 index 000000000..558078971 --- /dev/null +++ b/contracts/axelarnet-gateway/src/client.rs @@ -0,0 +1,125 @@ +use axelar_wasm_std::vec::VecExt; +use cosmwasm_std::{HexBinary, WasmMsg}; +use router_api::{Address, ChainName, CrossChainId, Message}; + +use crate::msg::{ExecuteMsg, QueryMsg}; + +impl<'a> From> for Client<'a> { + fn from(client: client::Client<'a, ExecuteMsg, QueryMsg>) -> Self { + Client { client } + } +} + +pub struct Client<'a> { + client: client::Client<'a, ExecuteMsg, QueryMsg>, +} + +impl<'a> Client<'a> { + pub fn call_contract( + &self, + destination_chain: ChainName, + destination_address: Address, + payload: HexBinary, + ) -> WasmMsg { + self.client.execute(&ExecuteMsg::CallContract { + destination_chain, + destination_address, + payload, + }) + } + + pub fn execute(&self, cc_id: CrossChainId, payload: HexBinary) -> WasmMsg { + self.client.execute(&ExecuteMsg::Execute { cc_id, payload }) + } + + pub fn route_messages(&self, msgs: Vec) -> Option { + msgs.to_none_if_empty() + .map(|messages| self.client.execute(&ExecuteMsg::RouteMessages(messages))) + } +} + +#[cfg(test)] +mod test { + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier}; + use cosmwasm_std::{to_json_binary, Addr, DepsMut, QuerierWrapper}; + + use super::*; + use crate::contract::instantiate; + use crate::msg::InstantiateMsg; + + #[test] + fn call_contract() { + let (querier, _, addr) = setup(); + let client: Client = + client::Client::new(QuerierWrapper::new(&querier), addr.clone()).into(); + + let destination_chain: ChainName = "destination-chain".parse().unwrap(); + let destination_address: Address = "destination-address".parse().unwrap(); + let payload = HexBinary::from(vec![1, 2, 3]); + + let msg = client.call_contract( + destination_chain.clone(), + destination_address.clone(), + payload.clone(), + ); + + assert_eq!( + msg, + WasmMsg::Execute { + contract_addr: addr.to_string(), + msg: to_json_binary(&ExecuteMsg::CallContract { + destination_chain, + destination_address, + payload, + }) + .unwrap(), + funds: vec![], + } + ); + } + + #[test] + fn execute_message() { + let (querier, _, addr) = setup(); + let client: Client = + client::Client::new(QuerierWrapper::new(&querier), addr.clone()).into(); + + let payload = HexBinary::from(vec![1, 2, 3]); + let cc_id = CrossChainId::new("source-chain", "message-id").unwrap(); + + let msg = client.execute(cc_id.clone(), payload.clone()); + + assert_eq!( + msg, + WasmMsg::Execute { + contract_addr: addr.to_string(), + msg: to_json_binary(&ExecuteMsg::Execute { cc_id, payload }).unwrap(), + funds: vec![], + } + ); + } + + fn setup() -> (MockQuerier, InstantiateMsg, Addr) { + let addr = "axelarnet-gateway"; + let mut deps = mock_dependencies(); + let instantiate_msg = instantiate_contract(deps.as_mut()); + + let querier = MockQuerier::default(); + + (querier, instantiate_msg, Addr::unchecked(addr)) + } + + fn instantiate_contract(deps: DepsMut) -> InstantiateMsg { + let env = mock_env(); + let info = mock_info("deployer", &[]); + + let msg = InstantiateMsg { + chain_name: "source-chain".parse().unwrap(), + router_address: "router".to_string(), + }; + + instantiate(deps, env, info, msg.clone()).unwrap(); + + msg + } +} diff --git a/contracts/axelarnet-gateway/src/contract.rs b/contracts/axelarnet-gateway/src/contract.rs new file mode 100644 index 000000000..aef268c66 --- /dev/null +++ b/contracts/axelarnet-gateway/src/contract.rs @@ -0,0 +1,155 @@ +use axelar_wasm_std::FnExt; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; +use error_stack::ResultExt; +use router_api::client::Router; +use router_api::CrossChainId; + +use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use crate::state::{self, Config}; + +mod execute; + +const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("contract config is missing")] + ConfigMissing, + #[error("invalid store access")] + InvalidStoreAccess, + #[error("failed to serialize the response")] + SerializeResponse, + #[error("failed to serialize wasm message")] + SerializeWasmMsg, + #[error("invalid address {0}")] + InvalidAddress(String), + #[error("invalid message id")] + InvalidMessageId, + #[error("failed to save outgoing message")] + SaveOutgoingMessage, + #[error("message with ID {0} not found")] + MessageNotFound(CrossChainId), + #[error("message with ID {0} is different")] + MessageMismatch(CrossChainId), + #[error("message with ID {0} not in approved status")] + MessageNotApproved(CrossChainId), + #[error("failed to set message with ID {0} as executed")] + SetMessageStatusExecutedFailed(CrossChainId), + #[error("payload hash doesn't match message")] + PayloadHashMismatch, + #[error("failed to route messages")] + RoutingFailed, +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate( + deps: DepsMut, + _env: Env, + _msg: Empty, +) -> Result { + // any version checks should be done before here + + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + let router = deps + .api + .addr_validate(&msg.router_address) + .change_context(Error::InvalidAddress(msg.router_address.clone()))?; + + let config = Config { + chain_name: msg.chain_name, + router, + }; + + state::save_config(deps.storage, &config).change_context(Error::InvalidStoreAccess)?; + + Ok(Response::new()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let msg = msg.ensure_permissions(deps.storage, &info.sender)?; + + let config = state::load_config(deps.storage).change_context(Error::ConfigMissing)?; + + let router = Router { + address: config.router, + }; + let chain_name = config.chain_name; + + match msg { + ExecuteMsg::CallContract { + destination_chain, + destination_address, + payload, + } => execute::call_contract( + deps.storage, + env.block.height, + &router, + chain_name, + info.sender, + destination_chain, + destination_address, + payload, + ), + ExecuteMsg::RouteMessages(msgs) => { + if info.sender == router.address { + execute::receive_messages(deps.storage, chain_name, msgs) + } else { + // Messages initiated via call contract can be routed again + execute::send_messages(deps.storage, &router, msgs) + } + } + ExecuteMsg::Execute { cc_id, payload } => { + execute::execute(deps.storage, deps.api, deps.querier, cc_id, payload) + } + }? + .then(Ok) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query( + _deps: Deps, + _env: Env, + _msg: QueryMsg, +) -> Result { + todo!() +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + + use super::*; + + #[test] + fn migrate_sets_contract_version() { + let mut deps = mock_dependencies(); + + migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); + + let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); + assert_eq!(contract_version.contract, "axelarnet-gateway"); + assert_eq!(contract_version.version, CONTRACT_VERSION); + } +} diff --git a/contracts/axelarnet-gateway/src/contract/execute.rs b/contracts/axelarnet-gateway/src/contract/execute.rs new file mode 100644 index 000000000..6f442ce28 --- /dev/null +++ b/contracts/axelarnet-gateway/src/contract/execute.rs @@ -0,0 +1,375 @@ +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; +use cosmwasm_std::{ + Addr, Api, Event, HexBinary, QuerierWrapper, Response, Storage, Uint256, WasmMsg, +}; +use error_stack::{report, Result, ResultExt}; +use router_api::client::Router; +use router_api::{Address, ChainName, CrossChainId, Message}; +use sha3::{Digest, Keccak256}; + +use crate::contract::Error; +use crate::events::AxelarnetGatewayEvent; +use crate::executable::AxelarExecutableClient; +use crate::state::{self}; + +#[allow(clippy::too_many_arguments)] +pub(crate) fn call_contract( + store: &mut dyn Storage, + block_height: u64, + router: &Router, + chain_name: ChainName, + sender: Addr, + destination_chain: ChainName, + destination_address: Address, + payload: HexBinary, +) -> Result { + let counter = state::increment_msg_counter(store).change_context(Error::InvalidStoreAccess)?; + + // TODO: Retrieve the actual tx hash from core, since cosmwasm doesn't provide it. Use the block height as the placeholder in the meantime. + let message_id = HexTxHashAndEventIndex { + tx_hash: Uint256::from(block_height).to_be_bytes(), + event_index: counter, + } + .into(); + + let cc_id = CrossChainId { + source_chain: chain_name.into(), + message_id, + }; + + let payload_hash = Keccak256::digest(payload.as_slice()).into(); + + let msg = Message { + cc_id: cc_id.clone(), + source_address: Address::try_from(sender.clone().into_string()) + .expect("failed to convert sender address"), + destination_chain, + destination_address, + payload_hash, + }; + + state::save_sent_msg(store, cc_id, &msg).change_context(Error::InvalidStoreAccess)?; + + let (wasm_msg, events) = route(router, vec![msg.clone()])?; + + Ok(Response::new() + .add_message(wasm_msg) + .add_event(AxelarnetGatewayEvent::ContractCalled { msg, payload }.into()) + .add_events(events)) +} + +// Because the messages came from the router, we can assume they are already verified +pub(crate) fn receive_messages( + store: &mut dyn Storage, + chain_name: ChainName, + msgs: Vec, +) -> Result { + for msg in msgs.iter() { + if chain_name != msg.destination_chain { + panic!("message destination chain should match chain name in the gateway") + } + + state::save_received_msg(store, msg.cc_id.clone(), msg.clone()) + .change_context(Error::SaveOutgoingMessage)?; + } + + Ok(Response::new().add_events( + msgs.into_iter() + .map(|msg| AxelarnetGatewayEvent::Routing { msg }.into()), + )) +} + +pub(crate) fn send_messages( + store: &mut dyn Storage, + router: &Router, + msgs: Vec, +) -> Result { + for msg in msgs.iter() { + let stored_msg = state::may_load_sent_msg(store, &msg.cc_id) + .change_context(Error::InvalidStoreAccess)?; + + match stored_msg { + Some(message) if msg != &message => { + Err(report!(Error::MessageMismatch(msg.cc_id.clone()))) + } + Some(_) => Ok(()), + None => Err(report!(Error::MessageNotFound(msg.cc_id.clone()))), + }? + } + + let (wasm_msg, events) = route(router, msgs)?; + + Ok(Response::new().add_message(wasm_msg).add_events(events)) +} + +fn route( + router: &Router, + msgs: Vec, +) -> Result<(WasmMsg, impl IntoIterator), Error> { + Ok(( + router.route(msgs.clone()).ok_or(Error::RoutingFailed)?, + msgs.into_iter() + .map(|msg| AxelarnetGatewayEvent::Routing { msg }.into()), + )) +} + +pub(crate) fn execute( + store: &mut dyn Storage, + api: &dyn Api, + querier: QuerierWrapper, + cc_id: CrossChainId, + payload: HexBinary, +) -> Result { + let msg = state::set_msg_as_executed(store, cc_id.clone()) + .change_context(Error::SetMessageStatusExecutedFailed(cc_id))?; + + let payload_hash: [u8; 32] = Keccak256::digest(payload.as_slice()).into(); + if payload_hash != msg.payload_hash { + return Err(report!(Error::PayloadHashMismatch)); + } + + let destination_contract = api + .addr_validate(&msg.destination_address) + .change_context(Error::InvalidAddress(msg.destination_address.to_string()))?; + + let executable: AxelarExecutableClient = + client::Client::new(querier, destination_contract).into(); + + // Call the destination contract + // Apps are required to expose AxelarExecutableMsg::Execute interface + Ok(Response::new() + .add_message(executable.execute(msg.cc_id.clone(), msg.source_address.clone(), payload)) + .add_event(AxelarnetGatewayEvent::MessageExecuted { msg }.into())) +} + +#[cfg(test)] +mod tests { + use axelar_wasm_std::err_contains; + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, + }; + use cosmwasm_std::{Addr, CosmosMsg, Empty, Env, MessageInfo, OwnedDeps}; + use router_api::{ChainName, CrossChainId, Message}; + + use super::*; + use crate::contract::{execute, instantiate}; + use crate::msg::{ExecuteMsg, InstantiateMsg}; + use crate::state::{self, MessageStatus}; + + const CHAIN: &str = "chain"; + const SOURCE_CHAIN: &str = "source-chain"; + const ROUTER: &str = "router"; + const PAYLOAD: [u8; 3] = [1, 2, 3]; + const SENDER: &str = "sender"; + + fn setup() -> ( + OwnedDeps, + Env, + MessageInfo, + ) { + let mut deps = mock_dependencies(); + let env = mock_env(); + let info = mock_info(SENDER, &[]); + + let chain_name: ChainName = CHAIN.parse().unwrap(); + let router = Addr::unchecked(ROUTER); + + let msg = InstantiateMsg { + chain_name: chain_name.clone(), + router_address: router.to_string(), + }; + + let _res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + (deps, env, info) + } + + fn dummy_message() -> Message { + Message { + cc_id: CrossChainId::new(SOURCE_CHAIN, "message-id").unwrap(), + source_address: "source-address".parse().unwrap(), + destination_chain: CHAIN.parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: Keccak256::digest(PAYLOAD).into(), + } + } + + #[test] + fn call_contract_and_send_message() { + let (mut deps, env, info) = setup(); + + let expected_message_id = HexTxHashAndEventIndex { + tx_hash: Uint256::from(env.block.height).to_be_bytes(), + event_index: 1, + }; + let expected_cc_id = CrossChainId::new(CHAIN, expected_message_id).unwrap(); + let message = Message { + cc_id: expected_cc_id.clone(), + source_address: info.sender.clone().into_string().parse().unwrap(), + destination_chain: "destination-chain".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: Keccak256::digest(PAYLOAD).into(), + }; + + let msg = ExecuteMsg::CallContract { + destination_chain: message.destination_chain.clone(), + destination_address: message.destination_address.clone(), + payload: PAYLOAD.into(), + }; + + let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + let sent_message = state::may_load_sent_msg(deps.as_mut().storage, &expected_cc_id) + .unwrap() + .unwrap(); + assert_eq!(sent_message, message); + + let router: Router = Router { + address: Addr::unchecked(ROUTER), + }; + assert_eq!(res.messages.len(), 1); + assert_eq!( + res.messages[0].msg, + CosmosMsg::Wasm(router.route(vec![message.clone()]).unwrap()) + ); + + // Re-route the message again + let msg = ExecuteMsg::RouteMessages(vec![message.clone()]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!(res.messages.len(), 1); + assert_eq!( + res.messages[0].msg, + CosmosMsg::Wasm(router.route(vec![message]).unwrap()) + ); + } + + #[test] + fn route_messages_from_router() { + let (mut deps, env, _) = setup(); + + let message = dummy_message(); + let msg = ExecuteMsg::RouteMessages(vec![message.clone()]); + + // Execute RouteMessages as if it's coming from the router + let info = mock_info(ROUTER, &[]); + execute(deps.as_mut(), env, info, msg).unwrap(); + + // Check that the message was saved as received + let received_message = state::may_load_received_msg(deps.as_mut().storage, &message.cc_id) + .unwrap() + .unwrap(); + assert_eq!(received_message.msg, message); + assert!(matches!(received_message.status, MessageStatus::Approved)); + } + + #[test] + fn execute_message() { + let (mut deps, env, info) = setup(); + + let message = dummy_message(); + let cc_id = message.cc_id.clone(); + + // Save the message as received + state::save_received_msg(deps.as_mut().storage, cc_id.clone(), message).unwrap(); + + let msg = ExecuteMsg::Execute { + cc_id: cc_id.clone(), + payload: PAYLOAD.into(), + }; + + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + // Check that a message was sent to the destination contract + assert_eq!(res.messages.len(), 1); + + // Check that the message status was updated to Executed + let executed_message = state::may_load_received_msg(deps.as_mut().storage, &cc_id) + .unwrap() + .unwrap(); + assert!(matches!(executed_message.status, MessageStatus::Executed)); + } + + #[test] + fn execute_not_found() { + let (mut deps, env, info) = setup(); + + let cc_id = CrossChainId::new(SOURCE_CHAIN, "message-id").unwrap(); + let msg = ExecuteMsg::Execute { + cc_id: cc_id.clone(), + payload: PAYLOAD.into(), + }; + + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert!(err_contains!( + err.report, + state::Error, + state::Error::MessageNotApproved(..) + )); + assert!(err_contains!( + err.report, + Error, + Error::SetMessageStatusExecutedFailed(..) + )); + } + + #[test] + fn execute_already_executed() { + let (mut deps, env, info) = setup(); + + let message = dummy_message(); + let cc_id = message.cc_id.clone(); + + // Save the message as already executed + state::save_received_msg(deps.as_mut().storage, cc_id.clone(), message).unwrap(); + state::set_msg_as_executed(deps.as_mut().storage, cc_id.clone()).unwrap(); + + let msg = ExecuteMsg::Execute { + cc_id, + payload: PAYLOAD.into(), + }; + + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert!(err_contains!( + err.report, + state::Error, + state::Error::MessageAlreadyExecuted(..) + )); + assert!(err_contains!( + err.report, + Error, + Error::SetMessageStatusExecutedFailed(..) + )); + } + + #[test] + fn execute_payload_mismatch() { + let (mut deps, env, info) = setup(); + + let message = dummy_message(); + let cc_id = message.cc_id.clone(); + + state::save_received_msg(deps.as_mut().storage, cc_id.clone(), message).unwrap(); + + let msg = ExecuteMsg::Execute { + cc_id, + payload: [4, 5, 6].into(), + }; + + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert!(err_contains!(err.report, Error, Error::PayloadHashMismatch)); + } + + #[test] + #[should_panic(expected = "should match chain name")] + fn receive_messages_wrong_chain() { + let (mut deps, _, _) = setup(); + + let mut message = dummy_message(); + message.destination_chain = "wrong-chain".parse().unwrap(); + + let msg = ExecuteMsg::RouteMessages(vec![message]); + let info = mock_info(ROUTER, &[]); + + // This should panic because the destination chain doesn't match the gateway's chain name + execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + } +} diff --git a/contracts/axelarnet-gateway/src/events.rs b/contracts/axelarnet-gateway/src/events.rs new file mode 100644 index 000000000..c62479999 --- /dev/null +++ b/contracts/axelarnet-gateway/src/events.rs @@ -0,0 +1,37 @@ +use cosmwasm_std::{Attribute, Event, HexBinary}; +use router_api::Message; + +pub enum AxelarnetGatewayEvent { + ContractCalled { + msg: Message, + payload: HexBinary, + }, + /// Uses the same event name as `GatewayEvent` for consistency + Routing { + msg: Message, + }, + MessageExecuted { + msg: Message, + }, +} + +impl From for Event { + fn from(other: AxelarnetGatewayEvent) -> Self { + match other { + AxelarnetGatewayEvent::ContractCalled { msg, payload } => { + make_message_event("contract_called", msg) + .add_attributes(vec![("payload", payload.to_string())]) + } + AxelarnetGatewayEvent::Routing { msg } => make_message_event("routing", msg), + AxelarnetGatewayEvent::MessageExecuted { msg } => { + make_message_event("message_executed", msg) + } + } + } +} + +fn make_message_event(event_name: &str, msg: Message) -> Event { + let attrs: Vec = msg.into(); + + Event::new(event_name).add_attributes(attrs) +} diff --git a/contracts/axelarnet-gateway/src/executable.rs b/contracts/axelarnet-gateway/src/executable.rs new file mode 100644 index 000000000..00148a813 --- /dev/null +++ b/contracts/axelarnet-gateway/src/executable.rs @@ -0,0 +1,88 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{HexBinary, WasmMsg}; +use router_api::{Address, CrossChainId}; + +/// `AxelarExecutableMsg` is a struct containing the args used by the axelarnet gateway to execute a destination contract on Axelar. +/// Each App needs to expose a `ExecuteMsg::Execute(AxelarExecutableMsg)` variant that only the gateway is allowed to call. +#[cw_serde] +pub struct AxelarExecutableMsg { + pub cc_id: CrossChainId, + pub source_address: Address, + pub payload: HexBinary, +} + +/// Crate-specific `ExecuteMsg` type wraps the `AxelarExecutableMsg` for the AxelarExecutable client. +#[cw_serde] +pub(crate) enum AxelarExecutableExecuteMsg { + /// Execute the message at the destination contract with the corresponding payload. + Execute(AxelarExecutableMsg), +} + +impl<'a> From> for AxelarExecutableClient<'a> { + fn from(client: client::Client<'a, AxelarExecutableExecuteMsg, ()>) -> Self { + AxelarExecutableClient { client } + } +} + +pub struct AxelarExecutableClient<'a> { + client: client::Client<'a, AxelarExecutableExecuteMsg, ()>, +} + +impl<'a> AxelarExecutableClient<'a> { + pub fn execute( + &self, + cc_id: CrossChainId, + source_address: Address, + payload: HexBinary, + ) -> WasmMsg { + self.client + .execute(&AxelarExecutableExecuteMsg::Execute(AxelarExecutableMsg { + cc_id, + source_address, + payload, + })) + } +} + +#[cfg(test)] +mod test { + use cosmwasm_std::testing::MockQuerier; + use cosmwasm_std::{to_json_binary, Addr, QuerierWrapper}; + + use super::*; + + #[test] + fn execute_message() { + let (querier, addr) = setup(); + let client: AxelarExecutableClient = + client::Client::new(QuerierWrapper::new(&querier), addr.clone()).into(); + + let cc_id = CrossChainId::new("source-chain", "message-id").unwrap(); + let source_address: Address = "source-address".parse().unwrap(); + let payload = HexBinary::from(vec![1, 2, 3]); + + let msg = client.execute(cc_id.clone(), source_address.clone(), payload.clone()); + + assert_eq!( + msg, + WasmMsg::Execute { + contract_addr: addr.to_string(), + msg: to_json_binary(&AxelarExecutableExecuteMsg::Execute(AxelarExecutableMsg { + cc_id, + source_address, + payload, + })) + .unwrap(), + funds: vec![], + } + ); + } + + fn setup() -> (MockQuerier, Addr) { + let addr = Addr::unchecked("axelar-executable"); + + let querier = MockQuerier::default(); + + (querier, addr) + } +} diff --git a/contracts/axelarnet-gateway/src/lib.rs b/contracts/axelarnet-gateway/src/lib.rs new file mode 100644 index 000000000..c7af4a4da --- /dev/null +++ b/contracts/axelarnet-gateway/src/lib.rs @@ -0,0 +1,10 @@ +pub mod contract; +pub mod events; +pub mod msg; +pub mod state; + +mod client; +pub use client::Client; + +mod executable; +pub use executable::AxelarExecutableMsg; diff --git a/contracts/axelarnet-gateway/src/msg.rs b/contracts/axelarnet-gateway/src/msg.rs new file mode 100644 index 000000000..8c407fd63 --- /dev/null +++ b/contracts/axelarnet-gateway/src/msg.rs @@ -0,0 +1,43 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::HexBinary; +use msgs_derive::EnsurePermissions; +use router_api::{Address, ChainName, CrossChainId, Message}; + +#[cw_serde] +pub struct InstantiateMsg { + /// The chain name for this gateway. + pub chain_name: ChainName, + /// Address of the router contract on axelar. + pub router_address: String, +} + +#[cw_serde] +#[derive(EnsurePermissions)] +pub enum ExecuteMsg { + /// Initiate a cross-chain contract call from Axelarnet to another chain. + /// The message will be routed to the destination chain's gateway via the router. + #[permission(Any)] + CallContract { + destination_chain: ChainName, + destination_address: Address, + payload: HexBinary, + }, + + /// Forward the given messages to the next step of the routing layer. + /// Messages initiated via `CallContract` can be forwarded again to the router. + /// If the messages are coming from the router, then they are marked ready for execution. + #[permission(Any)] + RouteMessages(Vec), + + /// Execute the message at the destination contract with the corresponding payload. + /// The message is marked as executed and thus can't be executed again. + #[permission(Any)] + Execute { + cc_id: CrossChainId, + payload: HexBinary, + }, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg {} diff --git a/contracts/axelarnet-gateway/src/state.rs b/contracts/axelarnet-gateway/src/state.rs new file mode 100644 index 000000000..a4f947346 --- /dev/null +++ b/contracts/axelarnet-gateway/src/state.rs @@ -0,0 +1,339 @@ +use axelar_wasm_std::counter::Counter; +use axelar_wasm_std::{FnExt, IntoContractError}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, StdError, Storage}; +use cw_storage_plus::{Item, Map}; +use router_api::{ChainName, CrossChainId, Message}; + +#[cw_serde] +pub(crate) struct Config { + pub chain_name: ChainName, + pub router: Addr, +} + +#[cw_serde] +pub(crate) enum MessageStatus { + Approved, + Executed, +} + +#[cw_serde] +pub(crate) struct MessageWithStatus { + pub msg: Message, + pub status: MessageStatus, +} + +const CONFIG_NAME: &str = "config"; +const CONFIG: Item = Item::new(CONFIG_NAME); + +const SENT_MESSAGE_COUNTER_NAME: &str = "sent_message_counter"; +const SENT_MESSAGE_COUNTER: Counter = Counter::new(SENT_MESSAGE_COUNTER_NAME); + +const SENT_MESSAGES_NAME: &str = "sent_messages"; +const SENT_MESSAGES: Map = Map::new(SENT_MESSAGES_NAME); + +const RECEIVED_MESSAGES_NAME: &str = "received_messages"; +const RECEIVED_MESSAGES: Map = Map::new(RECEIVED_MESSAGES_NAME); + +#[derive(thiserror::Error, Debug, PartialEq, IntoContractError)] +pub enum Error { + #[error(transparent)] + Std(#[from] StdError), + #[error("gateway got into an invalid state, its config is missing")] + MissingConfig, + #[error("message with ID {0} mismatches with the stored one")] + MessageMismatch(CrossChainId), + #[error("message with ID {0} not found")] + MessageNotFound(CrossChainId), + #[error("message with ID {0} not approved")] + MessageNotApproved(CrossChainId), + #[error("message with ID {0} already executed")] + MessageAlreadyExecuted(CrossChainId), + #[error("sent message with ID {0} already exists")] + MessageAlreadyExists(CrossChainId), +} + +pub(crate) fn save_config(storage: &mut dyn Storage, value: &Config) -> Result<(), Error> { + CONFIG.save(storage, value).map_err(Error::from) +} + +pub(crate) fn load_config(storage: &dyn Storage) -> Result { + CONFIG + .may_load(storage) + .map_err(Error::from)? + .ok_or(Error::MissingConfig) +} + +pub(crate) fn save_sent_msg( + storage: &mut dyn Storage, + key: CrossChainId, + msg: &Message, +) -> Result<(), Error> { + match SENT_MESSAGES.may_load(storage, key.clone())? { + Some(_) => Err(Error::MessageAlreadyExists(key)), + None => SENT_MESSAGES.save(storage, key, msg).map_err(Error::from), + } +} + +pub(crate) fn may_load_sent_msg( + storage: &dyn Storage, + id: &CrossChainId, +) -> Result, Error> { + SENT_MESSAGES + .may_load(storage, id.clone()) + .map_err(Error::from) +} + +#[cfg(test)] +pub(crate) fn may_load_received_msg( + storage: &dyn Storage, + cc_id: &CrossChainId, +) -> Result, Error> { + RECEIVED_MESSAGES + .may_load(storage, cc_id.clone()) + .map_err(Error::from) +} + +pub(crate) fn save_received_msg( + storage: &mut dyn Storage, + cc_id: CrossChainId, + msg: Message, +) -> Result<(), Error> { + let existing = RECEIVED_MESSAGES + .may_load(storage, cc_id.clone()) + .map_err(Error::from)?; + + match existing { + Some(MessageWithStatus { + msg: existing_msg, .. + }) if msg != existing_msg => Err(Error::MessageMismatch(msg.cc_id.clone())), + Some(_) => Ok(()), // new message is identical, no need to store it + None => RECEIVED_MESSAGES + .save( + storage, + cc_id, + &MessageWithStatus { + msg, + status: MessageStatus::Approved, + }, + ) + .map_err(Error::from)? + .then(Ok), + } +} + +/// Update the status of a message to executed if it is in approved status, error otherwise. +pub(crate) fn set_msg_as_executed( + storage: &mut dyn Storage, + cc_id: CrossChainId, +) -> Result { + let existing = RECEIVED_MESSAGES + .may_load(storage, cc_id.clone()) + .map_err(Error::from)?; + + match existing { + Some(MessageWithStatus { + msg, + status: MessageStatus::Approved, + }) => { + RECEIVED_MESSAGES + .save( + storage, + cc_id, + &MessageWithStatus { + msg: msg.clone(), + status: MessageStatus::Executed, + }, + ) + .map_err(Error::from)?; + + Ok(msg) + } + Some(MessageWithStatus { + status: MessageStatus::Executed, + .. + }) => Err(Error::MessageAlreadyExecuted(cc_id)), + _ => Err(Error::MessageNotApproved(cc_id)), + } +} + +pub(crate) fn increment_msg_counter(storage: &mut dyn Storage) -> Result { + SENT_MESSAGE_COUNTER.incr(storage).map_err(Error::from) +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::Addr; + use router_api::{CrossChainId, Message}; + + use super::*; + + fn create_test_message() -> Message { + Message { + cc_id: CrossChainId::new("source-chain", "message-id").unwrap(), + source_address: "source-address".parse().unwrap(), + destination_chain: "destination-chain".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: [1; 32], + } + } + + #[test] + fn config_storage() { + let mut deps = mock_dependencies(); + + let config = Config { + chain_name: "test-chain".parse().unwrap(), + router: Addr::unchecked("router-address"), + }; + + // Test saving config + super::save_config(deps.as_mut().storage, &config).unwrap(); + + // Test loading config + let loaded_config = super::load_config(deps.as_ref().storage).unwrap(); + assert_eq!(config, loaded_config); + + // Test loading non-existent config + CONFIG.remove(deps.as_mut().storage); + let result = super::load_config(deps.as_ref().storage); + assert_eq!(result, Err(Error::MissingConfig)); + } + + #[test] + fn sent_message_storage() { + let mut deps = mock_dependencies(); + let message = create_test_message(); + + // Test saving sent message + super::save_sent_msg(deps.as_mut().storage, message.cc_id.clone(), &message).unwrap(); + + // Test loading sent message + let loaded_message = + super::may_load_sent_msg(deps.as_ref().storage, &message.cc_id).unwrap(); + assert_eq!(Some(message.clone()), loaded_message); + + // Test loading non-existent message + let non_existent_id = CrossChainId::new("non-existent", "id").unwrap(); + assert_eq!( + None, + super::may_load_sent_msg(deps.as_ref().storage, &non_existent_id).unwrap() + ); + + // Test saving duplicate message + let result = super::save_sent_msg(deps.as_mut().storage, message.cc_id.clone(), &message); + assert_eq!(result, Err(Error::MessageAlreadyExists(message.cc_id))); + } + + #[test] + fn received_message_storage() { + let mut deps = mock_dependencies(); + let message = create_test_message(); + + // Test saving received message + super::save_received_msg( + deps.as_mut().storage, + message.cc_id.clone(), + message.clone(), + ) + .unwrap(); + + // Test loading received message + let loaded_message = + super::may_load_received_msg(deps.as_ref().storage, &message.cc_id).unwrap(); + assert_eq!( + Some(MessageWithStatus { + msg: message.clone(), + status: MessageStatus::Approved + }), + loaded_message + ); + + // Test loading non-existent message + let non_existent_id = CrossChainId::new("non-existent", "id").unwrap(); + assert_eq!( + None, + super::may_load_received_msg(deps.as_ref().storage, &non_existent_id).unwrap() + ); + + // Test saving duplicate message (should not error, but also not change the stored message) + super::save_received_msg( + deps.as_mut().storage, + message.cc_id.clone(), + message.clone(), + ) + .unwrap(); + let loaded_message = + super::may_load_received_msg(deps.as_ref().storage, &message.cc_id).unwrap(); + assert_eq!( + Some(MessageWithStatus { + msg: message.clone(), + status: MessageStatus::Approved + }), + loaded_message + ); + + // Test saving mismatched message + let mismatched_message = Message { + cc_id: message.cc_id.clone(), + source_address: "different-address".parse().unwrap(), + ..message.clone() + }; + let result = super::save_received_msg( + deps.as_mut().storage, + message.cc_id.clone(), + mismatched_message, + ); + assert_eq!(result, Err(Error::MessageMismatch(message.cc_id))); + } + + #[test] + fn set_msg_as_executed() { + let mut deps = mock_dependencies(); + let message = create_test_message(); + + // Save a received message + super::save_received_msg( + deps.as_mut().storage, + message.cc_id.clone(), + message.clone(), + ) + .unwrap(); + + // Test setting message as executed + let executed_message = + super::set_msg_as_executed(deps.as_mut().storage, message.cc_id.clone()).unwrap(); + assert_eq!(message, executed_message); + + // Verify the message status is now Executed + let loaded_message = + super::may_load_received_msg(deps.as_ref().storage, &message.cc_id).unwrap(); + assert_eq!( + Some(MessageWithStatus { + msg: message.clone(), + status: MessageStatus::Executed + }), + loaded_message + ); + + // Test setting an already executed message + let result = super::set_msg_as_executed(deps.as_mut().storage, message.cc_id.clone()); + assert_eq!(result, Err(Error::MessageAlreadyExecuted(message.cc_id))); + + // Test setting a non-existent message + let non_existent_id = CrossChainId::new("non-existent", "id").unwrap(); + let result = super::set_msg_as_executed(deps.as_mut().storage, non_existent_id.clone()); + assert_eq!(result, Err(Error::MessageNotApproved(non_existent_id))); + } + + #[test] + fn increment_msg_counter() { + let mut deps = mock_dependencies(); + + for i in 1..=3 { + let count = super::increment_msg_counter(deps.as_mut().storage).unwrap(); + assert_eq!(i, count); + } + } +} diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index 1b8712aa0..445eec117 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -24,6 +24,7 @@ pub enum Error { #[error("message with ID {0} not found")] MessageNotFound(CrossChainId), } + pub(crate) fn load_config(storage: &dyn Storage) -> Result { CONFIG .may_load(storage) @@ -53,6 +54,7 @@ pub(crate) fn save_outgoing_message( let existing = OUTGOING_MESSAGES .may_load(storage, cc_id) .map_err(Error::from)?; + match existing { Some(existing) if msg.hash() != existing.hash() => { Err(Error::MessageMismatch(msg.cc_id.clone())) diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index f0c107a01..1414e7097 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::vec::VecExt; use axelar_wasm_std::voting::{PollId, Vote}; use axelar_wasm_std::{nonempty, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{Addr, WasmMsg}; @@ -27,7 +28,8 @@ pub struct Client<'a> { impl<'a> Client<'a> { pub fn verify_messages(&self, messages: Vec) -> Option { - ignore_empty(messages) + messages + .to_none_if_empty() .map(|messages| self.client.execute(&ExecuteMsg::VerifyMessages(messages))) } @@ -85,15 +87,6 @@ impl<'a> Client<'a> { } } -// TODO: unify across contract clients -fn ignore_empty(msgs: Vec) -> Option> { - if msgs.is_empty() { - None - } else { - Some(msgs) - } -} - #[cfg(test)] mod test { use std::collections::BTreeMap; diff --git a/packages/axelar-wasm-std/src/error.rs b/packages/axelar-wasm-std/src/error.rs index 0e994e51a..1e2922591 100644 --- a/packages/axelar-wasm-std/src/error.rs +++ b/packages/axelar-wasm-std/src/error.rs @@ -82,7 +82,11 @@ macro_rules! err_contains { ($expression:expr, $error_type:ty, $pattern:pat $(if $guard:expr)? $(,)?) => { match $expression.downcast_ref::<$error_type>() { Some($pattern) $(if $guard)? => true, - _ => false, + _ => { + println!("actual: {:?}", $expression); + + false + } } }; } diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 8f6299a4f..740b86458 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -17,6 +17,7 @@ pub mod permission_control; pub mod snapshot; pub mod threshold; pub mod utils; +pub mod vec; pub mod verification; pub mod voting; diff --git a/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs b/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs index 63be431d6..9f9bf8376 100644 --- a/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs +++ b/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs @@ -75,6 +75,15 @@ impl Display for HexTxHashAndEventIndex { } } +impl From for nonempty::String { + fn from(msg_id: HexTxHashAndEventIndex) -> Self { + msg_id + .to_string() + .try_into() + .expect("failed to convert msg id to non-empty string") + } +} + #[cfg(test)] mod tests { diff --git a/packages/axelar-wasm-std/src/vec.rs b/packages/axelar-wasm-std/src/vec.rs new file mode 100644 index 000000000..d24479fd0 --- /dev/null +++ b/packages/axelar-wasm-std/src/vec.rs @@ -0,0 +1,13 @@ +pub trait VecExt { + fn to_none_if_empty(self) -> Option>; +} + +impl VecExt for Vec { + fn to_none_if_empty(self) -> Option> { + if self.is_empty() { + None + } else { + Some(self) + } + } +} diff --git a/packages/router-api/src/client.rs b/packages/router-api/src/client.rs index e756a318d..6b3182edb 100644 --- a/packages/router-api/src/client.rs +++ b/packages/router-api/src/client.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::vec::VecExt; use cosmwasm_std::{to_json_binary, Addr, WasmMsg}; use crate::msg::ExecuteMsg; @@ -17,15 +18,7 @@ impl Router { } pub fn route(&self, msgs: Vec) -> Option { - ignore_empty(msgs).map(|msgs| self.execute(&ExecuteMsg::RouteMessages(msgs))) - } -} - -// TODO: unify across contract clients -fn ignore_empty(msgs: Vec) -> Option> { - if msgs.is_empty() { - None - } else { - Some(msgs) + msgs.to_none_if_empty() + .map(|msgs| self.execute(&ExecuteMsg::RouteMessages(msgs))) } } From e97633215982e4d4dab450efe4eb8e5a1f17b6f5 Mon Sep 17 00:00:00 2001 From: Sammy Date: Fri, 9 Aug 2024 14:20:13 -0400 Subject: [PATCH 144/168] feat(multisig-prover): bcs payload encoding (#525) --- Cargo.lock | 20 ++ Cargo.toml | 2 + ampd/Cargo.toml | 3 +- ampd/src/sui/verifier.rs | 143 +++------ contracts/multisig-prover/Cargo.toml | 7 +- .../multisig-prover/src/contract/execute.rs | 8 +- .../multisig-prover/src/contract/query.rs | 3 +- .../src/encoding/abi/execute_data.rs | 45 +-- .../multisig-prover/src/encoding/abi/mod.rs | 8 +- contracts/multisig-prover/src/encoding/bcs.rs | 290 ++++++++++++++++++ contracts/multisig-prover/src/encoding/mod.rs | 82 +++++ ...hould_encode_correctly_for_messages.golden | 1 + ...d_encode_correctly_for_verifier_set.golden | 1 + contracts/multisig-prover/src/payload.rs | 36 --- packages/sui-gateway/Cargo.toml | 24 ++ packages/sui-gateway/release.toml | 1 + packages/sui-gateway/src/base_types.rs | 94 ++++++ packages/sui-gateway/src/error.rs | 13 + packages/sui-gateway/src/gateway/events.rs | 41 +++ packages/sui-gateway/src/gateway/mod.rs | 180 +++++++++++ packages/sui-gateway/src/lib.rs | 3 + 21 files changed, 822 insertions(+), 183 deletions(-) create mode 100644 contracts/multisig-prover/src/encoding/bcs.rs create mode 100644 contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_messages.golden create mode 100644 contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_verifier_set.golden create mode 100644 packages/sui-gateway/Cargo.toml create mode 100644 packages/sui-gateway/release.toml create mode 100644 packages/sui-gateway/src/base_types.rs create mode 100644 packages/sui-gateway/src/error.rs create mode 100644 packages/sui-gateway/src/gateway/events.rs create mode 100644 packages/sui-gateway/src/gateway/mod.rs create mode 100644 packages/sui-gateway/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index b97aed73b..92d7f7b64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,6 +267,7 @@ dependencies = [ "serde_with 3.8.1", "service-registry", "sha3", + "sui-gateway", "sui-json-rpc-types", "sui-types", "tendermint 0.33.0", @@ -4902,6 +4903,7 @@ dependencies = [ "serde_json", "service-registry", "sha3", + "sui-gateway", "thiserror", "voting-verifier", ] @@ -7563,6 +7565,24 @@ dependencies = [ "serde_yaml", ] +[[package]] +name = "sui-gateway" +version = "1.0.0" +dependencies = [ + "bcs", + "bs58 0.5.1", + "cosmwasm-std", + "error-stack", + "hex", + "multisig", + "rand", + "router-api", + "serde", + "serde_json", + "sha3", + "thiserror", +] + [[package]] name = "sui-json" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 8c2fb420b..879b4802b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ error-stack = { version = "0.4.0", features = ["eyre"] } events = { version = "^1.0.0", path = "packages/events" } events-derive = { version = "^1.0.0", path = "packages/events-derive" } evm-gateway = { version = "^1.0.0", path = "packages/evm-gateway" } +sui-gateway = { version = "^1.0.0", path = "packages/sui-gateway" } axelar-wasm-std = { version = "^1.0.0", path = "packages/axelar-wasm-std" } axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std-derive" } integration-tests = { version = "^1.0.0", path = "integration-tests" } @@ -34,6 +35,7 @@ router-api = { version = "^1.0.0", path = "packages/router-api" } report = { version = "^1.0.0", path = "packages/report" } client = { version = "^1.0.0", path = "packages/client" } quote = "1.0.36" +bcs = "0.1.5" rewards = { version = "^1.0.0", path = "contracts/rewards" } thiserror = "1.0.61" mockall = "0.12.1" diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index d70e1ef52..634aa841a 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -10,7 +10,7 @@ async-trait = "0.1.59" axelar-wasm-std = { workspace = true } axum = "0.7.5" base64 = "0.21.2" -bcs = "0.1.5" +bcs = { workspace = true } clap = { version = "4.2.7", features = ["derive", "cargo"] } config = "0.13.2" cosmrs = { version = "0.14.0", features = ["cosmwasm", "grpc"] } @@ -47,6 +47,7 @@ serde_json = { workspace = true } serde_with = "3.2.0" service-registry = { workspace = true } sha3 = { workspace = true } +sui-gateway = { workspace = true } sui-json-rpc-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.26.2" } sui-types = { git = "https://github.com/mystenlabs/sui", features = ["test-utils"], tag = "mainnet-v1.26.2" } # Need to switch to our own fork of tendermint and tendermint-rpc due to event attribute value being nullable. diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index d088b2125..26d85b366 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -1,75 +1,14 @@ -use std::collections::HashMap; - use axelar_wasm_std::voting::Vote; use axelar_wasm_std::{self}; use cosmwasm_std::HexBinary; use move_core_types::language_storage::StructTag; -use serde::de::Error; -use serde::{Deserialize, Deserializer}; +use sui_gateway::gateway::events::{ContractCall, SignersRotated}; +use sui_gateway::gateway::{WeightedSigner, WeightedSigners}; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockResponse}; use sui_types::base_types::SuiAddress; use crate::handlers::sui_verify_msg::Message; use crate::handlers::sui_verify_verifier_set::VerifierSetConfirmation; -use crate::types::Hash; - -fn deserialize_from_str<'de, D, R>(deserializer: D) -> Result -where - D: Deserializer<'de>, - R: std::str::FromStr, - R::Err: std::fmt::Display, -{ - let string: String = Deserialize::deserialize(deserializer)?; - - R::from_str(&string).map_err(Error::custom) -} - -fn deserialize_sui_bytes<'de, D, const LENGTH: usize>( - deserializer: D, -) -> Result<[u8; LENGTH], D::Error> -where - D: Deserializer<'de>, -{ - let bytes: HashMap = Deserialize::deserialize(deserializer)?; - let hex = bytes - .get("bytes") - .ok_or_else(|| Error::custom("missing bytes"))? - .trim_start_matches("0x"); - - hex::decode(hex) - .map_err(Error::custom)? - .try_into() - .map_err(|_| Error::custom(format!("failed deserialize into [u8; {}]", LENGTH))) -} - -#[derive(Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)] -struct WeightedSigner { - pub_key: Vec, - #[serde(deserialize_with = "deserialize_from_str")] - weight: u128, -} - -#[derive(Deserialize, Debug)] -struct WeightedSigners { - signers: Vec, - #[serde(deserialize_with = "deserialize_from_str")] - threshold: u128, - #[serde(deserialize_with = "deserialize_sui_bytes")] - nonce: [u8; 32], -} - -#[derive(Deserialize, Debug)] -struct SignersRotated { - signers: WeightedSigners, -} - -#[derive(Deserialize)] -struct ContractCall { - pub source_id: SuiAddress, - pub destination_chain: String, - pub destination_address: String, - pub payload_hash: Hash, -} enum EventType { ContractCall, @@ -97,17 +36,18 @@ impl EventType { impl PartialEq<&Message> for &SuiEvent { fn eq(&self, msg: &&Message) -> bool { - match serde_json::from_value::(self.parsed_json.clone()) { + match bcs::from_bytes::(&self.bcs) { Ok(ContractCall { source_id, destination_chain, destination_address, payload_hash, + .. }) => { - msg.source_address == source_id + msg.source_address.as_ref() == source_id.as_bytes() && msg.destination_chain == destination_chain && msg.destination_address == destination_address - && msg.payload_hash == payload_hash + && msg.payload_hash.to_fixed_bytes().to_vec() == payload_hash.to_vec() } _ => false, } @@ -133,7 +73,7 @@ impl PartialEq<&VerifierSetConfirmation> for &SuiEvent { .chain(expected.created_at.to_be_bytes()) .collect::>(); - match serde_json::from_value::(self.parsed_json.clone()) { + match bcs::from_bytes::(&self.bcs) { Ok(SignersRotated { signers: WeightedSigners { @@ -141,12 +81,13 @@ impl PartialEq<&VerifierSetConfirmation> for &SuiEvent { threshold, nonce, }, + .. }) => { signers.sort(); signers == expected_signers && threshold == expected.threshold.u128() - && nonce.as_slice() == expected_created_at.as_slice() + && nonce.as_ref() == expected_created_at.as_slice() } _ => false, } @@ -205,7 +146,6 @@ mod tests { use cosmrs::crypto::PublicKey; use cosmwasm_std::{Addr, HexBinary, Uint128}; use ecdsa::SigningKey; - use ethers_core::abi::AbiEncode; use move_core_types::language_storage::StructTag; use multisig::key::KeyType; use multisig::msg::Signer; @@ -214,6 +154,8 @@ mod tests { use random_string::generate; use router_api::ChainName; use serde_json::json; + use sui_gateway::gateway::events::{ContractCall, SignersRotated}; + use sui_gateway::gateway::{WeightedSigner, WeightedSigners}; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockEvents, SuiTransactionBlockResponse}; use sui_types::base_types::{SuiAddress, TransactionDigest}; use sui_types::event::EventID; @@ -417,16 +359,13 @@ mod tests { payload_hash: Hash::random(), }; - let json_str = format!( - r#"{{"destination_address": "{}", "destination_chain": "{}", "payload": "[1,2,3]", - "payload_hash": "{}", "source_id": "{}"}}"#, - msg.destination_address, - msg.destination_chain, - msg.payload_hash.encode_hex(), - msg.source_address - ); - let parsed: serde_json::Value = serde_json::from_str(json_str.as_str()).unwrap(); - + let contract_call = ContractCall { + destination_address: msg.destination_address.clone(), + destination_chain: msg.destination_chain.to_string(), + payload: msg.payload_hash.to_fixed_bytes().to_vec(), + payload_hash: msg.payload_hash.to_fixed_bytes(), + source_id: msg.source_address.to_string().parse().unwrap(), + }; let event = SuiEvent { id: EventID { tx_digest: msg.tx_id, @@ -441,8 +380,8 @@ mod tests { name: "ContractCall".parse().unwrap(), type_params: vec![], }, - parsed_json: parsed, - bcs: vec![], + parsed_json: json!({}), + bcs: bcs::to_bytes(&contract_call).unwrap(), timestamp_ms: None, }; @@ -492,26 +431,28 @@ mod tests { }, }; - let parsed_json = json!({ - "epoch": "1", - "signers": { - "nonce": { - "bytes": format!("0x{:0>64}", HexBinary::from(created_at.to_be_bytes()).to_hex()) - }, - - "signers": signers.into_iter().map(|signer| { - json!({ - "pub_key": HexBinary::from(signer.pub_key).to_vec(), - "weight": signer.weight.u128().to_string() + let signers_rotated = SignersRotated { + epoch: 0, + signers_hash: [0; 32].into(), + signers: WeightedSigners { + signers: signers + .into_iter() + .map(|signer| WeightedSigner { + pub_key: HexBinary::from(signer.pub_key).to_vec(), + weight: signer.weight.u128(), }) - }).collect::>(), - "threshold": threshold.to_string(), + .collect(), + threshold: threshold.u128(), + nonce: <[u8; 32]>::try_from( + [0u8; 24] + .into_iter() + .chain(created_at.to_be_bytes()) + .collect::>(), + ) + .unwrap() + .into(), }, - "signers_hash": { - "bytes": format!("0x{:0>64}", HexBinary::from(verifier_set_confirmation.verifier_set.hash()).to_hex()) - } - }); - + }; let event = SuiEvent { id: EventID { tx_digest: verifier_set_confirmation.tx_id, @@ -526,8 +467,8 @@ mod tests { name: "SignersRotated".parse().unwrap(), type_params: vec![], }, - parsed_json, - bcs: vec![], + parsed_json: json!({}), + bcs: bcs::to_bytes(&signers_rotated).unwrap(), timestamp_ms: None, }; diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index bad6c9b62..83b386b0f 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -6,9 +6,9 @@ edition = { workspace = true } description = "Multisig prover contract" exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", + # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -57,6 +57,7 @@ router-api = { workspace = true } serde_json = "1.0.89" service-registry = { workspace = true } sha3 = { workspace = true } +sui-gateway = { workspace = true } thiserror = { workspace = true } voting-verifier = { workspace = true, features = ["library"] } diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index b29947ab5..1e9872a09 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -64,7 +64,9 @@ pub fn construct_proof( .map_err(ContractError::from)? .ok_or(ContractError::NoVerifierSet)?; - let digest = payload.digest(config.encoder, &config.domain_separator, &verifier_set)?; + let digest = config + .encoder + .digest(&config.domain_separator, &verifier_set, &payload)?; let start_sig_msg = multisig::msg::ExecuteMsg::StartSigningSession { verifier_set_id: verifier_set.id(), @@ -260,7 +262,9 @@ pub fn update_verifier_set( .map_err(ContractError::from)?; let digest = - payload.digest(config.encoder, &config.domain_separator, &cur_verifier_set)?; + config + .encoder + .digest(&config.domain_separator, &cur_verifier_set, &payload)?; let start_sig_msg = multisig::msg::ExecuteMsg::StartSigningSession { verifier_set_id: cur_verifier_set.id(), diff --git a/contracts/multisig-prover/src/contract/query.rs b/contracts/multisig-prover/src/contract/query.rs index 14c35a102..998b572c1 100644 --- a/contracts/multisig-prover/src/contract/query.rs +++ b/contracts/multisig-prover/src/contract/query.rs @@ -35,8 +35,7 @@ pub fn proof(deps: Deps, multisig_session_id: Uint64) -> Result ProofStatus::Pending, MultisigState::Completed { .. } => { - let execute_data = payload.execute_data( - config.encoder, + let execute_data = config.encoder.execute_data( &config.domain_separator, &multisig.verifier_set, multisig.optimize_signatures(), diff --git a/contracts/multisig-prover/src/encoding/abi/execute_data.rs b/contracts/multisig-prover/src/encoding/abi/execute_data.rs index dea1d443e..199986969 100644 --- a/contracts/multisig-prover/src/encoding/abi/execute_data.rs +++ b/contracts/multisig-prover/src/encoding/abi/execute_data.rs @@ -2,12 +2,12 @@ use axelar_wasm_std::hash::Hash; use cosmwasm_std::HexBinary; use error_stack::ResultExt; use ethers_contract::contract::EthCall; -use ethers_core::abi::{encode as abi_encode, Tokenize}; +use ethers_core::abi::{self, Tokenize}; use evm_gateway::{ApproveMessagesCall, Message, Proof, RotateSignersCall, WeightedSigners}; -use multisig::key::Signature; use multisig::msg::SignerWithSig; use multisig::verifier_set::VerifierSet; +use crate::encoding::{to_recoverable, Encoder}; use crate::error::ContractError; use crate::payload::Payload; @@ -17,7 +17,7 @@ pub fn encode( payload_digest: &Hash, payload: &Payload, ) -> error_stack::Result { - let signers = to_recoverable(payload_digest.as_slice(), signers); + let signers = to_recoverable(Encoder::Abi, payload_digest, signers); let proof = Proof::new(verifier_set, signers).change_context(ContractError::Proof)?; @@ -31,7 +31,7 @@ pub fn encode( ( ApproveMessagesCall::selector(), - abi_encode(&ApproveMessagesCall { messages, proof }.into_tokens()), + abi::encode(&ApproveMessagesCall { messages, proof }.into_tokens()), ) } Payload::VerifierSet(new_verifier_set) => { @@ -40,7 +40,7 @@ pub fn encode( ( RotateSignersCall::selector(), - abi_encode(&RotateSignersCall { new_signers, proof }.into_tokens()), + abi::encode(&RotateSignersCall { new_signers, proof }.into_tokens()), ) } }; @@ -52,30 +52,6 @@ pub fn encode( .into()) } -// Convert non-recoverable ECDSA signatures to recoverable ones. -fn to_recoverable(msg: &[u8], signers: Vec) -> Vec { - signers - .into_iter() - .map(|mut signer| { - if let Signature::Ecdsa(nonrecoverable) = signer.signature { - signer.signature = nonrecoverable - .to_recoverable(msg, &signer.signer.pub_key, add27) - .map(Signature::EcdsaRecoverable) - .expect("failed to convert non-recoverable signature to recoverable"); - } - - signer - }) - .collect() -} - -pub fn add27(recovery_byte: k256::ecdsa::RecoveryId) -> u8 { - recovery_byte - .to_byte() - .checked_add(27) - .expect("overflow when adding 27 to recovery byte") -} - #[cfg(test)] mod tests { use std::str::FromStr; @@ -93,8 +69,9 @@ mod tests { use multisig::msg::{Signer, SignerWithSig}; use sha3::{Digest, Keccak256}; - use crate::encoding::abi::execute_data::{add27, encode}; - use crate::encoding::abi::payload_hash_to_sign; + use crate::encoding::abi::execute_data::encode; + use crate::encoding::abi::payload_digest; + use crate::encoding::add_27; use crate::payload::Payload; use crate::test::test_data::{ curr_verifier_set, domain_separator, messages, verifier_set_from_pub_keys, @@ -130,7 +107,7 @@ mod tests { let signers_with_sigs = signers_with_sigs(verifier_set.signers.values(), sigs); let payload = Payload::VerifierSet(new_verifier_set); - let payload_hash: Hash = payload_hash_to_sign(&domain_separator, &verifier_set, &payload) + let payload_hash: Hash = payload_digest(&domain_separator, &verifier_set, &payload) .unwrap() .as_slice() .try_into() @@ -172,7 +149,7 @@ mod tests { .to_recoverable( HexBinary::from_hex(digest).unwrap().as_slice(), &multisig::key::PublicKey::Ecdsa(HexBinary::from(pub_key.to_vec())), - add27, + add_27, ) .unwrap(); @@ -202,7 +179,7 @@ mod tests { let signers_with_sigs = signers_with_sigs(verifier_set.signers.values(), sigs); let payload = Payload::Messages(messages()); - let payload_hash: Hash = payload_hash_to_sign(&domain_separator, &verifier_set, &payload) + let payload_hash: Hash = payload_digest(&domain_separator, &verifier_set, &payload) .unwrap() .as_slice() .try_into() diff --git a/contracts/multisig-prover/src/encoding/abi/mod.rs b/contracts/multisig-prover/src/encoding/abi/mod.rs index 6ed8a79b0..2a0439b6d 100644 --- a/contracts/multisig-prover/src/encoding/abi/mod.rs +++ b/contracts/multisig-prover/src/encoding/abi/mod.rs @@ -20,7 +20,7 @@ impl From<&Payload> for CommandType { } } -pub fn payload_hash_to_sign( +pub fn payload_digest( domain_separator: &Hash, signer: &VerifierSet, payload: &Payload, @@ -72,7 +72,7 @@ pub fn encode(payload: &Payload) -> Result, ContractError> { mod tests { use cosmwasm_std::HexBinary; - use crate::encoding::abi::{payload_hash_to_sign, CommandType}; + use crate::encoding::abi::{payload_digest, CommandType}; use crate::payload::Payload; use crate::test::test_data::{ curr_verifier_set, domain_separator, messages, new_verifier_set, verifier_set_from_pub_keys, @@ -104,7 +104,7 @@ mod tests { ]; let new_verifier_set = verifier_set_from_pub_keys(new_pub_keys); - let msg_to_sign = payload_hash_to_sign( + let msg_to_sign = payload_digest( &domain_separator, &curr_verifier_set(), &Payload::VerifierSet(new_verifier_set), @@ -122,7 +122,7 @@ mod tests { let domain_separator = domain_separator(); - let digest = payload_hash_to_sign( + let digest = payload_digest( &domain_separator, &curr_verifier_set(), &Payload::Messages(messages()), diff --git a/contracts/multisig-prover/src/encoding/bcs.rs b/contracts/multisig-prover/src/encoding/bcs.rs new file mode 100644 index 000000000..80ba60ed6 --- /dev/null +++ b/contracts/multisig-prover/src/encoding/bcs.rs @@ -0,0 +1,290 @@ +use std::iter; + +use axelar_wasm_std::hash::Hash; +use cosmwasm_std::HexBinary; +use error_stack::{Result, ResultExt}; +use multisig::msg::SignerWithSig; +use multisig::verifier_set::VerifierSet; +use sha3::{Digest, Keccak256}; +use sui_gateway::gateway::{ + CommandType, ExecuteData, Message, MessageToSign, Proof, WeightedSigners, +}; + +use crate::encoding::{to_recoverable, Encoder}; +use crate::error::ContractError; +use crate::payload::Payload; + +fn encode_payload(payload: &Payload) -> Result, ContractError> { + let encoded: Vec = match payload { + Payload::Messages(messages) => bcs::to_bytes( + &messages + .iter() + .map(Message::try_from) + .collect::, _>>() + .change_context(ContractError::InvalidMessage)?, + ) + .expect("failed to serialize messages"), + Payload::VerifierSet(verifier_set) => bcs::to_bytes( + &WeightedSigners::try_from(verifier_set.clone()) + .change_context(ContractError::InvalidVerifierSet)?, + ) + .expect("failed to weighted signers"), + }; + + Ok(encoded) +} + +pub fn payload_digest( + domain_separator: &Hash, + verifier_set: &VerifierSet, + payload: &Payload, +) -> Result { + let command_type = match payload { + Payload::Messages(_) => CommandType::ApproveMessages, + Payload::VerifierSet(_) => CommandType::RotateSigners, + }; + let data = iter::once(command_type as u8) + .chain(encode_payload(payload)?) + .collect::>(); + let msg = MessageToSign { + domain_separator: (*domain_separator).into(), + signers_hash: WeightedSigners::try_from(verifier_set.clone()) + .change_context(ContractError::InvalidVerifierSet)? + .hash() + .into(), + data_hash: <[u8; 32]>::from(Keccak256::digest(data)).into(), + }; + + Ok(msg.hash()) +} + +/// `encode_execute_data` returns the BCS encoded execute data that contains the payload and the proof. +/// The relayer will use this data to submit the payload to the contract. +pub fn encode_execute_data( + verifier_set: &VerifierSet, + signatures: Vec, + payload_digest: &Hash, + payload: &Payload, +) -> Result { + let signatures = to_recoverable(Encoder::Bcs, payload_digest, signatures); + + let encoded_payload = encode_payload(payload)?; + let encoded_proof = bcs::to_bytes( + &Proof::try_from((verifier_set.clone(), signatures)) + .change_context(ContractError::Proof)?, + ) + .expect("failed to serialize proof"); + let execute_data = ExecuteData::new(encoded_payload, encoded_proof); + + Ok(bcs::to_bytes(&execute_data) + .expect("failed to serialize execute data") + .into()) +} + +#[cfg(test)] +mod tests { + use axelar_wasm_std::hash::Hash; + use cosmwasm_std::{Addr, HexBinary, Uint128}; + use multisig::key::KeyType; + use multisig::msg::Signer; + use multisig::verifier_set::VerifierSet; + use router_api::{CrossChainId, Message}; + + use super::payload_digest; + use crate::payload::Payload; + + #[test] + fn payload_digest_should_encode_correctly_for_verifier_set() { + let verifier_set = VerifierSet { + signers: vec![ + ( + "addr_1".to_string(), + Signer { + address: Addr::unchecked("addr_1"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("02a7ecca982c2d9ac150c629699c4c601032b42429b418799d6c08ce7d966f518b").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ( + "addr_2".to_string(), + Signer { + address: Addr::unchecked("addr_2"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("023e44013597b8a49df193265ae443e1a9970626d4df92e4ebad677ab2aca5c13a").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ( + "addr_3".to_string(), + Signer { + address: Addr::unchecked("addr_3"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("024fa6a34ec85dc2618d730ad68ab914ccc492e54b573172083c0fa44465f54dcc").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ] + .into_iter() + .collect(), + threshold: 2u128.into(), + created_at: 2024, + }; + let payload = Payload::VerifierSet(VerifierSet { + signers: vec![ + ( + "addr_1".to_string(), + Signer { + address: Addr::unchecked("addr_1"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("0309613c4ae8b9ac87bdb3c4ff240a7e5f905f59754f377ccf54fbd8ce0e8ba636").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ( + "addr_2".to_string(), + Signer { + address: Addr::unchecked("addr_2"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("032b14344bda89d1a0f1a976af94648f1b4a5df5397d008f3b2032267c11eda7c9").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ( + "addr_3".to_string(), + Signer { + address: Addr::unchecked("addr_3"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("031fb4e7844794a28bc49e8a702c984031d8627befea844932a02e5e918f59f610").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ] + .into_iter() + .collect(), + threshold: 2u128.into(), + created_at: 2025, + }); + + goldie::assert!(hex::encode( + payload_digest(&Hash::from([1; 32]), &verifier_set, &payload).unwrap() + )); + } + + #[test] + fn payload_digest_should_encode_correctly_for_messages() { + let verifier_set = VerifierSet { + signers: vec![ + ( + "addr_1".to_string(), + Signer { + address: Addr::unchecked("addr_1"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("02a7ecca982c2d9ac150c629699c4c601032b42429b418799d6c08ce7d966f518b").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ( + "addr_2".to_string(), + Signer { + address: Addr::unchecked("addr_2"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("023e44013597b8a49df193265ae443e1a9970626d4df92e4ebad677ab2aca5c13a").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ( + "addr_3".to_string(), + Signer { + address: Addr::unchecked("addr_3"), + pub_key: ( + KeyType::Ecdsa, + HexBinary::from_hex("024fa6a34ec85dc2618d730ad68ab914ccc492e54b573172083c0fa44465f54dcc").unwrap(), + ) + .try_into() + .unwrap(), + weight: Uint128::one(), + }, + ), + ] + .into_iter() + .collect(), + threshold: 2u128.into(), + created_at: 2024, + }; + let payload = Payload::Messages(vec![ + Message { + cc_id: CrossChainId { + source_chain: "ethereum".parse().unwrap(), + message_id: + "0xbb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1:0" + .parse() + .unwrap(), + }, + source_address: "0x1a68E002efa42CF3bDEF81d66bB41f9d677420bE" + .parse() + .unwrap(), + destination_chain: "sui".parse().unwrap(), + destination_address: + "0xdf4dd40feff3c09bb5c559d0cfd7d1c5025fa802bba275453e48af7d2b437727" + .parse() + .unwrap(), + payload_hash: [2; 32], + }, + Message { + cc_id: CrossChainId { + source_chain: "ethereum".parse().unwrap(), + message_id: + "0xd695e1ee9d73aeee677d4cec13d17351c1e86a0ce49b7fd3de94350e9cd0b3a9:1" + .parse() + .unwrap(), + }, + source_address: "0x876EabF441B2EE5B5b0554Fd502a8E0600950cFa" + .parse() + .unwrap(), + destination_chain: "sui".parse().unwrap(), + destination_address: + "0x7bcef829e138fb8fff88671514597313153b9f5501a282bee68a2d9b66aa66e8" + .parse() + .unwrap(), + payload_hash: [3; 32], + }, + ]); + + goldie::assert!(hex::encode( + payload_digest(&Hash::from([1; 32]), &verifier_set, &payload).unwrap() + )); + } +} diff --git a/contracts/multisig-prover/src/encoding/mod.rs b/contracts/multisig-prover/src/encoding/mod.rs index 3ab989f42..054cd6ff5 100644 --- a/contracts/multisig-prover/src/encoding/mod.rs +++ b/contracts/multisig-prover/src/encoding/mod.rs @@ -1,6 +1,16 @@ pub mod abi; +pub mod bcs; +use axelar_wasm_std::hash::Hash; use cosmwasm_schema::cw_serde; +use cosmwasm_std::HexBinary; +use error_stack::Result; +use multisig::key::Signature; +use multisig::msg::SignerWithSig; +use multisig::verifier_set::VerifierSet; + +use crate::error::ContractError; +use crate::payload::Payload; #[cw_serde] #[derive(Copy)] @@ -8,3 +18,75 @@ pub enum Encoder { Abi, Bcs, } + +impl Encoder { + pub fn digest( + &self, + domain_separator: &Hash, + verifier_set: &VerifierSet, + payload: &Payload, + ) -> Result { + match self { + Encoder::Abi => abi::payload_digest(domain_separator, verifier_set, payload), + Encoder::Bcs => bcs::payload_digest(domain_separator, verifier_set, payload), + } + } + + pub fn execute_data( + &self, + domain_separator: &Hash, + verifier_set: &VerifierSet, + sigs: Vec, + payload: &Payload, + ) -> Result { + match self { + Encoder::Abi => abi::execute_data::encode( + verifier_set, + sigs, + &self.digest(domain_separator, verifier_set, payload)?, + payload, + ), + Encoder::Bcs => bcs::encode_execute_data( + verifier_set, + sigs, + &self.digest(domain_separator, verifier_set, payload)?, + payload, + ), + } + } +} + +// Convert non-recoverable ECDSA signatures to recoverable ones. +fn to_recoverable(encoder: Encoder, msg: M, signers: Vec) -> Vec +where + M: AsRef<[u8]>, +{ + let recovery_transform = match encoder { + Encoder::Abi => add_27, + Encoder::Bcs => no_op, + }; + signers + .into_iter() + .map(|mut signer| { + if let Signature::Ecdsa(nonrecoverable) = signer.signature { + signer.signature = nonrecoverable + .to_recoverable(msg.as_ref(), &signer.signer.pub_key, recovery_transform) + .map(Signature::EcdsaRecoverable) + .expect("failed to convert non-recoverable signature to recoverable"); + } + + signer + }) + .collect() +} + +fn add_27(recovery_byte: k256::ecdsa::RecoveryId) -> u8 { + recovery_byte + .to_byte() + .checked_add(27) + .expect("overflow when adding 27 to recovery byte") +} + +fn no_op(recovery_byte: k256::ecdsa::RecoveryId) -> u8 { + recovery_byte.to_byte() +} diff --git a/contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_messages.golden b/contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_messages.golden new file mode 100644 index 000000000..3083f74e5 --- /dev/null +++ b/contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_messages.golden @@ -0,0 +1 @@ +26d564a2e0f5336170857e4a3436ac05f3883ed293dbf674aa0787478723a1af \ No newline at end of file diff --git a/contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_verifier_set.golden b/contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_verifier_set.golden new file mode 100644 index 000000000..5e4e52923 --- /dev/null +++ b/contracts/multisig-prover/src/encoding/testdata/payload_digest_should_encode_correctly_for_verifier_set.golden @@ -0,0 +1 @@ +1775806969d1e2e6bac62484ed8d7be8c6c48c2f6bb4075ee60a45548140aaa9 \ No newline at end of file diff --git a/contracts/multisig-prover/src/payload.rs b/contracts/multisig-prover/src/payload.rs index b757e4ad4..1daa2d254 100644 --- a/contracts/multisig-prover/src/payload.rs +++ b/contracts/multisig-prover/src/payload.rs @@ -1,16 +1,10 @@ -use axelar_wasm_std::hash::Hash; use cosmwasm_schema::cw_serde; use cosmwasm_std::{from_json, HexBinary, StdResult}; use cw_storage_plus::{Key, KeyDeserialize, PrimaryKey}; -use error_stack::Result; -use multisig::msg::SignerWithSig; use multisig::verifier_set::VerifierSet; use router_api::{CrossChainId, Message, FIELD_DELIMITER}; use sha3::{Digest, Keccak256}; -use crate::encoding::{abi, Encoder}; -use crate::error::ContractError; - #[cw_serde] pub enum Payload { Messages(Vec), @@ -45,42 +39,12 @@ impl Payload { } } - pub fn digest( - &self, - encoder: Encoder, - domain_separator: &Hash, - cur_verifier_set: &VerifierSet, - ) -> Result { - match encoder { - Encoder::Abi => abi::payload_hash_to_sign(domain_separator, cur_verifier_set, self), - Encoder::Bcs => todo!(), - } - } - pub fn message_ids(&self) -> Option> { match &self { Payload::Messages(msgs) => Some(msgs.iter().map(|msg| msg.cc_id.clone()).collect()), Payload::VerifierSet(_) => None, } } - - pub fn execute_data( - &self, - encoder: Encoder, - domain_separator: &Hash, - verifier_set: &VerifierSet, - signers_with_sigs: Vec, - payload: &Payload, - ) -> Result { - let payload_hash = payload.digest(encoder, domain_separator, verifier_set)?; - - match encoder { - Encoder::Abi => { - abi::execute_data::encode(verifier_set, signers_with_sigs, &payload_hash, payload) - } - Encoder::Bcs => todo!(), - } - } } #[cw_serde] diff --git a/packages/sui-gateway/Cargo.toml b/packages/sui-gateway/Cargo.toml new file mode 100644 index 000000000..f2d152ab9 --- /dev/null +++ b/packages/sui-gateway/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "sui-gateway" +version = "1.0.0" +edition = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +bcs = { workspace = true } +cosmwasm-std = { workspace = true } +error-stack = { workspace = true } +hex = "0.4.3" +multisig = { workspace = true, features = ["library"] } +router-api = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sha3 = { workspace = true } +thiserror = { workspace = true } + +[lints] +workspace = true + +[dev-dependencies] +bs58 = "0.5.1" +rand = "0.8.5" diff --git a/packages/sui-gateway/release.toml b/packages/sui-gateway/release.toml new file mode 100644 index 000000000..954564097 --- /dev/null +++ b/packages/sui-gateway/release.toml @@ -0,0 +1 @@ +release = false diff --git a/packages/sui-gateway/src/base_types.rs b/packages/sui-gateway/src/base_types.rs new file mode 100644 index 000000000..fc7e0e5db --- /dev/null +++ b/packages/sui-gateway/src/base_types.rs @@ -0,0 +1,94 @@ +use std::str::FromStr; + +use error_stack::{report, Report, Result, ResultExt}; +use serde::{Deserialize, Serialize}; + +use crate::error::Error; + +const ADDRESS_PREFIX: &str = "0x"; +const SUI_ADDRESS_LENGTH: usize = 32; + +#[derive(Serialize, Deserialize, Debug)] +pub struct SuiAddress([u8; SUI_ADDRESS_LENGTH]); + +impl SuiAddress { + pub fn as_bytes(&self) -> &[u8; SUI_ADDRESS_LENGTH] { + &self.0 + } +} + +impl TryFrom<&[u8]> for SuiAddress { + type Error = Report; + + fn try_from(bytes: &[u8]) -> Result { + bytes + .try_into() + .map(Self) + .change_context(Error::InvalidAddressBytes(bytes.to_vec())) + } +} + +impl FromStr for SuiAddress { + type Err = Report; + + fn from_str(s: &str) -> Result { + hex::decode( + s.strip_prefix(ADDRESS_PREFIX) + .ok_or(report!(Error::InvalidAddressHex(s.to_string())))?, + ) + .change_context(Error::InvalidAddressHex(s.to_string()))? + .as_slice() + .try_into() + } +} + +#[cfg(test)] +mod tests { + use rand::RngCore; + + use super::*; + + #[test] + fn sui_address_try_from() { + let mut bytes = [0u8; SUI_ADDRESS_LENGTH]; + rand::thread_rng().fill_bytes(&mut bytes); + let address = SuiAddress::try_from(&bytes[..]).unwrap(); + assert_eq!(address.as_bytes(), &bytes); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH + 1]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::try_from(&bytes[..]).is_err()); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH - 1]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::try_from(&bytes[..]).is_err()); + } + + #[test] + fn sui_address_from_str() { + let mut bytes = [0u8; SUI_ADDRESS_LENGTH]; + rand::thread_rng().fill_bytes(&mut bytes); + let address = SuiAddress::from_str(format!("0x{}", hex::encode(bytes)).as_str()).unwrap(); + assert_eq!(address.as_bytes(), &bytes); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH + 1]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::from_str(format!("0x{}", hex::encode(bytes)).as_str()).is_err()); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH - 1]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::from_str(format!("0x{}", hex::encode(bytes)).as_str()).is_err()); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::from_str(format!("0x0x{}", hex::encode(bytes)).as_str()).is_err()); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::from_str(format!("test{}", hex::encode(bytes)).as_str()).is_err()); + + let mut bytes = [0u8; SUI_ADDRESS_LENGTH]; + rand::thread_rng().fill_bytes(&mut bytes); + assert!(SuiAddress::from_str(hex::encode(bytes).as_str()).is_err()); + } +} diff --git a/packages/sui-gateway/src/error.rs b/packages/sui-gateway/src/error.rs new file mode 100644 index 000000000..7d85c08bd --- /dev/null +++ b/packages/sui-gateway/src/error.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("invalid address bytes: {:?}", .0)] + InvalidAddressBytes(Vec), + #[error("invalid address hex: {0}")] + InvalidAddressHex(String), + #[error("unsupported type of public key")] + UnsupportedPublicKey, + #[error("unsupported type of signature")] + UnsupportedSignature, +} diff --git a/packages/sui-gateway/src/gateway/events.rs b/packages/sui-gateway/src/gateway/events.rs new file mode 100644 index 000000000..83b4008fa --- /dev/null +++ b/packages/sui-gateway/src/gateway/events.rs @@ -0,0 +1,41 @@ +use serde::{Deserialize, Serialize}; + +use crate::base_types::SuiAddress; +use crate::gateway::{Bytes32, WeightedSigners}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct SignersRotated { + pub epoch: u64, + pub signers_hash: Bytes32, + pub signers: WeightedSigners, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ContractCall { + pub source_id: SuiAddress, + pub destination_chain: String, + pub destination_address: String, + pub payload: Vec, + pub payload_hash: [u8; 32], +} + +#[cfg(test)] +mod tests { + use super::{ContractCall, SignersRotated}; + + #[test] + fn signers_rotated_should_serialize_and_deserialize_correct_bcs() { + let bcs_bytes = bs58::decode("7VmsFWvv3atGxVB1oUDZAx6nRWoE1xiWYxqLP6mcWD3Rf4wFjhfMwjKmxjXHyVc9ZTdCRdt25rUCWxCBRGEuFogKfgXkUXSkHPxirMeS4R8kJn1pgA7bkMwQywgFnrmd1ceeWNCCBQuUGr83Gx8mbyZeN7W2EAct14rKQ5zukNZH6mKv7n4dmBasFm8vT").into_vec().unwrap(); + + let event = bcs::from_bytes::(&bcs_bytes).unwrap(); + assert_eq!(bcs::to_bytes(&event).unwrap(), bcs_bytes); + } + + #[test] + fn contract_call_should_serialize_and_deserialize_correct_bcs() { + let bcs_bytes = bs58::decode("3Q9LRQe3KX2E3VNVjMLzWhDwSrNBB2Js9KPoW1SFuj2HVTgp9SXezEPFtqYhddwb8AvKQSaednVibTWz9upFy51px2nnwKgfNcwK2JDckvMENBdEtTnpKJnfizA2vC9qzxiPtE17ANnK629HzkpMqPKpvJjDueJ9zMw").into_vec().unwrap(); + + let event = bcs::from_bytes::(&bcs_bytes).unwrap(); + assert_eq!(bcs::to_bytes(&event).unwrap(), bcs_bytes); + } +} diff --git a/packages/sui-gateway/src/gateway/mod.rs b/packages/sui-gateway/src/gateway/mod.rs new file mode 100644 index 000000000..f24212b15 --- /dev/null +++ b/packages/sui-gateway/src/gateway/mod.rs @@ -0,0 +1,180 @@ +use cosmwasm_std::Uint256; +use error_stack::{report, Report}; +use multisig::key::PublicKey; +use multisig::msg::SignerWithSig; +use multisig::verifier_set::VerifierSet; +use serde::{Deserialize, Serialize}; +use sha3::{Digest, Keccak256}; + +use crate::base_types::SuiAddress; +use crate::error::Error; + +pub mod events; + +#[repr(u8)] +pub enum CommandType { + ApproveMessages = 0, + RotateSigners = 1, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Bytes32 { + bytes: [u8; 32], +} + +impl AsRef<[u8]> for Bytes32 { + fn as_ref(&self) -> &[u8] { + &self.bytes + } +} + +impl From<[u8; 32]> for Bytes32 { + fn from(bytes: [u8; 32]) -> Self { + Self { bytes } + } +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct WeightedSigner { + pub pub_key: Vec, + pub weight: u128, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WeightedSigners { + pub signers: Vec, + pub threshold: u128, + pub nonce: Bytes32, +} + +impl TryFrom for WeightedSigners { + type Error = Report; + + fn try_from(verifier_set: VerifierSet) -> Result { + let mut signers = verifier_set + .signers + .values() + .map(|signer| match &signer.pub_key { + PublicKey::Ecdsa(key) => Ok(WeightedSigner { + pub_key: key.to_vec(), + weight: signer.weight.into(), + }), + PublicKey::Ed25519(_) => Err(Report::new(Error::UnsupportedPublicKey)), + }) + .collect::, _>>()?; + signers.sort_by(|signer1, signer2| signer1.pub_key.cmp(&signer2.pub_key)); + + let nonce = Uint256::from(verifier_set.created_at).to_be_bytes().into(); + + Ok(Self { + signers, + threshold: verifier_set.threshold.into(), + nonce, + }) + } +} + +impl WeightedSigners { + pub fn hash(&self) -> [u8; 32] { + let hash = + Keccak256::digest(bcs::to_bytes(&self).expect("failed to serialize WeightedSigners")); + + hash.into() + } +} + +#[derive(Serialize)] +pub struct MessageToSign { + pub domain_separator: Bytes32, + pub signers_hash: Bytes32, + pub data_hash: Bytes32, +} + +impl MessageToSign { + pub fn hash(&self) -> [u8; 32] { + let hash = + Keccak256::digest(bcs::to_bytes(&self).expect("failed to serialize MessageToSign")); + + hash.into() + } +} + +#[derive(Serialize)] +pub struct Message { + source_chain: String, + message_id: String, + source_address: String, + destination_id: SuiAddress, + payload_hash: Bytes32, +} + +impl TryFrom<&router_api::Message> for Message { + type Error = Report; + + fn try_from(value: &router_api::Message) -> Result { + Ok(Self { + source_chain: value.cc_id.source_chain.to_string(), + message_id: value.cc_id.message_id.to_string(), + source_address: value.source_address.to_string(), + destination_id: value.destination_address.parse()?, + payload_hash: value.payload_hash.into(), + }) + } +} + +#[derive(Serialize)] +pub struct Signature { + bytes: Vec, +} + +impl TryFrom for Signature { + type Error = Report; + + fn try_from(signature: multisig::key::Signature) -> Result { + match signature { + // The move contracts require recoverable signatures. This should + // only be called after the proper conversion during encoding. + multisig::key::Signature::EcdsaRecoverable(signature) => Ok(Self { + bytes: signature.as_ref().to_vec(), + }), + _ => Err(report!(Error::UnsupportedSignature)), + } + } +} + +#[derive(Serialize)] +pub struct Proof { + signers: WeightedSigners, + signatures: Vec, +} + +impl TryFrom<(VerifierSet, Vec)> for Proof { + type Error = Report; + + fn try_from( + (verifier_set, mut signatures): (VerifierSet, Vec), + ) -> Result { + signatures.sort_by(|signer1, signer2| signer1.signer.pub_key.cmp(&signer2.signer.pub_key)); + + Ok(Self { + signers: verifier_set.try_into()?, + signatures: signatures + .into_iter() + .map(|signer| signer.signature) + .map(TryInto::try_into) + .collect::, _>>()?, + }) + } +} + +#[derive(Serialize, Deserialize)] +pub struct ExecuteData { + pub payload: Vec, + pub proof: Vec, +} + +impl ExecuteData { + pub fn new(payload: Vec, proof: Vec) -> Self { + Self { payload, proof } + } +} diff --git a/packages/sui-gateway/src/lib.rs b/packages/sui-gateway/src/lib.rs new file mode 100644 index 000000000..2f5f7b253 --- /dev/null +++ b/packages/sui-gateway/src/lib.rs @@ -0,0 +1,3 @@ +pub mod base_types; +pub mod error; +pub mod gateway; From 176adfadc76a251d290729132b7bfd50de5d1b81 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 9 Aug 2024 15:12:12 -0400 Subject: [PATCH 145/168] ci: support release for axelarnet-gateway (#579) --- .github/workflows/release.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index cb59d5b44..e022a6a2a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,6 +17,7 @@ on: - service-registry - voting-verifier - coordinator + - axelarnet-gateway dry-run: description: Dry run type: boolean @@ -48,6 +49,7 @@ jobs: ["service-registry"]="service-registry,/(major)|(major-service-registry)|(major-contracts)/,/(minor)|(minor-service-registry)|(minor-contracts)/,contracts/service-registry packages" ["voting-verifier"]="voting-verifier,/(major)|(major-voting-verifier)|(major-contracts)/,/(minor)|(minor-voting-verifier)|(minor-contracts)/,contracts/voting-verifier packages" ["coordinator"]="coordinator,/(major)|(major-coordinator)|(major-contracts)/,/(minor)|(minor-coordinator)|(minor-contracts)/,contracts/coordinator packages" + ["axelarnet-gateway"]="axelarnet-gateway,/(major)|(major-axelarnet-gateway)|(major-contracts)/,/(minor)|(minor-axelarnet-gateway)|(minor-contracts)/,contracts/axelarnet-gateway packages" ) if [[ -n "${binaries_data[$binary]}" ]]; then From 746bb066a82536a71ce126ea2375ecd58fd9d6b1 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 9 Aug 2024 15:56:07 -0400 Subject: [PATCH 146/168] fix(signature-verifier-api): exclude package from release (#577) --- packages/signature-verifier-api/release.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/signature-verifier-api/release.toml diff --git a/packages/signature-verifier-api/release.toml b/packages/signature-verifier-api/release.toml new file mode 100644 index 000000000..954564097 --- /dev/null +++ b/packages/signature-verifier-api/release.toml @@ -0,0 +1 @@ +release = false From 9781e1c691db5adf15d2504cd1f34d9aa97ccb6d Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Fri, 9 Aug 2024 18:30:34 -0400 Subject: [PATCH 147/168] feat(axelarnet-gateway): add query to retrieve sent/received messages (#578) --- contracts/axelarnet-gateway/src/contract.rs | 15 +- .../axelarnet-gateway/src/contract/query.rs | 165 ++++++++++++++++++ contracts/axelarnet-gateway/src/msg.rs | 12 +- contracts/axelarnet-gateway/src/state.rs | 1 - 4 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 contracts/axelarnet-gateway/src/contract/query.rs diff --git a/contracts/axelarnet-gateway/src/contract.rs b/contracts/axelarnet-gateway/src/contract.rs index aef268c66..53f0bc44b 100644 --- a/contracts/axelarnet-gateway/src/contract.rs +++ b/contracts/axelarnet-gateway/src/contract.rs @@ -1,7 +1,7 @@ use axelar_wasm_std::FnExt; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; use error_stack::ResultExt; use router_api::client::Router; use router_api::CrossChainId; @@ -10,6 +10,7 @@ use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{self, Config}; mod execute; +mod query; const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME"); const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -129,11 +130,17 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query( - _deps: Deps, + deps: Deps, _env: Env, - _msg: QueryMsg, + msg: QueryMsg, ) -> Result { - todo!() + match msg { + QueryMsg::SentMessages { cc_ids } => to_json_binary(&query::sent_messages(deps, cc_ids)?), + QueryMsg::ReceivedMessages { cc_ids } => { + to_json_binary(&query::received_messages(deps, cc_ids)?) + } + } + .map_err(axelar_wasm_std::error::ContractError::from) } #[cfg(test)] diff --git a/contracts/axelarnet-gateway/src/contract/query.rs b/contracts/axelarnet-gateway/src/contract/query.rs new file mode 100644 index 000000000..8476227ae --- /dev/null +++ b/contracts/axelarnet-gateway/src/contract/query.rs @@ -0,0 +1,165 @@ +use cosmwasm_std::Deps; +use router_api::{CrossChainId, Message}; + +use crate::state::{self, MessageWithStatus}; + +pub fn sent_messages(deps: Deps, cc_ids: Vec) -> Result, state::Error> { + cc_ids + .into_iter() + .map(|cc_id| { + state::may_load_sent_msg(deps.storage, &cc_id)? + .ok_or(state::Error::MessageNotFound(cc_id)) + }) + .collect::, _>>() +} + +pub fn received_messages( + deps: Deps, + cc_ids: Vec, +) -> Result, state::Error> { + cc_ids + .into_iter() + .map(|cc_id| { + state::may_load_received_msg(deps.storage, &cc_id)? + .ok_or(state::Error::MessageNotFound(cc_id)) + }) + .collect::, _>>() +} + +#[cfg(test)] +mod tests { + use axelar_wasm_std::{err_contains, FnExt}; + use cosmwasm_std::from_json; + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + use router_api::{CrossChainId, Message}; + use serde::de::DeserializeOwned; + use state::MessageStatus; + + use super::*; + use crate::contract; + use crate::msg::QueryMsg; + + const SOURCE_CHAIN: &str = "source-chain"; + const DESTINATION_CHAIN: &str = "destination-chain"; + + fn dummy_message(id: &str) -> Message { + Message { + cc_id: CrossChainId::new(SOURCE_CHAIN, id).unwrap(), + source_address: "source-address".parse().unwrap(), + destination_chain: DESTINATION_CHAIN.parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: [0; 32], + } + } + + // Query a msg and deserialize it. If the query fails, the error is returned + fn query( + deps: Deps, + msg: QueryMsg, + ) -> Result { + contract::query(deps, mock_env(), msg)? + .then(from_json::) + .unwrap() + .then(Ok) + } + + #[test] + fn query_sent_messages() { + let mut deps = mock_dependencies(); + + let message1 = dummy_message("message-1"); + let message2 = dummy_message("message-2"); + let message3 = dummy_message("message-3"); + + // Save messages + state::save_sent_msg(deps.as_mut().storage, message1.cc_id.clone(), &message1).unwrap(); + state::save_sent_msg(deps.as_mut().storage, message2.cc_id.clone(), &message2).unwrap(); + + // Query existing messages + let result: Vec = query( + deps.as_ref(), + QueryMsg::SentMessages { + cc_ids: vec![message1.cc_id.clone(), message2.cc_id.clone()], + }, + ) + .unwrap(); + assert_eq!(result, vec![message1, message2]); + + // Query with non-existent message + let err = query::>( + deps.as_ref(), + QueryMsg::SentMessages { + cc_ids: vec![message3.cc_id], + }, + ) + .unwrap_err(); + assert!(err_contains!( + err.report, + state::Error, + state::Error::MessageNotFound(..) + )); + } + + #[test] + fn query_received_messages() { + let mut deps = mock_dependencies(); + + let message1 = dummy_message("message-1"); + let message2 = dummy_message("message-2"); + let message3 = dummy_message("message-3"); + + // Save messages + state::save_received_msg( + deps.as_mut().storage, + message1.cc_id.clone(), + message1.clone(), + ) + .unwrap(); + state::save_received_msg( + deps.as_mut().storage, + message2.cc_id.clone(), + message2.clone(), + ) + .unwrap(); + + // Set message2 as executed + state::set_msg_as_executed(deps.as_mut().storage, message2.cc_id.clone()).unwrap(); + + // Query existing messages + let result: Vec = query( + deps.as_ref(), + QueryMsg::ReceivedMessages { + cc_ids: vec![message1.cc_id.clone(), message2.cc_id.clone()], + }, + ) + .unwrap(); + + assert_eq!( + result, + vec![ + MessageWithStatus { + msg: message1, + status: MessageStatus::Approved + }, + MessageWithStatus { + msg: message2, + status: MessageStatus::Executed + } + ] + ); + + // Query with non-existent message + let err = query::>( + deps.as_ref(), + QueryMsg::ReceivedMessages { + cc_ids: vec![message3.cc_id], + }, + ) + .unwrap_err(); + assert!(err_contains!( + err.report, + state::Error, + state::Error::MessageNotFound(..) + )); + } +} diff --git a/contracts/axelarnet-gateway/src/msg.rs b/contracts/axelarnet-gateway/src/msg.rs index 8c407fd63..a28ef14e6 100644 --- a/contracts/axelarnet-gateway/src/msg.rs +++ b/contracts/axelarnet-gateway/src/msg.rs @@ -3,6 +3,8 @@ use cosmwasm_std::HexBinary; use msgs_derive::EnsurePermissions; use router_api::{Address, ChainName, CrossChainId, Message}; +use crate::state::MessageWithStatus; + #[cw_serde] pub struct InstantiateMsg { /// The chain name for this gateway. @@ -40,4 +42,12 @@ pub enum ExecuteMsg { #[cw_serde] #[derive(QueryResponses)] -pub enum QueryMsg {} +pub enum QueryMsg { + /// Returns the sent messages for the given cross-chain ids. + #[returns(Vec)] + SentMessages { cc_ids: Vec }, + + /// Returns the received messages with their status for the given cross-chain ids. + #[returns(Vec)] + ReceivedMessages { cc_ids: Vec }, +} diff --git a/contracts/axelarnet-gateway/src/state.rs b/contracts/axelarnet-gateway/src/state.rs index a4f947346..7df260c86 100644 --- a/contracts/axelarnet-gateway/src/state.rs +++ b/contracts/axelarnet-gateway/src/state.rs @@ -84,7 +84,6 @@ pub(crate) fn may_load_sent_msg( .map_err(Error::from) } -#[cfg(test)] pub(crate) fn may_load_received_msg( storage: &dyn Storage, cc_id: &CrossChainId, From 8644f88f037c7553b4ff2f4eb60dca11d8fa3913 Mon Sep 17 00:00:00 2001 From: Sammy Date: Fri, 9 Aug 2024 22:06:43 -0400 Subject: [PATCH 148/168] feat(ampd): integrate ampd queued broadcaster with the axelar batch request (#554) --- ampd/build.rs | 8 + ampd/proto/axelar/README.md | 11 + .../axelar/auxiliary/v1beta1/events.proto | 12 + .../axelar/auxiliary/v1beta1/genesis.proto | 11 + .../axelar/auxiliary/v1beta1/service.proto | 20 + ampd/proto/axelar/auxiliary/v1beta1/tx.proto | 30 ++ .../axelar/axelarnet/v1beta1/events.proto | 131 ++++++ .../axelar/axelarnet/v1beta1/genesis.proto | 27 ++ .../axelar/axelarnet/v1beta1/params.proto | 33 ++ .../axelar/axelarnet/v1beta1/proposal.proto | 29 ++ .../axelar/axelarnet/v1beta1/query.proto | 39 ++ .../axelar/axelarnet/v1beta1/service.proto | 118 +++++ ampd/proto/axelar/axelarnet/v1beta1/tx.proto | 188 ++++++++ .../axelar/axelarnet/v1beta1/types.proto | 62 +++ ampd/proto/axelar/evm/v1beta1/events.proto | 340 ++++++++++++++ ampd/proto/axelar/evm/v1beta1/genesis.proto | 39 ++ ampd/proto/axelar/evm/v1beta1/params.proto | 37 ++ ampd/proto/axelar/evm/v1beta1/query.proto | 243 +++++++++++ ampd/proto/axelar/evm/v1beta1/service.proto | 208 +++++++++ ampd/proto/axelar/evm/v1beta1/tx.proto | 259 +++++++++++ ampd/proto/axelar/evm/v1beta1/types.proto | 375 ++++++++++++++++ .../multisig/exported/v1beta1/types.proto | 28 ++ .../axelar/multisig/v1beta1/events.proto | 127 ++++++ .../axelar/multisig/v1beta1/genesis.proto | 20 + .../axelar/multisig/v1beta1/params.proto | 21 + .../proto/axelar/multisig/v1beta1/query.proto | 114 +++++ .../axelar/multisig/v1beta1/service.proto | 92 ++++ ampd/proto/axelar/multisig/v1beta1/tx.proto | 86 ++++ .../proto/axelar/multisig/v1beta1/types.proto | 84 ++++ .../axelar/nexus/exported/v1beta1/types.proto | 129 ++++++ ampd/proto/axelar/nexus/v1beta1/events.proto | 66 +++ ampd/proto/axelar/nexus/v1beta1/genesis.proto | 32 ++ ampd/proto/axelar/nexus/v1beta1/params.proto | 22 + ampd/proto/axelar/nexus/v1beta1/query.proto | 175 ++++++++ ampd/proto/axelar/nexus/v1beta1/service.proto | 150 +++++++ ampd/proto/axelar/nexus/v1beta1/tx.proto | 87 ++++ ampd/proto/axelar/nexus/v1beta1/types.proto | 65 +++ .../permission/exported/v1beta1/types.proto | 24 + .../axelar/permission/v1beta1/genesis.proto | 19 + .../axelar/permission/v1beta1/params.proto | 10 + .../axelar/permission/v1beta1/query.proto | 27 ++ .../axelar/permission/v1beta1/service.proto | 54 +++ ampd/proto/axelar/permission/v1beta1/tx.proto | 41 ++ .../axelar/permission/v1beta1/types.proto | 15 + .../proto/axelar/reward/v1beta1/genesis.proto | 17 + ampd/proto/axelar/reward/v1beta1/params.proto | 20 + ampd/proto/axelar/reward/v1beta1/query.proto | 28 ++ .../proto/axelar/reward/v1beta1/service.proto | 42 ++ ampd/proto/axelar/reward/v1beta1/tx.proto | 24 + ampd/proto/axelar/reward/v1beta1/types.proto | 33 ++ .../snapshot/exported/v1beta1/types.proto | 39 ++ .../axelar/snapshot/v1beta1/genesis.proto | 18 + .../axelar/snapshot/v1beta1/params.proto | 11 + .../proto/axelar/snapshot/v1beta1/query.proto | 35 ++ .../axelar/snapshot/v1beta1/service.proto | 41 ++ ampd/proto/axelar/snapshot/v1beta1/tx.proto | 28 ++ .../proto/axelar/snapshot/v1beta1/types.proto | 17 + .../axelar/tss/exported/v1beta1/types.proto | 68 +++ .../axelar/tss/tofnd/v1beta1/common.proto | 28 ++ .../axelar/tss/tofnd/v1beta1/multisig.proto | 40 ++ .../axelar/tss/tofnd/v1beta1/tofnd.proto | 129 ++++++ ampd/proto/axelar/tss/v1beta1/genesis.proto | 12 + ampd/proto/axelar/tss/v1beta1/params.proto | 32 ++ ampd/proto/axelar/tss/v1beta1/query.proto | 14 + ampd/proto/axelar/tss/v1beta1/service.proto | 32 ++ ampd/proto/axelar/tss/v1beta1/tx.proto | 147 +++++++ ampd/proto/axelar/tss/v1beta1/types.proto | 63 +++ ampd/proto/axelar/utils/v1beta1/bitmap.proto | 16 + ampd/proto/axelar/utils/v1beta1/queuer.proto | 19 + .../axelar/utils/v1beta1/threshold.proto | 16 + .../axelar/vote/exported/v1beta1/types.proto | 73 ++++ ampd/proto/axelar/vote/v1beta1/events.proto | 16 + ampd/proto/axelar/vote/v1beta1/genesis.proto | 17 + ampd/proto/axelar/vote/v1beta1/params.proto | 16 + ampd/proto/axelar/vote/v1beta1/query.proto | 14 + ampd/proto/axelar/vote/v1beta1/service.proto | 30 ++ ampd/proto/axelar/vote/v1beta1/tx.proto | 31 ++ ampd/proto/axelar/vote/v1beta1/types.proto | 33 ++ ampd/proto/third_party/buf.yaml | 20 + .../cosmos/auth/v1beta1/auth.proto | 50 +++ .../cosmos/auth/v1beta1/genesis.proto | 17 + .../cosmos/auth/v1beta1/query.proto | 89 ++++ .../cosmos/authz/v1beta1/authz.proto | 39 ++ .../cosmos/authz/v1beta1/event.proto | 25 ++ .../cosmos/authz/v1beta1/genesis.proto | 13 + .../cosmos/authz/v1beta1/query.proto | 81 ++++ .../third_party/cosmos/authz/v1beta1/tx.proto | 70 +++ .../cosmos/bank/v1beta1/authz.proto | 19 + .../cosmos/bank/v1beta1/bank.proto | 96 ++++ .../cosmos/bank/v1beta1/genesis.proto | 39 ++ .../cosmos/bank/v1beta1/query.proto | 193 ++++++++ .../third_party/cosmos/bank/v1beta1/tx.proto | 42 ++ .../cosmos/base/abci/v1beta1/abci.proto | 144 ++++++ .../cosmos/base/kv/v1beta1/kv.proto | 17 + .../cosmos/base/node/v1beta1/query.proto | 22 + .../base/query/v1beta1/pagination.proto | 55 +++ .../base/reflection/v1beta1/reflection.proto | 44 ++ .../base/reflection/v2alpha1/reflection.proto | 218 +++++++++ .../base/snapshots/v1beta1/snapshot.proto | 57 +++ .../base/store/v1beta1/commit_info.proto | 29 ++ .../cosmos/base/store/v1beta1/listening.proto | 34 ++ .../base/tendermint/v1beta1/query.proto | 138 ++++++ .../cosmos/base/v1beta1/coin.proto | 40 ++ .../capability/v1beta1/capability.proto | 30 ++ .../cosmos/capability/v1beta1/genesis.proto | 26 ++ .../cosmos/crisis/v1beta1/genesis.proto | 15 + .../cosmos/crisis/v1beta1/tx.proto | 25 ++ .../cosmos/crypto/ed25519/keys.proto | 23 + .../cosmos/crypto/multisig/keys.proto | 18 + .../crypto/multisig/v1beta1/multisig.proto | 25 ++ .../cosmos/crypto/secp256k1/keys.proto | 22 + .../cosmos/crypto/secp256r1/keys.proto | 23 + .../distribution/v1beta1/distribution.proto | 157 +++++++ .../cosmos/distribution/v1beta1/genesis.proto | 155 +++++++ .../cosmos/distribution/v1beta1/query.proto | 218 +++++++++ .../cosmos/distribution/v1beta1/tx.proto | 79 ++++ .../cosmos/evidence/v1beta1/evidence.proto | 21 + .../cosmos/evidence/v1beta1/genesis.proto | 12 + .../cosmos/evidence/v1beta1/query.proto | 51 +++ .../cosmos/evidence/v1beta1/tx.proto | 32 ++ .../cosmos/feegrant/v1beta1/feegrant.proto | 78 ++++ .../cosmos/feegrant/v1beta1/genesis.proto | 13 + .../cosmos/feegrant/v1beta1/query.proto | 78 ++++ .../cosmos/feegrant/v1beta1/tx.proto | 49 +++ .../cosmos/genutil/v1beta1/genesis.proto | 16 + .../cosmos/gov/v1beta1/genesis.proto | 26 ++ .../third_party/cosmos/gov/v1beta1/gov.proto | 200 +++++++++ .../cosmos/gov/v1beta1/query.proto | 190 ++++++++ .../third_party/cosmos/gov/v1beta1/tx.proto | 99 +++++ .../cosmos/mint/v1beta1/genesis.proto | 16 + .../cosmos/mint/v1beta1/mint.proto | 53 +++ .../cosmos/mint/v1beta1/query.proto | 57 +++ .../cosmos/params/v1beta1/params.proto | 27 ++ .../cosmos/params/v1beta1/query.proto | 32 ++ .../cosmos/slashing/v1beta1/genesis.proto | 50 +++ .../cosmos/slashing/v1beta1/query.proto | 63 +++ .../cosmos/slashing/v1beta1/slashing.proto | 58 +++ .../cosmos/slashing/v1beta1/tx.proto | 26 ++ .../cosmos/staking/v1beta1/authz.proto | 47 ++ .../cosmos/staking/v1beta1/genesis.proto | 53 +++ .../cosmos/staking/v1beta1/query.proto | 348 +++++++++++++++ .../cosmos/staking/v1beta1/staking.proto | 334 ++++++++++++++ .../cosmos/staking/v1beta1/tx.proto | 123 ++++++ .../cosmos/tx/signing/v1beta1/signing.proto | 91 ++++ .../cosmos/tx/v1beta1/service.proto | 165 +++++++ .../third_party/cosmos/tx/v1beta1/tx.proto | 183 ++++++++ .../cosmos/upgrade/v1beta1/query.proto | 104 +++++ .../cosmos/upgrade/v1beta1/upgrade.proto | 78 ++++ .../cosmos/vesting/v1beta1/tx.proto | 31 ++ .../cosmos/vesting/v1beta1/vesting.proto | 85 ++++ .../third_party/cosmos_proto/cosmos.proto | 16 + .../third_party/cosmwasm/wasm/v1/authz.proto | 118 +++++ .../cosmwasm/wasm/v1/genesis.proto | 46 ++ .../third_party/cosmwasm/wasm/v1/ibc.proto | 37 ++ .../cosmwasm/wasm/v1/proposal.proto | 272 ++++++++++++ .../third_party/cosmwasm/wasm/v1/query.proto | 263 +++++++++++ .../third_party/cosmwasm/wasm/v1/tx.proto | 192 ++++++++ .../third_party/cosmwasm/wasm/v1/types.proto | 145 ++++++ ampd/proto/third_party/gogoproto/gogo.proto | 145 ++++++ .../third_party/google/api/annotations.proto | 31 ++ ampd/proto/third_party/google/api/http.proto | 379 ++++++++++++++++ .../applications/transfer/v1/genesis.proto | 19 + .../ibc/applications/transfer/v1/query.proto | 105 +++++ .../applications/transfer/v1/transfer.proto | 30 ++ .../ibc/applications/transfer/v1/tx.proto | 49 +++ .../ibc/applications/transfer/v2/packet.proto | 21 + .../ibc/core/channel/v1/channel.proto | 162 +++++++ .../ibc/core/channel/v1/genesis.proto | 32 ++ .../ibc/core/channel/v1/query.proto | 376 ++++++++++++++++ .../third_party/ibc/core/channel/v1/tx.proto | 245 +++++++++++ .../ibc/core/client/v1/client.proto | 103 +++++ .../ibc/core/client/v1/genesis.proto | 48 ++ .../ibc/core/client/v1/query.proto | 207 +++++++++ .../third_party/ibc/core/client/v1/tx.proto | 99 +++++ .../ibc/core/commitment/v1/commitment.proto | 41 ++ .../ibc/core/connection/v1/connection.proto | 114 +++++ .../ibc/core/connection/v1/genesis.proto | 18 + .../ibc/core/connection/v1/query.proto | 138 ++++++ .../ibc/core/connection/v1/tx.proto | 118 +++++ .../ibc/core/types/v1/genesis.proto | 23 + .../lightclients/localhost/v1/localhost.proto | 18 + .../solomachine/v1/solomachine.proto | 189 ++++++++ .../solomachine/v2/solomachine.proto | 189 ++++++++ .../tendermint/v1/tendermint.proto | 114 +++++ ampd/proto/third_party/proofs.proto | 234 ++++++++++ .../third_party/tendermint/abci/types.proto | 413 ++++++++++++++++++ .../third_party/tendermint/crypto/keys.proto | 17 + .../third_party/tendermint/crypto/proof.proto | 41 ++ .../tendermint/libs/bits/types.proto | 9 + .../third_party/tendermint/p2p/types.proto | 34 ++ .../third_party/tendermint/types/block.proto | 15 + .../tendermint/types/evidence.proto | 38 ++ .../third_party/tendermint/types/params.proto | 80 ++++ .../third_party/tendermint/types/types.proto | 157 +++++++ .../tendermint/types/validator.proto | 25 ++ .../tendermint/version/types.proto | 24 + ampd/src/broadcaster/confirm_tx.rs | 346 +++++++++++++++ ampd/src/broadcaster/mod.rs | 162 +------ ampd/src/lib.rs | 27 +- ampd/src/queue/mod.rs | 1 + ampd/src/queue/proto.rs | 42 ++ ampd/src/queue/queued_broadcaster.rs | 231 +++++++--- 202 files changed, 15999 insertions(+), 202 deletions(-) create mode 100644 ampd/proto/axelar/README.md create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/events.proto create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/service.proto create mode 100644 ampd/proto/axelar/auxiliary/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/events.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/params.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/proposal.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/query.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/service.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/axelarnet/v1beta1/types.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/events.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/params.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/query.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/service.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/evm/v1beta1/types.proto create mode 100644 ampd/proto/axelar/multisig/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/events.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/params.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/query.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/service.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/multisig/v1beta1/types.proto create mode 100644 ampd/proto/axelar/nexus/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/events.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/params.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/query.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/service.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/nexus/v1beta1/types.proto create mode 100644 ampd/proto/axelar/permission/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/params.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/query.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/service.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/permission/v1beta1/types.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/params.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/query.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/service.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/reward/v1beta1/types.proto create mode 100644 ampd/proto/axelar/snapshot/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/params.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/query.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/service.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/snapshot/v1beta1/types.proto create mode 100644 ampd/proto/axelar/tss/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/common.proto create mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto create mode 100644 ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/params.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/query.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/service.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/tss/v1beta1/types.proto create mode 100644 ampd/proto/axelar/utils/v1beta1/bitmap.proto create mode 100644 ampd/proto/axelar/utils/v1beta1/queuer.proto create mode 100644 ampd/proto/axelar/utils/v1beta1/threshold.proto create mode 100644 ampd/proto/axelar/vote/exported/v1beta1/types.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/events.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/genesis.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/params.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/query.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/service.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/tx.proto create mode 100644 ampd/proto/axelar/vote/v1beta1/types.proto create mode 100644 ampd/proto/third_party/buf.yaml create mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto create mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/auth/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/event.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto create mode 100644 ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto create mode 100644 ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto create mode 100644 ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto create mode 100644 ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto create mode 100644 ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto create mode 100644 ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto create mode 100644 ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto create mode 100644 ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/base/v1beta1/coin.proto create mode 100644 ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto create mode 100644 ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/multisig/keys.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto create mode 100644 ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto create mode 100644 ampd/proto/third_party/cosmos/mint/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/params/v1beta1/params.proto create mode 100644 ampd/proto/third_party/cosmos/params/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto create mode 100644 ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto create mode 100644 ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto create mode 100644 ampd/proto/third_party/cosmos/tx/v1beta1/service.proto create mode 100644 ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto create mode 100644 ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto create mode 100644 ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto create mode 100644 ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto create mode 100644 ampd/proto/third_party/cosmos_proto/cosmos.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/query.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto create mode 100644 ampd/proto/third_party/cosmwasm/wasm/v1/types.proto create mode 100644 ampd/proto/third_party/gogoproto/gogo.proto create mode 100644 ampd/proto/third_party/google/api/annotations.proto create mode 100644 ampd/proto/third_party/google/api/http.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/channel.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/core/channel/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/client.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/core/client/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/connection.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/query.proto create mode 100644 ampd/proto/third_party/ibc/core/connection/v1/tx.proto create mode 100644 ampd/proto/third_party/ibc/core/types/v1/genesis.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto create mode 100644 ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto create mode 100644 ampd/proto/third_party/proofs.proto create mode 100644 ampd/proto/third_party/tendermint/abci/types.proto create mode 100644 ampd/proto/third_party/tendermint/crypto/keys.proto create mode 100644 ampd/proto/third_party/tendermint/crypto/proof.proto create mode 100644 ampd/proto/third_party/tendermint/libs/bits/types.proto create mode 100644 ampd/proto/third_party/tendermint/p2p/types.proto create mode 100644 ampd/proto/third_party/tendermint/types/block.proto create mode 100644 ampd/proto/third_party/tendermint/types/evidence.proto create mode 100644 ampd/proto/third_party/tendermint/types/params.proto create mode 100644 ampd/proto/third_party/tendermint/types/types.proto create mode 100644 ampd/proto/third_party/tendermint/types/validator.proto create mode 100644 ampd/proto/third_party/tendermint/version/types.proto create mode 100644 ampd/src/broadcaster/confirm_tx.rs create mode 100644 ampd/src/queue/proto.rs diff --git a/ampd/build.rs b/ampd/build.rs index 7581fa013..cd5acc3b9 100644 --- a/ampd/build.rs +++ b/ampd/build.rs @@ -8,5 +8,13 @@ fn main() -> Result<(), Box> { .build_client(true) .compile(&["proto/ampd.proto"], &["proto"])?; + tonic_build::configure() + .build_server(false) + .build_client(false) + .compile( + &["proto/axelar/auxiliary/v1beta1/tx.proto"], + &["proto", "proto/third_party"], + )?; + Ok(()) } diff --git a/ampd/proto/axelar/README.md b/ampd/proto/axelar/README.md new file mode 100644 index 000000000..519187b2b --- /dev/null +++ b/ampd/proto/axelar/README.md @@ -0,0 +1,11 @@ +# Axelar Protobufs + +This folder defines protobufs used by Axelar specific Cosmos SDK msg, event, and query types. + +## REST API + +The REST API (LCD) gets generated automatically from the gRPC service definitions. +The request/response types are defined in `query.proto` for the respective modules, and the query is defined in the `service.proto`. + +Note: The request types cannot make use of custom types encoded as bytes as that would be awkward +for REST-based calls. Instead, primitive types such as string is used (for e.g. when specifying addresses, instead of using sdk.AccAddress). diff --git a/ampd/proto/axelar/auxiliary/v1beta1/events.proto b/ampd/proto/axelar/auxiliary/v1beta1/events.proto new file mode 100644 index 000000000..90956b702 --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/events.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; +option (gogoproto.messagename_all) = true; + +import "gogoproto/gogo.proto"; + +message BatchedMessageFailed { + int32 index = 1; + string error = 2; +} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto b/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto new file mode 100644 index 000000000..0d766e10f --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/genesis.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState {} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/service.proto b/ampd/proto/axelar/auxiliary/v1beta1/service.proto new file mode 100644 index 000000000..6d2a08e9b --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/service.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/auxiliary/v1beta1/tx.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the nexus Msg service. +service MsgService { + rpc Batch(BatchRequest) returns (BatchResponse) { + option (google.api.http) = { + post : "/axelar/auxiliary/batch" + body : "*" + }; + } +} diff --git a/ampd/proto/axelar/auxiliary/v1beta1/tx.proto b/ampd/proto/axelar/auxiliary/v1beta1/tx.proto new file mode 100644 index 000000000..065016da4 --- /dev/null +++ b/ampd/proto/axelar/auxiliary/v1beta1/tx.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package axelar.auxiliary.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; + +import "axelar/permission/exported/v1beta1/types.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/auxiliary/types"; + +message BatchRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated google.protobuf.Any messages = 2 + [ (gogoproto.nullable) = false, (cosmos_proto.accepts_interface) = "cosmos.base.v1beta1.Msg" ]; +} + +message BatchResponse { + message Response { + oneof res { + cosmos.base.abci.v1beta1.Result result = 1; + string err = 2; + } + } + repeated Response responses = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/events.proto b/ampd/proto/axelar/axelarnet/v1beta1/events.proto new file mode 100644 index 000000000..a5e9e0a67 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/events.proto @@ -0,0 +1,131 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.messagename_all) = true; + +message IBCTransferSent { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string receipient = 2 [ deprecated = true ]; + cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; + uint64 sequence = 4; + string port_id = 5 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 6 [ (gogoproto.customname) = "ChannelID" ]; + string recipient = 7; +} + +message IBCTransferCompleted { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + uint64 sequence = 2; + string port_id = 3 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 4 [ (gogoproto.customname) = "ChannelID" ]; +} + +message IBCTransferFailed { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + uint64 sequence = 2; + string port_id = 3 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 4 [ (gogoproto.customname) = "ChannelID" ]; +} + +message IBCTransferRetried { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string receipient = 2 [ deprecated = true ]; + cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; + uint64 sequence = 4; + string port_id = 5 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 6 [ (gogoproto.customname) = "ChannelID" ]; + string recipient = 7; +} + +message AxelarTransferCompleted { + uint64 id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string receipient = 2 [ deprecated = true ]; + cosmos.base.v1beta1.Coin asset = 3 [ (gogoproto.nullable) = false ]; + string recipient = 4; +} + +message FeeCollected { + bytes collector = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + cosmos.base.v1beta1.Coin fee = 2 [ (gogoproto.nullable) = false ]; +} + +message FeePaid { + string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; + bytes recipient = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + cosmos.base.v1beta1.Coin fee = 3 [ (gogoproto.nullable) = false ]; + string refund_recipient = 4; + string asset = 5; // registered asset name in nexus +} + +message ContractCallSubmitted { + string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; + string sender = 2; + string source_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 5; + bytes payload = 6; + bytes payload_hash = 7; +} + +message ContractCallWithTokenSubmitted { + string message_id = 1 [ (gogoproto.customname) = "MessageID" ]; + string sender = 2; + string source_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 5; + bytes payload = 6; + bytes payload_hash = 7; + cosmos.base.v1beta1.Coin asset = 8 [ (gogoproto.nullable) = false ]; +} + +message TokenSent { + uint64 transfer_id = 1 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string sender = 2; + string source_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 5; + cosmos.base.v1beta1.Coin asset = 6 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto b/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto new file mode 100644 index 000000000..8cfea9cd5 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/genesis.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "axelar/axelarnet/v1beta1/params.proto"; +import "axelar/axelarnet/v1beta1/types.proto"; +import "axelar/utils/v1beta1/queuer.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GenesisState { + option (gogoproto.stable_marshaler) = true; + + Params params = 1 [ (gogoproto.nullable) = false ]; + bytes collector_address = 2 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated CosmosChain chains = 3 [ (gogoproto.nullable) = false ]; + reserved 4; // pending_transfers was removed in v0.20 + utils.v1beta1.QueueState transfer_queue = 5 [ (gogoproto.nullable) = false ]; + reserved 6; // failed_transfers was removed in v0.22 + repeated IBCTransfer ibc_transfers = 7 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "IBCTransfers" ]; + map seq_id_mapping = 8 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "SeqIDMapping" ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/params.proto b/ampd/proto/axelar/axelarnet/v1beta1/params.proto new file mode 100644 index 000000000..5d669fbc6 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/params.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + // IBC packet route timeout window + uint64 route_timeout_window = 1; + reserved 2; // transaction_fee_rate was removed in v0.15 + uint64 transfer_limit = 3; + uint64 end_blocker_limit = 4; + repeated CallContractProposalMinDeposit call_contracts_proposal_min_deposits = + 5 [ + (gogoproto.castrepeated) = "CallContractProposalMinDeposits", + (gogoproto.nullable) = false + ]; +} + +message CallContractProposalMinDeposit { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 2; + repeated cosmos.base.v1beta1.Coin min_deposits = 3 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto b/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto new file mode 100644 index 000000000..2994ca8c8 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/proposal.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package axelar.axelarnet.v1beta1; + +import "gogoproto/gogo.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; +option (gogoproto.goproto_getters_all) = false; + +// CallContractsProposal is a gov Content type for calling contracts on other +// chains +message CallContractsProposal { + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + repeated ContractCall contract_calls = 3 [ (gogoproto.nullable) = false ]; +} + +message ContractCall { + option (gogoproto.goproto_stringer) = false; + + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 2; + bytes payload = 3; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/query.proto b/ampd/proto/axelar/axelarnet/v1beta1/query.proto new file mode 100644 index 000000000..64fc7088d --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/query.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "axelar/axelarnet/v1beta1/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "axelar/nexus/v1beta1/query.proto"; +import "axelar/axelarnet/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message PendingIBCTransferCountRequest {} + +message PendingIBCTransferCountResponse { + map transfers_by_chain = 1 [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } + +// IBCPathRequest represents a message that queries the IBC path registered for +// a given chain +message IBCPathRequest { string chain = 1; } + +message IBCPathResponse { string ibc_path = 1 [ (gogoproto.customname) = "IBCPath" ]; } + +// ChainByIBCPathRequest represents a message that queries the chain that an IBC +// path is registered to +message ChainByIBCPathRequest { string ibc_path = 1; } + +message ChainByIBCPathResponse { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/service.proto b/ampd/proto/axelar/axelarnet/v1beta1/service.proto new file mode 100644 index 000000000..c2ed583e8 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/service.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/axelarnet/v1beta1/tx.proto"; +import "axelar/axelarnet/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the axelarnet Msg service. +service MsgService { + rpc Link(LinkRequest) returns (LinkResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/link" + body : "*" + }; + } + + rpc ConfirmDeposit(ConfirmDepositRequest) returns (ConfirmDepositResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/confirm_deposit" + body : "*" + }; + } + + rpc ExecutePendingTransfers(ExecutePendingTransfersRequest) + returns (ExecutePendingTransfersResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/execute_pending_transfers" + body : "*" + }; + } + + rpc AddCosmosBasedChain(AddCosmosBasedChainRequest) + returns (AddCosmosBasedChainResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/add_cosmos_based_chain" + body : "*" + }; + } + + rpc RegisterAsset(RegisterAssetRequest) returns (RegisterAssetResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/register_asset" + body : "*" + }; + } + + rpc RouteIBCTransfers(RouteIBCTransfersRequest) + returns (RouteIBCTransfersResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/route_ibc_transfers" + body : "*" + }; + } + + rpc RegisterFeeCollector(RegisterFeeCollectorRequest) + returns (RegisterFeeCollectorResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/register_fee_collector" + body : "*" + }; + } + + rpc RetryIBCTransfer(RetryIBCTransferRequest) + returns (RetryIBCTransferResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/retry_ibc_transfer" + body : "*" + }; + } + + rpc RouteMessage(RouteMessageRequest) returns (RouteMessageResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/route_message" + body : "*" + }; + } + + rpc CallContract(CallContractRequest) returns (CallContractResponse) { + option (google.api.http) = { + post : "/axelar/axelarnet/call_contract" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + + // PendingIBCTransferCount queries the pending ibc transfers for all chains + rpc PendingIBCTransferCount(PendingIBCTransferCountRequest) + returns (PendingIBCTransferCountResponse) { + option (google.api.http).get = + "/axelar/axelarnet/v1beta1/ibc_transfer_count"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/axelarnet/v1beta1/params" + }; + } + + rpc IBCPath(IBCPathRequest) returns (IBCPathResponse) { + option (google.api.http) = { + get : "/axelar/axelarnet/v1beta1/ibc_path/{chain}" + }; + } + + rpc ChainByIBCPath(ChainByIBCPathRequest) returns (ChainByIBCPathResponse) { + option (google.api.http) = { + get : "/axelar/axelarnet/v1beta1/chain_by_ibc_path/{ibc_path}" + }; + } +} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/tx.proto b/ampd/proto/axelar/axelarnet/v1beta1/tx.proto new file mode 100644 index 000000000..95c5e5c7c --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/tx.proto @@ -0,0 +1,188 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/axelarnet/v1beta1/types.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// MsgLink represents a message to link a cross-chain address to an Axelar +// address +message LinkRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string recipient_addr = 2; + string recipient_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string asset = 4; +} + +message LinkResponse { string deposit_addr = 1; }; + +// MsgConfirmDeposit represents a deposit confirmation message +message ConfirmDepositRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + reserved 2; // tx_id was removed in v0.14 + + reserved 3; // token was removed in v0.15 + + bytes deposit_address = 4 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + string denom = 5; +} + +message ConfirmDepositResponse {} + +// MsgExecutePendingTransfers represents a message to trigger transfer all +// pending transfers +message ExecutePendingTransfersRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message ExecutePendingTransfersResponse {} + +// MSgRegisterIBCPath represents a message to register an IBC tracing path for +// a cosmos chain +message RegisterIBCPathRequest { + option deprecated = true; + + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string path = 3; +} + +message RegisterIBCPathResponse {} + +// MsgAddCosmosBasedChain represents a message to register a cosmos based chain +// to nexus +message AddCosmosBasedChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + nexus.exported.v1beta1.Chain chain = 2 [ + deprecated = true, + (gogoproto.nullable) = false + ]; // chain was deprecated in v0.27 + string addr_prefix = 3; + reserved 4; // min_amount was removed in v0.15 + repeated nexus.exported.v1beta1.Asset native_assets = 5 [ + deprecated = true, + (gogoproto.nullable) = false + ]; // native_assets was deprecated in v0.27 + // TODO: Rename this to `chain` after v1beta1 -> v1 version bump + string cosmos_chain = 6 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string ibc_path = 7 [ (gogoproto.customname) = "IBCPath" ]; +} + +message AddCosmosBasedChainResponse {} + +// RegisterAssetRequest represents a message to register an asset to a cosmos +// based chain +message RegisterAssetRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + nexus.exported.v1beta1.Asset asset = 3 [ (gogoproto.nullable) = false ]; + bytes limit = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration window = 5 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message RegisterAssetResponse {} + +// RouteIBCTransfersRequest represents a message to route pending transfers to +// cosmos based chains +message RouteIBCTransfersRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RouteIBCTransfersResponse {} + +// RegisterFeeCollectorRequest represents a message to register axelarnet fee +// collector account +message RegisterFeeCollectorRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes fee_collector = 2 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RegisterFeeCollectorResponse {} + +message RetryIBCTransferRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 [ + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName", + deprecated = true + ]; + uint64 id = 3 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; +} + +message RetryIBCTransferResponse {} + +message RouteMessageRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string id = 2 [ (gogoproto.customname) = "ID" ]; + bytes payload = 3; + bytes feegranter = 4 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RouteMessageResponse {} + +message CallContractRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 3; + bytes payload = 4; + Fee fee = 5; +} + +message CallContractResponse {} diff --git a/ampd/proto/axelar/axelarnet/v1beta1/types.proto b/ampd/proto/axelar/axelarnet/v1beta1/types.proto new file mode 100644 index 000000000..b20ae2799 --- /dev/null +++ b/ampd/proto/axelar/axelarnet/v1beta1/types.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; +package axelar.axelarnet.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/axelarnet/types"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message IBCTransfer { + enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "TransferNonExistent" ]; + STATUS_PENDING = 1 [ (gogoproto.enumvalue_customname) = "TransferPending" ]; + STATUS_COMPLETED = 2 + [ (gogoproto.enumvalue_customname) = "TransferCompleted" ]; + STATUS_FAILED = 3 [ (gogoproto.enumvalue_customname) = "TransferFailed" ]; + } + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string receiver = 2; + cosmos.base.v1beta1.Coin token = 3 [ (gogoproto.nullable) = false ]; + string port_id = 4 [ (gogoproto.customname) = "PortID" ]; + string channel_id = 5 [ (gogoproto.customname) = "ChannelID" ]; + uint64 sequence = 6 [ deprecated = true ]; + uint64 id = 7 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + Status status = 8; +} + +message CosmosChain { + string name = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string ibc_path = 2 [ (gogoproto.customname) = "IBCPath" ]; + repeated Asset assets = 3 [ (gogoproto.nullable) = false, deprecated = true ]; + string addr_prefix = 4; +} + +message Asset { + option deprecated = true; + string denom = 1; + bytes min_amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message Fee { + cosmos.base.v1beta1.Coin amount = 1 [ (gogoproto.nullable) = false ]; + bytes recipient = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes refund_recipient = 3 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} diff --git a/ampd/proto/axelar/evm/v1beta1/events.proto b/ampd/proto/axelar/evm/v1beta1/events.proto new file mode 100644 index 000000000..bcdd74e99 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/events.proto @@ -0,0 +1,340 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; +option (gogoproto.messagename_all) = true; + +import "gogoproto/gogo.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +message PollFailed { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message PollExpired { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message PollCompleted { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message NoEventsConfirmed { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 poll_id = 3 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; +} + +message ConfirmKeyTransferStarted { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 4; + vote.exported.v1beta1.PollParticipants participants = 5 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; +} + +message ConfirmGatewayTxStarted { + option deprecated = true; + + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 4; + vote.exported.v1beta1.PollParticipants participants = 5 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; +} + +message PollMapping { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + uint64 poll_id = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID" + ]; +} + +message ConfirmGatewayTxsStarted { + repeated PollMapping poll_mappings = 1 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "poll_mappings,omitempty" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 4; + repeated bytes participants = 5 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +message ConfirmDepositStarted { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes deposit_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes token_address = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 confirmation_height = 5; + vote.exported.v1beta1.PollParticipants participants = 6 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; + string asset = 7; +} + +message ConfirmTokenStarted { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes gateway_address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes token_address = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + evm.v1beta1.TokenDetails token_details = 5 [ (gogoproto.nullable) = false ]; + uint64 confirmation_height = 6; + vote.exported.v1beta1.PollParticipants participants = 7 + [ (gogoproto.nullable) = false, (gogoproto.embed) = true ]; +} + +message ChainAdded { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CommandBatchSigned { + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; +} + +message CommandBatchAborted { + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; +} + +message EVMEventConfirmed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message EVMEventCompleted { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message EVMEventFailed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message EVMEventRetryFailed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + string type = 3; +} + +message ContractCallApproved { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + bytes command_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string sender = 4; + string destination_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 6; + bytes payload_hash = 7 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; +} + +message ContractCallFailed { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string msg_id = 2 [ (gogoproto.customname) = "MessageID" ]; +} + +message ContractCallWithMintApproved { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + bytes command_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string sender = 4; + string destination_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 6; + bytes payload_hash = 7 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + cosmos.base.v1beta1.Coin asset = 8 [ (gogoproto.nullable) = false ]; +} + +message TokenSent { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 2 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; + uint64 transfer_id = 3 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string sender = 4; + string destination_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 6; + cosmos.base.v1beta1.Coin asset = 7 [ (gogoproto.nullable) = false ]; +} + +message MintCommand { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 transfer_id = 2 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + bytes command_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 5; + cosmos.base.v1beta1.Coin asset = 6 [ (gogoproto.nullable) = false ]; +} + +message BurnCommand { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_id = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandID", + (gogoproto.customtype) = "CommandID" + ]; + string destination_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string deposit_address = 4; + string asset = 5; +} diff --git a/ampd/proto/axelar/evm/v1beta1/genesis.proto b/ampd/proto/axelar/evm/v1beta1/genesis.proto new file mode 100644 index 000000000..3e0edc463 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/genesis.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "axelar/utils/v1beta1/queuer.proto"; +import "gogoproto/gogo.proto"; +import "axelar/evm/v1beta1/params.proto"; +import "axelar/evm/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + option (gogoproto.stable_marshaler) = true; + + message Chain { + Params params = 1 [ (gogoproto.nullable) = false ]; + repeated BurnerInfo burner_infos = 2 [ (gogoproto.nullable) = false ]; + utils.v1beta1.QueueState command_queue = 3 [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit confirmed_deposits = 4 + [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit burned_deposits = 5 [ (gogoproto.nullable) = false ]; + + repeated CommandBatchMetadata command_batches = 8 + [ (gogoproto.nullable) = false ]; + + Gateway gateway = 9 [ (gogoproto.nullable) = false ]; + repeated ERC20TokenMetadata tokens = 10 [ (gogoproto.nullable) = false ]; + repeated Event events = 11 [ (gogoproto.nullable) = false ]; + utils.v1beta1.QueueState confirmed_event_queue = 12 + [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit legacy_confirmed_deposits = 13 + [ (gogoproto.nullable) = false ]; + repeated ERC20Deposit legacy_burned_deposits = 14 + [ (gogoproto.nullable) = false ]; + } + + repeated Chain chains = 3 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/evm/v1beta1/params.proto b/ampd/proto/axelar/evm/v1beta1/params.proto new file mode 100644 index 000000000..6fc387be1 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/params.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "gogoproto/gogo.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params is the parameter set for this module +message Params { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + uint64 confirmation_height = 2; + string network = 3; + reserved 4; // gateway_code was removed in v0.16 + bytes token_code = 5; + bytes burnable = 6; + int64 revote_locking_period = 7; + repeated evm.v1beta1.NetworkInfo networks = 8 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold voting_threshold = 9 [ (gogoproto.nullable) = false ]; + int64 min_voter_count = 10; + uint32 commands_gas_limit = 11; + reserved 12; // transaction_fee_rate was removed in v0.15 + int64 voting_grace_period = 13; + int64 end_blocker_limit = 14; + uint64 transfer_limit = 15; +} + +message PendingChain { + Params params = 1 [ (gogoproto.nullable) = false ]; + nexus.exported.v1beta1.Chain chain = 2 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/evm/v1beta1/query.proto b/ampd/proto/axelar/evm/v1beta1/query.proto new file mode 100644 index 000000000..61de10b01 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/query.proto @@ -0,0 +1,243 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "gogoproto/gogo.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "axelar/evm/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// DepositQueryParams describe the parameters used to query for an EVM +// deposit address +message DepositQueryParams { + string address = 1; + string asset = 2; + string chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message BatchedCommandsRequest { + string chain = 1; + // id defines an optional id for the commandsbatch. If not specified the + // latest will be returned + string id = 2; +} + +message BatchedCommandsResponse { + string id = 1 [ (gogoproto.customname) = "ID" ]; + string data = 2; + BatchedCommandsStatus status = 3; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + reserved 5; // signature was removed in v0.20.0 + string execute_data = 6; + string prev_batched_commands_id = 7 + [ (gogoproto.customname) = "PrevBatchedCommandsID" ]; + repeated string command_ids = 8 [ (gogoproto.customname) = "CommandIDs" ]; + Proof proof = 9; +} + +message KeyAddressRequest { + reserved 2, 3; + + string chain = 1; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeyAddressResponse { + message WeightedAddress { + string address = 1; + string weight = 2; + }; + + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + repeated WeightedAddress addresses = 2 [ (gogoproto.nullable) = false ]; + string threshold = 3; +} + +message QueryTokenAddressResponse { + option deprecated = true; // Deprecated in v19 + + string address = 1; + bool confirmed = 2; +} + +message QueryDepositStateParams { + option deprecated = true; + + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes burner_address = 2 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message DepositStateRequest { + option deprecated = true; + + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + QueryDepositStateParams params = 2; +} + +message DepositStateResponse { + option deprecated = true; + + DepositStatus status = 2; +} + +message EventRequest { + string chain = 1; + string event_id = 2; +} + +message EventResponse { Event event = 1; } + +message QueryBurnerAddressResponse { string address = 1; } + +enum ChainStatus { + option (gogoproto.goproto_enum_prefix) = false; + + CHAIN_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "StatusUnspecified" ]; + CHAIN_STATUS_ACTIVATED = 1 [ (gogoproto.enumvalue_customname) = "Activated" ]; + CHAIN_STATUS_DEACTIVATED = 2 + [ (gogoproto.enumvalue_customname) = "Deactivated" ]; +} + +message ChainsRequest { ChainStatus status = 1; } + +message ChainsResponse { + repeated string chains = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CommandRequest { + string chain = 1; + string id = 2 [ (gogoproto.customname) = "ID" ]; +} + +message CommandResponse { + string id = 1 [ (gogoproto.customname) = "ID" ]; + string type = 2; + map params = 3 [ (gogoproto.nullable) = false ]; + string key_id = 4 [ (gogoproto.customname) = "KeyID" ]; + uint32 max_gas_cost = 5; +} + +message PendingCommandsRequest { string chain = 1; } + +message PendingCommandsResponse { + repeated QueryCommandResponse commands = 1 [ (gogoproto.nullable) = false ]; +} + +message QueryCommandResponse { + string id = 1 [ (gogoproto.customname) = "ID" ]; + string type = 2; + map params = 3 [ (gogoproto.nullable) = false ]; + string key_id = 4 [ (gogoproto.customname) = "KeyID" ]; + uint32 max_gas_cost = 5; +} + +message BurnerInfoRequest { + bytes address = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message BurnerInfoResponse { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + BurnerInfo burner_info = 2; +} + +message ConfirmationHeightRequest { string chain = 1; } + +message ConfirmationHeightResponse { uint64 height = 1; } + +message GatewayAddressRequest { string chain = 1; } + +message GatewayAddressResponse { string address = 1; } + +message BytecodeRequest { + string chain = 1; + string contract = 2; +} + +message BytecodeResponse { string bytecode = 1; } + +enum TokenType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + TOKEN_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + TOKEN_TYPE_INTERNAL = 1 [ (gogoproto.enumvalue_customname) = "Internal" ]; + TOKEN_TYPE_EXTERNAL = 2 [ (gogoproto.enumvalue_customname) = "External" ]; +} + +// ERC20TokensRequest describes the chain for which the type of ERC20 tokens are +// requested. +message ERC20TokensRequest { + string chain = 1; + TokenType type = 2; +} + +// ERC20TokensResponse describes the asset and symbol for all +// ERC20 tokens requested for a chain +message ERC20TokensResponse { + message Token { + string asset = 1; + string symbol = 2; + } + + repeated Token tokens = 1 [ (gogoproto.nullable) = false ]; +} + +message TokenInfoRequest { + string chain = 1; + oneof find_by { + string asset = 2; + string symbol = 3; + string address = 4; + } +} + +message TokenInfoResponse { + string asset = 1; + TokenDetails details = 2 [ (gogoproto.nullable) = false ]; + string address = 3; + bool confirmed = 4; + bool is_external = 5; + string burner_code_hash = 6; +} + +message Proof { + repeated string addresses = 1; + repeated string weights = 2; + string threshold = 3; + repeated string signatures = 4; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest { string chain = 1; } + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/evm/v1beta1/service.proto b/ampd/proto/axelar/evm/v1beta1/service.proto new file mode 100644 index 000000000..6cc9b02f0 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/service.proto @@ -0,0 +1,208 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/evm/v1beta1/tx.proto"; +import "axelar/evm/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the evm Msg service. +service MsgService { + rpc SetGateway(SetGatewayRequest) returns (SetGatewayResponse) { + option (google.api.http) = { + post : "/axelar/evm/set_gateway" + body : "*" + }; + } + + // Deprecated: use ConfirmGatewayTxs instead + rpc ConfirmGatewayTx(ConfirmGatewayTxRequest) + returns (ConfirmGatewayTxResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_gateway_tx" + body : "*" + }; + } + + rpc ConfirmGatewayTxs(ConfirmGatewayTxsRequest) + returns (ConfirmGatewayTxsResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_gateway_txs" + body : "*" + }; + } + + rpc Link(LinkRequest) returns (LinkResponse) { + option (google.api.http) = { + post : "/axelar/evm/link" + body : "*" + }; + } + + rpc ConfirmToken(ConfirmTokenRequest) returns (ConfirmTokenResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_token" + body : "*" + }; + } + + rpc ConfirmDeposit(ConfirmDepositRequest) returns (ConfirmDepositResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_deposit" + body : "*" + }; + } + + rpc ConfirmTransferKey(ConfirmTransferKeyRequest) + returns (ConfirmTransferKeyResponse) { + option (google.api.http) = { + post : "/axelar/evm/confirm_transfer_key" + body : "*" + }; + } + + rpc CreateDeployToken(CreateDeployTokenRequest) + returns (CreateDeployTokenResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_deploy_token" + body : "*" + }; + } + + rpc CreateBurnTokens(CreateBurnTokensRequest) + returns (CreateBurnTokensResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_burn_tokens" + body : "*" + }; + } + + rpc CreatePendingTransfers(CreatePendingTransfersRequest) + returns (CreatePendingTransfersResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_pending_transfers" + body : "*" + }; + } + + rpc CreateTransferOperatorship(CreateTransferOperatorshipRequest) + returns (CreateTransferOperatorshipResponse) { + option (google.api.http) = { + post : "/axelar/evm/create_transfer_operatorship" + body : "*" + }; + } + + rpc SignCommands(SignCommandsRequest) returns (SignCommandsResponse) { + option (google.api.http) = { + post : "/axelar/evm/sign_commands" + body : "*" + }; + } + + rpc AddChain(AddChainRequest) returns (AddChainResponse) { + option (google.api.http) = { + post : "/axelar/evm/add_chain" + body : "*" + }; + } + + rpc RetryFailedEvent(RetryFailedEventRequest) + returns (RetryFailedEventResponse) { + option (google.api.http) = { + post : "/axelar/evm/retry-failed-event" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + + // BatchedCommands queries the batched commands for a specified chain and + // BatchedCommandsID if no BatchedCommandsID is specified, then it returns the + // latest batched commands + rpc BatchedCommands(BatchedCommandsRequest) + returns (BatchedCommandsResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/batched_commands/{chain}/{id}"; + } + + // BurnerInfo queries the burner info for the specified address + rpc BurnerInfo(BurnerInfoRequest) returns (BurnerInfoResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/burner_info"; + } + + // ConfirmationHeight queries the confirmation height for the specified chain + rpc ConfirmationHeight(ConfirmationHeightRequest) + returns (ConfirmationHeightResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/confirmation_height/{chain}"; + } + + // DepositState queries the state of the specified deposit + rpc DepositState(DepositStateRequest) returns (DepositStateResponse) { + option deprecated = true; + option (google.api.http).get = "/axelar/evm/v1beta1/deposit_state"; + } + + // PendingCommands queries the pending commands for the specified chain + rpc PendingCommands(PendingCommandsRequest) + returns (PendingCommandsResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/pending_commands/{chain}"; + } + + // Chains queries the available evm chains + rpc Chains(ChainsRequest) returns (ChainsResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/chains"; + } + + // Command queries the command of a chain provided the command id + rpc Command(CommandRequest) returns (CommandResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/command_request"; + } + + // KeyAddress queries the address of key of a chain + rpc KeyAddress(KeyAddressRequest) returns (KeyAddressResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/key_address/{chain}"; + } + + // GatewayAddress queries the address of axelar gateway at the specified + // chain + rpc GatewayAddress(GatewayAddressRequest) returns (GatewayAddressResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/gateway_address/{chain}"; + } + + // Bytecode queries the bytecode of a specified gateway at the specified + // chain + rpc Bytecode(BytecodeRequest) returns (BytecodeResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/bytecode/{chain}/{contract}"; + } + + // Event queries an event at the specified chain + rpc Event(EventRequest) returns (EventResponse) { + option (google.api.http).get = + "/axelar/evm/v1beta1/event/{chain}/{event_id}"; + } + + // ERC20Tokens queries the ERC20 tokens registered for a chain + rpc ERC20Tokens(ERC20TokensRequest) returns (ERC20TokensResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/erc20_tokens/{chain}"; + } + + // TokenInfo queries the token info for a registered ERC20 Token + rpc TokenInfo(TokenInfoRequest) returns (TokenInfoResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/token_info/{chain}"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http).get = "/axelar/evm/v1beta1/params/{chain}"; + } +} diff --git a/ampd/proto/axelar/evm/v1beta1/tx.proto b/ampd/proto/axelar/evm/v1beta1/tx.proto new file mode 100644 index 000000000..9aaef12e4 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/tx.proto @@ -0,0 +1,259 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "gogoproto/gogo.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; +import "axelar/evm/v1beta1/types.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message SetGatewayRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes address = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message SetGatewayResponse {} + +message ConfirmGatewayTxRequest { + option deprecated = true; + + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; +} + +message ConfirmGatewayTxResponse { option deprecated = true; } + +message ConfirmGatewayTxsRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated bytes tx_ids = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxIDs" + ]; +} + +message ConfirmGatewayTxsResponse {} + +// MsgConfirmDeposit represents an erc20 deposit confirmation message +message ConfirmDepositRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes amount = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false, + deprecated = true + ]; + bytes burner_address = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message ConfirmDepositResponse {} + +// MsgConfirmToken represents a token deploy confirmation message +message ConfirmTokenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + Asset asset = 4 [ (gogoproto.nullable) = false ]; +} + +message ConfirmTokenResponse {} + +message ConfirmTransferKeyRequest { + reserved 4, 5; // transfer_type and key_id were deleted in v0.20 + + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 3 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; +} + +message ConfirmTransferKeyResponse {} + +// MsgLink represents the message that links a cross chain address to a burner +// address +message LinkRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string recipient_addr = 3; + string asset = 4; + string recipient_chain = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message LinkResponse { string deposit_addr = 1; } + +// CreateBurnTokensRequest represents the message to create commands to burn +// tokens with AxelarGateway +message CreateBurnTokensRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CreateBurnTokensResponse {} + +// CreateDeployTokenRequest represents the message to create a deploy token +// command for AxelarGateway +message CreateDeployTokenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + Asset asset = 3 [ (gogoproto.nullable) = false ]; + TokenDetails token_details = 4 [ (gogoproto.nullable) = false ]; + reserved 5; // min_amount was removed in v0.15 + bytes address = 6 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string daily_mint_limit = 7; +} + +message CreateDeployTokenResponse {} + +// CreatePendingTransfersRequest represents a message to trigger the creation of +// commands handling all pending transfers +message CreatePendingTransfersRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message CreatePendingTransfersResponse {} + +message CreateTransferOwnershipRequest { + option deprecated = true; + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message CreateTransferOwnershipResponse { option deprecated = true; } + +message CreateTransferOperatorshipRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message CreateTransferOperatorshipResponse {} + +message SignCommandsRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message SignCommandsResponse { + bytes batched_commands_id = 1 + [ (gogoproto.customname) = "BatchedCommandsID" ]; + uint32 command_count = 2; +} + +message AddChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + reserved 3; // native_asset was removed in v0.14 + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string name = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + tss.exported.v1beta1.KeyType key_type = 4 [ deprecated = true ]; + bytes params = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Params" ]; +} + +message AddChainResponse {} + +message RetryFailedEventRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string event_id = 3 + [ (gogoproto.customname) = "EventID", (gogoproto.casttype) = "EventID" ]; +} + +message RetryFailedEventResponse {} diff --git a/ampd/proto/axelar/evm/v1beta1/types.proto b/ampd/proto/axelar/evm/v1beta1/types.proto new file mode 100644 index 000000000..13a849cf9 --- /dev/null +++ b/ampd/proto/axelar/evm/v1beta1/types.proto @@ -0,0 +1,375 @@ +syntax = "proto3"; +package axelar.evm.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/evm/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/multisig/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message VoteEvents { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated Event events = 2 [ (gogoproto.nullable) = false ]; +} + +message Event { + enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "EventNonExistent" ]; + STATUS_CONFIRMED = 1 + [ (gogoproto.enumvalue_customname) = "EventConfirmed" ]; + STATUS_COMPLETED = 2 + [ (gogoproto.enumvalue_customname) = "EventCompleted" ]; + STATUS_FAILED = 3 [ (gogoproto.enumvalue_customname) = "EventFailed" ]; + } + + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 2 [ + (gogoproto.customname) = "TxID", + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash" + ]; + uint64 index = 3; + Status status = 4; + + oneof event { + EventTokenSent token_sent = 5; + EventContractCall contract_call = 6; + EventContractCallWithToken contract_call_with_token = 7; + EventTransfer transfer = 8; + EventTokenDeployed token_deployed = 9; + EventMultisigOwnershipTransferred multisig_ownership_transferred = 10 + [ deprecated = true ]; + EventMultisigOperatorshipTransferred multisig_operatorship_transferred = 11; + } + + reserved 12; // singlesig_ownership_transferred was removed in v0.23 + reserved 13; // singlesig_operatorship_transferred was removed in v0.23 +} + +message EventTokenSent { + bytes sender = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string destination_address = 3; + string symbol = 4; + bytes amount = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventContractCall { + bytes sender = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 3; + bytes payload_hash = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; +} + +message EventContractCallWithToken { + bytes sender = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string contract_address = 3; + bytes payload_hash = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + string symbol = 5; + bytes amount = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventTransfer { + bytes to = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventTokenDeployed { + string symbol = 1; + bytes token_address = 2 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message EventMultisigOwnershipTransferred { + option deprecated = true; + + repeated bytes pre_owners = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes prev_threshold = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + repeated bytes new_owners = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes new_threshold = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message EventMultisigOperatorshipTransferred { + reserved 1, 2; // pre_operators and prev_threshold were removed in v0.20 + + repeated bytes new_operators = 3 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes new_threshold = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + repeated bytes new_weights = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +// NetworkInfo describes information about a network +message NetworkInfo { + string name = 1; + bytes id = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// BurnerInfo describes information required to burn token at an burner address +// that is deposited by an user +message BurnerInfo { + bytes burner_address = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + bytes token_address = 2 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string destination_chain = 3 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string symbol = 4; + string asset = 5; + bytes salt = 6 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; +} + +// ERC20Deposit contains information for an ERC20 deposit +message ERC20Deposit { + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + bytes amount = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + string asset = 3; + string destination_chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes burner_address = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + uint64 log_index = 6; +} + +// ERC20TokenMetadata describes information about an ERC20 token +message ERC20TokenMetadata { + string asset = 1; + bytes chain_id = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.customname) = "ChainID", + (gogoproto.nullable) = false + ]; + TokenDetails details = 3 [ (gogoproto.nullable) = false ]; + string token_address = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; + string tx_hash = 5 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + reserved 6; // min_amount was removed in v0.15 + Status status = 7; + bool is_external = 8; + bytes burner_code = 9; +} + +enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + // these enum values are used for bitwise operations, therefore they need to + // be powers of 2 + STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + STATUS_INITIALIZED = 1 [ (gogoproto.enumvalue_customname) = "Initialized" ]; + STATUS_PENDING = 2 [ (gogoproto.enumvalue_customname) = "Pending" ]; + STATUS_CONFIRMED = 4 [ (gogoproto.enumvalue_customname) = "Confirmed" ]; +} + +message TransactionMetadata { + bytes raw_tx = 1 [ (gogoproto.customname) = "RawTX" ]; + bytes pub_key = 2; +} + +enum CommandType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = false; + + COMMAND_TYPE_UNSPECIFIED = 0; + COMMAND_TYPE_MINT_TOKEN = 1; + COMMAND_TYPE_DEPLOY_TOKEN = 2; + COMMAND_TYPE_BURN_TOKEN = 3; + COMMAND_TYPE_TRANSFER_OPERATORSHIP = 4; + COMMAND_TYPE_APPROVE_CONTRACT_CALL_WITH_MINT = 5; + COMMAND_TYPE_APPROVE_CONTRACT_CALL = 6; +} + +message Command { + bytes id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "ID", + (gogoproto.customtype) = "CommandID" + ]; + string command = 2 [ deprecated = true ]; + bytes params = 3; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + uint32 max_gas_cost = 5; + CommandType type = 6; +} + +enum BatchedCommandsStatus { + option (gogoproto.goproto_enum_prefix) = false; + + BATCHED_COMMANDS_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "BatchNonExistent" ]; + BATCHED_COMMANDS_STATUS_SIGNING = 1 + [ (gogoproto.enumvalue_customname) = "BatchSigning" ]; + BATCHED_COMMANDS_STATUS_ABORTED = 2 + [ (gogoproto.enumvalue_customname) = "BatchAborted" ]; + BATCHED_COMMANDS_STATUS_SIGNED = 3 + [ (gogoproto.enumvalue_customname) = "BatchSigned" ]; +} + +message CommandBatchMetadata { + bytes id = 1 [ (gogoproto.customname) = "ID" ]; + repeated bytes command_ids = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "CommandIDs", + (gogoproto.customtype) = "CommandID" + ]; + bytes data = 3; + bytes sig_hash = 4 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Hash" ]; + BatchedCommandsStatus status = 5; + string key_id = 6 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes prev_batched_commands_id = 7 + [ (gogoproto.customname) = "PrevBatchedCommandsID" ]; + google.protobuf.Any signature = 8 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +// SigMetadata stores necessary information for external apps to map signature +// results to evm relay transaction types +message SigMetadata { + SigType type = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes command_batch_id = 3 [ (gogoproto.customname) = "CommandBatchID" ]; +} + +enum SigType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + SIG_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "None" ]; + SIG_TYPE_TX = 1 [ (gogoproto.enumvalue_customname) = "SigTx" ]; + SIG_TYPE_COMMAND = 2 [ (gogoproto.enumvalue_customname) = "SigCommand" ]; +} + +// TransferKey contains information for a transfer operatorship +message TransferKey { + reserved 2; // type was deleted in v0.20 + + bytes tx_id = 1 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash", + (gogoproto.customname) = "TxID" + ]; + string next_key_id = 3 [ + (gogoproto.customname) = "NextKeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +enum DepositStatus { + option (gogoproto.goproto_enum_prefix) = true; + option (gogoproto.goproto_enum_stringer) = true; + + DEPOSIT_STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "None" ]; + DEPOSIT_STATUS_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + DEPOSIT_STATUS_CONFIRMED = 2 + [ (gogoproto.enumvalue_customname) = "Confirmed" ]; + DEPOSIT_STATUS_BURNED = 3 [ (gogoproto.enumvalue_customname) = "Burned" ]; +} + +message Asset { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string name = 2; +} + +message TokenDetails { + string token_name = 1; + string symbol = 2; + uint32 decimals = 3 [ (gogoproto.casttype) = "uint8" ]; + bytes capacity = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message Gateway { + reserved 2; // status was removed in v0.27 + + bytes address = 1 + [ (gogoproto.nullable) = false, (gogoproto.customtype) = "Address" ]; +} + +message PollMetadata { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + bytes tx_id = 2 [ + (gogoproto.customname) = "TxID", + (gogoproto.nullable) = false, + (gogoproto.customtype) = "Hash" + ]; +} diff --git a/ampd/proto/axelar/multisig/exported/v1beta1/types.proto b/ampd/proto/axelar/multisig/exported/v1beta1/types.proto new file mode 100644 index 000000000..97014922f --- /dev/null +++ b/ampd/proto/axelar/multisig/exported/v1beta1/types.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package axelar.multisig.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/exported"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +enum MultisigState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + MULTISIG_STATE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + MULTISIG_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + MULTISIG_STATE_COMPLETED = 2 + [ (gogoproto.enumvalue_customname) = "Completed" ]; +} + +enum KeyState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_STATE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "Inactive" ]; + KEY_STATE_ASSIGNED = 1 [ (gogoproto.enumvalue_customname) = "Assigned" ]; + KEY_STATE_ACTIVE = 2 [ (gogoproto.enumvalue_customname) = "Active" ]; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/events.proto b/ampd/proto/axelar/multisig/v1beta1/events.proto new file mode 100644 index 000000000..80607c48e --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/events.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; + +message KeygenStarted { + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + repeated bytes participants = 3 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +message KeygenCompleted { + option (gogoproto.messagename) = true; + + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeygenExpired { + option (gogoproto.messagename) = true; + + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message PubKeySubmitted { + string module = 1; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes participant = 3 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes pub_key = 4 [ + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; +} + +message SigningStarted { + option (gogoproto.stable_marshaler) = true; + + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + map pub_keys = 4 [ + (gogoproto.castvalue) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; + bytes payload_hash = 5 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.Hash" ]; + string requesting_module = 6; +} + +message SigningCompleted { + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; +} + +message SigningExpired { + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; +} + +message SignatureSubmitted { + string module = 1; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + bytes participant = 3 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes signature = 4 [ (gogoproto.casttype) = "Signature" ]; +} + +message KeyAssigned { + string module = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeyRotated { + string module = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeygenOptOut { + bytes participant = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message KeygenOptIn { + bytes participant = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/genesis.proto b/ampd/proto/axelar/multisig/v1beta1/genesis.proto new file mode 100644 index 000000000..adbe82867 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/genesis.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "axelar/multisig/v1beta1/params.proto"; +import "axelar/multisig/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated KeygenSession keygen_sessions = 2 [ (gogoproto.nullable) = false ]; + repeated SigningSession signing_sessions = 3 [ (gogoproto.nullable) = false ]; + repeated Key keys = 4 [ (gogoproto.nullable) = false ]; + repeated KeyEpoch key_epochs = 5 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/params.proto b/ampd/proto/axelar/multisig/v1beta1/params.proto new file mode 100644 index 000000000..da500f485 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/params.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + utils.v1beta1.Threshold keygen_threshold = 1 [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold signing_threshold = 2 + [ (gogoproto.nullable) = false ]; + int64 keygen_timeout = 3; + int64 keygen_grace_period = 4; + int64 signing_timeout = 5; + int64 signing_grace_period = 6; + uint64 active_epoch_count = 7; +} diff --git a/ampd/proto/axelar/multisig/v1beta1/query.proto b/ampd/proto/axelar/multisig/v1beta1/query.proto new file mode 100644 index 000000000..d3b33c622 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/query.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "axelar/multisig/exported/v1beta1/types.proto"; +import "axelar/multisig/v1beta1/types.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/multisig/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message KeyIDRequest { string chain = 1; } + +// KeyIDResponse contains the key ID of the key assigned to a given chain. +message KeyIDResponse { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message NextKeyIDRequest { string chain = 1; } + +// NextKeyIDResponse contains the key ID for the next rotation on the given +// chain +message NextKeyIDResponse { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeyRequest { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message KeygenParticipant { + string address = 1; + bytes weight = 2 [ + (gogoproto.nullable) = false, + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint" + ]; + string pub_key = 3; +} + +// KeyResponse contains the key corresponding to a given key id. +message KeyResponse { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + multisig.exported.v1beta1.KeyState state = 2; + int64 started_at = 3; + google.protobuf.Timestamp started_at_timestamp = 4 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + bytes threshold_weight = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + bytes bonded_weight = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + // Keygen participants in descending order by weight + repeated KeygenParticipant participants = 7 [ (gogoproto.nullable) = false ]; +} + +message KeygenSessionRequest { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +// KeygenSessionResponse contains the keygen session info for a given key ID. +message KeygenSessionResponse { + int64 started_at = 1; + google.protobuf.Timestamp started_at_timestamp = 2 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + int64 expires_at = 3; + int64 completed_at = 4; + int64 grace_period = 5; + multisig.exported.v1beta1.MultisigState state = 6; + bytes keygen_threshold_weight = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + bytes signing_threshold_weight = 8 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + bytes bonded_weight = 9 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + // Keygen candidates in descending order by weight + repeated KeygenParticipant participants = 10 [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/multisig/v1beta1/service.proto b/ampd/proto/axelar/multisig/v1beta1/service.proto new file mode 100644 index 000000000..c7c39ae60 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/service.proto @@ -0,0 +1,92 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/multisig/v1beta1/tx.proto"; +import "axelar/multisig/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the multisig Msg service. +service MsgService { + rpc StartKeygen(StartKeygenRequest) returns (StartKeygenResponse) { + option (google.api.http) = { + post : "/axelar/multisig/start_keygen" + body : "*" + }; + } + + rpc SubmitPubKey(SubmitPubKeyRequest) returns (SubmitPubKeyResponse) { + option (google.api.http) = { + post : "/axelar/multisig/submit_pub_key" + body : "*" + }; + } + + rpc SubmitSignature(SubmitSignatureRequest) + returns (SubmitSignatureResponse) { + option (google.api.http) = { + post : "/axelar/multisig/submit_signature" + body : "*" + }; + } + + rpc RotateKey(RotateKeyRequest) returns (RotateKeyResponse) { + option (google.api.http) = { + post : "/axelar/multisig/rotate_key" + body : "*" + }; + } + + rpc KeygenOptOut(KeygenOptOutRequest) returns (KeygenOptOutResponse) { + option (google.api.http) = { + post : "/axelar/multisig/v1beta1/keygen_opt_out" + body : "*" + }; + } + + rpc KeygenOptIn(KeygenOptInRequest) returns (KeygenOptInResponse) { + option (google.api.http) = { + post : "/axelar/multisig/v1beta1/keygen_opt_in" + body : "*" + }; + } +} + +// Query defines the gRPC querier service. +service QueryService { + // KeyID returns the key ID of a key assigned to a given chain. + // If no key is assigned, it returns the grpc NOT_FOUND error. + rpc KeyID(KeyIDRequest) returns (KeyIDResponse) { + option (google.api.http).get = "/axelar/multisig/v1beta1/key_id/{chain}"; + } + + // NextKeyID returns the key ID assigned for the next rotation on a given + // chain. If no key rotation is in progress, it returns the grpc NOT_FOUND + // error. + rpc NextKeyID(NextKeyIDRequest) returns (NextKeyIDResponse) { + option (google.api.http).get = + "/axelar/multisig/v1beta1/next_key_id/{chain}"; + } + + // Key returns the key corresponding to a given key ID. + // If no key is found, it returns the grpc NOT_FOUND error. + rpc Key(KeyRequest) returns (KeyResponse) { + option (google.api.http).get = "/axelar/multisig/v1beta1/key"; + } + + // KeygenSession returns the keygen session info for a given key ID. + // If no key is found, it returns the grpc NOT_FOUND error. + rpc KeygenSession(KeygenSessionRequest) returns (KeygenSessionResponse) { + option (google.api.http).get = "/axelar/multisig/v1beta1/keygen_session"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/multisig/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/multisig/v1beta1/tx.proto b/ampd/proto/axelar/multisig/v1beta1/tx.proto new file mode 100644 index 000000000..f816389e3 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/tx.proto @@ -0,0 +1,86 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; +option (gogoproto.goproto_getters_all) = false; + +import "gogoproto/gogo.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +message StartKeygenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message StartKeygenResponse {} + +message SubmitPubKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes pub_key = 3 [ + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; + bytes signature = 4 [ (gogoproto.casttype) = "Signature" ]; +} + +message SubmitPubKeyResponse {} + +message SubmitSignatureRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + uint64 sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + bytes signature = 3 [ (gogoproto.casttype) = "Signature" ]; +} + +message SubmitSignatureResponse {} + +message RotateKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} + +message RotateKeyResponse {} + +message KeygenOptOutRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message KeygenOptOutResponse {} + +message KeygenOptInRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message KeygenOptInResponse {} diff --git a/ampd/proto/axelar/multisig/v1beta1/types.proto b/ampd/proto/axelar/multisig/v1beta1/types.proto new file mode 100644 index 000000000..fe32c3da6 --- /dev/null +++ b/ampd/proto/axelar/multisig/v1beta1/types.proto @@ -0,0 +1,84 @@ +syntax = "proto3"; +package axelar.multisig.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/multisig/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/snapshot/exported/v1beta1/types.proto"; +import "axelar/multisig/exported/v1beta1/types.proto"; + +message Key { + option (gogoproto.stable_marshaler) = true; + + string id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + snapshot.exported.v1beta1.Snapshot snapshot = 2 + [ (gogoproto.nullable) = false ]; + map pub_keys = 3 [ + (gogoproto.castvalue) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.PublicKey" + ]; + utils.v1beta1.Threshold signing_threshold = 4 + [ (gogoproto.nullable) = false ]; + multisig.exported.v1beta1.KeyState state = 5; +} + +message KeygenSession { + option (gogoproto.stable_marshaler) = true; + + Key key = 1 [ (gogoproto.nullable) = false ]; + multisig.exported.v1beta1.MultisigState state = 2; + utils.v1beta1.Threshold keygen_threshold = 3 [ (gogoproto.nullable) = false ]; + int64 expires_at = 4; + int64 completed_at = 5; + map is_pub_key_received = 6; + int64 grace_period = 7; +} + +message MultiSig { + option (gogoproto.stable_marshaler) = true; + + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; + bytes payload_hash = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.Hash" ]; + map sigs = 3 [ (gogoproto.castvalue) = "Signature" ]; +} + +message SigningSession { + option (gogoproto.stable_marshaler) = true; + + uint64 id = 1 [ (gogoproto.customname) = "ID" ]; + MultiSig multi_sig = 2 [ (gogoproto.nullable) = false ]; + multisig.exported.v1beta1.MultisigState state = 3; + Key key = 4 [ (gogoproto.nullable) = false ]; + int64 expires_at = 5; + int64 completed_at = 6; + int64 grace_period = 7; + string module = 8; + google.protobuf.Any module_metadata = 9 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +message KeyEpoch { + uint64 epoch = 1; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string key_id = 3 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/multisig/exported.KeyID" + ]; +} diff --git a/ampd/proto/axelar/nexus/exported/v1beta1/types.proto b/ampd/proto/axelar/nexus/exported/v1beta1/types.proto new file mode 100644 index 000000000..f108c119f --- /dev/null +++ b/ampd/proto/axelar/nexus/exported/v1beta1/types.proto @@ -0,0 +1,129 @@ +syntax = "proto3"; +package axelar.nexus.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/exported"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Chain represents the properties of a registered blockchain +message Chain { + reserved 2; // native_asset was removed in 0.14 + + string name = 1 [ (gogoproto.casttype) = "ChainName" ]; + bool supports_foreign_assets = 3; + tss.exported.v1beta1.KeyType key_type = 4; + string module = 5; +} + +// CrossChainAddress represents a generalized address on any registered chain +message CrossChainAddress { + Chain chain = 1 [ (gogoproto.nullable) = false ]; + string address = 2; +} + +// CrossChainTransfer represents a generalized transfer of some asset to a +// registered blockchain +message CrossChainTransfer { + CrossChainAddress recipient = 1 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin asset = 2 [ (gogoproto.nullable) = false ]; + uint64 id = 3 + [ (gogoproto.customname) = "ID", (gogoproto.casttype) = "TransferID" ]; + TransferState state = 4; +} + +enum TransferState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + TRANSFER_STATE_UNSPECIFIED = 0; + TRANSFER_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + TRANSFER_STATE_ARCHIVED = 2 [ (gogoproto.enumvalue_customname) = "Archived" ]; + TRANSFER_STATE_INSUFFICIENT_AMOUNT = 3 + [ (gogoproto.enumvalue_customname) = "InsufficientAmount" ]; +} + +// TransferFee represents accumulated fees generated by the network +message TransferFee { + repeated cosmos.base.v1beta1.Coin coins = 1 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.nullable) = false + ]; +} + +message FeeInfo { + string chain = 1 [ (gogoproto.casttype) = "ChainName" ]; + string asset = 2; + bytes fee_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes min_fee = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + bytes max_fee = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message Asset { + string denom = 1; + reserved 2; // min_amount was removed in v0.15 + bool is_native_asset = 3; +} + +enum TransferDirection { + option (gogoproto.goproto_enum_prefix) = false; + + TRANSFER_DIRECTION_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + TRANSFER_DIRECTION_FROM = 1 + [ (gogoproto.enumvalue_customname) = "TransferDirectionFrom" ]; + TRANSFER_DIRECTION_TO = 2 + [ (gogoproto.enumvalue_customname) = "TransferDirectionTo" ]; +} + +message GeneralMessage { + enum Status { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + STATUS_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + STATUS_APPROVED = 1 [ (gogoproto.enumvalue_customname) = "Approved" ]; + STATUS_PROCESSING = 2 [ (gogoproto.enumvalue_customname) = "Processing" ]; + STATUS_EXECUTED = 3 [ (gogoproto.enumvalue_customname) = "Executed" ]; + STATUS_FAILED = 4 [ (gogoproto.enumvalue_customname) = "Failed" ]; + } + + string id = 1 [ (gogoproto.customname) = "ID" ]; + CrossChainAddress sender = 2 [ (gogoproto.nullable) = false ]; + CrossChainAddress recipient = 3 [ (gogoproto.nullable) = false ]; + bytes payload_hash = 4; + Status status = 5; + cosmos.base.v1beta1.Coin asset = 6; + bytes source_tx_id = 7 [ (gogoproto.customname) = "SourceTxID" ]; + uint64 source_tx_index = 8; +} + +message WasmMessage { + string source_chain = 1 [ (gogoproto.casttype) = "ChainName" ]; + string source_address = 2; + string destination_chain = 3 [ (gogoproto.casttype) = "ChainName" ]; + string destination_address = 4; + bytes payload_hash = 5 [ (gogoproto.casttype) = "WasmBytes" ]; + bytes source_tx_id = 6 [ + (gogoproto.customname) = "SourceTxID", + (gogoproto.casttype) = "WasmBytes" + ]; + uint64 source_tx_index = 7 [ (gogoproto.jsontag) = "source_tx_index" ]; + bytes sender = 8 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string id = 9 [ + (gogoproto.customname) = "ID" + ]; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/events.proto b/ampd/proto/axelar/nexus/v1beta1/events.proto new file mode 100644 index 000000000..7ec5ec829 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/events.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; +option (gogoproto.messagename_all) = true; + +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; + +message FeeDeducted { + uint64 transfer_id = 1 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string recipient_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string recipient_address = 3; + cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin fee = 5 [ (gogoproto.nullable) = false ]; +} + +message InsufficientFee { + uint64 transfer_id = 1 [ + (gogoproto.customname) = "TransferID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.TransferID" + ]; + string recipient_chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + string recipient_address = 3; + cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin fee = 5 [ (gogoproto.nullable) = false ]; +} + +message RateLimitUpdated { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin limit = 2 [ (gogoproto.nullable) = false ]; + google.protobuf.Duration window = 3 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message MessageReceived { + string id = 1 [ (gogoproto.customname) = "ID" ]; + bytes payload_hash = 2; + exported.v1beta1.CrossChainAddress sender = 3 + [ (gogoproto.nullable) = false ]; + exported.v1beta1.CrossChainAddress recipient = 4 + [ (gogoproto.nullable) = false ]; +} + +message MessageProcessing { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message MessageExecuted { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message MessageFailed { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message WasmMessageRouted { + exported.v1beta1.WasmMessage message = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/genesis.proto b/ampd/proto/axelar/nexus/v1beta1/genesis.proto new file mode 100644 index 000000000..78011ebd7 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/genesis.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "gogoproto/gogo.proto"; +import "axelar/nexus/v1beta1/params.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/nexus/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + uint64 nonce = 2; + repeated nexus.exported.v1beta1.Chain chains = 3 + [ (gogoproto.nullable) = false ]; + repeated ChainState chain_states = 4 [ (gogoproto.nullable) = false ]; + repeated LinkedAddresses linked_addresses = 5 + [ (gogoproto.nullable) = false ]; + repeated nexus.exported.v1beta1.CrossChainTransfer transfers = 6 + [ (gogoproto.nullable) = false ]; + nexus.exported.v1beta1.TransferFee fee = 7 [ (gogoproto.nullable) = false ]; + repeated nexus.exported.v1beta1.FeeInfo fee_infos = 8 + [ (gogoproto.nullable) = false ]; + repeated RateLimit rate_limits = 9 [ (gogoproto.nullable) = false ]; + repeated TransferEpoch transfer_epochs = 10 [ (gogoproto.nullable) = false ]; + repeated nexus.exported.v1beta1.GeneralMessage messages = 11 + [ (gogoproto.nullable) = false ]; + uint64 message_nonce = 12; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/params.proto b/ampd/proto/axelar/nexus/v1beta1/params.proto new file mode 100644 index 000000000..30c9074fa --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/params.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + utils.v1beta1.Threshold chain_activation_threshold = 1 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold chain_maintainer_missing_vote_threshold = 2 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold chain_maintainer_incorrect_vote_threshold = 3 + [ (gogoproto.nullable) = false ]; + int32 chain_maintainer_check_window = 4; + bytes gateway = 5 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + uint64 end_blocker_limit = 6; +} diff --git a/ampd/proto/axelar/nexus/v1beta1/query.proto b/ampd/proto/axelar/nexus/v1beta1/query.proto new file mode 100644 index 000000000..b6371f4a8 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/query.proto @@ -0,0 +1,175 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/nexus/v1beta1/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// ChainMaintainersRequest represents a message that queries +// the chain maintainers for the specified chain +message ChainMaintainersRequest { string chain = 1; } + +message ChainMaintainersResponse { + repeated bytes maintainers = 1 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +// LatestDepositAddressRequest represents a message that queries a deposit +// address by recipient address +message LatestDepositAddressRequest { + string recipient_addr = 1; + string recipient_chain = 2; + string deposit_chain = 3; +} + +message LatestDepositAddressResponse { string deposit_addr = 1; }; + +// TransfersForChainRequest represents a message that queries the +// transfers for the specified chain +message TransfersForChainRequest { + string chain = 1; + exported.v1beta1.TransferState state = 2; + cosmos.base.query.v1beta1.PageRequest pagination = 3; +} + +message TransfersForChainResponse { + repeated exported.v1beta1.CrossChainTransfer transfers = 1 + [ (gogoproto.nullable) = false ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// FeeInfoRequest represents a message that queries the transfer fees associated +// to an asset on a chain +message FeeInfoRequest { + string chain = 1; + string asset = 2; +} + +message FeeInfoResponse { exported.v1beta1.FeeInfo fee_info = 1; } + +// TransferFeeRequest represents a message that queries the fees charged by +// the network for a cross-chain transfer +message TransferFeeRequest { + string source_chain = 1; + string destination_chain = 2; + string amount = 3; +} + +message TransferFeeResponse { + cosmos.base.v1beta1.Coin fee = 1 [ (gogoproto.nullable) = false ]; +} + +enum ChainStatus { + option (gogoproto.goproto_enum_prefix) = false; + + CHAIN_STATUS_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + CHAIN_STATUS_ACTIVATED = 1 [ (gogoproto.enumvalue_customname) = "Activated" ]; + CHAIN_STATUS_DEACTIVATED = 2 + [ (gogoproto.enumvalue_customname) = "Deactivated" ]; +} + +// ChainsRequest represents a message that queries the chains +// registered on the network +message ChainsRequest { ChainStatus status = 1; } + +message ChainsResponse { + repeated string chains = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +// AssetsRequest represents a message that queries the registered assets of a +// chain +message AssetsRequest { string chain = 1; } + +message AssetsResponse { repeated string assets = 1; } + +// ChainStateRequest represents a message that queries the state of a chain +// registered on the network +message ChainStateRequest { string chain = 1; } + +message ChainStateResponse { + ChainState state = 1 [ (gogoproto.nullable) = false ]; +} + +// ChainsByAssetRequest represents a message that queries the chains +// that support an asset on the network +message ChainsByAssetRequest { string asset = 1; } + +message ChainsByAssetResponse { + repeated string chains = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +// RecipientAddressRequest represents a message that queries the registered +// recipient address for a given deposit address +message RecipientAddressRequest { + string deposit_addr = 1; + string deposit_chain = 2; +} + +message RecipientAddressResponse { + string recipient_addr = 1; + string recipient_chain = 2; +}; + +// TransferRateLimitRequest represents a message that queries the registered +// transfer rate limit and current transfer amounts for a given chain and asset +message TransferRateLimitRequest { + string chain = 1; + string asset = 2; +} + +message TransferRateLimitResponse { TransferRateLimit transfer_rate_limit = 1; } + +message TransferRateLimit { + bytes limit = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration window = 2 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; + bytes incoming = 3 [ + deprecated = true, + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + bytes outgoing = 4 [ + deprecated = true, + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + // time_left indicates the time left in the rate limit window + google.protobuf.Duration time_left = 5 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; + bytes from = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + bytes to = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +message MessageRequest { string id = 1 [ (gogoproto.customname) = "ID" ]; } + +message MessageResponse { + exported.v1beta1.GeneralMessage message = 1 [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/nexus/v1beta1/service.proto b/ampd/proto/axelar/nexus/v1beta1/service.proto new file mode 100644 index 000000000..881d2a4d7 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/service.proto @@ -0,0 +1,150 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/nexus/v1beta1/tx.proto"; +import "axelar/nexus/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the nexus Msg service. +service MsgService { + rpc RegisterChainMaintainer(RegisterChainMaintainerRequest) + returns (RegisterChainMaintainerResponse) { + option (google.api.http) = { + post : "/axelar/nexus/register_chain_maintainer" + body : "*" + }; + } + + rpc DeregisterChainMaintainer(DeregisterChainMaintainerRequest) + returns (DeregisterChainMaintainerResponse) { + option (google.api.http) = { + post : "/axelar/nexus/deregister_chain_maintainer" + body : "*" + }; + } + + rpc ActivateChain(ActivateChainRequest) returns (ActivateChainResponse) { + option (google.api.http) = { + post : "/axelar/nexus/activate_chain" + body : "*" + }; + } + + rpc DeactivateChain(axelar.nexus.v1beta1.DeactivateChainRequest) + returns (axelar.nexus.v1beta1.DeactivateChainResponse) { + option (google.api.http) = { + post : "/axelar/nexus/deactivate_chain" + body : "*" + }; + } + + rpc RegisterAssetFee(RegisterAssetFeeRequest) + returns (RegisterAssetFeeResponse) { + option (google.api.http) = { + post : "/axelar/nexus/register_asset_fee" + body : "*" + }; + } + + rpc SetTransferRateLimit(SetTransferRateLimitRequest) + returns (SetTransferRateLimitResponse) { + option (google.api.http) = { + post : "/axelar/nexus/set_transfer_rate_limit" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + // LatestDepositAddress queries the a deposit address by recipient + rpc LatestDepositAddress(LatestDepositAddressRequest) + returns (LatestDepositAddressResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/latest_deposit_address/" + "{recipient_addr}/{recipient_chain}/{deposit_chain}"; + } + + // TransfersForChain queries transfers by chain + rpc TransfersForChain(TransfersForChainRequest) + returns (TransfersForChainResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/transfers_for_chain/{chain}/{state}"; + } + + // FeeInfo queries the fee info by chain and asset + rpc FeeInfo(FeeInfoRequest) returns (FeeInfoResponse) { + option (google.api.http) = { + get : "/axelar/nexus/v1beta1/fee_info/{chain}/{asset}" + additional_bindings : {get : "/axelar/nexus/v1beta1/fee"} + }; + } + + // TransferFee queries the transfer fee by the source, destination chain, + // and amount. If amount is 0, the min fee is returned + rpc TransferFee(TransferFeeRequest) returns (TransferFeeResponse) { + option (google.api.http) = { + get : "/axelar/nexus/v1beta1/transfer_fee/{source_chain}/" + "{destination_chain}/{amount}" + additional_bindings : {get : "/axelar/nexus/v1beta1/transfer_fee"} + }; + } + + // Chains queries the chains registered on the network + rpc Chains(ChainsRequest) returns (ChainsResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/chains"; + } + + // Assets queries the assets registered for a chain + rpc Assets(AssetsRequest) returns (AssetsResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/assets/{chain}"; + } + + // ChainState queries the state of a registered chain on the network + rpc ChainState(ChainStateRequest) returns (ChainStateResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/chain_state/{chain}"; + } + + // ChainsByAsset queries the chains that support an asset on the network + rpc ChainsByAsset(ChainsByAssetRequest) returns (ChainsByAssetResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/chains_by_asset/{asset}"; + } + + // RecipientAddress queries the recipient address for a given deposit address + rpc RecipientAddress(RecipientAddressRequest) + returns (RecipientAddressResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/recipient_address/" + "{deposit_chain}/{deposit_addr}"; + } + + // ChainMaintainers queries the chain maintainers for a given chain + rpc ChainMaintainers(ChainMaintainersRequest) + returns (ChainMaintainersResponse) { + option (google.api.http).get = + "/axelar/nexus/v1beta1/chain_maintainers/{chain}"; + } + + // TransferRateLimit queries the transfer rate limit for a given chain and + // asset. If a rate limit is not set, nil is returned. + rpc TransferRateLimit(TransferRateLimitRequest) + returns (TransferRateLimitResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/transfer_rate_limit/" + "{chain}/{asset}"; + } + + rpc Message(MessageRequest) returns (MessageResponse) { + option (google.api.http).get = "/axelar/nexus/v1beta1/message"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/nexus/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/nexus/v1beta1/tx.proto b/ampd/proto/axelar/nexus/v1beta1/tx.proto new file mode 100644 index 000000000..555930043 --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/tx.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "google/api/annotations.proto"; +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message RegisterChainMaintainerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message RegisterChainMaintainerResponse {} + +message DeregisterChainMaintainerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message DeregisterChainMaintainerResponse {} + +// ActivateChainRequest represents a message to activate chains +message ActivateChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message ActivateChainResponse {} + +// DeactivateChainRequest represents a message to deactivate chains +message DeactivateChainRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + repeated string chains = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +message DeactivateChainResponse {} + +// RegisterAssetFeeRequest represents a message to register the transfer fee +// info associated to an asset on a chain +message RegisterAssetFeeRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + nexus.exported.v1beta1.FeeInfo fee_info = 2 [ (gogoproto.nullable) = false ]; +} + +message RegisterAssetFeeResponse {} + +// SetTransferRateLimitRequest represents a message to set rate limits on +// transfers +message SetTransferRateLimitRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin limit = 3 [ (gogoproto.nullable) = false ]; + google.protobuf.Duration window = 4 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message SetTransferRateLimitResponse {} diff --git a/ampd/proto/axelar/nexus/v1beta1/types.proto b/ampd/proto/axelar/nexus/v1beta1/types.proto new file mode 100644 index 000000000..14503683f --- /dev/null +++ b/ampd/proto/axelar/nexus/v1beta1/types.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; +package axelar.nexus.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/nexus/types"; + +import "google/protobuf/duration.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/nexus/exported/v1beta1/types.proto"; +import "axelar/utils/v1beta1/bitmap.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message MaintainerState { + bytes address = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + axelar.utils.v1beta1.Bitmap missing_votes = 2 + [ (gogoproto.nullable) = false ]; + axelar.utils.v1beta1.Bitmap incorrect_votes = 3 + [ (gogoproto.nullable) = false ]; + string chain = 4 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; +} + +// ChainState represents the state of a registered blockchain +message ChainState { + reserved 4; // total was removed in v0.13 + reserved 2; // maintainers was removed in v0.24 + + axelar.nexus.exported.v1beta1.Chain chain = 1 + [ (gogoproto.nullable) = false ]; + bool activated = 3; + repeated axelar.nexus.exported.v1beta1.Asset assets = 5 + [ (gogoproto.nullable) = false ]; + repeated MaintainerState maintainer_states = 6 + [ (gogoproto.nullable) = false, deprecated = true ]; +} + +message LinkedAddresses { + axelar.nexus.exported.v1beta1.CrossChainAddress deposit_address = 1 + [ (gogoproto.nullable) = false ]; + axelar.nexus.exported.v1beta1.CrossChainAddress recipient_address = 2 + [ (gogoproto.nullable) = false ]; +} + +message RateLimit { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin limit = 2 [ (gogoproto.nullable) = false ]; + google.protobuf.Duration window = 3 + [ (gogoproto.stdduration) = true, (gogoproto.nullable) = false ]; +} + +message TransferEpoch { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + cosmos.base.v1beta1.Coin amount = 2 [ (gogoproto.nullable) = false ]; + uint64 epoch = 3; + axelar.nexus.exported.v1beta1.TransferDirection direction = + 4; // indicates whether the rate tracking is for transfers going + // to that chain or coming from it +} diff --git a/ampd/proto/axelar/permission/exported/v1beta1/types.proto b/ampd/proto/axelar/permission/exported/v1beta1/types.proto new file mode 100644 index 000000000..7251daa8e --- /dev/null +++ b/ampd/proto/axelar/permission/exported/v1beta1/types.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package axelar.permission.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/exported"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/descriptor.proto"; + +option (gogoproto.goproto_getters_all) = false; + +enum Role { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + ROLE_UNSPECIFIED = 0; + ROLE_UNRESTRICTED = 1; + ROLE_CHAIN_MANAGEMENT = 2; + ROLE_ACCESS_CONTROL = 3; +} + +extend google.protobuf.MessageOptions { + permission.exported.v1beta1.Role permission_role = + 50000; // 50000-99999 reserved for use withing individual organizations +} diff --git a/ampd/proto/axelar/permission/v1beta1/genesis.proto b/ampd/proto/axelar/permission/v1beta1/genesis.proto new file mode 100644 index 000000000..7eef9a82e --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/genesis.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/v1beta1/types.proto"; +import "axelar/permission/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 2; + repeated GovAccount gov_accounts = 3 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/permission/v1beta1/params.proto b/ampd/proto/axelar/permission/v1beta1/params.proto new file mode 100644 index 000000000..232900e1b --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/params.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params {} diff --git a/ampd/proto/axelar/permission/v1beta1/query.proto b/ampd/proto/axelar/permission/v1beta1/query.proto new file mode 100644 index 000000000..997d72a8a --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/query.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// QueryGovernanceKeyRequest is the request type for the +// Query/GovernanceKey RPC method +message QueryGovernanceKeyRequest {} + +// QueryGovernanceKeyResponse is the response type for the +// Query/GovernanceKey RPC method +message QueryGovernanceKeyResponse { + cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 1 + [ (gogoproto.nullable) = false ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/permission/v1beta1/service.proto b/ampd/proto/axelar/permission/v1beta1/service.proto new file mode 100644 index 000000000..02767573f --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/service.proto @@ -0,0 +1,54 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/permission/v1beta1/tx.proto"; +import "axelar/permission/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the gov Msg service. +service Msg { + rpc RegisterController(axelar.permission.v1beta1.RegisterControllerRequest) + returns (axelar.permission.v1beta1.RegisterControllerResponse) { + option (google.api.http) = { + post : "/axelar/permission/register_controller" + body : "*" + }; + } + + rpc DeregisterController( + axelar.permission.v1beta1.DeregisterControllerRequest) + returns (axelar.permission.v1beta1.DeregisterControllerResponse) { + option (google.api.http) = { + post : "/axelar/permission/deregister_controller" + body : "*" + }; + } + + rpc UpdateGovernanceKey(axelar.permission.v1beta1.UpdateGovernanceKeyRequest) + returns (axelar.permission.v1beta1.UpdateGovernanceKeyResponse) { + option (google.api.http) = { + post : "/axelar/permission/update_governance_key" + body : "*" + }; + } +} + +// Query defines the gRPC querier service. +service Query { + // GovernanceKey returns the multisig governance key + rpc GovernanceKey(QueryGovernanceKeyRequest) + returns (QueryGovernanceKeyResponse) { + option (google.api.http).get = "/axelar/permission/v1beta1/governance_key"; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/permission/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/permission/v1beta1/tx.proto b/ampd/proto/axelar/permission/v1beta1/tx.proto new file mode 100644 index 000000000..c06b467f3 --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/tx.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message UpdateGovernanceKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + cosmos.crypto.multisig.LegacyAminoPubKey governance_key = 2 + [ (gogoproto.nullable) = false ]; +} + +message UpdateGovernanceKeyResponse {} + +// MsgRegisterController represents a message to register a controller account +message RegisterControllerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes controller = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RegisterControllerResponse {} + +// DeregisterController represents a message to deregister a controller account +message DeregisterControllerRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_ACCESS_CONTROL; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bytes controller = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} +message DeregisterControllerResponse {} diff --git a/ampd/proto/axelar/permission/v1beta1/types.proto b/ampd/proto/axelar/permission/v1beta1/types.proto new file mode 100644 index 000000000..beb401ed0 --- /dev/null +++ b/ampd/proto/axelar/permission/v1beta1/types.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package axelar.permission.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/permission/types"; + +import "gogoproto/gogo.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GovAccount { + bytes address = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + permission.exported.v1beta1.Role role = 2; +} diff --git a/ampd/proto/axelar/reward/v1beta1/genesis.proto b/ampd/proto/axelar/reward/v1beta1/genesis.proto new file mode 100644 index 000000000..a805e07e9 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "axelar/reward/v1beta1/params.proto"; +import "axelar/reward/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated Pool pools = 2 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/reward/v1beta1/params.proto b/ampd/proto/axelar/reward/v1beta1/params.proto new file mode 100644 index 000000000..8fba73ecf --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/params.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + bytes external_chain_voting_inflation_rate = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes key_mgmt_relative_inflation_rate = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/axelar/reward/v1beta1/query.proto b/ampd/proto/axelar/reward/v1beta1/query.proto new file mode 100644 index 000000000..f3f7225ad --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/query.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "axelar/reward/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// InflationRateRequest represents a message that queries the Axelar specific +// inflation RPC method. Ideally, this would use ValAddress as the validator +// field type. However, this makes it awkward for REST-based calls, because it +// would expect a byte array as part of the url. So, the bech32 encoded address +// string is used for this request instead. +message InflationRateRequest { string validator = 1; } + +message InflationRateResponse { + bytes inflation_rate = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/reward/v1beta1/service.proto b/ampd/proto/axelar/reward/v1beta1/service.proto new file mode 100644 index 000000000..363f136e9 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/service.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/reward/v1beta1/tx.proto"; +import "axelar/reward/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the axelarnet Msg service. +service MsgService { + rpc RefundMsg(RefundMsgRequest) returns (RefundMsgResponse) { + option (google.api.http) = { + post : "/axelar/reward/refund_message" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + rpc InflationRate(InflationRateRequest) returns (InflationRateResponse) { + option (google.api.http) = { + get : "/axelar/reward/v1beta1/inflation_rate/{validator}", + additional_bindings : { + get : "/axelar/reward/v1beta1/inflation_rate" // query network inflation + // rate, without having to + // pass empty validator + // `.../inflation_rate//` + } + }; + } + + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/reward/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/reward/v1beta1/tx.proto b/ampd/proto/axelar/reward/v1beta1/tx.proto new file mode 100644 index 000000000..ec472dd52 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/tx.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message RefundMsgRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + google.protobuf.Any inner_message = 2 + [ (cosmos_proto.accepts_interface) = "Refundable" ]; +} + +message RefundMsgResponse { + bytes data = 1; + string log = 2; +} diff --git a/ampd/proto/axelar/reward/v1beta1/types.proto b/ampd/proto/axelar/reward/v1beta1/types.proto new file mode 100644 index 000000000..b025a95c0 --- /dev/null +++ b/ampd/proto/axelar/reward/v1beta1/types.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package axelar.reward.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/reward/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Pool { + message Reward { + bytes validator = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + repeated cosmos.base.v1beta1.Coin coins = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + } + + string name = 1; + repeated Reward rewards = 2 [ (gogoproto.nullable) = false ]; +} + +message Refund { + bytes payer = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + repeated cosmos.base.v1beta1.Coin fees = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} diff --git a/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto b/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto new file mode 100644 index 000000000..80d4a4435 --- /dev/null +++ b/ampd/proto/axelar/snapshot/exported/v1beta1/types.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package axelar.snapshot.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/exported"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Participant { + bytes address = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} + +message Snapshot { + reserved 1, 4, 5, 6, 7; // validators, total_share_count, counter and + // corruption_threshold were deleted in v0.26 + + option (gogoproto.stable_marshaler) = true; + + google.protobuf.Timestamp timestamp = 2 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + int64 height = 3; + map participants = 8 [ (gogoproto.nullable) = false ]; + bytes bonded_weight = 9 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/axelar/snapshot/v1beta1/genesis.proto b/ampd/proto/axelar/snapshot/v1beta1/genesis.proto new file mode 100644 index 000000000..08d954526 --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/genesis.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "axelar/snapshot/v1beta1/params.proto"; +import "axelar/snapshot/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// GenesisState represents the genesis state +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated ProxiedValidator proxied_validators = 2 + [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/snapshot/v1beta1/params.proto b/ampd/proto/axelar/snapshot/v1beta1/params.proto new file mode 100644 index 000000000..c22c60186 --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/params.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { int64 min_proxy_balance = 1; } diff --git a/ampd/proto/axelar/snapshot/v1beta1/query.proto b/ampd/proto/axelar/snapshot/v1beta1/query.proto new file mode 100644 index 000000000..0e9f53def --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/query.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "axelar/snapshot/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message QueryValidatorsResponse { + message TssIllegibilityInfo { + bool tombstoned = 1; + bool jailed = 2; + bool missed_too_many_blocks = 3; + bool no_proxy_registered = 4; + bool tss_suspended = 5; + bool proxy_insuficient_funds = 6; + bool stale_tss_heartbeat = 7; + } + + message Validator { + string operator_address = 1; + string moniker = 2; + TssIllegibilityInfo tss_illegibility_info = 3 + [ (gogoproto.nullable) = false ]; + } + + repeated Validator validators = 1; +} + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/snapshot/v1beta1/service.proto b/ampd/proto/axelar/snapshot/v1beta1/service.proto new file mode 100644 index 000000000..82f430fd9 --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/service.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/snapshot/v1beta1/tx.proto"; +import "axelar/snapshot/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the snapshot Msg service. +service MsgService { + // RegisterProxy defines a method for registering a proxy account that can act + // in a validator account's stead. + rpc RegisterProxy(RegisterProxyRequest) returns (RegisterProxyResponse) { + option (google.api.http) = { + post : "/axelar/snapshot/register_proxy" + body : "*" + }; + } + + // DeactivateProxy defines a method for deregistering a proxy account. + rpc DeactivateProxy(DeactivateProxyRequest) + returns (DeactivateProxyResponse) { + option (google.api.http) = { + post : "/axelar/snapshot/deactivate_proxy" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/snapshot/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/snapshot/v1beta1/tx.proto b/ampd/proto/axelar/snapshot/v1beta1/tx.proto new file mode 100644 index 000000000..70a1c2c0e --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/tx.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message RegisterProxyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes proxy_addr = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; +} + +message RegisterProxyResponse {} + +message DeactivateProxyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} + +message DeactivateProxyResponse {} diff --git a/ampd/proto/axelar/snapshot/v1beta1/types.proto b/ampd/proto/axelar/snapshot/v1beta1/types.proto new file mode 100644 index 000000000..279c6e6fd --- /dev/null +++ b/ampd/proto/axelar/snapshot/v1beta1/types.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package axelar.snapshot.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/snapshot/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message ProxiedValidator { + bytes validator = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + bytes proxy = 2 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + bool active = 3; +} diff --git a/ampd/proto/axelar/tss/exported/v1beta1/types.proto b/ampd/proto/axelar/tss/exported/v1beta1/types.proto new file mode 100644 index 000000000..4b0d8bf1d --- /dev/null +++ b/ampd/proto/axelar/tss/exported/v1beta1/types.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; +package axelar.tss.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/exported"; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "gogoproto/gogo.proto"; + +// KeyRequirement defines requirements for keys +message KeyRequirement { + KeyRole key_role = 1; + KeyType key_type = 2; + utils.v1beta1.Threshold min_keygen_threshold = 3 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold safety_threshold = 4 [ (gogoproto.nullable) = false ]; + KeyShareDistributionPolicy key_share_distribution_policy = 5; + int64 max_total_share_count = 6; + int64 min_total_share_count = 7; + utils.v1beta1.Threshold keygen_voting_threshold = 8 + [ (gogoproto.nullable) = false ]; + utils.v1beta1.Threshold sign_voting_threshold = 9 + [ (gogoproto.nullable) = false ]; + int64 keygen_timeout = 10; + int64 sign_timeout = 11; +} + +enum KeyRole { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_ROLE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "Unknown" ]; + KEY_ROLE_MASTER_KEY = 1 [ (gogoproto.enumvalue_customname) = "MasterKey" ]; + KEY_ROLE_SECONDARY_KEY = 2 + [ (gogoproto.enumvalue_customname) = "SecondaryKey" ]; + KEY_ROLE_EXTERNAL_KEY = 3 + [ (gogoproto.enumvalue_customname) = "ExternalKey" ]; +} + +enum KeyType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_TYPE_UNSPECIFIED = 0; + KEY_TYPE_NONE = 1 [ (gogoproto.enumvalue_customname) = "None" ]; + KEY_TYPE_THRESHOLD = 2 [ (gogoproto.enumvalue_customname) = "Threshold" ]; + KEY_TYPE_MULTISIG = 3 [ (gogoproto.enumvalue_customname) = "Multisig" ]; +} + +enum KeyShareDistributionPolicy { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + KEY_SHARE_DISTRIBUTION_POLICY_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "Unspecified" ]; + KEY_SHARE_DISTRIBUTION_POLICY_WEIGHTED_BY_STAKE = 1 + [ (gogoproto.enumvalue_customname) = "WeightedByStake" ]; + KEY_SHARE_DISTRIBUTION_POLICY_ONE_PER_VALIDATOR = 2 + [ (gogoproto.enumvalue_customname) = "OnePerValidator" ]; +} + +// PubKeyInfo holds a pubkey and a signature +message SigKeyPair { + bytes pub_key = 1; + bytes signature = 2; +} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto new file mode 100644 index 000000000..0683c5189 --- /dev/null +++ b/ampd/proto/axelar/tss/tofnd/v1beta1/common.proto @@ -0,0 +1,28 @@ +// File copied from golang tofnd with minor tweaks +syntax = "proto3"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; + +import "gogoproto/gogo.proto"; + +package axelar.tss.tofnd.v1beta1; + +// Key presence check types +message KeyPresenceRequest { + string key_uid = 1; + bytes pub_key = 2; // SEC1-encoded compressed pub key bytes to find the right + // mnemonic. Latest is used, if empty. +} + +message KeyPresenceResponse { + enum Response { + option (gogoproto.goproto_enum_prefix) = false; + + RESPONSE_UNSPECIFIED = 0; + RESPONSE_PRESENT = 1; + RESPONSE_ABSENT = 2; + RESPONSE_FAIL = 3; + } + + Response response = 1; +} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto new file mode 100644 index 000000000..82abaaf56 --- /dev/null +++ b/ampd/proto/axelar/tss/tofnd/v1beta1/multisig.proto @@ -0,0 +1,40 @@ +// File copied from golang tofnd with minor tweaks +syntax = "proto3"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; +import "axelar/tss/tofnd/v1beta1/common.proto"; // import key presence request/response + +package axelar.tss.tofnd.v1beta1; + +// service Multisig { +// rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); +// rpc Keygen(KeygenRequest) returns (KeygenResponse); +// rpc Sign(SignRequest) returns (SignResponse); +//} + +message KeygenRequest { + string key_uid = 1; + string party_uid = 2; // used only for logging +} + +message KeygenResponse { + oneof keygen_response { + bytes pub_key = 1; // SEC1-encoded compressed curve point + string error = 2; // reply with an error message if keygen fails + } +} + +message SignRequest { + string key_uid = 1; + bytes msg_to_sign = 2; // 32-byte pre-hashed message digest + string party_uid = 3; // used only for logging + bytes pub_key = 4; // SEC1-encoded compressed pub key bytes to find the right + // mnemonic. Latest is used, if empty. +} + +message SignResponse { + oneof sign_response { + bytes signature = 1; // ASN.1 DER-encoded ECDSA signature + string error = 2; // reply with an error message if sign fails + } +} diff --git a/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto b/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto new file mode 100644 index 000000000..96140268a --- /dev/null +++ b/ampd/proto/axelar/tss/tofnd/v1beta1/tofnd.proto @@ -0,0 +1,129 @@ +// File copied from golang tofnd with minor tweaks +syntax = "proto3"; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/tofnd"; +import "gogoproto/gogo.proto"; +import "axelar/tss/tofnd/v1beta1/common.proto"; // import key presence request/response + +package axelar.tss.tofnd.v1beta1; + +// TODO: figure out why gogoproto produces unusable services +// GG20 is the protocol https://eprint.iacr.org/2020/540 +// rpc definitions intended to wrap the API for this library: +// https://github.com/axelarnetwork/tofn +// service GG20 { +// rpc Recover(RecoverRequest) returns (RecoverResponse); +// rpc Keygen(stream MessageIn) returns (stream MessageOut); +// rpc Sign(stream MessageIn) returns (stream MessageOut); +// rpc KeyPresence(KeyPresenceRequest) returns (KeyPresenceResponse); +//} + +message RecoverRequest { + KeygenInit keygen_init = 1; + KeygenOutput keygen_output = 2; +} +message RecoverResponse { + enum Response { + RESPONSE_UNSPECIFIED = 0; + RESPONSE_SUCCESS = 1; + RESPONSE_FAIL = 2; + } + Response response = 1; +} + +// Keygen's success response +message KeygenOutput { + bytes pub_key = 1; // pub_key; common for all parties + bytes group_recover_info = + 2; // recover info of all parties' shares; common for all parties + bytes private_recover_info = + 3; // private recover info of this party's shares; unique for each party +} + +// generic message types shared by Keygen, Sign + +// TODO use nested message types +// eg. KeygenInit, SignInit should be defined inside MessageIn, etc. + +message MessageIn { + oneof data { // TODO don't reuse `data` + KeygenInit keygen_init = 1; // first message only, Keygen + SignInit sign_init = 2; // first message only, Sign + TrafficIn traffic = 3; // all subsequent messages + bool abort = 4; // abort the protocol, ignore the bool value + } +} + +message MessageOut { + oneof data { // TODO don't reuse `data` + TrafficOut traffic = 1; // all but final message + KeygenResult keygen_result = 2; // final message only, Keygen + SignResult sign_result = 3; // final message only, Sign + bool need_recover = 4; // issue recover from client + } + + // Keygen's response types + message KeygenResult { + oneof keygen_result_data { + KeygenOutput data = 1; // Success response + CriminalList criminals = 2; // Faiilure response + } + } + + // Sign's response types + message SignResult { + oneof sign_result_data { + bytes signature = 1; // Success response + CriminalList criminals = 2; // Failure response + } + } + + // Keygen/Sign failure response message + message CriminalList { + repeated Criminal criminals = 1; + + message Criminal { + string party_uid = 1; + + enum CrimeType { + option (gogoproto.goproto_enum_prefix) = false; + + CRIME_TYPE_UNSPECIFIED = 0; + CRIME_TYPE_NON_MALICIOUS = 1; + CRIME_TYPE_MALICIOUS = 2; + } + CrimeType crime_type = 2; + } + } +} + +message TrafficIn { + string from_party_uid = 1; + bytes payload = 2; + bool is_broadcast = 3; +} + +message TrafficOut { + string to_party_uid = 1; + bytes payload = 2; + bool is_broadcast = 3; +} + +// Keygen-specific message types + +message KeygenInit { + string new_key_uid = 1; + repeated string party_uids = 2; + repeated uint32 party_share_counts = 5; + uint32 my_party_index = 3; // parties[my_party_index] belongs to the server + uint32 threshold = 4; +} + +// Sign-specific message types + +message SignInit { + string new_sig_uid = 1; + string key_uid = 2; + repeated string party_uids = 3; // TODO replace this with a subset of indices? + bytes message_to_sign = 4; +} diff --git a/ampd/proto/axelar/tss/v1beta1/genesis.proto b/ampd/proto/axelar/tss/v1beta1/genesis.proto new file mode 100644 index 000000000..1e411bb56 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/genesis.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/v1beta1/params.proto"; +import "axelar/tss/v1beta1/types.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/tss/v1beta1/params.proto b/ampd/proto/axelar/tss/v1beta1/params.proto new file mode 100644 index 000000000..ab44ac748 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/params.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package axelar.tss.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params is the parameter set for this module +message Params { + // KeyRequirements defines the requirement for each key role + repeated tss.exported.v1beta1.KeyRequirement key_requirements = 1 + [ (gogoproto.nullable) = false ]; + // SuspendDurationInBlocks defines the number of blocks a + // validator is disallowed to participate in any TSS ceremony after + // committing a malicious behaviour during signing + int64 suspend_duration_in_blocks = 2; + // HeartBeatPeriodInBlocks defines the time period in blocks for tss to + // emit the event asking validators to send their heartbeats + int64 heartbeat_period_in_blocks = 3; + utils.v1beta1.Threshold max_missed_blocks_per_window = 4 + [ (gogoproto.nullable) = false ]; + int64 unbonding_locking_key_rotation_count = 5; + utils.v1beta1.Threshold external_multisig_threshold = 6 + [ (gogoproto.nullable) = false ]; + int64 max_sign_queue_size = 7; + int64 max_simultaneous_sign_shares = 8; + int64 tss_signed_blocks_window = 9; +} diff --git a/ampd/proto/axelar/tss/v1beta1/query.proto b/ampd/proto/axelar/tss/v1beta1/query.proto new file mode 100644 index 000000000..748cfefee --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/query.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/tss/v1beta1/service.proto b/ampd/proto/axelar/tss/v1beta1/service.proto new file mode 100644 index 000000000..01dfce6ec --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/service.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/snapshot/v1beta1/tx.proto"; +import "axelar/tss/v1beta1/tx.proto"; +import "axelar/tss/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the tss Msg service. +service MsgService { + rpc HeartBeat(axelar.tss.v1beta1.HeartBeatRequest) + returns (axelar.tss.v1beta1.HeartBeatResponse) { + option (google.api.http) = { + post : "/axelar/tss/heartbeat" + body : "*" + }; + } +} + +// Query defines the gRPC querier service. +service QueryService { + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/tss/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/tss/v1beta1/tx.proto b/ampd/proto/axelar/tss/v1beta1/tx.proto new file mode 100644 index 000000000..2cc6981d1 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/tx.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; +import "axelar/tss/v1beta1/types.proto"; +import "axelar/tss/tofnd/v1beta1/tofnd.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; +import "cosmos/crypto/multisig/keys.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// StartKeygenRequest indicate the start of keygen +message StartKeygenRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + string sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + tss.v1beta1.KeyInfo key_info = 2 [ (gogoproto.nullable) = false ]; +} + +message StartKeygenResponse {} + +message RotateKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + tss.exported.v1beta1.KeyRole key_role = 3; + string key_id = 4 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; +} + +message RotateKeyResponse {} + +// ProcessKeygenTrafficRequest protocol message +message ProcessKeygenTrafficRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string session_id = 2 [ (gogoproto.customname) = "SessionID" ]; + tss.tofnd.v1beta1.TrafficOut payload = 3 [ (gogoproto.nullable) = false ]; +} + +message ProcessKeygenTrafficResponse {} + +// ProcessSignTrafficRequest protocol message +message ProcessSignTrafficRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string session_id = 2 [ (gogoproto.customname) = "SessionID" ]; + tss.tofnd.v1beta1.TrafficOut payload = 3 [ (gogoproto.nullable) = false ]; +} + +message ProcessSignTrafficResponse {} + +// VotePubKeyRequest represents the message to vote on a public key +message VotePubKeyRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + vote.exported.v1beta1.PollKey poll_key = 2 [ (gogoproto.nullable) = false ]; + tss.tofnd.v1beta1.MessageOut.KeygenResult result = 3 + [ (gogoproto.nullable) = false ]; +} +message VotePubKeyResponse { string log = 1; } + +// VoteSigRequest represents a message to vote for a signature +message VoteSigRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + vote.exported.v1beta1.PollKey poll_key = 2 [ (gogoproto.nullable) = false ]; + tss.tofnd.v1beta1.MessageOut.SignResult result = 3 + [ (gogoproto.nullable) = false ]; +} + +message VoteSigResponse { string log = 1; } + +message HeartBeatRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + + repeated string key_ids = 2 [ + (gogoproto.customname) = "KeyIDs", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; +} + +message HeartBeatResponse {} + +message RegisterExternalKeysRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_CHAIN_MANAGEMENT; + message ExternalKey { + string id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + bytes pub_key = 2; + } + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string chain = 2 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated ExternalKey external_keys = 3 [ (gogoproto.nullable) = false ]; +} + +message RegisterExternalKeysResponse {}; + +message SubmitMultisigPubKeysRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string key_id = 2 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + repeated exported.v1beta1.SigKeyPair sig_key_pairs = 3 + [ (gogoproto.nullable) = false ]; +} + +message SubmitMultisigPubKeysResponse {} + +message SubmitMultisigSignaturesRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + string sig_id = 2 [ (gogoproto.customname) = "SigID" ]; + + repeated bytes signatures = 3; +} + +message SubmitMultisigSignaturesResponse {} diff --git a/ampd/proto/axelar/tss/v1beta1/types.proto b/ampd/proto/axelar/tss/v1beta1/types.proto new file mode 100644 index 000000000..86fd8dae2 --- /dev/null +++ b/ampd/proto/axelar/tss/v1beta1/types.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +package axelar.tss.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/tss/types"; + +import "gogoproto/gogo.proto"; +import "axelar/tss/exported/v1beta1/types.proto"; + +message KeygenVoteData { + bytes pub_key = 1; + bytes group_recovery_info = 2; +} + +// KeyInfo holds information about a key +message KeyInfo { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + tss.exported.v1beta1.KeyRole key_role = 2; + tss.exported.v1beta1.KeyType key_type = 3; +} + +message MultisigInfo { + message Info { + bytes participant = 1 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + repeated bytes data = 2; + } + string id = 1 [ (gogoproto.customname) = "ID" ]; + int64 timeout = 2; + int64 target_num = 3; + repeated Info infos = 4; +} + +message KeyRecoveryInfo { + string key_id = 1 [ + (gogoproto.customname) = "KeyID", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; + bytes public = 2; + map private = 3 [ (gogoproto.nullable) = false ]; +} + +message ExternalKeys { + string chain = 1 + [ (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/nexus/exported.ChainName" ]; + repeated string key_ids = 2 [ + (gogoproto.customname) = "KeyIDs", + (gogoproto.casttype) = + "github.com/axelarnetwork/axelar-core/x/tss/exported.KeyID" + ]; +} + +message ValidatorStatus { + bytes validator = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; + uint64 suspended_until = 2; +} diff --git a/ampd/proto/axelar/utils/v1beta1/bitmap.proto b/ampd/proto/axelar/utils/v1beta1/bitmap.proto new file mode 100644 index 000000000..4f9c714c2 --- /dev/null +++ b/ampd/proto/axelar/utils/v1beta1/bitmap.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package axelar.utils.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/utils"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Bitmap { CircularBuffer true_count_cache = 2; } + +message CircularBuffer { + repeated uint64 cumulative_value = 1; + int32 index = 2; + int32 max_size = 3; +} diff --git a/ampd/proto/axelar/utils/v1beta1/queuer.proto b/ampd/proto/axelar/utils/v1beta1/queuer.proto new file mode 100644 index 000000000..663d9b5a5 --- /dev/null +++ b/ampd/proto/axelar/utils/v1beta1/queuer.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package axelar.utils.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/utils"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message QueueState { + option (gogoproto.stable_marshaler) = true; + + message Item { + bytes key = 1; + bytes value = 2; + } + + map items = 1 [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/utils/v1beta1/threshold.proto b/ampd/proto/axelar/utils/v1beta1/threshold.proto new file mode 100644 index 000000000..3d0f17a70 --- /dev/null +++ b/ampd/proto/axelar/utils/v1beta1/threshold.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package axelar.utils.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/utils"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Threshold { + option (gogoproto.goproto_stringer) = false; + // split threshold into Numerator and denominator to avoid floating point + // errors down the line + int64 numerator = 1; + int64 denominator = 2; +} diff --git a/ampd/proto/axelar/vote/exported/v1beta1/types.proto b/ampd/proto/axelar/vote/exported/v1beta1/types.proto new file mode 100644 index 000000000..bc5e9f32e --- /dev/null +++ b/ampd/proto/axelar/vote/exported/v1beta1/types.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; +package axelar.vote.exported.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/exported"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/snapshot/exported/v1beta1/types.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// PollMetadata represents a poll with write-in voting, i.e. the result of the +// vote can have any data type +message PollMetadata { + reserved 1, 8, 9, 14; // deleted poll key, total voting power, voters and + // module_metadata in 0.20.x + + int64 expires_at = 3; + google.protobuf.Any result = 4 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; + utils.v1beta1.Threshold voting_threshold = 5 [ (gogoproto.nullable) = false ]; + PollState state = 6; + int64 min_voter_count = 7; + string reward_pool_name = 10; + int64 grace_period = 11; + int64 completed_at = 12; + uint64 id = 13 [ + (gogoproto.customname) = "ID", + (gogoproto.customtype) = "PollID", + (gogoproto.nullable) = false + ]; + snapshot.exported.v1beta1.Snapshot snapshot = 15 + [ (gogoproto.nullable) = false ]; + string module = 16; + google.protobuf.Any module_metadata = 17 + [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +// PollKey represents the key data for a poll +message PollKey { + option deprecated = true; + option (gogoproto.goproto_stringer) = false; + + string module = 1; + string id = 2 [ (gogoproto.customname) = "ID" ]; +} + +enum PollState { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = true; + + POLL_STATE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "NonExistent" ]; + POLL_STATE_PENDING = 1 [ (gogoproto.enumvalue_customname) = "Pending" ]; + POLL_STATE_COMPLETED = 2 [ (gogoproto.enumvalue_customname) = "Completed" ]; + POLL_STATE_FAILED = 3 [ (gogoproto.enumvalue_customname) = "Failed" ]; +} + +// PollParticipants should be embedded in poll events in other modules +message PollParticipants { + uint64 poll_id = 1 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = "PollID", + (gogoproto.nullable) = false + ]; + repeated bytes participants = 2 + [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.ValAddress" ]; +} diff --git a/ampd/proto/axelar/vote/v1beta1/events.proto b/ampd/proto/axelar/vote/v1beta1/events.proto new file mode 100644 index 000000000..8a81dad60 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/events.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package axelar.vote.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message Voted { + string module = 1; + string action = 2; + string poll = 3; + string voter = 4; + string state = 5; +} diff --git a/ampd/proto/axelar/vote/v1beta1/genesis.proto b/ampd/proto/axelar/vote/v1beta1/genesis.proto new file mode 100644 index 000000000..b26503c51 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package axelar.vote.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "axelar/vote/v1beta1/params.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated vote.exported.v1beta1.PollMetadata poll_metadatas = 2 + [ (gogoproto.nullable) = false ]; +} diff --git a/ampd/proto/axelar/vote/v1beta1/params.proto b/ampd/proto/axelar/vote/v1beta1/params.proto new file mode 100644 index 000000000..95f853532 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/params.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package axelar.vote.v1beta1; +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "axelar/utils/v1beta1/threshold.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// Params represent the genesis parameters for the module +message Params { + utils.v1beta1.Threshold default_voting_threshold = 1 + [ (gogoproto.nullable) = false ]; + int64 end_blocker_limit = 2; +} diff --git a/ampd/proto/axelar/vote/v1beta1/query.proto b/ampd/proto/axelar/vote/v1beta1/query.proto new file mode 100644 index 000000000..d99457a28 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/query.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "axelar/vote/v1beta1/params.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// ParamsRequest represents a message that queries the params +message ParamsRequest {} + +message ParamsResponse { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/ampd/proto/axelar/vote/v1beta1/service.proto b/ampd/proto/axelar/vote/v1beta1/service.proto new file mode 100644 index 000000000..1dfd1574f --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/service.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "axelar/vote/v1beta1/tx.proto"; +import "axelar/vote/v1beta1/query.proto"; + +option (gogoproto.goproto_registration) = true; + +// Msg defines the vote Msg service. +service MsgService { + rpc Vote(VoteRequest) returns (VoteResponse) { + option (google.api.http) = { + post : "/axelar/vote/vote" + body : "*" + }; + } +} + +// QueryService defines the gRPC querier service. +service QueryService { + rpc Params(ParamsRequest) returns (ParamsResponse) { + option (google.api.http) = { + get : "/axelar/vote/v1beta1/params" + }; + } +} diff --git a/ampd/proto/axelar/vote/v1beta1/tx.proto b/ampd/proto/axelar/vote/v1beta1/tx.proto new file mode 100644 index 000000000..771005831 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/tx.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/permission/exported/v1beta1/types.proto"; +import "axelar/vote/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +message VoteRequest { + option (permission.exported.v1beta1.permission_role) = ROLE_UNRESTRICTED; + + reserved 2, 3; // poll_key and vote were removed in v0.20 + + bytes sender = 1 [ (gogoproto.casttype) = + "github.com/cosmos/cosmos-sdk/types.AccAddress" ]; + uint64 poll_id = 4 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; + google.protobuf.Any vote = 5 [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; +} + +message VoteResponse { string log = 1; } diff --git a/ampd/proto/axelar/vote/v1beta1/types.proto b/ampd/proto/axelar/vote/v1beta1/types.proto new file mode 100644 index 000000000..92b64ce57 --- /dev/null +++ b/ampd/proto/axelar/vote/v1beta1/types.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package axelar.vote.v1beta1; + +option go_package = "github.com/axelarnetwork/axelar-core/x/vote/types"; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "axelar/vote/exported/v1beta1/types.proto"; + +option (gogoproto.goproto_getters_all) = false; + +// TalliedVote represents a vote for a poll with the accumulated stake of all +// validators voting for the same data +message TalliedVote { + reserved 2; // voters is deleted in version 0.20.x + + option (gogoproto.stable_marshaler) = true; + + bytes tally = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint", + (gogoproto.nullable) = false + ]; + google.protobuf.Any data = 3 [ (cosmos_proto.accepts_interface) = + "github.com/cosmos/codec/ProtoMarshaler" ]; + uint64 poll_id = 4 [ + (gogoproto.customname) = "PollID", + (gogoproto.customtype) = + "github.com/axelarnetwork/axelar-core/x/vote/exported.PollID", + (gogoproto.nullable) = false + ]; + map is_voter_late = 5; +} diff --git a/ampd/proto/third_party/buf.yaml b/ampd/proto/third_party/buf.yaml new file mode 100644 index 000000000..aae636f0a --- /dev/null +++ b/ampd/proto/third_party/buf.yaml @@ -0,0 +1,20 @@ +# Generated by "buf config migrate-v1beta1". Edit as necessary, and +# remove this comment when you're finished. +# +# This module represents the "proto" root found in +# the previous configuration. +version: v1 +breaking: + use: + - FILE +lint: + use: + - DEFAULT + - COMMENTS + - FILE_LOWER_SNAKE_CASE + except: + - UNARY_RPC + - COMMENT_FIELD + - SERVICE_SUFFIX + - PACKAGE_VERSION_SUFFIX + - RPC_REQUEST_STANDARD_NAME diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto new file mode 100644 index 000000000..72e1d9ec2 --- /dev/null +++ b/ampd/proto/third_party/cosmos/auth/v1beta1/auth.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// BaseAccount defines a base account type. It contains all the necessary fields +// for basic account functionality. Any custom account type should extend this +// type for additional functionality (e.g. vesting). +message BaseAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = false; + + option (cosmos_proto.implements_interface) = "AccountI"; + + string address = 1; + google.protobuf.Any pub_key = 2 + [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; + uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""]; + uint64 sequence = 4; +} + +// ModuleAccount defines an account for modules that holds coins on a pool. +message ModuleAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (cosmos_proto.implements_interface) = "ModuleAccountI"; + + BaseAccount base_account = 1 [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"base_account\""]; + string name = 2; + repeated string permissions = 3; +} + +// Params defines the parameters for the auth module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + uint64 max_memo_characters = 1 [(gogoproto.moretags) = "yaml:\"max_memo_characters\""]; + uint64 tx_sig_limit = 2 [(gogoproto.moretags) = "yaml:\"tx_sig_limit\""]; + uint64 tx_size_cost_per_byte = 3 [(gogoproto.moretags) = "yaml:\"tx_size_cost_per_byte\""]; + uint64 sig_verify_cost_ed25519 = 4 + [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""]; + uint64 sig_verify_cost_secp256k1 = 5 + [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; +} diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto new file mode 100644 index 000000000..c88b94ee4 --- /dev/null +++ b/ampd/proto/third_party/cosmos/auth/v1beta1/genesis.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// GenesisState defines the auth module's genesis state. +message GenesisState { + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // accounts are the accounts present at genesis. + repeated google.protobuf.Any accounts = 2; +} diff --git a/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto b/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto new file mode 100644 index 000000000..79799a4b7 --- /dev/null +++ b/ampd/proto/third_party/cosmos/auth/v1beta1/query.proto @@ -0,0 +1,89 @@ +syntax = "proto3"; +package cosmos.auth.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "cosmos/auth/v1beta1/auth.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/types"; + +// Query defines the gRPC querier service. +service Query { + // Accounts returns all the existing accounts + // + // Since: cosmos-sdk 0.43 + rpc Accounts(QueryAccountsRequest) returns (QueryAccountsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts"; + } + + // Account returns account details based on address. + rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/accounts/{address}"; + } + + // Params queries all parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/params"; + } + + // ModuleAccountByName returns the module account info by module name + rpc ModuleAccountByName(QueryModuleAccountByNameRequest) returns (QueryModuleAccountByNameResponse) { + option (google.api.http).get = "/cosmos/auth/v1beta1/module_accounts/{name}"; + } +} + +// QueryAccountsRequest is the request type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryAccountsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryAccountsResponse is the response type for the Query/Accounts RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryAccountsResponse { + // accounts are the existing accounts + repeated google.protobuf.Any accounts = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryAccountRequest is the request type for the Query/Account RPC method. +message QueryAccountRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address defines the address to query for. + string address = 1; +} + +// QueryAccountResponse is the response type for the Query/Account RPC method. +message QueryAccountResponse { + // account defines the account of the corresponding address. + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "AccountI"]; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryModuleAccountByNameRequest is the request type for the Query/ModuleAccountByName RPC method. +message QueryModuleAccountByNameRequest { + string name = 1; +} + +// QueryModuleAccountByNameResponse is the response type for the Query/ModuleAccountByName RPC method. +message QueryModuleAccountByNameResponse { + google.protobuf.Any account = 1 [(cosmos_proto.accepts_interface) = "ModuleAccountI"]; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto new file mode 100644 index 000000000..05b1feefa --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/authz.proto @@ -0,0 +1,39 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; +option (gogoproto.goproto_getters_all) = false; + +// GenericAuthorization gives the grantee unrestricted permissions to execute +// the provided method on behalf of the granter's account. +message GenericAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // Msg, identified by it's type URL, to grant unrestricted permissions to execute + string msg = 1; +} + +// Grant gives permissions to execute +// the provide method with expiration time. +message Grant { + google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"]; + google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +// GrantAuthorization extends a grant with both the addresses of the grantee and granter. +// It is used in genesis.proto and query.proto +// +// Since: cosmos-sdk 0.45.2 +message GrantAuthorization { + string granter = 1; + string grantee = 2; + + google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"]; + google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto new file mode 100644 index 000000000..7a3cf7c8c --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/event.proto @@ -0,0 +1,25 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; + +// EventGrant is emitted on Msg/Grant +message EventGrant { + // Msg type URL for which an autorization is granted + string msg_type_url = 2; + // Granter account address + string granter = 3; + // Grantee account address + string grantee = 4; +} + +// EventRevoke is emitted on Msg/Revoke +message EventRevoke { + // Msg type URL for which an autorization is revoked + string msg_type_url = 2; + // Granter account address + string granter = 3; + // Grantee account address + string grantee = 4; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto new file mode 100644 index 000000000..310f62656 --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/genesis.proto @@ -0,0 +1,13 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/authz/v1beta1/authz.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; + +// GenesisState defines the authz module's genesis state. +message GenesisState { + repeated GrantAuthorization authorization = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto new file mode 100644 index 000000000..f668309be --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/query.proto @@ -0,0 +1,81 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "cosmos/authz/v1beta1/authz.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; + +// Query defines the gRPC querier service. +service Query { + // Returns list of `Authorization`, granted to the grantee by the granter. + rpc Grants(QueryGrantsRequest) returns (QueryGrantsResponse) { + option (google.api.http).get = "/cosmos/authz/v1beta1/grants"; + } + + // GranterGrants returns list of `GrantAuthorization`, granted by granter. + // + // Since: cosmos-sdk 0.45.2 + rpc GranterGrants(QueryGranterGrantsRequest) returns (QueryGranterGrantsResponse) { + option (google.api.http).get = "/cosmos/authz/v1beta1/grants/granter/{granter}"; + } + + // GranteeGrants returns a list of `GrantAuthorization` by grantee. + // + // Since: cosmos-sdk 0.45.2 + rpc GranteeGrants(QueryGranteeGrantsRequest) returns (QueryGranteeGrantsResponse) { + option (google.api.http).get = "/cosmos/authz/v1beta1/grants/grantee/{grantee}"; + } +} + +// QueryGrantsRequest is the request type for the Query/Grants RPC method. +message QueryGrantsRequest { + string granter = 1; + string grantee = 2; + // Optional, msg_type_url, when set, will query only grants matching given msg type. + string msg_type_url = 3; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryGrantsResponse is the response type for the Query/Authorizations RPC method. +message QueryGrantsResponse { + // authorizations is a list of grants granted for grantee by granter. + repeated Grant grants = 1; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryGranterGrantsRequest is the request type for the Query/GranterGrants RPC method. +message QueryGranterGrantsRequest { + string granter = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryGranterGrantsResponse is the response type for the Query/GranterGrants RPC method. +message QueryGranterGrantsResponse { + // grants is a list of grants granted by the granter. + repeated GrantAuthorization grants = 1; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryGranteeGrantsRequest is the request type for the Query/IssuedGrants RPC method. +message QueryGranteeGrantsRequest { + string grantee = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryGranteeGrantsResponse is the response type for the Query/GranteeGrants RPC method. +message QueryGranteeGrantsResponse { + // grants is a list of grants granted to the grantee. + repeated GrantAuthorization grants = 1; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto new file mode 100644 index 000000000..457f0d662 --- /dev/null +++ b/ampd/proto/third_party/cosmos/authz/v1beta1/tx.proto @@ -0,0 +1,70 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.authz.v1beta1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/authz/v1beta1/authz.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; +option (gogoproto.goproto_getters_all) = false; + +// Msg defines the authz Msg service. +service Msg { + // Grant grants the provided authorization to the grantee on the granter's + // account with the provided expiration time. If there is already a grant + // for the given (granter, grantee, Authorization) triple, then the grant + // will be overwritten. + rpc Grant(MsgGrant) returns (MsgGrantResponse); + + // Exec attempts to execute the provided messages using + // authorizations granted to the grantee. Each message should have only + // one signer corresponding to the granter of the authorization. + rpc Exec(MsgExec) returns (MsgExecResponse); + + // Revoke revokes any authorization corresponding to the provided method name on the + // granter's account that has been granted to the grantee. + rpc Revoke(MsgRevoke) returns (MsgRevokeResponse); +} + +// MsgGrant is a request type for Grant method. It declares authorization to the grantee +// on behalf of the granter with the provided expiration time. +message MsgGrant { + string granter = 1; + string grantee = 2; + + cosmos.authz.v1beta1.Grant grant = 3 [(gogoproto.nullable) = false]; +} + +// MsgExecResponse defines the Msg/MsgExecResponse response type. +message MsgExecResponse { + repeated bytes results = 1; +} + +// MsgExec attempts to execute the provided messages using +// authorizations granted to the grantee. Each message should have only +// one signer corresponding to the granter of the authorization. +message MsgExec { + string grantee = 1; + // Authorization Msg requests to execute. Each msg must implement Authorization interface + // The x/authz will try to find a grant matching (msg.signers[0], grantee, MsgTypeURL(msg)) + // triple and validate it. + repeated google.protobuf.Any msgs = 2 [(cosmos_proto.accepts_interface) = "sdk.Msg, authz.Authorization"]; +} + +// MsgGrantResponse defines the Msg/MsgGrant response type. +message MsgGrantResponse {} + +// MsgRevoke revokes any authorization with the provided sdk.Msg type on the +// granter's account with that has been granted to the grantee. +message MsgRevoke { + string granter = 1; + string grantee = 2; + string msg_type_url = 3; +} + +// MsgRevokeResponse defines the Msg/MsgRevokeResponse response type. +message MsgRevokeResponse {} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto new file mode 100644 index 000000000..4f58b15e4 --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/authz.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// SendAuthorization allows the grantee to spend up to spend_limit coins from +// the granter's account. +// +// Since: cosmos-sdk 0.43 +message SendAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + repeated cosmos.base.v1beta1.Coin spend_limit = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto new file mode 100644 index 000000000..df91008df --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/bank.proto @@ -0,0 +1,96 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Params defines the parameters for the bank module. +message Params { + option (gogoproto.goproto_stringer) = false; + repeated SendEnabled send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled,omitempty\""]; + bool default_send_enabled = 2 [(gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\""]; +} + +// SendEnabled maps coin denom to a send_enabled status (whether a denom is +// sendable). +message SendEnabled { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + string denom = 1; + bool enabled = 2; +} + +// Input models transaction input. +message Input { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1; + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Output models transaction outputs. +message Output { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string address = 1; + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Supply represents a struct that passively keeps track of the total supply +// amounts in the network. +// This message is deprecated now that supply is indexed by denom. +message Supply { + option deprecated = true; + + option (gogoproto.equal) = true; + option (gogoproto.goproto_getters) = false; + + option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/legacy/v040.SupplyI"; + + repeated cosmos.base.v1beta1.Coin total = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// DenomUnit represents a struct that describes a given +// denomination unit of the basic token. +message DenomUnit { + // denom represents the string name of the given denom unit (e.g uatom). + string denom = 1; + // exponent represents power of 10 exponent that one must + // raise the base_denom to in order to equal the given DenomUnit's denom + // 1 denom = 1^exponent base_denom + // (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with + // exponent = 6, thus: 1 atom = 10^6 uatom). + uint32 exponent = 2; + // aliases is a list of string aliases for the given denom + repeated string aliases = 3; +} + +// Metadata represents a struct that describes +// a basic token. +message Metadata { + string description = 1; + // denom_units represents the list of DenomUnit's for a given coin + repeated DenomUnit denom_units = 2; + // base represents the base denom (should be the DenomUnit with exponent = 0). + string base = 3; + // display indicates the suggested denom that should be + // displayed in clients. + string display = 4; + // name defines the name of the token (eg: Cosmos Atom) + // + // Since: cosmos-sdk 0.43 + string name = 5; + // symbol is the token symbol usually shown on exchanges (eg: ATOM). This can + // be the same as the display. + // + // Since: cosmos-sdk 0.43 + string symbol = 6; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto new file mode 100644 index 000000000..8fd7329a0 --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/genesis.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// GenesisState defines the bank module's genesis state. +message GenesisState { + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // balances is an array containing the balances of all the accounts. + repeated Balance balances = 2 [(gogoproto.nullable) = false]; + + // supply represents the total supply. If it is left empty, then supply will be calculated based on the provided + // balances. Otherwise, it will be used to validate that the sum of the balances equals this amount. + repeated cosmos.base.v1beta1.Coin supply = 3 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; + + // denom_metadata defines the metadata of the differents coins. + repeated Metadata denom_metadata = 4 [(gogoproto.moretags) = "yaml:\"denom_metadata\"", (gogoproto.nullable) = false]; +} + +// Balance defines an account address and balance pair used in the bank module's +// genesis state. +message Balance { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address of the balance holder. + string address = 1; + + // coins defines the different coins this balance holds. + repeated cosmos.base.v1beta1.Coin coins = 2 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto new file mode 100644 index 000000000..a567e073f --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/query.proto @@ -0,0 +1,193 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Query defines the gRPC querier service. +service Query { + // Balance queries the balance of a single coin for a single account. + rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}/by_denom"; + } + + // AllBalances queries the balance of all coins for a single account. + rpc AllBalances(QueryAllBalancesRequest) returns (QueryAllBalancesResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/balances/{address}"; + } + + // SpendableBalances queries the spenable balance of all coins for a single + // account. + rpc SpendableBalances(QuerySpendableBalancesRequest) returns (QuerySpendableBalancesResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/spendable_balances/{address}"; + } + + // TotalSupply queries the total supply of all coins. + rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/supply"; + } + + // SupplyOf queries the supply of a single coin. + rpc SupplyOf(QuerySupplyOfRequest) returns (QuerySupplyOfResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/supply/{denom}"; + } + + // Params queries the parameters of x/bank module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/params"; + } + + // DenomsMetadata queries the client metadata of a given coin denomination. + rpc DenomMetadata(QueryDenomMetadataRequest) returns (QueryDenomMetadataResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata/{denom}"; + } + + // DenomsMetadata queries the client metadata for all registered coin denominations. + rpc DenomsMetadata(QueryDenomsMetadataRequest) returns (QueryDenomsMetadataResponse) { + option (google.api.http).get = "/cosmos/bank/v1beta1/denoms_metadata"; + } +} + +// QueryBalanceRequest is the request type for the Query/Balance RPC method. +message QueryBalanceRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query balances for. + string address = 1; + + // denom is the coin denom to query balances for. + string denom = 2; +} + +// QueryBalanceResponse is the response type for the Query/Balance RPC method. +message QueryBalanceResponse { + // balance is the balance of the coin. + cosmos.base.v1beta1.Coin balance = 1; +} + +// QueryBalanceRequest is the request type for the Query/AllBalances RPC method. +message QueryAllBalancesRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query balances for. + string address = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC +// method. +message QueryAllBalancesResponse { + // balances is the balances of all the coins. + repeated cosmos.base.v1beta1.Coin balances = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QuerySpendableBalancesRequest defines the gRPC request structure for querying +// an account's spendable balances. +message QuerySpendableBalancesRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address to query spendable balances for. + string address = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QuerySpendableBalancesResponse defines the gRPC response structure for querying +// an account's spendable balances. +message QuerySpendableBalancesResponse { + // balances is the spendable balances of all the coins. + repeated cosmos.base.v1beta1.Coin balances = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC +// method. +message QueryTotalSupplyRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // pagination defines an optional pagination for the request. + // + // Since: cosmos-sdk 0.43 + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC +// method +message QueryTotalSupplyResponse { + // supply is the supply of the coins + repeated cosmos.base.v1beta1.Coin supply = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // pagination defines the pagination in the response. + // + // Since: cosmos-sdk 0.43 + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QuerySupplyOfRequest is the request type for the Query/SupplyOf RPC method. +message QuerySupplyOfRequest { + // denom is the coin denom to query balances for. + string denom = 1; +} + +// QuerySupplyOfResponse is the response type for the Query/SupplyOf RPC method. +message QuerySupplyOfResponse { + // amount is the supply of the coin. + cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; +} + +// QueryParamsRequest defines the request type for querying x/bank parameters. +message QueryParamsRequest {} + +// QueryParamsResponse defines the response type for querying x/bank parameters. +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryDenomsMetadataRequest is the request type for the Query/DenomsMetadata RPC method. +message QueryDenomsMetadataRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryDenomsMetadataResponse is the response type for the Query/DenomsMetadata RPC +// method. +message QueryDenomsMetadataResponse { + // metadata provides the client information for all the registered tokens. + repeated Metadata metadatas = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDenomMetadataRequest is the request type for the Query/DenomMetadata RPC method. +message QueryDenomMetadataRequest { + // denom is the coin denom to query the metadata for. + string denom = 1; +} + +// QueryDenomMetadataResponse is the response type for the Query/DenomMetadata RPC +// method. +message QueryDenomMetadataResponse { + // metadata describes and provides all the client information for the requested token. + Metadata metadata = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto new file mode 100644 index 000000000..26b2ab41f --- /dev/null +++ b/ampd/proto/third_party/cosmos/bank/v1beta1/tx.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package cosmos.bank.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; + +// Msg defines the bank Msg service. +service Msg { + // Send defines a method for sending coins from one account to another account. + rpc Send(MsgSend) returns (MsgSendResponse); + + // MultiSend defines a method for sending coins from some accounts to other accounts. + rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse); +} + +// MsgSend represents a message to send coins from one account to another. +message MsgSend { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// MsgSendResponse defines the Msg/Send response type. +message MsgSendResponse {} + +// MsgMultiSend represents an arbitrary multi-in, multi-out send message. +message MsgMultiSend { + option (gogoproto.equal) = false; + + repeated Input inputs = 1 [(gogoproto.nullable) = false]; + repeated Output outputs = 2 [(gogoproto.nullable) = false]; +} + +// MsgMultiSendResponse defines the Msg/MultiSend response type. +message MsgMultiSendResponse {} diff --git a/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto b/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto new file mode 100644 index 000000000..e24ae7bd5 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/abci/v1beta1/abci.proto @@ -0,0 +1,144 @@ +syntax = "proto3"; +package cosmos.base.abci.v1beta1; + +import "gogoproto/gogo.proto"; +import "tendermint/abci/types.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types"; +option (gogoproto.goproto_stringer_all) = false; + +// TxResponse defines a structure containing relevant tx data and metadata. The +// tags are stringified and the log is JSON decoded. +message TxResponse { + option (gogoproto.goproto_getters) = false; + // The block height + int64 height = 1; + // The transaction hash. + string txhash = 2 [(gogoproto.customname) = "TxHash"]; + // Namespace for the Code + string codespace = 3; + // Response code. + uint32 code = 4; + // Result bytes, if any. + string data = 5; + // The output of the application's logger (raw string). May be + // non-deterministic. + string raw_log = 6; + // The output of the application's logger (typed). May be non-deterministic. + repeated ABCIMessageLog logs = 7 [(gogoproto.castrepeated) = "ABCIMessageLogs", (gogoproto.nullable) = false]; + // Additional information. May be non-deterministic. + string info = 8; + // Amount of gas requested for transaction. + int64 gas_wanted = 9; + // Amount of gas consumed by transaction. + int64 gas_used = 10; + // The request transaction bytes. + google.protobuf.Any tx = 11; + // Time of the previous block. For heights > 1, it's the weighted median of + // the timestamps of the valid votes in the block.LastCommit. For height == 1, + // it's genesis time. + string timestamp = 12; + // Events defines all the events emitted by processing a transaction. Note, + // these events include those emitted by processing all the messages and those + // emitted from the ante handler. Whereas Logs contains the events, with + // additional metadata, emitted only by processing the messages. + // + // Since: cosmos-sdk 0.42.11, 0.44.5, 0.45 + repeated tendermint.abci.Event events = 13 [(gogoproto.nullable) = false]; +} + +// ABCIMessageLog defines a structure containing an indexed tx ABCI message log. +message ABCIMessageLog { + option (gogoproto.stringer) = true; + + uint32 msg_index = 1; + string log = 2; + + // Events contains a slice of Event objects that were emitted during some + // execution. + repeated StringEvent events = 3 [(gogoproto.castrepeated) = "StringEvents", (gogoproto.nullable) = false]; +} + +// StringEvent defines en Event object wrapper where all the attributes +// contain key/value pairs that are strings instead of raw bytes. +message StringEvent { + option (gogoproto.stringer) = true; + + string type = 1; + repeated Attribute attributes = 2 [(gogoproto.nullable) = false]; +} + +// Attribute defines an attribute wrapper where the key and value are +// strings instead of raw bytes. +message Attribute { + string key = 1; + string value = 2; +} + +// GasInfo defines tx execution gas context. +message GasInfo { + // GasWanted is the maximum units of work we allow this tx to perform. + uint64 gas_wanted = 1 [(gogoproto.moretags) = "yaml:\"gas_wanted\""]; + + // GasUsed is the amount of gas actually consumed. + uint64 gas_used = 2 [(gogoproto.moretags) = "yaml:\"gas_used\""]; +} + +// Result is the union of ResponseFormat and ResponseCheckTx. +message Result { + option (gogoproto.goproto_getters) = false; + + // Data is any data returned from message or handler execution. It MUST be + // length prefixed in order to separate data from multiple message executions. + bytes data = 1; + + // Log contains the log information from message or handler execution. + string log = 2; + + // Events contains a slice of Event objects that were emitted during message + // or handler execution. + repeated tendermint.abci.Event events = 3 [(gogoproto.nullable) = false]; +} + +// SimulationResponse defines the response generated when a transaction is +// successfully simulated. +message SimulationResponse { + GasInfo gas_info = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + Result result = 2; +} + +// MsgData defines the data returned in a Result object during message +// execution. +message MsgData { + option (gogoproto.stringer) = true; + + string msg_type = 1; + bytes data = 2; +} + +// TxMsgData defines a list of MsgData. A transaction will have a MsgData object +// for each message. +message TxMsgData { + option (gogoproto.stringer) = true; + + repeated MsgData data = 1; +} + +// SearchTxsResult defines a structure for querying txs pageable +message SearchTxsResult { + option (gogoproto.stringer) = true; + + // Count of all txs + uint64 total_count = 1 [(gogoproto.moretags) = "yaml:\"total_count\"", (gogoproto.jsontag) = "total_count"]; + // Count of txs in current page + uint64 count = 2; + // Index of current page, start from 1 + uint64 page_number = 3 [(gogoproto.moretags) = "yaml:\"page_number\"", (gogoproto.jsontag) = "page_number"]; + // Count of total pages + uint64 page_total = 4 [(gogoproto.moretags) = "yaml:\"page_total\"", (gogoproto.jsontag) = "page_total"]; + // Max count txs per page + uint64 limit = 5; + // List of txs in current page + repeated TxResponse txs = 6; +} diff --git a/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto b/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto new file mode 100644 index 000000000..4e9b8d285 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/kv/v1beta1/kv.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package cosmos.base.kv.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/kv"; + +// Pairs defines a repeated slice of Pair objects. +message Pairs { + repeated Pair pairs = 1 [(gogoproto.nullable) = false]; +} + +// Pair defines a key/value bytes tuple. +message Pair { + bytes key = 1; + bytes value = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto b/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto new file mode 100644 index 000000000..8070f7b90 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/node/v1beta1/query.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.base.node.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/node"; + +// Service defines the gRPC querier service for node related queries. +service Service { + // Config queries for the operator configuration. + rpc Config(ConfigRequest) returns (ConfigResponse) { + option (google.api.http).get = "/cosmos/base/node/v1beta1/config"; + } +} + +// ConfigRequest defines the request structure for the Config gRPC query. +message ConfigRequest {} + +// ConfigResponse defines the response structure for the Config gRPC query. +message ConfigResponse { + string minimum_gas_price = 1; +} diff --git a/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto b/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto new file mode 100644 index 000000000..cd5eb066d --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/query/v1beta1/pagination.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; +package cosmos.base.query.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/types/query"; + +// PageRequest is to be embedded in gRPC request messages for efficient +// pagination. Ex: +// +// message SomeRequest { +// Foo some_parameter = 1; +// PageRequest pagination = 2; +// } +message PageRequest { + // key is a value returned in PageResponse.next_key to begin + // querying the next page most efficiently. Only one of offset or key + // should be set. + bytes key = 1; + + // offset is a numeric offset that can be used when key is unavailable. + // It is less efficient than using key. Only one of offset or key should + // be set. + uint64 offset = 2; + + // limit is the total number of results to be returned in the result page. + // If left empty it will default to a value to be set by each app. + uint64 limit = 3; + + // count_total is set to true to indicate that the result set should include + // a count of the total number of items available for pagination in UIs. + // count_total is only respected when offset is used. It is ignored when key + // is set. + bool count_total = 4; + + // reverse is set to true if results are to be returned in the descending order. + // + // Since: cosmos-sdk 0.43 + bool reverse = 5; +} + +// PageResponse is to be embedded in gRPC response messages where the +// corresponding request message has used PageRequest. +// +// message SomeResponse { +// repeated Bar results = 1; +// PageResponse page = 2; +// } +message PageResponse { + // next_key is the key to be passed to PageRequest.key to + // query the next page most efficiently + bytes next_key = 1; + + // total is total number of results available if PageRequest.count_total + // was set, its value is undefined otherwise + uint64 total = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto b/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto new file mode 100644 index 000000000..22670e72b --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/reflection/v1beta1/reflection.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; +package cosmos.base.reflection.v1beta1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/reflection"; + +// ReflectionService defines a service for interface reflection. +service ReflectionService { + // ListAllInterfaces lists all the interfaces registered in the interface + // registry. + rpc ListAllInterfaces(ListAllInterfacesRequest) returns (ListAllInterfacesResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces"; + }; + + // ListImplementations list all the concrete types that implement a given + // interface. + rpc ListImplementations(ListImplementationsRequest) returns (ListImplementationsResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/" + "{interface_name}/implementations"; + }; +} + +// ListAllInterfacesRequest is the request type of the ListAllInterfaces RPC. +message ListAllInterfacesRequest {} + +// ListAllInterfacesResponse is the response type of the ListAllInterfaces RPC. +message ListAllInterfacesResponse { + // interface_names is an array of all the registered interfaces. + repeated string interface_names = 1; +} + +// ListImplementationsRequest is the request type of the ListImplementations +// RPC. +message ListImplementationsRequest { + // interface_name defines the interface to query the implementations for. + string interface_name = 1; +} + +// ListImplementationsResponse is the response type of the ListImplementations +// RPC. +message ListImplementationsResponse { + repeated string implementation_message_names = 1; +} diff --git a/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto b/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto new file mode 100644 index 000000000..d5b048558 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/reflection/v2alpha1/reflection.proto @@ -0,0 +1,218 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.base.reflection.v2alpha1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/server/grpc/reflection/v2alpha1"; + +// AppDescriptor describes a cosmos-sdk based application +message AppDescriptor { + // AuthnDescriptor provides information on how to authenticate transactions on the application + // NOTE: experimental and subject to change in future releases. + AuthnDescriptor authn = 1; + // chain provides the chain descriptor + ChainDescriptor chain = 2; + // codec provides metadata information regarding codec related types + CodecDescriptor codec = 3; + // configuration provides metadata information regarding the sdk.Config type + ConfigurationDescriptor configuration = 4; + // query_services provides metadata information regarding the available queriable endpoints + QueryServicesDescriptor query_services = 5; + // tx provides metadata information regarding how to send transactions to the given application + TxDescriptor tx = 6; +} + +// TxDescriptor describes the accepted transaction type +message TxDescriptor { + // fullname is the protobuf fullname of the raw transaction type (for instance the tx.Tx type) + // it is not meant to support polymorphism of transaction types, it is supposed to be used by + // reflection clients to understand if they can handle a specific transaction type in an application. + string fullname = 1; + // msgs lists the accepted application messages (sdk.Msg) + repeated MsgDescriptor msgs = 2; +} + +// AuthnDescriptor provides information on how to sign transactions without relying +// on the online RPCs GetTxMetadata and CombineUnsignedTxAndSignatures +message AuthnDescriptor { + // sign_modes defines the supported signature algorithm + repeated SigningModeDescriptor sign_modes = 1; +} + +// SigningModeDescriptor provides information on a signing flow of the application +// NOTE(fdymylja): here we could go as far as providing an entire flow on how +// to sign a message given a SigningModeDescriptor, but it's better to think about +// this another time +message SigningModeDescriptor { + // name defines the unique name of the signing mode + string name = 1; + // number is the unique int32 identifier for the sign_mode enum + int32 number = 2; + // authn_info_provider_method_fullname defines the fullname of the method to call to get + // the metadata required to authenticate using the provided sign_modes + string authn_info_provider_method_fullname = 3; +} + +// ChainDescriptor describes chain information of the application +message ChainDescriptor { + // id is the chain id + string id = 1; +} + +// CodecDescriptor describes the registered interfaces and provides metadata information on the types +message CodecDescriptor { + // interfaces is a list of the registerted interfaces descriptors + repeated InterfaceDescriptor interfaces = 1; +} + +// InterfaceDescriptor describes the implementation of an interface +message InterfaceDescriptor { + // fullname is the name of the interface + string fullname = 1; + // interface_accepting_messages contains information regarding the proto messages which contain the interface as + // google.protobuf.Any field + repeated InterfaceAcceptingMessageDescriptor interface_accepting_messages = 2; + // interface_implementers is a list of the descriptors of the interface implementers + repeated InterfaceImplementerDescriptor interface_implementers = 3; +} + +// InterfaceImplementerDescriptor describes an interface implementer +message InterfaceImplementerDescriptor { + // fullname is the protobuf queryable name of the interface implementer + string fullname = 1; + // type_url defines the type URL used when marshalling the type as any + // this is required so we can provide type safe google.protobuf.Any marshalling and + // unmarshalling, making sure that we don't accept just 'any' type + // in our interface fields + string type_url = 2; +} + +// InterfaceAcceptingMessageDescriptor describes a protobuf message which contains +// an interface represented as a google.protobuf.Any +message InterfaceAcceptingMessageDescriptor { + // fullname is the protobuf fullname of the type containing the interface + string fullname = 1; + // field_descriptor_names is a list of the protobuf name (not fullname) of the field + // which contains the interface as google.protobuf.Any (the interface is the same, but + // it can be in multiple fields of the same proto message) + repeated string field_descriptor_names = 2; +} + +// ConfigurationDescriptor contains metadata information on the sdk.Config +message ConfigurationDescriptor { + // bech32_account_address_prefix is the account address prefix + string bech32_account_address_prefix = 1; +} + +// MsgDescriptor describes a cosmos-sdk message that can be delivered with a transaction +message MsgDescriptor { + // msg_type_url contains the TypeURL of a sdk.Msg. + string msg_type_url = 1; +} + +// ReflectionService defines a service for application reflection. +service ReflectionService { + // GetAuthnDescriptor returns information on how to authenticate transactions in the application + // NOTE: this RPC is still experimental and might be subject to breaking changes or removal in + // future releases of the cosmos-sdk. + rpc GetAuthnDescriptor(GetAuthnDescriptorRequest) returns (GetAuthnDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/authn"; + } + // GetChainDescriptor returns the description of the chain + rpc GetChainDescriptor(GetChainDescriptorRequest) returns (GetChainDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/chain"; + }; + // GetCodecDescriptor returns the descriptor of the codec of the application + rpc GetCodecDescriptor(GetCodecDescriptorRequest) returns (GetCodecDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/codec"; + } + // GetConfigurationDescriptor returns the descriptor for the sdk.Config of the application + rpc GetConfigurationDescriptor(GetConfigurationDescriptorRequest) returns (GetConfigurationDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/configuration"; + } + // GetQueryServicesDescriptor returns the available gRPC queryable services of the application + rpc GetQueryServicesDescriptor(GetQueryServicesDescriptorRequest) returns (GetQueryServicesDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/query_services"; + } + // GetTxDescriptor returns information on the used transaction object and available msgs that can be used + rpc GetTxDescriptor(GetTxDescriptorRequest) returns (GetTxDescriptorResponse) { + option (google.api.http).get = "/cosmos/base/reflection/v1beta1/app_descriptor/tx_descriptor"; + } +} + +// GetAuthnDescriptorRequest is the request used for the GetAuthnDescriptor RPC +message GetAuthnDescriptorRequest {} +// GetAuthnDescriptorResponse is the response returned by the GetAuthnDescriptor RPC +message GetAuthnDescriptorResponse { + // authn describes how to authenticate to the application when sending transactions + AuthnDescriptor authn = 1; +} + +// GetChainDescriptorRequest is the request used for the GetChainDescriptor RPC +message GetChainDescriptorRequest {} +// GetChainDescriptorResponse is the response returned by the GetChainDescriptor RPC +message GetChainDescriptorResponse { + // chain describes application chain information + ChainDescriptor chain = 1; +} + +// GetCodecDescriptorRequest is the request used for the GetCodecDescriptor RPC +message GetCodecDescriptorRequest {} +// GetCodecDescriptorResponse is the response returned by the GetCodecDescriptor RPC +message GetCodecDescriptorResponse { + // codec describes the application codec such as registered interfaces and implementations + CodecDescriptor codec = 1; +} + +// GetConfigurationDescriptorRequest is the request used for the GetConfigurationDescriptor RPC +message GetConfigurationDescriptorRequest {} +// GetConfigurationDescriptorResponse is the response returned by the GetConfigurationDescriptor RPC +message GetConfigurationDescriptorResponse { + // config describes the application's sdk.Config + ConfigurationDescriptor config = 1; +} + +// GetQueryServicesDescriptorRequest is the request used for the GetQueryServicesDescriptor RPC +message GetQueryServicesDescriptorRequest {} +// GetQueryServicesDescriptorResponse is the response returned by the GetQueryServicesDescriptor RPC +message GetQueryServicesDescriptorResponse { + // queries provides information on the available queryable services + QueryServicesDescriptor queries = 1; +} + +// GetTxDescriptorRequest is the request used for the GetTxDescriptor RPC +message GetTxDescriptorRequest {} +// GetTxDescriptorResponse is the response returned by the GetTxDescriptor RPC +message GetTxDescriptorResponse { + // tx provides information on msgs that can be forwarded to the application + // alongside the accepted transaction protobuf type + TxDescriptor tx = 1; +} + +// QueryServicesDescriptor contains the list of cosmos-sdk queriable services +message QueryServicesDescriptor { + // query_services is a list of cosmos-sdk QueryServiceDescriptor + repeated QueryServiceDescriptor query_services = 1; +} + +// QueryServiceDescriptor describes a cosmos-sdk queryable service +message QueryServiceDescriptor { + // fullname is the protobuf fullname of the service descriptor + string fullname = 1; + // is_module describes if this service is actually exposed by an application's module + bool is_module = 2; + // methods provides a list of query service methods + repeated QueryMethodDescriptor methods = 3; +} + +// QueryMethodDescriptor describes a queryable method of a query service +// no other info is provided beside method name and tendermint queryable path +// because it would be redundant with the grpc reflection service +message QueryMethodDescriptor { + // name is the protobuf name (not fullname) of the method + string name = 1; + // full_query_path is the path that can be used to query + // this method via tendermint abci.Query + string full_query_path = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto b/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto new file mode 100644 index 000000000..6dcc4a933 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/snapshots/v1beta1/snapshot.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package cosmos.base.snapshots.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/snapshots/types"; + +// Snapshot contains Tendermint state sync snapshot info. +message Snapshot { + uint64 height = 1; + uint32 format = 2; + uint32 chunks = 3; + bytes hash = 4; + Metadata metadata = 5 [(gogoproto.nullable) = false]; +} + +// Metadata contains SDK-specific snapshot metadata. +message Metadata { + repeated bytes chunk_hashes = 1; // SHA-256 chunk hashes +} + +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +message SnapshotItem { + // item is the specific type of snapshot item. + oneof item { + SnapshotStoreItem store = 1; + SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; + SnapshotExtensionMeta extension = 3; + SnapshotExtensionPayload extension_payload = 4; + } +} + +// SnapshotStoreItem contains metadata about a snapshotted store. +message SnapshotStoreItem { + string name = 1; +} + +// SnapshotIAVLItem is an exported IAVL node. +message SnapshotIAVLItem { + bytes key = 1; + bytes value = 2; + // version is block height + int64 version = 3; + // height is depth of the tree. + int32 height = 4; +} + +// SnapshotExtensionMeta contains metadata about an external snapshotter. +message SnapshotExtensionMeta { + string name = 1; + uint32 format = 2; +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +message SnapshotExtensionPayload { + bytes payload = 1; +} diff --git a/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto b/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto new file mode 100644 index 000000000..98a33d30e --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/store/v1beta1/commit_info.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; +package cosmos.base.store.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/store/types"; + +// CommitInfo defines commit information used by the multi-store when committing +// a version/height. +message CommitInfo { + int64 version = 1; + repeated StoreInfo store_infos = 2 [(gogoproto.nullable) = false]; +} + +// StoreInfo defines store-specific commit information. It contains a reference +// between a store name and the commit ID. +message StoreInfo { + string name = 1; + CommitID commit_id = 2 [(gogoproto.nullable) = false]; +} + +// CommitID defines the committment information when a specific store is +// committed. +message CommitID { + option (gogoproto.goproto_stringer) = false; + + int64 version = 1; + bytes hash = 2; +} diff --git a/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto b/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto new file mode 100644 index 000000000..753f7c165 --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/store/v1beta1/listening.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package cosmos.base.store.v1beta1; + +import "tendermint/abci/types.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/store/types"; + +// StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) +// It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and +// Deletes +// +// Since: cosmos-sdk 0.43 +message StoreKVPair { + string store_key = 1; // the store key for the KVStore this pair originates from + bool delete = 2; // true indicates a delete operation, false indicates a set operation + bytes key = 3; + bytes value = 4; +} + +// BlockMetadata contains all the abci event data of a block +// the file streamer dump them into files together with the state changes. +message BlockMetadata { + // DeliverTx encapulate deliver tx request and response. + message DeliverTx { + tendermint.abci.RequestDeliverTx request = 1; + tendermint.abci.ResponseDeliverTx response = 2; + } + tendermint.abci.RequestBeginBlock request_begin_block = 1; + tendermint.abci.ResponseBeginBlock response_begin_block = 2; + repeated DeliverTx deliver_txs = 3; + tendermint.abci.RequestEndBlock request_end_block = 4; + tendermint.abci.ResponseEndBlock response_end_block = 5; + tendermint.abci.ResponseCommit response_commit = 6; +} diff --git a/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto b/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto new file mode 100644 index 000000000..98542d23d --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/tendermint/v1beta1/query.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; +package cosmos.base.tendermint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "tendermint/p2p/types.proto"; +import "tendermint/types/block.proto"; +import "tendermint/types/types.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"; + +// Service defines the gRPC querier service for tendermint queries. +service Service { + // GetNodeInfo queries the current node info. + rpc GetNodeInfo(GetNodeInfoRequest) returns (GetNodeInfoResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/node_info"; + } + // GetSyncing queries node syncing. + rpc GetSyncing(GetSyncingRequest) returns (GetSyncingResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/syncing"; + } + // GetLatestBlock returns the latest block. + rpc GetLatestBlock(GetLatestBlockRequest) returns (GetLatestBlockResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/latest"; + } + // GetBlockByHeight queries block for given height. + rpc GetBlockByHeight(GetBlockByHeightRequest) returns (GetBlockByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/blocks/{height}"; + } + + // GetLatestValidatorSet queries latest validator-set. + rpc GetLatestValidatorSet(GetLatestValidatorSetRequest) returns (GetLatestValidatorSetResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/latest"; + } + // GetValidatorSetByHeight queries validator-set at a given height. + rpc GetValidatorSetByHeight(GetValidatorSetByHeightRequest) returns (GetValidatorSetByHeightResponse) { + option (google.api.http).get = "/cosmos/base/tendermint/v1beta1/validatorsets/{height}"; + } +} + +// GetValidatorSetByHeightRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightRequest { + int64 height = 1; + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// GetValidatorSetByHeightResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetValidatorSetByHeightResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// GetLatestValidatorSetRequest is the request type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetRequest { + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// GetLatestValidatorSetResponse is the response type for the Query/GetValidatorSetByHeight RPC method. +message GetLatestValidatorSetResponse { + int64 block_height = 1; + repeated Validator validators = 2; + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// Validator is the type for the validator-set. +message Validator { + string address = 1; + google.protobuf.Any pub_key = 2; + int64 voting_power = 3; + int64 proposer_priority = 4; +} + +// GetBlockByHeightRequest is the request type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightRequest { + int64 height = 1; +} + +// GetBlockByHeightResponse is the response type for the Query/GetBlockByHeight RPC method. +message GetBlockByHeightResponse { + .tendermint.types.BlockID block_id = 1; + .tendermint.types.Block block = 2; +} + +// GetLatestBlockRequest is the request type for the Query/GetLatestBlock RPC method. +message GetLatestBlockRequest {} + +// GetLatestBlockResponse is the response type for the Query/GetLatestBlock RPC method. +message GetLatestBlockResponse { + .tendermint.types.BlockID block_id = 1; + .tendermint.types.Block block = 2; +} + +// GetSyncingRequest is the request type for the Query/GetSyncing RPC method. +message GetSyncingRequest {} + +// GetSyncingResponse is the response type for the Query/GetSyncing RPC method. +message GetSyncingResponse { + bool syncing = 1; +} + +// GetNodeInfoRequest is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoRequest {} + +// GetNodeInfoResponse is the request type for the Query/GetNodeInfo RPC method. +message GetNodeInfoResponse { + .tendermint.p2p.DefaultNodeInfo default_node_info = 1; + VersionInfo application_version = 2; +} + +// VersionInfo is the type for the GetNodeInfoResponse message. +message VersionInfo { + string name = 1; + string app_name = 2; + string version = 3; + string git_commit = 4; + string build_tags = 5; + string go_version = 6; + repeated Module build_deps = 7; + // Since: cosmos-sdk 0.43 + string cosmos_sdk_version = 8; +} + +// Module is the type for VersionInfo +message Module { + // module path + string path = 1; + // module version + string version = 2; + // checksum + string sum = 3; +} diff --git a/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto b/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto new file mode 100644 index 000000000..fab75284b --- /dev/null +++ b/ampd/proto/third_party/cosmos/base/v1beta1/coin.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package cosmos.base.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = false; + +// Coin defines a token with a denomination and an amount. +// +// NOTE: The amount field is an Int which implements the custom method +// signatures required by gogoproto. +message Coin { + option (gogoproto.equal) = true; + + string denom = 1; + string amount = 2 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; +} + +// DecCoin defines a token with a denomination and a decimal amount. +// +// NOTE: The amount field is an Dec which implements the custom method +// signatures required by gogoproto. +message DecCoin { + option (gogoproto.equal) = true; + + string denom = 1; + string amount = 2 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; +} + +// IntProto defines a Protobuf wrapper around an Int object. +message IntProto { + string int = 1 [(gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; +} + +// DecProto defines a Protobuf wrapper around a Dec object. +message DecProto { + string dec = 1 [(gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto b/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto new file mode 100644 index 000000000..1c8332f34 --- /dev/null +++ b/ampd/proto/third_party/cosmos/capability/v1beta1/capability.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package cosmos.capability.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +import "gogoproto/gogo.proto"; + +// Capability defines an implementation of an object capability. The index +// provided to a Capability must be globally unique. +message Capability { + option (gogoproto.goproto_stringer) = false; + + uint64 index = 1 [(gogoproto.moretags) = "yaml:\"index\""]; +} + +// Owner defines a single capability owner. An owner is defined by the name of +// capability and the module name. +message Owner { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + string module = 1 [(gogoproto.moretags) = "yaml:\"module\""]; + string name = 2 [(gogoproto.moretags) = "yaml:\"name\""]; +} + +// CapabilityOwners defines a set of owners of a single Capability. The set of +// owners must be unique. +message CapabilityOwners { + repeated Owner owners = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto new file mode 100644 index 000000000..05bb0afc4 --- /dev/null +++ b/ampd/proto/third_party/cosmos/capability/v1beta1/genesis.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.capability.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/capability/v1beta1/capability.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; + +// GenesisOwners defines the capability owners with their corresponding index. +message GenesisOwners { + // index is the index of the capability owner. + uint64 index = 1; + + // index_owners are the owners at the given index. + CapabilityOwners index_owners = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"index_owners\""]; +} + +// GenesisState defines the capability module's genesis state. +message GenesisState { + // index is the capability global index. + uint64 index = 1; + + // owners represents a map from index to owners of the capability index + // index key is string to allow amino marshalling. + repeated GenesisOwners owners = 2 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto new file mode 100644 index 000000000..5b0ff7ec7 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crisis/v1beta1/genesis.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package cosmos.crisis.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// GenesisState defines the crisis module's genesis state. +message GenesisState { + // constant_fee is the fee used to verify the invariant in the crisis + // module. + cosmos.base.v1beta1.Coin constant_fee = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"constant_fee\""]; +} diff --git a/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto new file mode 100644 index 000000000..26457ad6d --- /dev/null +++ b/ampd/proto/third_party/cosmos/crisis/v1beta1/tx.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package cosmos.crisis.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; + +import "gogoproto/gogo.proto"; + +// Msg defines the bank Msg service. +service Msg { + // VerifyInvariant defines a method to verify a particular invariance. + rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse); +} + +// MsgVerifyInvariant represents a message to verify a particular invariance. +message MsgVerifyInvariant { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string sender = 1; + string invariant_module_name = 2 [(gogoproto.moretags) = "yaml:\"invariant_module_name\""]; + string invariant_route = 3 [(gogoproto.moretags) = "yaml:\"invariant_route\""]; +} + +// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type. +message MsgVerifyInvariantResponse {} diff --git a/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto b/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto new file mode 100644 index 000000000..6ffec3448 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/ed25519/keys.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package cosmos.crypto.ed25519; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"; + +// PubKey is an ed25519 public key for handling Tendermint keys in SDK. +// It's needed for Any serialization and SDK compatibility. +// It must not be used in a non Tendermint key context because it doesn't implement +// ADR-28. Nevertheless, you will like to use ed25519 in app user level +// then you must create a new proto message and follow ADR-28 for Address construction. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PublicKey"]; +} + +// Deprecated: PrivKey defines a ed25519 private key. +// NOTE: ed25519 keys must not be used in SDK apps except in a tendermint validator context. +message PrivKey { + bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PrivateKey"]; +} diff --git a/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto b/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto new file mode 100644 index 000000000..f8398e805 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/multisig/keys.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package cosmos.crypto.multisig; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"; + +// LegacyAminoPubKey specifies a public key type +// which nests multiple public keys and a threshold, +// it uses legacy amino address rules. +message LegacyAminoPubKey { + option (gogoproto.goproto_getters) = false; + + uint32 threshold = 1 [(gogoproto.moretags) = "yaml:\"threshold\""]; + repeated google.protobuf.Any public_keys = 2 + [(gogoproto.customname) = "PubKeys", (gogoproto.moretags) = "yaml:\"pubkeys\""]; +} diff --git a/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto b/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto new file mode 100644 index 000000000..bf671f171 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/multisig/v1beta1/multisig.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package cosmos.crypto.multisig.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/types"; + +// MultiSignature wraps the signatures from a multisig.LegacyAminoPubKey. +// See cosmos.tx.v1betata1.ModeInfo.Multi for how to specify which signers +// signed and with which modes. +message MultiSignature { + option (gogoproto.goproto_unrecognized) = true; + repeated bytes signatures = 1; +} + +// CompactBitArray is an implementation of a space efficient bit array. +// This is used to ensure that the encoded data takes up a minimal amount of +// space after proto encoding. +// This is not thread safe, and is not intended for concurrent usage. +message CompactBitArray { + option (gogoproto.goproto_stringer) = false; + + uint32 extra_bits_stored = 1; + bytes elems = 2; +} diff --git a/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto b/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto new file mode 100644 index 000000000..a22725713 --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/secp256k1/keys.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.crypto.secp256k1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"; + +// PubKey defines a secp256k1 public key +// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte +// if the y-coordinate is the lexicographically largest of the two associated with +// the x-coordinate. Otherwise the first byte is a 0x03. +// This prefix is followed with the x-coordinate. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1; +} + +// PrivKey defines a secp256k1 private key. +message PrivKey { + bytes key = 1; +} diff --git a/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto b/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto new file mode 100644 index 000000000..2e96c6e3c --- /dev/null +++ b/ampd/proto/third_party/cosmos/crypto/secp256r1/keys.proto @@ -0,0 +1,23 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.crypto.secp256r1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1"; +option (gogoproto.messagename_all) = true; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; + +// PubKey defines a secp256r1 ECDSA public key. +message PubKey { + // Point on secp256r1 curve in a compressed representation as specified in section + // 4.3.6 of ANSI X9.62: https://webstore.ansi.org/standards/ascx9/ansix9621998 + bytes key = 1 [(gogoproto.customtype) = "ecdsaPK"]; +} + +// PrivKey defines a secp256r1 ECDSA private key. +message PrivKey { + // secret number serialized using big-endian encoding + bytes secret = 1 [(gogoproto.customtype) = "ecdsaSK"]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto new file mode 100644 index 000000000..ae98ec0b9 --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/distribution.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Params defines the set of params for the distribution module. +message Params { + option (gogoproto.goproto_stringer) = false; + string community_tax = 1 [ + (gogoproto.moretags) = "yaml:\"community_tax\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string base_proposer_reward = 2 [ + (gogoproto.moretags) = "yaml:\"base_proposer_reward\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + string bonus_proposer_reward = 3 [ + (gogoproto.moretags) = "yaml:\"bonus_proposer_reward\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bool withdraw_addr_enabled = 4 [(gogoproto.moretags) = "yaml:\"withdraw_addr_enabled\""]; +} + +// ValidatorHistoricalRewards represents historical rewards for a validator. +// Height is implicit within the store key. +// Cumulative reward ratio is the sum from the zeroeth period +// until this period of rewards / tokens, per the spec. +// The reference count indicates the number of objects +// which might need to reference this historical entry at any point. +// ReferenceCount = +// number of outstanding delegations which ended the associated period (and +// might need to read that record) +// + number of slashes which ended the associated period (and might need to +// read that record) +// + one per validator for the zeroeth period, set on initialization +message ValidatorHistoricalRewards { + repeated cosmos.base.v1beta1.DecCoin cumulative_reward_ratio = 1 [ + (gogoproto.moretags) = "yaml:\"cumulative_reward_ratio\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; + uint32 reference_count = 2 [(gogoproto.moretags) = "yaml:\"reference_count\""]; +} + +// ValidatorCurrentRewards represents current rewards and current +// period for a validator kept as a running counter and incremented +// each block as long as the validator's tokens remain constant. +message ValidatorCurrentRewards { + repeated cosmos.base.v1beta1.DecCoin rewards = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; + uint64 period = 2; +} + +// ValidatorAccumulatedCommission represents accumulated commission +// for a validator kept as a running counter, can be withdrawn at any time. +message ValidatorAccumulatedCommission { + repeated cosmos.base.v1beta1.DecCoin commission = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} + +// ValidatorOutstandingRewards represents outstanding (un-withdrawn) rewards +// for a validator inexpensive to track, allows simple sanity checks. +message ValidatorOutstandingRewards { + repeated cosmos.base.v1beta1.DecCoin rewards = 1 [ + (gogoproto.moretags) = "yaml:\"rewards\"", + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false + ]; +} + +// ValidatorSlashEvent represents a validator slash event. +// Height is implicit within the store key. +// This is needed to calculate appropriate amount of staking tokens +// for delegations which are withdrawn after a slash has occurred. +message ValidatorSlashEvent { + uint64 validator_period = 1 [(gogoproto.moretags) = "yaml:\"validator_period\""]; + string fraction = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// ValidatorSlashEvents is a collection of ValidatorSlashEvent messages. +message ValidatorSlashEvents { + option (gogoproto.goproto_stringer) = false; + repeated ValidatorSlashEvent validator_slash_events = 1 + [(gogoproto.moretags) = "yaml:\"validator_slash_events\"", (gogoproto.nullable) = false]; +} + +// FeePool is the global fee pool for distribution. +message FeePool { + repeated cosmos.base.v1beta1.DecCoin community_pool = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.moretags) = "yaml:\"community_pool\"" + ]; +} + +// CommunityPoolSpendProposal details a proposal for use of community funds, +// together with how many coins are proposed to be spent, and to which +// recipient account. +message CommunityPoolSpendProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + string recipient = 3; + repeated cosmos.base.v1beta1.Coin amount = 4 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// DelegatorStartingInfo represents the starting info for a delegator reward +// period. It tracks the previous validator period, the delegation's amount of +// staking token, and the creation height (to check later on if any slashes have +// occurred). NOTE: Even though validators are slashed to whole staking tokens, +// the delegators within the validator may be left with less than a full token, +// thus sdk.Dec is used. +message DelegatorStartingInfo { + uint64 previous_period = 1 [(gogoproto.moretags) = "yaml:\"previous_period\""]; + string stake = 2 [ + (gogoproto.moretags) = "yaml:\"stake\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + uint64 height = 3 [(gogoproto.moretags) = "yaml:\"creation_height\"", (gogoproto.jsontag) = "creation_height"]; +} + +// DelegationDelegatorReward represents the properties +// of a delegator's delegation reward. +message DelegationDelegatorReward { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + repeated cosmos.base.v1beta1.DecCoin reward = 2 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} + +// CommunityPoolSpendProposalWithDeposit defines a CommunityPoolSpendProposal +// with a deposit +message CommunityPoolSpendProposalWithDeposit { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string title = 1 [(gogoproto.moretags) = "yaml:\"title\""]; + string description = 2 [(gogoproto.moretags) = "yaml:\"description\""]; + string recipient = 3 [(gogoproto.moretags) = "yaml:\"recipient\""]; + string amount = 4 [(gogoproto.moretags) = "yaml:\"amount\""]; + string deposit = 5 [(gogoproto.moretags) = "yaml:\"deposit\""]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto new file mode 100644 index 000000000..c0b17cdf1 --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/genesis.proto @@ -0,0 +1,155 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/distribution/v1beta1/distribution.proto"; + +// DelegatorWithdrawInfo is the address for where distributions rewards are +// withdrawn to by default this struct is only used at genesis to feed in +// default withdraw addresses. +message DelegatorWithdrawInfo { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address is the address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + + // withdraw_address is the address to withdraw the delegation rewards to. + string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; +} + +// ValidatorOutstandingRewardsRecord is used for import/export via genesis json. +message ValidatorOutstandingRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // outstanding_rewards represents the oustanding rewards of a validator. + repeated cosmos.base.v1beta1.DecCoin outstanding_rewards = 2 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"outstanding_rewards\"" + ]; +} + +// ValidatorAccumulatedCommissionRecord is used for import / export via genesis +// json. +message ValidatorAccumulatedCommissionRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // accumulated is the accumulated commission of a validator. + ValidatorAccumulatedCommission accumulated = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"accumulated\""]; +} + +// ValidatorHistoricalRewardsRecord is used for import / export via genesis +// json. +message ValidatorHistoricalRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // period defines the period the historical rewards apply to. + uint64 period = 2; + + // rewards defines the historical rewards of a validator. + ValidatorHistoricalRewards rewards = 3 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; +} + +// ValidatorCurrentRewardsRecord is used for import / export via genesis json. +message ValidatorCurrentRewardsRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // rewards defines the current rewards of a validator. + ValidatorCurrentRewards rewards = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"rewards\""]; +} + +// DelegatorStartingInfoRecord used for import / export via genesis json. +message DelegatorStartingInfoRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address is the address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + + // validator_address is the address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + + // starting_info defines the starting info of a delegator. + DelegatorStartingInfo starting_info = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"starting_info\""]; +} + +// ValidatorSlashEventRecord is used for import / export via genesis json. +message ValidatorSlashEventRecord { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator_address is the address of the validator. + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // height defines the block height at which the slash event occured. + uint64 height = 2; + // period is the period of the slash event. + uint64 period = 3; + // validator_slash_event describes the slash event. + ValidatorSlashEvent validator_slash_event = 4 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"event\""]; +} + +// GenesisState defines the distribution module's genesis state. +message GenesisState { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // params defines all the paramaters of the module. + Params params = 1 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"params\""]; + + // fee_pool defines the fee pool at genesis. + FeePool fee_pool = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"fee_pool\""]; + + // fee_pool defines the delegator withdraw infos at genesis. + repeated DelegatorWithdrawInfo delegator_withdraw_infos = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_withdraw_infos\""]; + + // fee_pool defines the previous proposer at genesis. + string previous_proposer = 4 [(gogoproto.moretags) = "yaml:\"previous_proposer\""]; + + // fee_pool defines the outstanding rewards of all validators at genesis. + repeated ValidatorOutstandingRewardsRecord outstanding_rewards = 5 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"outstanding_rewards\""]; + + // fee_pool defines the accumulated commisions of all validators at genesis. + repeated ValidatorAccumulatedCommissionRecord validator_accumulated_commissions = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_accumulated_commissions\""]; + + // fee_pool defines the historical rewards of all validators at genesis. + repeated ValidatorHistoricalRewardsRecord validator_historical_rewards = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_historical_rewards\""]; + + // fee_pool defines the current rewards of all validators at genesis. + repeated ValidatorCurrentRewardsRecord validator_current_rewards = 8 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_current_rewards\""]; + + // fee_pool defines the delegator starting infos at genesis. + repeated DelegatorStartingInfoRecord delegator_starting_infos = 9 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"delegator_starting_infos\""]; + + // fee_pool defines the validator slash events at genesis. + repeated ValidatorSlashEventRecord validator_slash_events = 10 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_slash_events\""]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto new file mode 100644 index 000000000..2991218d8 --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/query.proto @@ -0,0 +1,218 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/distribution/v1beta1/distribution.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; + +// Query defines the gRPC querier service for distribution module. +service Query { + // Params queries params of the distribution module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/params"; + } + + // ValidatorOutstandingRewards queries rewards of a validator address. + rpc ValidatorOutstandingRewards(QueryValidatorOutstandingRewardsRequest) + returns (QueryValidatorOutstandingRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" + "{validator_address}/outstanding_rewards"; + } + + // ValidatorCommission queries accumulated commission for a validator. + rpc ValidatorCommission(QueryValidatorCommissionRequest) returns (QueryValidatorCommissionResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/" + "{validator_address}/commission"; + } + + // ValidatorSlashes queries slash events of a validator. + rpc ValidatorSlashes(QueryValidatorSlashesRequest) returns (QueryValidatorSlashesResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/validators/{validator_address}/slashes"; + } + + // DelegationRewards queries the total rewards accrued by a delegation. + rpc DelegationRewards(QueryDelegationRewardsRequest) returns (QueryDelegationRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards/" + "{validator_address}"; + } + + // DelegationTotalRewards queries the total rewards accrued by a each + // validator. + rpc DelegationTotalRewards(QueryDelegationTotalRewardsRequest) returns (QueryDelegationTotalRewardsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/{delegator_address}/rewards"; + } + + // DelegatorValidators queries the validators of a delegator. + rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" + "{delegator_address}/validators"; + } + + // DelegatorWithdrawAddress queries withdraw address of a delegator. + rpc DelegatorWithdrawAddress(QueryDelegatorWithdrawAddressRequest) returns (QueryDelegatorWithdrawAddressResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/delegators/" + "{delegator_address}/withdraw_address"; + } + + // CommunityPool queries the community pool coins. + rpc CommunityPool(QueryCommunityPoolRequest) returns (QueryCommunityPoolResponse) { + option (google.api.http).get = "/cosmos/distribution/v1beta1/community_pool"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorOutstandingRewardsRequest is the request type for the +// Query/ValidatorOutstandingRewards RPC method. +message QueryValidatorOutstandingRewardsRequest { + // validator_address defines the validator address to query for. + string validator_address = 1; +} + +// QueryValidatorOutstandingRewardsResponse is the response type for the +// Query/ValidatorOutstandingRewards RPC method. +message QueryValidatorOutstandingRewardsResponse { + ValidatorOutstandingRewards rewards = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorCommissionRequest is the request type for the +// Query/ValidatorCommission RPC method +message QueryValidatorCommissionRequest { + // validator_address defines the validator address to query for. + string validator_address = 1; +} + +// QueryValidatorCommissionResponse is the response type for the +// Query/ValidatorCommission RPC method +message QueryValidatorCommissionResponse { + // commission defines the commision the validator received. + ValidatorAccumulatedCommission commission = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorSlashesRequest is the request type for the +// Query/ValidatorSlashes RPC method +message QueryValidatorSlashesRequest { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + // validator_address defines the validator address to query for. + string validator_address = 1; + // starting_height defines the optional starting height to query the slashes. + uint64 starting_height = 2; + // starting_height defines the optional ending height to query the slashes. + uint64 ending_height = 3; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryValidatorSlashesResponse is the response type for the +// Query/ValidatorSlashes RPC method. +message QueryValidatorSlashesResponse { + // slashes defines the slashes the validator received. + repeated ValidatorSlashEvent slashes = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegationRewardsRequest is the request type for the +// Query/DelegationRewards RPC method. +message QueryDelegationRewardsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; + // validator_address defines the validator address to query for. + string validator_address = 2; +} + +// QueryDelegationRewardsResponse is the response type for the +// Query/DelegationRewards RPC method. +message QueryDelegationRewardsResponse { + // rewards defines the rewards accrued by a delegation. + repeated cosmos.base.v1beta1.DecCoin rewards = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; +} + +// QueryDelegationTotalRewardsRequest is the request type for the +// Query/DelegationTotalRewards RPC method. +message QueryDelegationTotalRewardsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegationTotalRewardsResponse is the response type for the +// Query/DelegationTotalRewards RPC method. +message QueryDelegationTotalRewardsResponse { + // rewards defines all the rewards accrued by a delegator. + repeated DelegationDelegatorReward rewards = 1 [(gogoproto.nullable) = false]; + // total defines the sum of all the rewards. + repeated cosmos.base.v1beta1.DecCoin total = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins"]; +} + +// QueryDelegatorValidatorsRequest is the request type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegatorValidatorsResponse is the response type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validators defines the validators a delegator is delegating for. + repeated string validators = 1; +} + +// QueryDelegatorWithdrawAddressRequest is the request type for the +// Query/DelegatorWithdrawAddress RPC method. +message QueryDelegatorWithdrawAddressRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_address defines the delegator address to query for. + string delegator_address = 1; +} + +// QueryDelegatorWithdrawAddressResponse is the response type for the +// Query/DelegatorWithdrawAddress RPC method. +message QueryDelegatorWithdrawAddressResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // withdraw_address defines the delegator address to query for. + string withdraw_address = 1; +} + +// QueryCommunityPoolRequest is the request type for the Query/CommunityPool RPC +// method. +message QueryCommunityPoolRequest {} + +// QueryCommunityPoolResponse is the response type for the Query/CommunityPool +// RPC method. +message QueryCommunityPoolResponse { + // pool defines community pool's coins. + repeated cosmos.base.v1beta1.DecCoin pool = 1 + [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto new file mode 100644 index 000000000..e6ce478bc --- /dev/null +++ b/ampd/proto/third_party/cosmos/distribution/v1beta1/tx.proto @@ -0,0 +1,79 @@ +syntax = "proto3"; +package cosmos.distribution.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/distribution/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +// Msg defines the distribution Msg service. +service Msg { + // SetWithdrawAddress defines a method to change the withdraw address + // for a delegator (or validator self-delegation). + rpc SetWithdrawAddress(MsgSetWithdrawAddress) returns (MsgSetWithdrawAddressResponse); + + // WithdrawDelegatorReward defines a method to withdraw rewards of delegator + // from a single validator. + rpc WithdrawDelegatorReward(MsgWithdrawDelegatorReward) returns (MsgWithdrawDelegatorRewardResponse); + + // WithdrawValidatorCommission defines a method to withdraw the + // full commission to the validator address. + rpc WithdrawValidatorCommission(MsgWithdrawValidatorCommission) returns (MsgWithdrawValidatorCommissionResponse); + + // FundCommunityPool defines a method to allow an account to directly + // fund the community pool. + rpc FundCommunityPool(MsgFundCommunityPool) returns (MsgFundCommunityPoolResponse); +} + +// MsgSetWithdrawAddress sets the withdraw address for +// a delegator (or validator self-delegation). +message MsgSetWithdrawAddress { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string withdraw_address = 2 [(gogoproto.moretags) = "yaml:\"withdraw_address\""]; +} + +// MsgSetWithdrawAddressResponse defines the Msg/SetWithdrawAddress response type. +message MsgSetWithdrawAddressResponse {} + +// MsgWithdrawDelegatorReward represents delegation withdrawal to a delegator +// from a single validator. +message MsgWithdrawDelegatorReward { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// MsgWithdrawDelegatorRewardResponse defines the Msg/WithdrawDelegatorReward response type. +message MsgWithdrawDelegatorRewardResponse {} + +// MsgWithdrawValidatorCommission withdraws the full commission to the validator +// address. +message MsgWithdrawValidatorCommission { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string validator_address = 1 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// MsgWithdrawValidatorCommissionResponse defines the Msg/WithdrawValidatorCommission response type. +message MsgWithdrawValidatorCommissionResponse {} + +// MsgFundCommunityPool allows an account to directly +// fund the community pool. +message MsgFundCommunityPool { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + repeated cosmos.base.v1beta1.Coin amount = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + string depositor = 2; +} + +// MsgFundCommunityPoolResponse defines the Msg/FundCommunityPool response type. +message MsgFundCommunityPoolResponse {} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto new file mode 100644 index 000000000..14612c314 --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/evidence.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +// Equivocation implements the Evidence interface and defines evidence of double +// signing misbehavior. +message Equivocation { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + int64 height = 1; + google.protobuf.Timestamp time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + int64 power = 3; + string consensus_address = 4 [(gogoproto.moretags) = "yaml:\"consensus_address\""]; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto new file mode 100644 index 000000000..199f446f7 --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/genesis.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; + +import "google/protobuf/any.proto"; + +// GenesisState defines the evidence module's genesis state. +message GenesisState { + // evidence defines all the evidence at genesis. + repeated google.protobuf.Any evidence = 1; +} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto new file mode 100644 index 000000000..eda00544c --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/query.proto @@ -0,0 +1,51 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; + +// Query defines the gRPC querier service. +service Query { + // Evidence queries evidence based on evidence hash. + rpc Evidence(QueryEvidenceRequest) returns (QueryEvidenceResponse) { + option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence/{evidence_hash}"; + } + + // AllEvidence queries all evidence. + rpc AllEvidence(QueryAllEvidenceRequest) returns (QueryAllEvidenceResponse) { + option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence"; + } +} + +// QueryEvidenceRequest is the request type for the Query/Evidence RPC method. +message QueryEvidenceRequest { + // evidence_hash defines the hash of the requested evidence. + bytes evidence_hash = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"]; +} + +// QueryEvidenceResponse is the response type for the Query/Evidence RPC method. +message QueryEvidenceResponse { + // evidence returns the requested evidence. + google.protobuf.Any evidence = 1; +} + +// QueryEvidenceRequest is the request type for the Query/AllEvidence RPC +// method. +message QueryAllEvidenceRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryAllEvidenceResponse is the response type for the Query/AllEvidence RPC +// method. +message QueryAllEvidenceResponse { + // evidence returns all evidences. + repeated google.protobuf.Any evidence = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto new file mode 100644 index 000000000..38795f25d --- /dev/null +++ b/ampd/proto/third_party/cosmos/evidence/v1beta1/tx.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package cosmos.evidence.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; + +// Msg defines the evidence Msg service. +service Msg { + // SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or + // counterfactual signing. + rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse); +} + +// MsgSubmitEvidence represents a message that supports submitting arbitrary +// Evidence of misbehavior such as equivocation or counterfactual signing. +message MsgSubmitEvidence { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string submitter = 1; + google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"]; +} + +// MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type. +message MsgSubmitEvidenceResponse { + // hash defines the hash of the evidence. + bytes hash = 4; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto new file mode 100644 index 000000000..a86691f91 --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/feegrant.proto @@ -0,0 +1,78 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// BasicAllowance implements Allowance with a one-time grant of tokens +// that optionally expires. The grantee can use up to SpendLimit to cover fees. +message BasicAllowance { + option (cosmos_proto.implements_interface) = "FeeAllowanceI"; + + // spend_limit specifies the maximum amount of tokens that can be spent + // by this allowance and will be updated as tokens are spent. If it is + // empty, there is no spend limit and any amount of coins can be spent. + repeated cosmos.base.v1beta1.Coin spend_limit = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // expiration specifies an optional time when this allowance expires + google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true]; +} + +// PeriodicAllowance extends Allowance to allow for both a maximum cap, +// as well as a limit per time period. +message PeriodicAllowance { + option (cosmos_proto.implements_interface) = "FeeAllowanceI"; + + // basic specifies a struct of `BasicAllowance` + BasicAllowance basic = 1 [(gogoproto.nullable) = false]; + + // period specifies the time duration in which period_spend_limit coins can + // be spent before that allowance is reset + google.protobuf.Duration period = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + + // period_spend_limit specifies the maximum number of coins that can be spent + // in the period + repeated cosmos.base.v1beta1.Coin period_spend_limit = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // period_can_spend is the number of coins left to be spent before the period_reset time + repeated cosmos.base.v1beta1.Coin period_can_spend = 4 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // period_reset is the time at which this period resets and a new one begins, + // it is calculated from the start time of the first transaction after the + // last period ended + google.protobuf.Timestamp period_reset = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; +} + +// AllowedMsgAllowance creates allowance only for specified message types. +message AllowedMsgAllowance { + option (gogoproto.goproto_getters) = false; + option (cosmos_proto.implements_interface) = "FeeAllowanceI"; + + // allowance can be any of basic and filtered fee allowance. + google.protobuf.Any allowance = 1 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; + + // allowed_messages are the messages for which the grantee has the access. + repeated string allowed_messages = 2; +} + +// Grant is stored in the KVStore to record a grant with full context +message Grant { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; + + // allowance can be any of basic and filtered fee allowance. + google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto new file mode 100644 index 000000000..5b1ac4ca5 --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/genesis.proto @@ -0,0 +1,13 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/feegrant/v1beta1/feegrant.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// GenesisState contains a set of fee allowances, persisted from the store +message GenesisState { + repeated Grant allowances = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto new file mode 100644 index 000000000..42d7a842d --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/query.proto @@ -0,0 +1,78 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "cosmos/feegrant/v1beta1/feegrant.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// Query defines the gRPC querier service. +service Query { + + // Allowance returns fee granted to the grantee by the granter. + rpc Allowance(QueryAllowanceRequest) returns (QueryAllowanceResponse) { + option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowance/{granter}/{grantee}"; + } + + // Allowances returns all the grants for address. + rpc Allowances(QueryAllowancesRequest) returns (QueryAllowancesResponse) { + option (google.api.http).get = "/cosmos/feegrant/v1beta1/allowances/{grantee}"; + } + + // AllowancesByGranter returns all the grants given by an address + // Since v0.46 + rpc AllowancesByGranter(QueryAllowancesByGranterRequest) returns (QueryAllowancesByGranterResponse) { + option (google.api.http).get = "/cosmos/feegrant/v1beta1/issued/{granter}"; + } +} + +// QueryAllowanceRequest is the request type for the Query/Allowance RPC method. +message QueryAllowanceRequest { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; +} + +// QueryAllowanceResponse is the response type for the Query/Allowance RPC method. +message QueryAllowanceResponse { + // allowance is a allowance granted for grantee by granter. + cosmos.feegrant.v1beta1.Grant allowance = 1; +} + +// QueryAllowancesRequest is the request type for the Query/Allowances RPC method. +message QueryAllowancesRequest { + string grantee = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllowancesResponse is the response type for the Query/Allowances RPC method. +message QueryAllowancesResponse { + // allowances are allowance's granted for grantee by granter. + repeated cosmos.feegrant.v1beta1.Grant allowances = 1; + + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryAllowancesByGranterRequest is the request type for the Query/AllowancesByGranter RPC method. +message QueryAllowancesByGranterRequest { + string granter = 1; + + // pagination defines an pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllowancesByGranterResponse is the response type for the Query/AllowancesByGranter RPC method. +message QueryAllowancesByGranterResponse { + // allowances that have been issued by the granter. + repeated cosmos.feegrant.v1beta1.Grant allowances = 1; + + // pagination defines an pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto new file mode 100644 index 000000000..2d875e922 --- /dev/null +++ b/ampd/proto/third_party/cosmos/feegrant/v1beta1/tx.proto @@ -0,0 +1,49 @@ +// Since: cosmos-sdk 0.43 +syntax = "proto3"; +package cosmos.feegrant.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; + +// Msg defines the feegrant msg service. +service Msg { + + // GrantAllowance grants fee allowance to the grantee on the granter's + // account with the provided expiration time. + rpc GrantAllowance(MsgGrantAllowance) returns (MsgGrantAllowanceResponse); + + // RevokeAllowance revokes any fee allowance of granter's account that + // has been granted to the grantee. + rpc RevokeAllowance(MsgRevokeAllowance) returns (MsgRevokeAllowanceResponse); +} + +// MsgGrantAllowance adds permission for Grantee to spend up to Allowance +// of fees from the account of Granter. +message MsgGrantAllowance { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; + + // allowance can be any of basic and filtered fee allowance. + google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; +} + +// MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type. +message MsgGrantAllowanceResponse {} + +// MsgRevokeAllowance removes any existing Allowance from Granter to Grantee. +message MsgRevokeAllowance { + // granter is the address of the user granting an allowance of their funds. + string granter = 1; + + // grantee is the address of the user being granted an allowance of another user's funds. + string grantee = 2; +} + +// MsgRevokeAllowanceResponse defines the Msg/RevokeAllowanceResponse response type. +message MsgRevokeAllowanceResponse {} diff --git a/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto new file mode 100644 index 000000000..a0207793d --- /dev/null +++ b/ampd/proto/third_party/cosmos/genutil/v1beta1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos.genutil.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/genutil/types"; + +// GenesisState defines the raw genesis transaction in JSON. +message GenesisState { + // gen_txs defines the genesis transactions. + repeated bytes gen_txs = 1 [ + (gogoproto.casttype) = "encoding/json.RawMessage", + (gogoproto.jsontag) = "gentxs", + (gogoproto.moretags) = "yaml:\"gentxs\"" + ]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto new file mode 100644 index 000000000..a99950044 --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/genesis.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; + +package cosmos.gov.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/gov/v1beta1/gov.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// GenesisState defines the gov module's genesis state. +message GenesisState { + // starting_proposal_id is the ID of the starting proposal. + uint64 starting_proposal_id = 1 [(gogoproto.moretags) = "yaml:\"starting_proposal_id\""]; + // deposits defines all the deposits present at genesis. + repeated Deposit deposits = 2 [(gogoproto.castrepeated) = "Deposits", (gogoproto.nullable) = false]; + // votes defines all the votes present at genesis. + repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false]; + // proposals defines all the proposals present at genesis. + repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false]; + // params defines all the paramaters of related to deposit. + DepositParams deposit_params = 5 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_params\""]; + // params defines all the paramaters of related to voting. + VotingParams voting_params = 6 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_params\""]; + // params defines all the paramaters of related to tally. + TallyParams tally_params = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"tally_params\""]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto new file mode 100644 index 000000000..01aebf950 --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/gov.proto @@ -0,0 +1,200 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; + +// VoteOption enumerates the valid vote options for a given governance proposal. +enum VoteOption { + option (gogoproto.goproto_enum_prefix) = false; + + // VOTE_OPTION_UNSPECIFIED defines a no-op vote option. + VOTE_OPTION_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "OptionEmpty"]; + // VOTE_OPTION_YES defines a yes vote option. + VOTE_OPTION_YES = 1 [(gogoproto.enumvalue_customname) = "OptionYes"]; + // VOTE_OPTION_ABSTAIN defines an abstain vote option. + VOTE_OPTION_ABSTAIN = 2 [(gogoproto.enumvalue_customname) = "OptionAbstain"]; + // VOTE_OPTION_NO defines a no vote option. + VOTE_OPTION_NO = 3 [(gogoproto.enumvalue_customname) = "OptionNo"]; + // VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option. + VOTE_OPTION_NO_WITH_VETO = 4 [(gogoproto.enumvalue_customname) = "OptionNoWithVeto"]; +} + +// WeightedVoteOption defines a unit of vote for vote split. +// +// Since: cosmos-sdk 0.43 +message WeightedVoteOption { + VoteOption option = 1; + string weight = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"weight\"" + ]; +} + +// TextProposal defines a standard text proposal whose changes need to be +// manually updated in case of approval. +message TextProposal { + option (cosmos_proto.implements_interface) = "Content"; + + option (gogoproto.equal) = true; + + string title = 1; + string description = 2; +} + +// Deposit defines an amount deposited by an account address to an active +// proposal. +message Deposit { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string depositor = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// Proposal defines the core field members of a governance proposal. +message Proposal { + option (gogoproto.equal) = true; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""]; + google.protobuf.Any content = 2 [(cosmos_proto.accepts_interface) = "Content"]; + ProposalStatus status = 3 [(gogoproto.moretags) = "yaml:\"proposal_status\""]; + TallyResult final_tally_result = 4 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"final_tally_result\""]; + google.protobuf.Timestamp submit_time = 5 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"submit_time\""]; + google.protobuf.Timestamp deposit_end_time = 6 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"deposit_end_time\""]; + repeated cosmos.base.v1beta1.Coin total_deposit = 7 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"total_deposit\"" + ]; + google.protobuf.Timestamp voting_start_time = 8 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_start_time\""]; + google.protobuf.Timestamp voting_end_time = 9 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"voting_end_time\""]; +} + +// ProposalStatus enumerates the valid statuses of a proposal. +enum ProposalStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // PROPOSAL_STATUS_UNSPECIFIED defines the default propopsal status. + PROPOSAL_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "StatusNil"]; + // PROPOSAL_STATUS_DEPOSIT_PERIOD defines a proposal status during the deposit + // period. + PROPOSAL_STATUS_DEPOSIT_PERIOD = 1 [(gogoproto.enumvalue_customname) = "StatusDepositPeriod"]; + // PROPOSAL_STATUS_VOTING_PERIOD defines a proposal status during the voting + // period. + PROPOSAL_STATUS_VOTING_PERIOD = 2 [(gogoproto.enumvalue_customname) = "StatusVotingPeriod"]; + // PROPOSAL_STATUS_PASSED defines a proposal status of a proposal that has + // passed. + PROPOSAL_STATUS_PASSED = 3 [(gogoproto.enumvalue_customname) = "StatusPassed"]; + // PROPOSAL_STATUS_REJECTED defines a proposal status of a proposal that has + // been rejected. + PROPOSAL_STATUS_REJECTED = 4 [(gogoproto.enumvalue_customname) = "StatusRejected"]; + // PROPOSAL_STATUS_FAILED defines a proposal status of a proposal that has + // failed. + PROPOSAL_STATUS_FAILED = 5 [(gogoproto.enumvalue_customname) = "StatusFailed"]; +} + +// TallyResult defines a standard tally for a governance proposal. +message TallyResult { + option (gogoproto.equal) = true; + + string yes = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string abstain = 2 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string no = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + string no_with_veto = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"no_with_veto\"" + ]; +} + +// Vote defines a vote on a governance proposal. +// A Vote consists of a proposal ID, the voter, and the vote option. +message Vote { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + // Deprecated: Prefer to use `options` instead. This field is set in queries + // if and only if `len(options) == 1` and that option has weight 1. In all + // other cases, this field will default to VOTE_OPTION_UNSPECIFIED. + VoteOption option = 3 [deprecated = true]; + // Since: cosmos-sdk 0.43 + repeated WeightedVoteOption options = 4 [(gogoproto.nullable) = false]; +} + +// DepositParams defines the params for deposits on governance proposals. +message DepositParams { + // Minimum deposit for a proposal to enter voting period. + repeated cosmos.base.v1beta1.Coin min_deposit = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"min_deposit\"", + (gogoproto.jsontag) = "min_deposit,omitempty" + ]; + + // Maximum period for Atom holders to deposit on a proposal. Initial value: 2 + // months. + google.protobuf.Duration max_deposit_period = 2 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "max_deposit_period,omitempty", + (gogoproto.moretags) = "yaml:\"max_deposit_period\"" + ]; +} + +// VotingParams defines the params for voting on governance proposals. +message VotingParams { + // Length of the voting period. + google.protobuf.Duration voting_period = 1 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.jsontag) = "voting_period,omitempty", + (gogoproto.moretags) = "yaml:\"voting_period\"" + ]; +} + +// TallyParams defines the params for tallying votes on governance proposals. +message TallyParams { + // Minimum percentage of total stake needed to vote for a result to be + // considered valid. + bytes quorum = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quorum,omitempty" + ]; + + // Minimum proportion of Yes votes for proposal to pass. Default value: 0.5. + bytes threshold = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "threshold,omitempty" + ]; + + // Minimum value of Veto votes to Total votes ratio for proposal to be + // vetoed. Default value: 1/3. + bytes veto_threshold = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "veto_threshold,omitempty", + (gogoproto.moretags) = "yaml:\"veto_threshold\"" + ]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto new file mode 100644 index 000000000..da62bdbad --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/query.proto @@ -0,0 +1,190 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/gov/v1beta1/gov.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// Query defines the gRPC querier service for gov module +service Query { + // Proposal queries proposal details based on ProposalID. + rpc Proposal(QueryProposalRequest) returns (QueryProposalResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}"; + } + + // Proposals queries all proposals based on given status. + rpc Proposals(QueryProposalsRequest) returns (QueryProposalsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals"; + } + + // Vote queries voted information based on proposalID, voterAddr. + rpc Vote(QueryVoteRequest) returns (QueryVoteResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter}"; + } + + // Votes queries votes of a given proposal. + rpc Votes(QueryVotesRequest) returns (QueryVotesResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/votes"; + } + + // Params queries all parameters of the gov module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/params/{params_type}"; + } + + // Deposit queries single deposit information based proposalID, depositAddr. + rpc Deposit(QueryDepositRequest) returns (QueryDepositResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor}"; + } + + // Deposits queries all deposits of a single proposal. + rpc Deposits(QueryDepositsRequest) returns (QueryDepositsResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits"; + } + + // TallyResult queries the tally of a proposal vote. + rpc TallyResult(QueryTallyResultRequest) returns (QueryTallyResultResponse) { + option (google.api.http).get = "/cosmos/gov/v1beta1/proposals/{proposal_id}/tally"; + } +} + +// QueryProposalRequest is the request type for the Query/Proposal RPC method. +message QueryProposalRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +// QueryProposalResponse is the response type for the Query/Proposal RPC method. +message QueryProposalResponse { + Proposal proposal = 1 [(gogoproto.nullable) = false]; +} + +// QueryProposalsRequest is the request type for the Query/Proposals RPC method. +message QueryProposalsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // proposal_status defines the status of the proposals. + ProposalStatus proposal_status = 1; + + // voter defines the voter address for the proposals. + string voter = 2; + + // depositor defines the deposit addresses from the proposals. + string depositor = 3; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryProposalsResponse is the response type for the Query/Proposals RPC +// method. +message QueryProposalsResponse { + repeated Proposal proposals = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryVoteRequest is the request type for the Query/Vote RPC method. +message QueryVoteRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // voter defines the oter address for the proposals. + string voter = 2; +} + +// QueryVoteResponse is the response type for the Query/Vote RPC method. +message QueryVoteResponse { + // vote defined the queried vote. + Vote vote = 1 [(gogoproto.nullable) = false]; +} + +// QueryVotesRequest is the request type for the Query/Votes RPC method. +message QueryVotesRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryVotesResponse is the response type for the Query/Votes RPC method. +message QueryVotesResponse { + // votes defined the queried votes. + repeated Vote votes = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest { + // params_type defines which parameters to query for, can be one of "voting", + // "tallying" or "deposit". + string params_type = 1; +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // voting_params defines the parameters related to voting. + VotingParams voting_params = 1 [(gogoproto.nullable) = false]; + // deposit_params defines the parameters related to deposit. + DepositParams deposit_params = 2 [(gogoproto.nullable) = false]; + // tally_params defines the parameters related to tally. + TallyParams tally_params = 3 [(gogoproto.nullable) = false]; +} + +// QueryDepositRequest is the request type for the Query/Deposit RPC method. +message QueryDepositRequest { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = false; + + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // depositor defines the deposit addresses from the proposals. + string depositor = 2; +} + +// QueryDepositResponse is the response type for the Query/Deposit RPC method. +message QueryDepositResponse { + // deposit defines the requested deposit. + Deposit deposit = 1 [(gogoproto.nullable) = false]; +} + +// QueryDepositsRequest is the request type for the Query/Deposits RPC method. +message QueryDepositsRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDepositsResponse is the response type for the Query/Deposits RPC method. +message QueryDepositsResponse { + repeated Deposit deposits = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryTallyResultRequest is the request type for the Query/Tally RPC method. +message QueryTallyResultRequest { + // proposal_id defines the unique id of the proposal. + uint64 proposal_id = 1; +} + +// QueryTallyResultResponse is the response type for the Query/Tally RPC method. +message QueryTallyResultResponse { + // tally defines the requested tally. + TallyResult tally = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto new file mode 100644 index 000000000..36c0a95d2 --- /dev/null +++ b/ampd/proto/third_party/cosmos/gov/v1beta1/tx.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; +package cosmos.gov.v1beta1; + +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/gov/v1beta1/gov.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types"; + +// Msg defines the bank Msg service. +service Msg { + // SubmitProposal defines a method to create new proposal given a content. + rpc SubmitProposal(MsgSubmitProposal) returns (MsgSubmitProposalResponse); + + // Vote defines a method to add a vote on a specific proposal. + rpc Vote(MsgVote) returns (MsgVoteResponse); + + // VoteWeighted defines a method to add a weighted vote on a specific proposal. + // + // Since: cosmos-sdk 0.43 + rpc VoteWeighted(MsgVoteWeighted) returns (MsgVoteWeightedResponse); + + // Deposit defines a method to add deposit on a specific proposal. + rpc Deposit(MsgDeposit) returns (MsgDepositResponse); +} + +// MsgSubmitProposal defines an sdk.Msg type that supports submitting arbitrary +// proposal Content. +message MsgSubmitProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + google.protobuf.Any content = 1 [(cosmos_proto.accepts_interface) = "Content"]; + repeated cosmos.base.v1beta1.Coin initial_deposit = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"initial_deposit\"" + ]; + string proposer = 3; +} + +// MsgSubmitProposalResponse defines the Msg/SubmitProposal response type. +message MsgSubmitProposalResponse { + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; +} + +// MsgVote defines a message to cast a vote. +message MsgVote { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + VoteOption option = 3; +} + +// MsgVoteResponse defines the Msg/Vote response type. +message MsgVoteResponse {} + +// MsgVoteWeighted defines a message to cast a vote. +// +// Since: cosmos-sdk 0.43 +message MsgVoteWeighted { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.moretags) = "yaml:\"proposal_id\""]; + string voter = 2; + repeated WeightedVoteOption options = 3 [(gogoproto.nullable) = false]; +} + +// MsgVoteWeightedResponse defines the Msg/VoteWeighted response type. +// +// Since: cosmos-sdk 0.43 +message MsgVoteWeightedResponse {} + +// MsgDeposit defines a message to submit a deposit to an existing proposal. +message MsgDeposit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = false; + option (gogoproto.goproto_getters) = false; + + uint64 proposal_id = 1 [(gogoproto.jsontag) = "proposal_id", (gogoproto.moretags) = "yaml:\"proposal_id\""]; + string depositor = 2; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// MsgDepositResponse defines the Msg/Deposit response type. +message MsgDepositResponse {} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto new file mode 100644 index 000000000..4e783fb54 --- /dev/null +++ b/ampd/proto/third_party/cosmos/mint/v1beta1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/mint/v1beta1/mint.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +// GenesisState defines the mint module's genesis state. +message GenesisState { + // minter is a space for holding current inflation information. + Minter minter = 1 [(gogoproto.nullable) = false]; + + // params defines all the paramaters of the module. + Params params = 2 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto new file mode 100644 index 000000000..f94d4ae2e --- /dev/null +++ b/ampd/proto/third_party/cosmos/mint/v1beta1/mint.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +import "gogoproto/gogo.proto"; + +// Minter represents the minting state. +message Minter { + // current annual inflation rate + string inflation = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + // current annual expected provisions + string annual_provisions = 2 [ + (gogoproto.moretags) = "yaml:\"annual_provisions\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// Params holds parameters for the mint module. +message Params { + option (gogoproto.goproto_stringer) = false; + + // type of coin to mint + string mint_denom = 1; + // maximum annual change in inflation rate + string inflation_rate_change = 2 [ + (gogoproto.moretags) = "yaml:\"inflation_rate_change\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // maximum inflation rate + string inflation_max = 3 [ + (gogoproto.moretags) = "yaml:\"inflation_max\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // minimum inflation rate + string inflation_min = 4 [ + (gogoproto.moretags) = "yaml:\"inflation_min\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // goal of percent bonded atoms + string goal_bonded = 5 [ + (gogoproto.moretags) = "yaml:\"goal_bonded\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // expected blocks per year + uint64 blocks_per_year = 6 [(gogoproto.moretags) = "yaml:\"blocks_per_year\""]; +} diff --git a/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto b/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto new file mode 100644 index 000000000..acd341d77 --- /dev/null +++ b/ampd/proto/third_party/cosmos/mint/v1beta1/query.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package cosmos.mint.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/mint/v1beta1/mint.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; + +// Query provides defines the gRPC querier service. +service Query { + // Params returns the total set of minting parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/params"; + } + + // Inflation returns the current minting inflation value. + rpc Inflation(QueryInflationRequest) returns (QueryInflationResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/inflation"; + } + + // AnnualProvisions current minting annual provisions value. + rpc AnnualProvisions(QueryAnnualProvisionsRequest) returns (QueryAnnualProvisionsResponse) { + option (google.api.http).get = "/cosmos/mint/v1beta1/annual_provisions"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryInflationRequest is the request type for the Query/Inflation RPC method. +message QueryInflationRequest {} + +// QueryInflationResponse is the response type for the Query/Inflation RPC +// method. +message QueryInflationResponse { + // inflation is the current minting inflation value. + bytes inflation = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// QueryAnnualProvisionsRequest is the request type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsRequest {} + +// QueryAnnualProvisionsResponse is the response type for the +// Query/AnnualProvisions RPC method. +message QueryAnnualProvisionsResponse { + // annual_provisions is the current minting annual provisions value. + bytes annual_provisions = 1 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/params/v1beta1/params.proto b/ampd/proto/third_party/cosmos/params/v1beta1/params.proto new file mode 100644 index 000000000..5382fd799 --- /dev/null +++ b/ampd/proto/third_party/cosmos/params/v1beta1/params.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package cosmos.params.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; + +// ParameterChangeProposal defines a proposal to change one or more parameters. +message ParameterChangeProposal { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + repeated ParamChange changes = 3 [(gogoproto.nullable) = false]; +} + +// ParamChange defines an individual parameter change, for use in +// ParameterChangeProposal. +message ParamChange { + option (gogoproto.goproto_stringer) = false; + + string subspace = 1; + string key = 2; + string value = 3; +} diff --git a/ampd/proto/third_party/cosmos/params/v1beta1/query.proto b/ampd/proto/third_party/cosmos/params/v1beta1/query.proto new file mode 100644 index 000000000..1078e02ae --- /dev/null +++ b/ampd/proto/third_party/cosmos/params/v1beta1/query.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; +package cosmos.params.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/params/v1beta1/params.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; + +// Query defines the gRPC querier service. +service Query { + // Params queries a specific parameter of a module, given its subspace and + // key. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/params/v1beta1/params"; + } +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest { + // subspace defines the module to query the parameter for. + string subspace = 1; + + // key defines the key of the parameter in the subspace. + string key = 2; +} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // param defines the queried parameter. + ParamChange param = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto new file mode 100644 index 000000000..a7aebcfba --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/genesis.proto @@ -0,0 +1,50 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/slashing/v1beta1/slashing.proto"; + +// GenesisState defines the slashing module's genesis state. +message GenesisState { + // params defines all the paramaters of related to deposit. + Params params = 1 [(gogoproto.nullable) = false]; + + // signing_infos represents a map between validator addresses and their + // signing infos. + repeated SigningInfo signing_infos = 2 + [(gogoproto.moretags) = "yaml:\"signing_infos\"", (gogoproto.nullable) = false]; + + // missed_blocks represents a map between validator addresses and their + // missed blocks. + repeated ValidatorMissedBlocks missed_blocks = 3 + [(gogoproto.moretags) = "yaml:\"missed_blocks\"", (gogoproto.nullable) = false]; +} + +// SigningInfo stores validator signing info of corresponding address. +message SigningInfo { + // address is the validator address. + string address = 1; + // validator_signing_info represents the signing info of this validator. + ValidatorSigningInfo validator_signing_info = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"validator_signing_info\""]; +} + +// ValidatorMissedBlocks contains array of missed blocks of corresponding +// address. +message ValidatorMissedBlocks { + // address is the validator address. + string address = 1; + // missed_blocks is an array of missed blocks by the validator. + repeated MissedBlock missed_blocks = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"missed_blocks\""]; +} + +// MissedBlock contains height and missed status as boolean. +message MissedBlock { + // index is the height at which the block was missed. + int64 index = 1; + // missed is the missed status. + bool missed = 2; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto new file mode 100644 index 000000000..869049a0e --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/query.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/slashing/v1beta1/slashing.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; + +// Query provides defines the gRPC querier service +service Query { + // Params queries the parameters of slashing module + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/params"; + } + + // SigningInfo queries the signing info of given cons address + rpc SigningInfo(QuerySigningInfoRequest) returns (QuerySigningInfoResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos/{cons_address}"; + } + + // SigningInfos queries signing info of all validators + rpc SigningInfos(QuerySigningInfosRequest) returns (QuerySigningInfosResponse) { + option (google.api.http).get = "/cosmos/slashing/v1beta1/signing_infos"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method +message QueryParamsResponse { + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC +// method +message QuerySigningInfoRequest { + // cons_address is the address to query signing info of + string cons_address = 1; +} + +// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC +// method +message QuerySigningInfoResponse { + // val_signing_info is the signing info of requested val cons address + ValidatorSigningInfo val_signing_info = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC +// method +message QuerySigningInfosRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC +// method +message QuerySigningInfosResponse { + // info is the signing info of all validators + repeated cosmos.slashing.v1beta1.ValidatorSigningInfo info = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto new file mode 100644 index 000000000..882a0fb60 --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/slashing.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +// ValidatorSigningInfo defines a validator's signing info for monitoring their +// liveness activity. +message ValidatorSigningInfo { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string address = 1; + // Height at which validator was first a candidate OR was unjailed + int64 start_height = 2 [(gogoproto.moretags) = "yaml:\"start_height\""]; + // Index which is incremented each time the validator was a bonded + // in a block and may have signed a precommit or not. This in conjunction with the + // `SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`. + int64 index_offset = 3 [(gogoproto.moretags) = "yaml:\"index_offset\""]; + // Timestamp until which the validator is jailed due to liveness downtime. + google.protobuf.Timestamp jailed_until = 4 + [(gogoproto.moretags) = "yaml:\"jailed_until\"", (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + // Whether or not a validator has been tombstoned (killed out of validator set). It is set + // once the validator commits an equivocation or for any other configured misbehiavor. + bool tombstoned = 5; + // A counter kept to avoid unnecessary array reads. + // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. + int64 missed_blocks_counter = 6 [(gogoproto.moretags) = "yaml:\"missed_blocks_counter\""]; +} + +// Params represents the parameters used for by the slashing module. +message Params { + int64 signed_blocks_window = 1 [(gogoproto.moretags) = "yaml:\"signed_blocks_window\""]; + bytes min_signed_per_window = 2 [ + (gogoproto.moretags) = "yaml:\"min_signed_per_window\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + google.protobuf.Duration downtime_jail_duration = 3 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.moretags) = "yaml:\"downtime_jail_duration\"" + ]; + bytes slash_fraction_double_sign = 4 [ + (gogoproto.moretags) = "yaml:\"slash_fraction_double_sign\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + bytes slash_fraction_downtime = 5 [ + (gogoproto.moretags) = "yaml:\"slash_fraction_downtime\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} diff --git a/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto new file mode 100644 index 000000000..4d63370ec --- /dev/null +++ b/ampd/proto/third_party/cosmos/slashing/v1beta1/tx.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.slashing.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; +option (gogoproto.equal_all) = true; + +import "gogoproto/gogo.proto"; + +// Msg defines the slashing Msg service. +service Msg { + // Unjail defines a method for unjailing a jailed validator, thus returning + // them into the bonded validator set, so they can begin receiving provisions + // and rewards again. + rpc Unjail(MsgUnjail) returns (MsgUnjailResponse); +} + +// MsgUnjail defines the Msg/Unjail request type +message MsgUnjail { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = true; + + string validator_addr = 1 [(gogoproto.moretags) = "yaml:\"address\"", (gogoproto.jsontag) = "address"]; +} + +// MsgUnjailResponse defines the Msg/Unjail response type +message MsgUnjailResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto new file mode 100644 index 000000000..d50c329c9 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/authz.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// StakeAuthorization defines authorization for delegate/undelegate/redelegate. +// +// Since: cosmos-sdk 0.43 +message StakeAuthorization { + option (cosmos_proto.implements_interface) = "Authorization"; + + // max_tokens specifies the maximum amount of tokens can be delegate to a validator. If it is + // empty, there is no spend limit and any amount of coins can be delegated. + cosmos.base.v1beta1.Coin max_tokens = 1 [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"]; + // validators is the oneof that represents either allow_list or deny_list + oneof validators { + // allow_list specifies list of validator addresses to whom grantee can delegate tokens on behalf of granter's + // account. + Validators allow_list = 2; + // deny_list specifies list of validator addresses to whom grantee can not delegate tokens. + Validators deny_list = 3; + } + // Validators defines list of validator addresses. + message Validators { + repeated string address = 1; + } + // authorization_type defines one of AuthorizationType. + AuthorizationType authorization_type = 4; +} + +// AuthorizationType defines the type of staking module authorization type +// +// Since: cosmos-sdk 0.43 +enum AuthorizationType { + // AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type + AUTHORIZATION_TYPE_UNSPECIFIED = 0; + // AUTHORIZATION_TYPE_DELEGATE defines an authorization type for Msg/Delegate + AUTHORIZATION_TYPE_DELEGATE = 1; + // AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for Msg/Undelegate + AUTHORIZATION_TYPE_UNDELEGATE = 2; + // AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for Msg/BeginRedelegate + AUTHORIZATION_TYPE_REDELEGATE = 3; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto new file mode 100644 index 000000000..d1563dbc5 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/genesis.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +// GenesisState defines the staking module's genesis state. +message GenesisState { + // params defines all the paramaters of related to deposit. + Params params = 1 [(gogoproto.nullable) = false]; + + // last_total_power tracks the total amounts of bonded tokens recorded during + // the previous end block. + bytes last_total_power = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"last_total_power\"", + (gogoproto.nullable) = false + ]; + + // last_validator_powers is a special index that provides a historical list + // of the last-block's bonded validators. + repeated LastValidatorPower last_validator_powers = 3 + [(gogoproto.moretags) = "yaml:\"last_validator_powers\"", (gogoproto.nullable) = false]; + + // delegations defines the validator set at genesis. + repeated Validator validators = 4 [(gogoproto.nullable) = false]; + + // delegations defines the delegations active at genesis. + repeated Delegation delegations = 5 [(gogoproto.nullable) = false]; + + // unbonding_delegations defines the unbonding delegations active at genesis. + repeated UnbondingDelegation unbonding_delegations = 6 + [(gogoproto.moretags) = "yaml:\"unbonding_delegations\"", (gogoproto.nullable) = false]; + + // redelegations defines the redelegations active at genesis. + repeated Redelegation redelegations = 7 [(gogoproto.nullable) = false]; + + bool exported = 8; +} + +// LastValidatorPower required for validator set update logic. +message LastValidatorPower { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // address is the address of the validator. + string address = 1; + + // power defines the power of the validator. + int64 power = 2; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto new file mode 100644 index 000000000..4852c5353 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/query.proto @@ -0,0 +1,348 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// Query defines the gRPC querier service. +service Query { + // Validators queries all validators that match the given status. + rpc Validators(QueryValidatorsRequest) returns (QueryValidatorsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators"; + } + + // Validator queries validator info for given validator address. + rpc Validator(QueryValidatorRequest) returns (QueryValidatorResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}"; + } + + // ValidatorDelegations queries delegate info for given validator. + rpc ValidatorDelegations(QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations"; + } + + // ValidatorUnbondingDelegations queries unbonding delegations of a validator. + rpc ValidatorUnbondingDelegations(QueryValidatorUnbondingDelegationsRequest) + returns (QueryValidatorUnbondingDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/" + "{validator_addr}/unbonding_delegations"; + } + + // Delegation queries delegate info for given validator delegator pair. + rpc Delegation(QueryDelegationRequest) returns (QueryDelegationResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" + "{delegator_addr}"; + } + + // UnbondingDelegation queries unbonding info for given validator delegator + // pair. + rpc UnbondingDelegation(QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/validators/{validator_addr}/delegations/" + "{delegator_addr}/unbonding_delegation"; + } + + // DelegatorDelegations queries all delegations of a given delegator address. + rpc DelegatorDelegations(QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegations/{delegator_addr}"; + } + + // DelegatorUnbondingDelegations queries all unbonding delegations of a given + // delegator address. + rpc DelegatorUnbondingDelegations(QueryDelegatorUnbondingDelegationsRequest) + returns (QueryDelegatorUnbondingDelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/" + "{delegator_addr}/unbonding_delegations"; + } + + // Redelegations queries redelegations of given address. + rpc Redelegations(QueryRedelegationsRequest) returns (QueryRedelegationsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/redelegations"; + } + + // DelegatorValidators queries all validators info for given delegator + // address. + rpc DelegatorValidators(QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators"; + } + + // DelegatorValidator queries validator info for given delegator validator + // pair. + rpc DelegatorValidator(QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/delegators/{delegator_addr}/validators/" + "{validator_addr}"; + } + + // HistoricalInfo queries the historical info for given height. + rpc HistoricalInfo(QueryHistoricalInfoRequest) returns (QueryHistoricalInfoResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/historical_info/{height}"; + } + + // Pool queries the pool info. + rpc Pool(QueryPoolRequest) returns (QueryPoolResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/pool"; + } + + // Parameters queries the staking parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/staking/v1beta1/params"; + } +} + +// QueryValidatorsRequest is request type for Query/Validators RPC method. +message QueryValidatorsRequest { + // status enables to query for validators matching a given status. + string status = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorsResponse is response type for the Query/Validators RPC method +message QueryValidatorsResponse { + // validators contains all the queried validators. + repeated Validator validators = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryValidatorRequest is response type for the Query/Validator RPC method +message QueryValidatorRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; +} + +// QueryValidatorResponse is response type for the Query/Validator RPC method +message QueryValidatorResponse { + // validator defines the the validator info. + Validator validator = 1 [(gogoproto.nullable) = false]; +} + +// QueryValidatorDelegationsRequest is request type for the +// Query/ValidatorDelegations RPC method +message QueryValidatorDelegationsRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorDelegationsResponse is response type for the +// Query/ValidatorDelegations RPC method +message QueryValidatorDelegationsResponse { + repeated DelegationResponse delegation_responses = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "DelegationResponses"]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryValidatorUnbondingDelegationsRequest is required type for the +// Query/ValidatorUnbondingDelegations RPC method +message QueryValidatorUnbondingDelegationsRequest { + // validator_addr defines the validator address to query for. + string validator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryValidatorUnbondingDelegationsResponse is response type for the +// Query/ValidatorUnbondingDelegations RPC method. +message QueryValidatorUnbondingDelegationsResponse { + repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegationRequest is request type for the Query/Delegation RPC method. +message QueryDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegationResponse is response type for the Query/Delegation RPC method. +message QueryDelegationResponse { + // delegation_responses defines the delegation info of a delegation. + DelegationResponse delegation_response = 1; +} + +// QueryUnbondingDelegationRequest is request type for the +// Query/UnbondingDelegation RPC method. +message QueryUnbondingDelegationRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegationResponse is response type for the Query/UnbondingDelegation +// RPC method. +message QueryUnbondingDelegationResponse { + // unbond defines the unbonding information of a delegation. + UnbondingDelegation unbond = 1 [(gogoproto.nullable) = false]; +} + +// QueryDelegatorDelegationsRequest is request type for the +// Query/DelegatorDelegations RPC method. +message QueryDelegatorDelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDelegatorDelegationsResponse is response type for the +// Query/DelegatorDelegations RPC method. +message QueryDelegatorDelegationsResponse { + // delegation_responses defines all the delegations' info of a delegator. + repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorUnbondingDelegationsRequest is request type for the +// Query/DelegatorUnbondingDelegations RPC method. +message QueryDelegatorUnbondingDelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryUnbondingDelegatorDelegationsResponse is response type for the +// Query/UnbondingDelegatorDelegations RPC method. +message QueryDelegatorUnbondingDelegationsResponse { + repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryRedelegationsRequest is request type for the Query/Redelegations RPC +// method. +message QueryRedelegationsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // src_validator_addr defines the validator address to redelegate from. + string src_validator_addr = 2; + + // dst_validator_addr defines the validator address to redelegate to. + string dst_validator_addr = 3; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 4; +} + +// QueryRedelegationsResponse is response type for the Query/Redelegations RPC +// method. +message QueryRedelegationsResponse { + repeated RedelegationResponse redelegation_responses = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorValidatorsRequest is request type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryDelegatorValidatorsResponse is response type for the +// Query/DelegatorValidators RPC method. +message QueryDelegatorValidatorsResponse { + // validators defines the the validators' info of a delegator. + repeated Validator validators = 1 [(gogoproto.nullable) = false]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryDelegatorValidatorRequest is request type for the +// Query/DelegatorValidator RPC method. +message QueryDelegatorValidatorRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // delegator_addr defines the delegator address to query for. + string delegator_addr = 1; + + // validator_addr defines the validator address to query for. + string validator_addr = 2; +} + +// QueryDelegatorValidatorResponse response type for the +// Query/DelegatorValidator RPC method. +message QueryDelegatorValidatorResponse { + // validator defines the the validator info. + Validator validator = 1 [(gogoproto.nullable) = false]; +} + +// QueryHistoricalInfoRequest is request type for the Query/HistoricalInfo RPC +// method. +message QueryHistoricalInfoRequest { + // height defines at which height to query the historical info. + int64 height = 1; +} + +// QueryHistoricalInfoResponse is response type for the Query/HistoricalInfo RPC +// method. +message QueryHistoricalInfoResponse { + // hist defines the historical info at the given height. + HistoricalInfo hist = 1; +} + +// QueryPoolRequest is request type for the Query/Pool RPC method. +message QueryPoolRequest {} + +// QueryPoolResponse is response type for the Query/Pool RPC method. +message QueryPoolResponse { + // pool defines the pool info. + Pool pool = 1 [(gogoproto.nullable) = false]; +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // params holds all the parameters of this module. + Params params = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto new file mode 100644 index 000000000..76e9599e2 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/staking.proto @@ -0,0 +1,334 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "tendermint/types/types.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// HistoricalInfo contains header and validator information for a given block. +// It is stored as part of staking module's state, which persists the `n` most +// recent HistoricalInfo +// (`n` is set by the staking module's `historical_entries` parameter). +message HistoricalInfo { + tendermint.types.Header header = 1 [(gogoproto.nullable) = false]; + repeated Validator valset = 2 [(gogoproto.nullable) = false]; +} + +// CommissionRates defines the initial commission rates to be used for creating +// a validator. +message CommissionRates { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // rate is the commission rate charged to delegators, as a fraction. + string rate = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; + // max_rate defines the maximum commission rate which validator can ever charge, as a fraction. + string max_rate = 2 [ + (gogoproto.moretags) = "yaml:\"max_rate\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // max_change_rate defines the maximum daily increase of the validator commission, as a fraction. + string max_change_rate = 3 [ + (gogoproto.moretags) = "yaml:\"max_change_rate\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +// Commission defines commission parameters for a given validator. +message Commission { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // commission_rates defines the initial commission rates to be used for creating a validator. + CommissionRates commission_rates = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // update_time is the last time the commission rate was changed. + google.protobuf.Timestamp update_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"update_time\""]; +} + +// Description defines a validator description. +message Description { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // moniker defines a human-readable name for the validator. + string moniker = 1; + // identity defines an optional identity signature (ex. UPort or Keybase). + string identity = 2; + // website defines an optional website link. + string website = 3; + // security_contact defines an optional email for security contact. + string security_contact = 4 [(gogoproto.moretags) = "yaml:\"security_contact\""]; + // details define other optional details. + string details = 5; +} + +// Validator defines a validator, together with the total amount of the +// Validator's bond shares and their exchange rate to coins. Slashing results in +// a decrease in the exchange rate, allowing correct calculation of future +// undelegations without iterating over delegators. When coins are delegated to +// this validator, the validator is credited with a delegation whose number of +// bond shares is based on the amount of coins delegated divided by the current +// exchange rate. Voting power can be calculated as total bonded shares +// multiplied by exchange rate. +message Validator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + + // operator_address defines the address of the validator's operator; bech encoded in JSON. + string operator_address = 1 [(gogoproto.moretags) = "yaml:\"operator_address\""]; + // consensus_pubkey is the consensus public key of the validator, as a Protobuf Any. + google.protobuf.Any consensus_pubkey = 2 + [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\""]; + // jailed defined whether the validator has been jailed from bonded status or not. + bool jailed = 3; + // status is the validator status (bonded/unbonding/unbonded). + BondStatus status = 4; + // tokens define the delegated tokens (incl. self-delegation). + string tokens = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; + // delegator_shares defines total shares issued to a validator's delegators. + string delegator_shares = 6 [ + (gogoproto.moretags) = "yaml:\"delegator_shares\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // description defines the description terms for the validator. + Description description = 7 [(gogoproto.nullable) = false]; + // unbonding_height defines, if unbonding, the height at which this validator has begun unbonding. + int64 unbonding_height = 8 [(gogoproto.moretags) = "yaml:\"unbonding_height\""]; + // unbonding_time defines, if unbonding, the min time for the validator to complete unbonding. + google.protobuf.Timestamp unbonding_time = 9 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; + // commission defines the commission parameters. + Commission commission = 10 [(gogoproto.nullable) = false]; + // min_self_delegation is the validator's self declared minimum self delegation. + string min_self_delegation = 11 [ + (gogoproto.moretags) = "yaml:\"min_self_delegation\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; +} + +// BondStatus is the status of a validator. +enum BondStatus { + option (gogoproto.goproto_enum_prefix) = false; + + // UNSPECIFIED defines an invalid validator status. + BOND_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unspecified"]; + // UNBONDED defines a validator that is not bonded. + BOND_STATUS_UNBONDED = 1 [(gogoproto.enumvalue_customname) = "Unbonded"]; + // UNBONDING defines a validator that is unbonding. + BOND_STATUS_UNBONDING = 2 [(gogoproto.enumvalue_customname) = "Unbonding"]; + // BONDED defines a validator that is bonded. + BOND_STATUS_BONDED = 3 [(gogoproto.enumvalue_customname) = "Bonded"]; +} + +// ValAddresses defines a repeated set of validator addresses. +message ValAddresses { + option (gogoproto.goproto_stringer) = false; + option (gogoproto.stringer) = true; + + repeated string addresses = 1; +} + +// DVPair is struct that just has a delegator-validator pair with no other data. +// It is intended to be used as a marshalable pointer. For example, a DVPair can +// be used to construct the key to getting an UnbondingDelegation from state. +message DVPair { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; +} + +// DVPairs defines an array of DVPair objects. +message DVPairs { + repeated DVPair pairs = 1 [(gogoproto.nullable) = false]; +} + +// DVVTriplet is struct that just has a delegator-validator-validator triplet +// with no other data. It is intended to be used as a marshalable pointer. For +// example, a DVVTriplet can be used to construct the key to getting a +// Redelegation from state. +message DVVTriplet { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; +} + +// DVVTriplets defines an array of DVVTriplet objects. +message DVVTriplets { + repeated DVVTriplet triplets = 1 [(gogoproto.nullable) = false]; +} + +// Delegation represents the bond with tokens held by an account. It is +// owned by one delegator, and is associated with the voting power of one +// validator. +message Delegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_address is the bech32-encoded address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // shares define the delegation shares received. + string shares = 3 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// UnbondingDelegation stores all of a single delegator's unbonding bonds +// for a single validator in an time-ordered list. +message UnbondingDelegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_address is the bech32-encoded address of the validator. + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + // entries are the unbonding delegation entries. + repeated UnbondingDelegationEntry entries = 3 [(gogoproto.nullable) = false]; // unbonding delegation entries +} + +// UnbondingDelegationEntry defines an unbonding object with relevant metadata. +message UnbondingDelegationEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // creation_height is the height which the unbonding took place. + int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; + // completion_time is the unix time for unbonding completion. + google.protobuf.Timestamp completion_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; + // initial_balance defines the tokens initially scheduled to receive at completion. + string initial_balance = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"initial_balance\"" + ]; + // balance defines the tokens to receive at completion. + string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; +} + +// RedelegationEntry defines a redelegation object with relevant metadata. +message RedelegationEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // creation_height defines the height which the redelegation took place. + int64 creation_height = 1 [(gogoproto.moretags) = "yaml:\"creation_height\""]; + // completion_time defines the unix time for redelegation completion. + google.protobuf.Timestamp completion_time = 2 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"completion_time\""]; + // initial_balance defines the initial balance when redelegation started. + string initial_balance = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"initial_balance\"" + ]; + // shares_dst is the amount of destination-validator shares created by redelegation. + string shares_dst = 4 + [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false]; +} + +// Redelegation contains the list of a particular delegator's redelegating bonds +// from a particular source validator to a particular destination validator. +message Redelegation { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // delegator_address is the bech32-encoded address of the delegator. + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + // validator_src_address is the validator redelegation source operator address. + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + // validator_dst_address is the validator redelegation destination operator address. + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; + // entries are the redelegation entries. + repeated RedelegationEntry entries = 4 [(gogoproto.nullable) = false]; // redelegation entries +} + +// Params defines the parameters for the staking module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // unbonding_time is the time duration of unbonding. + google.protobuf.Duration unbonding_time = 1 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"unbonding_time\""]; + // max_validators is the maximum number of validators. + uint32 max_validators = 2 [(gogoproto.moretags) = "yaml:\"max_validators\""]; + // max_entries is the max entries for either unbonding delegation or redelegation (per pair/trio). + uint32 max_entries = 3 [(gogoproto.moretags) = "yaml:\"max_entries\""]; + // historical_entries is the number of historical entries to persist. + uint32 historical_entries = 4 [(gogoproto.moretags) = "yaml:\"historical_entries\""]; + // bond_denom defines the bondable coin denomination. + string bond_denom = 5 [(gogoproto.moretags) = "yaml:\"bond_denom\""]; +} + +// DelegationResponse is equivalent to Delegation except that it contains a +// balance in addition to shares which is more suitable for client responses. +message DelegationResponse { + option (gogoproto.equal) = false; + option (gogoproto.goproto_stringer) = false; + + Delegation delegation = 1 [(gogoproto.nullable) = false]; + + cosmos.base.v1beta1.Coin balance = 2 [(gogoproto.nullable) = false]; +} + +// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it +// contains a balance in addition to shares which is more suitable for client +// responses. +message RedelegationEntryResponse { + option (gogoproto.equal) = true; + + RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false]; + string balance = 4 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false]; +} + +// RedelegationResponse is equivalent to a Redelegation except that its entries +// contain a balance in addition to shares which is more suitable for client +// responses. +message RedelegationResponse { + option (gogoproto.equal) = false; + + Redelegation redelegation = 1 [(gogoproto.nullable) = false]; + repeated RedelegationEntryResponse entries = 2 [(gogoproto.nullable) = false]; +} + +// Pool is used for tracking bonded and not-bonded token supply of the bond +// denomination. +message Pool { + option (gogoproto.description) = true; + option (gogoproto.equal) = true; + string not_bonded_tokens = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.jsontag) = "not_bonded_tokens", + (gogoproto.nullable) = false + ]; + string bonded_tokens = 2 [ + (gogoproto.jsontag) = "bonded_tokens", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"bonded_tokens\"" + ]; +} diff --git a/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto new file mode 100644 index 000000000..d074fe010 --- /dev/null +++ b/ampd/proto/third_party/cosmos/staking/v1beta1/tx.proto @@ -0,0 +1,123 @@ +syntax = "proto3"; +package cosmos.staking.v1beta1; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; + +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/staking/v1beta1/staking.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types"; + +// Msg defines the staking Msg service. +service Msg { + // CreateValidator defines a method for creating a new validator. + rpc CreateValidator(MsgCreateValidator) returns (MsgCreateValidatorResponse); + + // EditValidator defines a method for editing an existing validator. + rpc EditValidator(MsgEditValidator) returns (MsgEditValidatorResponse); + + // Delegate defines a method for performing a delegation of coins + // from a delegator to a validator. + rpc Delegate(MsgDelegate) returns (MsgDelegateResponse); + + // BeginRedelegate defines a method for performing a redelegation + // of coins from a delegator and source validator to a destination validator. + rpc BeginRedelegate(MsgBeginRedelegate) returns (MsgBeginRedelegateResponse); + + // Undelegate defines a method for performing an undelegation from a + // delegate and a validator. + rpc Undelegate(MsgUndelegate) returns (MsgUndelegateResponse); +} + +// MsgCreateValidator defines a SDK message for creating a new validator. +message MsgCreateValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Description description = 1 [(gogoproto.nullable) = false]; + CommissionRates commission = 2 [(gogoproto.nullable) = false]; + string min_self_delegation = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"min_self_delegation\"", + (gogoproto.nullable) = false + ]; + string delegator_address = 4 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 5 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + google.protobuf.Any pubkey = 6 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"]; + cosmos.base.v1beta1.Coin value = 7 [(gogoproto.nullable) = false]; +} + +// MsgCreateValidatorResponse defines the Msg/CreateValidator response type. +message MsgCreateValidatorResponse {} + +// MsgEditValidator defines a SDK message for editing an existing validator. +message MsgEditValidator { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Description description = 1 [(gogoproto.nullable) = false]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"address\""]; + + // We pass a reference to the new commission rate and min self delegation as + // it's not mandatory to update. If not updated, the deserialized rate will be + // zero with no way to distinguish if an update was intended. + // REF: #2373 + string commission_rate = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.moretags) = "yaml:\"commission_rate\"" + ]; + string min_self_delegation = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.moretags) = "yaml:\"min_self_delegation\"" + ]; +} + +// MsgEditValidatorResponse defines the Msg/EditValidator response type. +message MsgEditValidatorResponse {} + +// MsgDelegate defines a SDK message for performing a delegation of coins +// from a delegator to a validator. +message MsgDelegate { + option (gogoproto.equal) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; +} + +// MsgDelegateResponse defines the Msg/Delegate response type. +message MsgDelegateResponse {} + +// MsgBeginRedelegate defines a SDK message for performing a redelegation +// of coins from a delegator and source validator to a destination validator. +message MsgBeginRedelegate { + option (gogoproto.equal) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_src_address = 2 [(gogoproto.moretags) = "yaml:\"validator_src_address\""]; + string validator_dst_address = 3 [(gogoproto.moretags) = "yaml:\"validator_dst_address\""]; + cosmos.base.v1beta1.Coin amount = 4 [(gogoproto.nullable) = false]; +} + +// MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type. +message MsgBeginRedelegateResponse { + google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +// MsgUndelegate defines a SDK message for performing an undelegation from a +// delegate and a validator. +message MsgUndelegate { + option (gogoproto.equal) = false; + + string delegator_address = 1 [(gogoproto.moretags) = "yaml:\"delegator_address\""]; + string validator_address = 2 [(gogoproto.moretags) = "yaml:\"validator_address\""]; + cosmos.base.v1beta1.Coin amount = 3 [(gogoproto.nullable) = false]; +} + +// MsgUndelegateResponse defines the Msg/Undelegate response type. +message MsgUndelegateResponse { + google.protobuf.Timestamp completion_time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} diff --git a/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto b/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto new file mode 100644 index 000000000..50de89c8f --- /dev/null +++ b/ampd/proto/third_party/cosmos/tx/signing/v1beta1/signing.proto @@ -0,0 +1,91 @@ +syntax = "proto3"; +package cosmos.tx.signing.v1beta1; + +import "cosmos/crypto/multisig/v1beta1/multisig.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx/signing"; + +// SignMode represents a signing mode with its own security guarantees. +enum SignMode { + // SIGN_MODE_UNSPECIFIED specifies an unknown signing mode and will be + // rejected + SIGN_MODE_UNSPECIFIED = 0; + + // SIGN_MODE_DIRECT specifies a signing mode which uses SignDoc and is + // verified with raw bytes from Tx + SIGN_MODE_DIRECT = 1; + + // SIGN_MODE_TEXTUAL is a future signing mode that will verify some + // human-readable textual representation on top of the binary representation + // from SIGN_MODE_DIRECT + SIGN_MODE_TEXTUAL = 2; + + // SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses + // Amino JSON and will be removed in the future + SIGN_MODE_LEGACY_AMINO_JSON = 127; + + // SIGN_MODE_EIP_191 specifies the sign mode for EIP 191 signing on the Cosmos + // SDK. Ref: https://eips.ethereum.org/EIPS/eip-191 + // + // Currently, SIGN_MODE_EIP_191 is registered as a SignMode enum variant, + // but is not implemented on the SDK by default. To enable EIP-191, you need + // to pass a custom `TxConfig` that has an implementation of + // `SignModeHandler` for EIP-191. The SDK may decide to fully support + // EIP-191 in the future. + // + // Since: cosmos-sdk 0.45.2 + SIGN_MODE_EIP_191 = 191; +} + +// SignatureDescriptors wraps multiple SignatureDescriptor's. +message SignatureDescriptors { + // signatures are the signature descriptors + repeated SignatureDescriptor signatures = 1; +} + +// SignatureDescriptor is a convenience type which represents the full data for +// a signature including the public key of the signer, signing modes and the +// signature itself. It is primarily used for coordinating signatures between +// clients. +message SignatureDescriptor { + // public_key is the public key of the signer + google.protobuf.Any public_key = 1; + + Data data = 2; + + // sequence is the sequence of the account, which describes the + // number of committed transactions signed by a given address. It is used to prevent + // replay attacks. + uint64 sequence = 3; + + // Data represents signature data + message Data { + // sum is the oneof that specifies whether this represents single or multi-signature data + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a multisig signer + Multi multi = 2; + } + + // Single is the signature data for a single signer + message Single { + // mode is the signing mode of the single signer + SignMode mode = 1; + + // signature is the raw signature bytes + bytes signature = 2; + } + + // Multi is the signature data for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; + + // signatures is the signatures of the multi-signature + repeated Data signatures = 2; + } + } +} diff --git a/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto b/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto new file mode 100644 index 000000000..d9f828f76 --- /dev/null +++ b/ampd/proto/third_party/cosmos/tx/v1beta1/service.proto @@ -0,0 +1,165 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "google/api/annotations.proto"; +import "cosmos/base/abci/v1beta1/abci.proto"; +import "cosmos/tx/v1beta1/tx.proto"; +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "tendermint/types/block.proto"; +import "tendermint/types/types.proto"; + +option (gogoproto.goproto_registration) = true; +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Service defines a gRPC service for interacting with transactions. +service Service { + // Simulate simulates executing a transaction for estimating gas usage. + rpc Simulate(SimulateRequest) returns (SimulateResponse) { + option (google.api.http) = { + post: "/cosmos/tx/v1beta1/simulate" + body: "*" + }; + } + // GetTx fetches a tx by hash. + rpc GetTx(GetTxRequest) returns (GetTxResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs/{hash}"; + } + // BroadcastTx broadcast transaction. + rpc BroadcastTx(BroadcastTxRequest) returns (BroadcastTxResponse) { + option (google.api.http) = { + post: "/cosmos/tx/v1beta1/txs" + body: "*" + }; + } + // GetTxsEvent fetches txs by event. + rpc GetTxsEvent(GetTxsEventRequest) returns (GetTxsEventResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs"; + } + // GetBlockWithTxs fetches a block with decoded txs. + // + // Since: cosmos-sdk 0.45.2 + rpc GetBlockWithTxs(GetBlockWithTxsRequest) returns (GetBlockWithTxsResponse) { + option (google.api.http).get = "/cosmos/tx/v1beta1/txs/block/{height}"; + } +} + +// GetTxsEventRequest is the request type for the Service.TxsByEvents +// RPC method. +message GetTxsEventRequest { + // events is the list of transaction event type. + repeated string events = 1; + // pagination defines a pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; + OrderBy order_by = 3; +} + +// OrderBy defines the sorting order +enum OrderBy { + // ORDER_BY_UNSPECIFIED specifies an unknown sorting order. OrderBy defaults to ASC in this case. + ORDER_BY_UNSPECIFIED = 0; + // ORDER_BY_ASC defines ascending order + ORDER_BY_ASC = 1; + // ORDER_BY_DESC defines descending order + ORDER_BY_DESC = 2; +} + +// GetTxsEventResponse is the response type for the Service.TxsByEvents +// RPC method. +message GetTxsEventResponse { + // txs is the list of queried transactions. + repeated cosmos.tx.v1beta1.Tx txs = 1; + // tx_responses is the list of queried TxResponses. + repeated cosmos.base.abci.v1beta1.TxResponse tx_responses = 2; + // pagination defines a pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 3; +} + +// BroadcastTxRequest is the request type for the Service.BroadcastTxRequest +// RPC method. +message BroadcastTxRequest { + // tx_bytes is the raw transaction. + bytes tx_bytes = 1; + BroadcastMode mode = 2; +} + +// BroadcastMode specifies the broadcast mode for the TxService.Broadcast RPC method. +enum BroadcastMode { + // zero-value for mode ordering + BROADCAST_MODE_UNSPECIFIED = 0; + // BROADCAST_MODE_BLOCK defines a tx broadcasting mode where the client waits for + // the tx to be committed in a block. + BROADCAST_MODE_BLOCK = 1; + // BROADCAST_MODE_SYNC defines a tx broadcasting mode where the client waits for + // a CheckTx execution response only. + BROADCAST_MODE_SYNC = 2; + // BROADCAST_MODE_ASYNC defines a tx broadcasting mode where the client returns + // immediately. + BROADCAST_MODE_ASYNC = 3; +} + +// BroadcastTxResponse is the response type for the +// Service.BroadcastTx method. +message BroadcastTxResponse { + // tx_response is the queried TxResponses. + cosmos.base.abci.v1beta1.TxResponse tx_response = 1; +} + +// SimulateRequest is the request type for the Service.Simulate +// RPC method. +message SimulateRequest { + // tx is the transaction to simulate. + // Deprecated. Send raw tx bytes instead. + cosmos.tx.v1beta1.Tx tx = 1 [deprecated = true]; + // tx_bytes is the raw transaction. + // + // Since: cosmos-sdk 0.43 + bytes tx_bytes = 2; +} + +// SimulateResponse is the response type for the +// Service.SimulateRPC method. +message SimulateResponse { + // gas_info is the information about gas used in the simulation. + cosmos.base.abci.v1beta1.GasInfo gas_info = 1; + // result is the result of the simulation. + cosmos.base.abci.v1beta1.Result result = 2; +} + +// GetTxRequest is the request type for the Service.GetTx +// RPC method. +message GetTxRequest { + // hash is the tx hash to query, encoded as a hex string. + string hash = 1; +} + +// GetTxResponse is the response type for the Service.GetTx method. +message GetTxResponse { + // tx is the queried transaction. + cosmos.tx.v1beta1.Tx tx = 1; + // tx_response is the queried TxResponses. + cosmos.base.abci.v1beta1.TxResponse tx_response = 2; +} + +// GetBlockWithTxsRequest is the request type for the Service.GetBlockWithTxs +// RPC method. +// +// Since: cosmos-sdk 0.45.2 +message GetBlockWithTxsRequest { + // height is the height of the block to query. + int64 height = 1; + // pagination defines a pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// GetBlockWithTxsResponse is the response type for the Service.GetBlockWithTxs method. +// +// Since: cosmos-sdk 0.45.2 +message GetBlockWithTxsResponse { + // txs are the transactions in the block. + repeated cosmos.tx.v1beta1.Tx txs = 1; + .tendermint.types.BlockID block_id = 2; + .tendermint.types.Block block = 3; + // pagination defines a pagination for the response. + cosmos.base.query.v1beta1.PageResponse pagination = 4; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto new file mode 100644 index 000000000..6d5caf12c --- /dev/null +++ b/ampd/proto/third_party/cosmos/tx/v1beta1/tx.proto @@ -0,0 +1,183 @@ +syntax = "proto3"; +package cosmos.tx.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/crypto/multisig/v1beta1/multisig.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/tx/signing/v1beta1/signing.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; + +// Tx is the standard type used for broadcasting transactions. +message Tx { + // body is the processable content of the transaction + TxBody body = 1; + + // auth_info is the authorization related content of the transaction, + // specifically signers, signer modes and fee + AuthInfo auth_info = 2; + + // signatures is a list of signatures that matches the length and order of + // AuthInfo's signer_infos to allow connecting signature meta information like + // public key and signing mode by position. + repeated bytes signatures = 3; +} + +// TxRaw is a variant of Tx that pins the signer's exact binary representation +// of body and auth_info. This is used for signing, broadcasting and +// verification. The binary `serialize(tx: TxRaw)` is stored in Tendermint and +// the hash `sha256(serialize(tx: TxRaw))` becomes the "txhash", commonly used +// as the transaction ID. +message TxRaw { + // body_bytes is a protobuf serialization of a TxBody that matches the + // representation in SignDoc. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the + // representation in SignDoc. + bytes auth_info_bytes = 2; + + // signatures is a list of signatures that matches the length and order of + // AuthInfo's signer_infos to allow connecting signature meta information like + // public key and signing mode by position. + repeated bytes signatures = 3; +} + +// SignDoc is the type used for generating sign bytes for SIGN_MODE_DIRECT. +message SignDoc { + // body_bytes is protobuf serialization of a TxBody that matches the + // representation in TxRaw. + bytes body_bytes = 1; + + // auth_info_bytes is a protobuf serialization of an AuthInfo that matches the + // representation in TxRaw. + bytes auth_info_bytes = 2; + + // chain_id is the unique identifier of the chain this transaction targets. + // It prevents signed transactions from being used on another chain by an + // attacker + string chain_id = 3; + + // account_number is the account number of the account in state + uint64 account_number = 4; +} + +// TxBody is the body of a transaction that all signers sign over. +message TxBody { + // messages is a list of messages to be executed. The required signers of + // those messages define the number and order of elements in AuthInfo's + // signer_infos and Tx's signatures. Each required signer address is added to + // the list only the first time it occurs. + // By convention, the first required signer (usually from the first message) + // is referred to as the primary signer and pays the fee for the whole + // transaction. + repeated google.protobuf.Any messages = 1; + + // memo is any arbitrary note/comment to be added to the transaction. + // WARNING: in clients, any publicly exposed text should not be called memo, + // but should be called `note` instead (see https://github.com/cosmos/cosmos-sdk/issues/9122). + string memo = 2; + + // timeout is the block height after which this transaction will not + // be processed by the chain + uint64 timeout_height = 3; + + // extension_options are arbitrary options that can be added by chains + // when the default options are not sufficient. If any of these are present + // and can't be handled, the transaction will be rejected + repeated google.protobuf.Any extension_options = 1023; + + // extension_options are arbitrary options that can be added by chains + // when the default options are not sufficient. If any of these are present + // and can't be handled, they will be ignored + repeated google.protobuf.Any non_critical_extension_options = 2047; +} + +// AuthInfo describes the fee and signer modes that are used to sign a +// transaction. +message AuthInfo { + // signer_infos defines the signing modes for the required signers. The number + // and order of elements must match the required signers from TxBody's + // messages. The first element is the primary signer and the one which pays + // the fee. + repeated SignerInfo signer_infos = 1; + + // Fee is the fee and gas limit for the transaction. The first signer is the + // primary signer and the one which pays the fee. The fee can be calculated + // based on the cost of evaluating the body and doing signature verification + // of the signers. This can be estimated via simulation. + Fee fee = 2; +} + +// SignerInfo describes the public key and signing mode of a single top-level +// signer. +message SignerInfo { + // public_key is the public key of the signer. It is optional for accounts + // that already exist in state. If unset, the verifier can use the required \ + // signer address for this position and lookup the public key. + google.protobuf.Any public_key = 1; + + // mode_info describes the signing mode of the signer and is a nested + // structure to support nested multisig pubkey's + ModeInfo mode_info = 2; + + // sequence is the sequence of the account, which describes the + // number of committed transactions signed by a given address. It is used to + // prevent replay attacks. + uint64 sequence = 3; +} + +// ModeInfo describes the signing mode of a single or nested multisig signer. +message ModeInfo { + // sum is the oneof that specifies whether this represents a single or nested + // multisig signer + oneof sum { + // single represents a single signer + Single single = 1; + + // multi represents a nested multisig signer + Multi multi = 2; + } + + // Single is the mode info for a single signer. It is structured as a message + // to allow for additional fields such as locale for SIGN_MODE_TEXTUAL in the + // future + message Single { + // mode is the signing mode of the single signer + cosmos.tx.signing.v1beta1.SignMode mode = 1; + } + + // Multi is the mode info for a multisig public key + message Multi { + // bitarray specifies which keys within the multisig are signing + cosmos.crypto.multisig.v1beta1.CompactBitArray bitarray = 1; + + // mode_infos is the corresponding modes of the signers of the multisig + // which could include nested multisig public keys + repeated ModeInfo mode_infos = 2; + } +} + +// Fee includes the amount of coins paid in fees and the maximum +// gas to be used by the transaction. The ratio yields an effective "gasprice", +// which must be above some miminum to be accepted into the mempool. +message Fee { + // amount is the amount of coins to be paid as a fee + repeated cosmos.base.v1beta1.Coin amount = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + // gas_limit is the maximum gas that can be used in transaction processing + // before an out of gas error occurs + uint64 gas_limit = 2; + + // if unset, the first signer is responsible for paying the fees. If set, the specified account must pay the fees. + // the payer must be a tx signer (and thus have signed this field in AuthInfo). + // setting this field does *not* change the ordering of required signers for the transaction. + string payer = 3; + + // if set, the fee payer (either the first signer or the value of the payer field) requests that a fee grant be used + // to pay fees instead of the fee payer's own balance. If an appropriate fee grant does not exist or the chain does + // not support fee grants, this will fail + string granter = 4; +} diff --git a/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto b/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto new file mode 100644 index 000000000..dd14ba640 --- /dev/null +++ b/ampd/proto/third_party/cosmos/upgrade/v1beta1/query.proto @@ -0,0 +1,104 @@ +syntax = "proto3"; +package cosmos.upgrade.v1beta1; + +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; + +// Query defines the gRPC upgrade querier service. +service Query { + // CurrentPlan queries the current upgrade plan. + rpc CurrentPlan(QueryCurrentPlanRequest) returns (QueryCurrentPlanResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/current_plan"; + } + + // AppliedPlan queries a previously applied upgrade plan by its name. + rpc AppliedPlan(QueryAppliedPlanRequest) returns (QueryAppliedPlanResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/applied_plan/{name}"; + } + + // UpgradedConsensusState queries the consensus state that will serve + // as a trusted kernel for the next version of this chain. It will only be + // stored at the last height of this chain. + // UpgradedConsensusState RPC not supported with legacy querier + // This rpc is deprecated now that IBC has its own replacement + // (https://github.com/cosmos/ibc-go/blob/2c880a22e9f9cc75f62b527ca94aa75ce1106001/proto/ibc/core/client/v1/query.proto#L54) + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option deprecated = true; + option (google.api.http).get = "/cosmos/upgrade/v1beta1/upgraded_consensus_state/{last_height}"; + } + + // ModuleVersions queries the list of module versions from state. + // + // Since: cosmos-sdk 0.43 + rpc ModuleVersions(QueryModuleVersionsRequest) returns (QueryModuleVersionsResponse) { + option (google.api.http).get = "/cosmos/upgrade/v1beta1/module_versions"; + } +} + +// QueryCurrentPlanRequest is the request type for the Query/CurrentPlan RPC +// method. +message QueryCurrentPlanRequest {} + +// QueryCurrentPlanResponse is the response type for the Query/CurrentPlan RPC +// method. +message QueryCurrentPlanResponse { + // plan is the current upgrade plan. + Plan plan = 1; +} + +// QueryCurrentPlanRequest is the request type for the Query/AppliedPlan RPC +// method. +message QueryAppliedPlanRequest { + // name is the name of the applied plan to query for. + string name = 1; +} + +// QueryAppliedPlanResponse is the response type for the Query/AppliedPlan RPC +// method. +message QueryAppliedPlanResponse { + // height is the block height at which the plan was applied. + int64 height = 1; +} + +// QueryUpgradedConsensusStateRequest is the request type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateRequest { + option deprecated = true; + + // last height of the current chain must be sent in request + // as this is the height under which next consensus state is stored + int64 last_height = 1; +} + +// QueryUpgradedConsensusStateResponse is the response type for the Query/UpgradedConsensusState +// RPC method. +message QueryUpgradedConsensusStateResponse { + option deprecated = true; + reserved 1; + + // Since: cosmos-sdk 0.43 + bytes upgraded_consensus_state = 2; +} + +// QueryModuleVersionsRequest is the request type for the Query/ModuleVersions +// RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryModuleVersionsRequest { + // module_name is a field to query a specific module + // consensus version from state. Leaving this empty will + // fetch the full list of module versions from state + string module_name = 1; +} + +// QueryModuleVersionsResponse is the response type for the Query/ModuleVersions +// RPC method. +// +// Since: cosmos-sdk 0.43 +message QueryModuleVersionsResponse { + // module_versions is a list of module names with their consensus versions. + repeated ModuleVersion module_versions = 1; +} diff --git a/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto b/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto new file mode 100644 index 000000000..e888b393d --- /dev/null +++ b/ampd/proto/third_party/cosmos/upgrade/v1beta1/upgrade.proto @@ -0,0 +1,78 @@ +syntax = "proto3"; +package cosmos.upgrade.v1beta1; + +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; +option (gogoproto.goproto_getters_all) = false; + +// Plan specifies information about a planned upgrade and when it should occur. +message Plan { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + // Sets the name for the upgrade. This name will be used by the upgraded + // version of the software to apply any special "on-upgrade" commands during + // the first BeginBlock method after the upgrade is applied. It is also used + // to detect whether a software version can handle a given upgrade. If no + // upgrade handler with this name has been set in the software, it will be + // assumed that the software is out-of-date when the upgrade Time or Height is + // reached and the software will exit. + string name = 1; + + // Deprecated: Time based upgrades have been deprecated. Time based upgrade logic + // has been removed from the SDK. + // If this field is not empty, an error will be thrown. + google.protobuf.Timestamp time = 2 [deprecated = true, (gogoproto.stdtime) = true, (gogoproto.nullable) = false]; + + // The height at which the upgrade must be performed. + // Only used if Time is not set. + int64 height = 3; + + // Any application specific upgrade info to be included on-chain + // such as a git commit that validators could automatically upgrade to + string info = 4; + + // Deprecated: UpgradedClientState field has been deprecated. IBC upgrade logic has been + // moved to the IBC module in the sub module 02-client. + // If this field is not empty, an error will be thrown. + google.protobuf.Any upgraded_client_state = 5 + [deprecated = true, (gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} + +// SoftwareUpgradeProposal is a gov Content type for initiating a software +// upgrade. +message SoftwareUpgradeProposal { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; + Plan plan = 3 [(gogoproto.nullable) = false]; +} + +// CancelSoftwareUpgradeProposal is a gov Content type for cancelling a software +// upgrade. +message CancelSoftwareUpgradeProposal { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + string title = 1; + string description = 2; +} + +// ModuleVersion specifies a module and its consensus version. +// +// Since: cosmos-sdk 0.43 +message ModuleVersion { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + // name of the app module + string name = 1; + + // consensus version of the app module + uint64 version = 2; +} diff --git a/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto b/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto new file mode 100644 index 000000000..c49be802a --- /dev/null +++ b/ampd/proto/third_party/cosmos/vesting/v1beta1/tx.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package cosmos.vesting.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; + +// Msg defines the bank Msg service. +service Msg { + // CreateVestingAccount defines a method that enables creating a vesting + // account. + rpc CreateVestingAccount(MsgCreateVestingAccount) returns (MsgCreateVestingAccountResponse); +} + +// MsgCreateVestingAccount defines a message that enables creating a vesting +// account. +message MsgCreateVestingAccount { + option (gogoproto.equal) = true; + + string from_address = 1 [(gogoproto.moretags) = "yaml:\"from_address\""]; + string to_address = 2 [(gogoproto.moretags) = "yaml:\"to_address\""]; + repeated cosmos.base.v1beta1.Coin amount = 3 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; + + int64 end_time = 4 [(gogoproto.moretags) = "yaml:\"end_time\""]; + bool delayed = 5; +} + +// MsgCreateVestingAccountResponse defines the Msg/CreateVestingAccount response type. +message MsgCreateVestingAccountResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto b/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto new file mode 100644 index 000000000..e9f661f93 --- /dev/null +++ b/ampd/proto/third_party/cosmos/vesting/v1beta1/vesting.proto @@ -0,0 +1,85 @@ +syntax = "proto3"; +package cosmos.vesting.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"; + +// BaseVestingAccount implements the VestingAccount interface. It contains all +// the necessary fields needed for any vesting account implementation. +message BaseVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + repeated cosmos.base.v1beta1.Coin original_vesting = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"original_vesting\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_free = 3 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_free\"" + ]; + repeated cosmos.base.v1beta1.Coin delegated_vesting = 4 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"delegated_vesting\"" + ]; + int64 end_time = 5 [(gogoproto.moretags) = "yaml:\"end_time\""]; +} + +// ContinuousVestingAccount implements the VestingAccount interface. It +// continuously vests by unlocking coins linearly with respect to time. +message ContinuousVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; +} + +// DelayedVestingAccount implements the VestingAccount interface. It vests all +// coins after a specific time, but non prior. In other words, it keeps them +// locked until a specified time. +message DelayedVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; +} + +// Period defines a length of time and amount of coins that will vest. +message Period { + option (gogoproto.goproto_stringer) = false; + + int64 length = 1; + repeated cosmos.base.v1beta1.Coin amount = 2 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; +} + +// PeriodicVestingAccount implements the VestingAccount interface. It +// periodically vests by unlocking coins during each specified period. +message PeriodicVestingAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; + int64 start_time = 2 [(gogoproto.moretags) = "yaml:\"start_time\""]; + repeated Period vesting_periods = 3 [(gogoproto.moretags) = "yaml:\"vesting_periods\"", (gogoproto.nullable) = false]; +} + +// PermanentLockedAccount implements the VestingAccount interface. It does +// not ever release coins, locking them indefinitely. Coins in this account can +// still be used for delegating and for governance votes even while locked. +// +// Since: cosmos-sdk 0.43 +message PermanentLockedAccount { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + BaseVestingAccount base_vesting_account = 1 [(gogoproto.embed) = true]; +} diff --git a/ampd/proto/third_party/cosmos_proto/cosmos.proto b/ampd/proto/third_party/cosmos_proto/cosmos.proto new file mode 100644 index 000000000..167b17075 --- /dev/null +++ b/ampd/proto/third_party/cosmos_proto/cosmos.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package cosmos_proto; + +import "google/protobuf/descriptor.proto"; + +option go_package = "github.com/regen-network/cosmos-proto"; + +extend google.protobuf.MessageOptions { + string interface_type = 93001; + + string implements_interface = 93002; +} + +extend google.protobuf.FieldOptions { + string accepts_interface = 93001; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto new file mode 100644 index 000000000..97a82275d --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/authz.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// ContractExecutionAuthorization defines authorization for wasm execute. +// Since: wasmd 0.30 +message ContractExecutionAuthorization { + option (cosmos_proto.implements_interface) = + "cosmos.authz.v1beta1.Authorization"; + + // Grants for contract executions + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} + +// ContractMigrationAuthorization defines authorization for wasm contract +// migration. Since: wasmd 0.30 +message ContractMigrationAuthorization { + option (cosmos_proto.implements_interface) = + "cosmos.authz.v1beta1.Authorization"; + + // Grants for contract migrations + repeated ContractGrant grants = 1 [ (gogoproto.nullable) = false ]; +} + +// ContractGrant a granted permission for a single contract +// Since: wasmd 0.30 +message ContractGrant { + // Contract is the bech32 address of the smart contract + string contract = 1; + + // Limit defines execution limits that are enforced and updated when the grant + // is applied. When the limit lapsed the grant is removed. + google.protobuf.Any limit = 2 [ (cosmos_proto.accepts_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX" ]; + + // Filter define more fine-grained control on the message payload passed + // to the contract in the operation. When no filter applies on execution, the + // operation is prohibited. + google.protobuf.Any filter = 3 + [ (cosmos_proto.accepts_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX" ]; +} + +// MaxCallsLimit limited number of calls to the contract. No funds transferable. +// Since: wasmd 0.30 +message MaxCallsLimit { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX"; + + // Remaining number that is decremented on each execution + uint64 remaining = 1; +} + +// MaxFundsLimit defines the maximal amounts that can be sent to the contract. +// Since: wasmd 0.30 +message MaxFundsLimit { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX"; + + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// CombinedLimit defines the maximal amounts that can be sent to a contract and +// the maximal number of calls executable. Both need to remain >0 to be valid. +// Since: wasmd 0.30 +message CombinedLimit { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzLimitX"; + + // Remaining number that is decremented on each execution + uint64 calls_remaining = 1; + // Amounts is the maximal amount of tokens transferable to the contract. + repeated cosmos.base.v1beta1.Coin amounts = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// AllowAllMessagesFilter is a wildcard to allow any type of contract payload +// message. +// Since: wasmd 0.30 +message AllowAllMessagesFilter { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX"; +} + +// AcceptedMessageKeysFilter accept only the specific contract message keys in +// the json object to be executed. +// Since: wasmd 0.30 +message AcceptedMessageKeysFilter { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX"; + + // Messages is the list of unique keys + repeated string keys = 1; +} + +// AcceptedMessagesFilter accept only the specific raw contract messages to be +// executed. +// Since: wasmd 0.30 +message AcceptedMessagesFilter { + option (cosmos_proto.implements_interface) = + "cosmwasm.wasm.v1.ContractAuthzFilterX"; + + // Messages is the list of raw contract messages + repeated bytes messages = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto new file mode 100644 index 000000000..4e728ff4b --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/genesis.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmwasm/wasm/v1/types.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; + +// GenesisState - genesis state of x/wasm +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + repeated Code codes = 2 + [ (gogoproto.nullable) = false, (gogoproto.jsontag) = "codes,omitempty" ]; + repeated Contract contracts = 3 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "contracts,omitempty" + ]; + repeated Sequence sequences = 4 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "sequences,omitempty" + ]; +} + +// Code struct encompasses CodeInfo and CodeBytes +message Code { + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + CodeInfo code_info = 2 [ (gogoproto.nullable) = false ]; + bytes code_bytes = 3; + // Pinned to wasmvm cache + bool pinned = 4; +} + +// Contract struct encompasses ContractAddress, ContractInfo, and ContractState +message Contract { + string contract_address = 1; + ContractInfo contract_info = 2 [ (gogoproto.nullable) = false ]; + repeated Model contract_state = 3 [ (gogoproto.nullable) = false ]; + repeated ContractCodeHistoryEntry contract_code_history = 4 + [ (gogoproto.nullable) = false ]; +} + +// Sequence key and value of an id generation counter +message Sequence { + bytes id_key = 1 [ (gogoproto.customname) = "IDKey" ]; + uint64 value = 2; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto new file mode 100644 index 000000000..feaad2936 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/ibc.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// MsgIBCSend +message MsgIBCSend { + // the channel by which the packet will be sent + string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; + + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + uint64 timeout_height = 4 + [ (gogoproto.moretags) = "yaml:\"timeout_height\"" ]; + // Timeout timestamp (in nanoseconds) relative to the current block timestamp. + // The timeout is disabled when set to 0. + uint64 timeout_timestamp = 5 + [ (gogoproto.moretags) = "yaml:\"timeout_timestamp\"" ]; + + // Data is the payload to transfer. We must not make assumption what format or + // content is in here. + bytes data = 6; +} + +// MsgIBCSendResponse +message MsgIBCSendResponse { + // Sequence number of the IBC packet sent + uint64 sequence = 1; +} + +// MsgIBCCloseChannel port and channel need to be owned by the contract +message MsgIBCCloseChannel { + string channel = 2 [ (gogoproto.moretags) = "yaml:\"source_channel\"" ]; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto new file mode 100644 index 000000000..b1c484bc9 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/proposal.proto @@ -0,0 +1,272 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmwasm/wasm/v1/types.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_stringer_all) = false; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = true; + +// StoreCodeProposal gov proposal content type to submit WASM code to the system +message StoreCodeProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; + // Used in v1beta1 + reserved 5, 6; + // InstantiatePermission to apply on contract creation, optional + AccessConfig instantiate_permission = 7; + // UnpinCode code on upload, optional + bool unpin_code = 8; + // Source is the URL where the code is hosted + string source = 9; + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + string builder = 10; + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + bytes code_hash = 11; +} + +// InstantiateContractProposal gov proposal content type to instantiate a +// contract. +message InstantiateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // Admin is an optional address that can execute migrations + string admin = 4; + // CodeID is the reference to the stored WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a constract instance. + string label = 6; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 8 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// InstantiateContract2Proposal gov proposal content type to instantiate +// contract 2 +message InstantiateContract2Proposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's enviroment as sender + string run_as = 3; + // Admin is an optional address that can execute migrations + string admin = 4; + // CodeID is the reference to the stored WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a constract instance. + string label = 6; + // Msg json encode message to be passed to the contract on instantiation + bytes msg = 7 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 8 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. + bytes salt = 9; + // FixMsg include the msg value into the hash for the predictable address. + // Default is false + bool fix_msg = 10; +} + +// MigrateContractProposal gov proposal content type to migrate a contract. +message MigrateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // Note: skipping 3 as this was previously used for unneeded run_as + + // Contract is the address of the smart contract + string contract = 4; + // CodeID references the new WASM code + uint64 code_id = 5 [ (gogoproto.customname) = "CodeID" ]; + // Msg json encoded message to be passed to the contract on migration + bytes msg = 6 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// SudoContractProposal gov proposal content type to call sudo on a contract. +message SudoContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // Contract is the address of the smart contract + string contract = 3; + // Msg json encoded message to be passed to the contract as sudo + bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// ExecuteContractProposal gov proposal content type to call execute on a +// contract. +message ExecuteContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // Contract is the address of the smart contract + string contract = 4; + // Msg json encoded message to be passed to the contract as execute + bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 6 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// UpdateAdminProposal gov proposal content type to set an admin for a contract. +message UpdateAdminProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // NewAdmin address to be set + string new_admin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; + // Contract is the address of the smart contract + string contract = 4; +} + +// ClearAdminProposal gov proposal content type to clear the admin of a +// contract. +message ClearAdminProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // Contract is the address of the smart contract + string contract = 3; +} + +// PinCodesProposal gov proposal content type to pin a set of code ids in the +// wasmvm cache. +message PinCodesProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + // Description is a human readable text + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // CodeIDs references the new WASM codes + repeated uint64 code_ids = 3 [ + (gogoproto.customname) = "CodeIDs", + (gogoproto.moretags) = "yaml:\"code_ids\"" + ]; +} + +// UnpinCodesProposal gov proposal content type to unpin a set of code ids in +// the wasmvm cache. +message UnpinCodesProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + // Description is a human readable text + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // CodeIDs references the WASM codes + repeated uint64 code_ids = 3 [ + (gogoproto.customname) = "CodeIDs", + (gogoproto.moretags) = "yaml:\"code_ids\"" + ]; +} + +// AccessConfigUpdate contains the code id and the access config to be +// applied. +message AccessConfigUpdate { + // CodeID is the reference to the stored WASM code to be updated + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + // InstantiatePermission to apply to the set of code ids + AccessConfig instantiate_permission = 2 [ (gogoproto.nullable) = false ]; +} + +// UpdateInstantiateConfigProposal gov proposal content type to update +// instantiate config to a set of code ids. +message UpdateInstantiateConfigProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + // Description is a human readable text + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // AccessConfigUpdate contains the list of code ids and the access config + // to be applied. + repeated AccessConfigUpdate access_config_updates = 3 + [ (gogoproto.nullable) = false ]; +} + +// StoreAndInstantiateContractProposal gov proposal content type to store +// and instantiate the contract. +message StoreAndInstantiateContractProposal { + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + // Title is a short summary + string title = 1; + // Description is a human readable text + string description = 2; + // RunAs is the address that is passed to the contract's environment as sender + string run_as = 3; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 4 [ (gogoproto.customname) = "WASMByteCode" ]; + // InstantiatePermission to apply on contract creation, optional + AccessConfig instantiate_permission = 5; + // UnpinCode code on upload, optional + bool unpin_code = 6; + // Admin is an optional address that can execute migrations + string admin = 7; + // Label is optional metadata to be stored with a constract instance. + string label = 8; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 9 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 10 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Source is the URL where the code is hosted + string source = 11; + // Builder is the docker image used to build the code deterministically, used + // for smart contract verification + string builder = 12; + // CodeHash is the SHA256 sum of the code outputted by builder, used for smart + // contract verification + bytes code_hash = 13; +} diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto new file mode 100644 index 000000000..ffe48d242 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/query.proto @@ -0,0 +1,263 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "gogoproto/gogo.proto"; +import "cosmwasm/wasm/v1/types.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = false; + +// Query provides defines the gRPC querier service +service Query { + // ContractInfo gets the contract meta data + rpc ContractInfo(QueryContractInfoRequest) + returns (QueryContractInfoResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/contract/{address}"; + } + // ContractHistory gets the contract code history + rpc ContractHistory(QueryContractHistoryRequest) + returns (QueryContractHistoryResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contract/{address}/history"; + } + // ContractsByCode lists all smart contracts for a code id + rpc ContractsByCode(QueryContractsByCodeRequest) + returns (QueryContractsByCodeResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}/contracts"; + } + // AllContractState gets all raw store data for a single contract + rpc AllContractState(QueryAllContractStateRequest) + returns (QueryAllContractStateResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/contract/{address}/state"; + } + // RawContractState gets single key from the raw store data of a contract + rpc RawContractState(QueryRawContractStateRequest) + returns (QueryRawContractStateResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}"; + } + // SmartContractState get smart query result from the contract + rpc SmartContractState(QuerySmartContractStateRequest) + returns (QuerySmartContractStateResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}"; + } + // Code gets the binary code and metadata for a singe wasm code + rpc Code(QueryCodeRequest) returns (QueryCodeResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/code/{code_id}"; + } + // Codes gets the metadata for all stored wasm codes + rpc Codes(QueryCodesRequest) returns (QueryCodesResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/code"; + } + + // PinnedCodes gets the pinned code ids + rpc PinnedCodes(QueryPinnedCodesRequest) returns (QueryPinnedCodesResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/codes/pinned"; + } + + // Params gets the module params + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmwasm/wasm/v1/codes/params"; + } + + // ContractsByCreator gets the contracts by creator + rpc ContractsByCreator(QueryContractsByCreatorRequest) + returns (QueryContractsByCreatorResponse) { + option (google.api.http).get = + "/cosmwasm/wasm/v1/contracts/creator/{creator_address}"; + } +} + +// QueryContractInfoRequest is the request type for the Query/ContractInfo RPC +// method +message QueryContractInfoRequest { + // address is the address of the contract to query + string address = 1; +} +// QueryContractInfoResponse is the response type for the Query/ContractInfo RPC +// method +message QueryContractInfoResponse { + option (gogoproto.equal) = true; + + // address is the address of the contract + string address = 1; + ContractInfo contract_info = 2 [ + (gogoproto.embed) = true, + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "" + ]; +} + +// QueryContractHistoryRequest is the request type for the Query/ContractHistory +// RPC method +message QueryContractHistoryRequest { + // address is the address of the contract to query + string address = 1; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractHistoryResponse is the response type for the +// Query/ContractHistory RPC method +message QueryContractHistoryResponse { + repeated ContractCodeHistoryEntry entries = 1 + [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryContractsByCodeRequest is the request type for the Query/ContractsByCode +// RPC method +message QueryContractsByCodeRequest { + uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractsByCodeResponse is the response type for the +// Query/ContractsByCode RPC method +message QueryContractsByCodeResponse { + // contracts are a set of contract addresses + repeated string contracts = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryAllContractStateRequest is the request type for the +// Query/AllContractState RPC method +message QueryAllContractStateRequest { + // address is the address of the contract + string address = 1; + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAllContractStateResponse is the response type for the +// Query/AllContractState RPC method +message QueryAllContractStateResponse { + repeated Model models = 1 [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryRawContractStateRequest is the request type for the +// Query/RawContractState RPC method +message QueryRawContractStateRequest { + // address is the address of the contract + string address = 1; + bytes query_data = 2; +} + +// QueryRawContractStateResponse is the response type for the +// Query/RawContractState RPC method +message QueryRawContractStateResponse { + // Data contains the raw store data + bytes data = 1; +} + +// QuerySmartContractStateRequest is the request type for the +// Query/SmartContractState RPC method +message QuerySmartContractStateRequest { + // address is the address of the contract + string address = 1; + // QueryData contains the query data passed to the contract + bytes query_data = 2 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// QuerySmartContractStateResponse is the response type for the +// Query/SmartContractState RPC method +message QuerySmartContractStateResponse { + // Data contains the json data returned from the smart contract + bytes data = 1 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// QueryCodeRequest is the request type for the Query/Code RPC method +message QueryCodeRequest { + uint64 code_id = 1; // grpc-gateway_out does not support Go style CodID +} + +// CodeInfoResponse contains code meta data from CodeInfo +message CodeInfoResponse { + option (gogoproto.equal) = true; + + uint64 code_id = 1 [ + (gogoproto.customname) = "CodeID", + (gogoproto.jsontag) = "id" + ]; // id for legacy support + string creator = 2; + bytes data_hash = 3 + [ (gogoproto.casttype) = + "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; + // Used in v1beta1 + reserved 4, 5; + AccessConfig instantiate_permission = 6 [ (gogoproto.nullable) = false ]; +} + +// QueryCodeResponse is the response type for the Query/Code RPC method +message QueryCodeResponse { + option (gogoproto.equal) = true; + CodeInfoResponse code_info = 1 + [ (gogoproto.embed) = true, (gogoproto.jsontag) = "" ]; + bytes data = 2 [ (gogoproto.jsontag) = "data" ]; +} + +// QueryCodesRequest is the request type for the Query/Codes RPC method +message QueryCodesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryCodesResponse is the response type for the Query/Codes RPC method +message QueryCodesResponse { + repeated CodeInfoResponse code_infos = 1 [ (gogoproto.nullable) = false ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryPinnedCodesRequest is the request type for the Query/PinnedCodes +// RPC method +message QueryPinnedCodesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryPinnedCodesResponse is the response type for the +// Query/PinnedCodes RPC method +message QueryPinnedCodesResponse { + repeated uint64 code_ids = 1 + [ (gogoproto.nullable) = false, (gogoproto.customname) = "CodeIDs" ]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +// QueryContractsByCreatorRequest is the request type for the +// Query/ContractsByCreator RPC method. +message QueryContractsByCreatorRequest { + // CreatorAddress is the address of contract creator + string creator_address = 1; + // Pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryContractsByCreatorResponse is the response type for the +// Query/ContractsByCreator RPC method. +message QueryContractsByCreatorResponse { + // ContractAddresses result set + repeated string contract_addresses = 1; + // Pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto new file mode 100644 index 000000000..741fbc494 --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/tx.proto @@ -0,0 +1,192 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "cosmwasm/wasm/v1/types.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; + +// Msg defines the wasm Msg service. +service Msg { + // StoreCode to submit Wasm code to the system + rpc StoreCode(MsgStoreCode) returns (MsgStoreCodeResponse); + // InstantiateContract creates a new smart contract instance for the given + // code id. + rpc InstantiateContract(MsgInstantiateContract) + returns (MsgInstantiateContractResponse); + // InstantiateContract2 creates a new smart contract instance for the given + // code id with a predictable address + rpc InstantiateContract2(MsgInstantiateContract2) + returns (MsgInstantiateContract2Response); + // Execute submits the given message data to a smart contract + rpc ExecuteContract(MsgExecuteContract) returns (MsgExecuteContractResponse); + // Migrate runs a code upgrade/ downgrade for a smart contract + rpc MigrateContract(MsgMigrateContract) returns (MsgMigrateContractResponse); + // UpdateAdmin sets a new admin for a smart contract + rpc UpdateAdmin(MsgUpdateAdmin) returns (MsgUpdateAdminResponse); + // ClearAdmin removes any admin stored for a smart contract + rpc ClearAdmin(MsgClearAdmin) returns (MsgClearAdminResponse); + // UpdateInstantiateConfig updates instantiate config for a smart contract + rpc UpdateInstantiateConfig(MsgUpdateInstantiateConfig) + returns (MsgUpdateInstantiateConfigResponse); +} + +// MsgStoreCode submit Wasm code to the system +message MsgStoreCode { + // Sender is the actor that signed the messages + string sender = 1; + // WASMByteCode can be raw or gzip compressed + bytes wasm_byte_code = 2 [ (gogoproto.customname) = "WASMByteCode" ]; + // Used in v1beta1 + reserved 3, 4; + // InstantiatePermission access control to apply on contract creation, + // optional + AccessConfig instantiate_permission = 5; +} +// MsgStoreCodeResponse returns store result data. +message MsgStoreCodeResponse { + // CodeID is the reference to the stored WASM code + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + // Checksum is the sha256 hash of the stored code + bytes checksum = 2; +} + +// MsgInstantiateContract create a new smart contract instance for the given +// code id. +message MsgInstantiateContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Admin is an optional address that can execute migrations + string admin = 2; + // CodeID is the reference to the stored WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a contract instance. + string label = 4; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 6 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// MsgInstantiateContract2 create a new smart contract instance for the given +// code id with a predicable address. +message MsgInstantiateContract2 { + // Sender is the that actor that signed the messages + string sender = 1; + // Admin is an optional address that can execute migrations + string admin = 2; + // CodeID is the reference to the stored WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // Label is optional metadata to be stored with a contract instance. + string label = 4; + // Msg json encoded message to be passed to the contract on instantiation + bytes msg = 5 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on instantiation + repeated cosmos.base.v1beta1.Coin funds = 6 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; + // Salt is an arbitrary value provided by the sender. Size can be 1 to 64. + bytes salt = 7; + // FixMsg include the msg value into the hash for the predictable address. + // Default is false + bool fix_msg = 8; +} + +// MsgInstantiateContractResponse return instantiation result data +message MsgInstantiateContractResponse { + // Address is the bech32 address of the new contract instance. + string address = 1; + // Data contains bytes to returned from the contract + bytes data = 2; +} + +// MsgInstantiateContract2Response return instantiation result data +message MsgInstantiateContract2Response { + // Address is the bech32 address of the new contract instance. + string address = 1; + // Data contains bytes to returned from the contract + bytes data = 2; +} + +// MsgExecuteContract submits the given message data to a smart contract +message MsgExecuteContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 2; + // Msg json encoded message to be passed to the contract + bytes msg = 3 [ (gogoproto.casttype) = "RawContractMessage" ]; + // Funds coins that are transferred to the contract on execution + repeated cosmos.base.v1beta1.Coin funds = 5 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} + +// MsgExecuteContractResponse returns execution result data. +message MsgExecuteContractResponse { + // Data contains bytes to returned from the contract + bytes data = 1; +} + +// MsgMigrateContract runs a code upgrade/ downgrade for a smart contract +message MsgMigrateContract { + // Sender is the that actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 2; + // CodeID references the new WASM code + uint64 code_id = 3 [ (gogoproto.customname) = "CodeID" ]; + // Msg json encoded message to be passed to the contract on migration + bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// MsgMigrateContractResponse returns contract migration result data. +message MsgMigrateContractResponse { + // Data contains same raw bytes returned as data from the wasm contract. + // (May be empty) + bytes data = 1; +} + +// MsgUpdateAdmin sets a new admin for a smart contract +message MsgUpdateAdmin { + // Sender is the that actor that signed the messages + string sender = 1; + // NewAdmin address to be set + string new_admin = 2; + // Contract is the address of the smart contract + string contract = 3; +} + +// MsgUpdateAdminResponse returns empty data +message MsgUpdateAdminResponse {} + +// MsgClearAdmin removes any admin stored for a smart contract +message MsgClearAdmin { + // Sender is the actor that signed the messages + string sender = 1; + // Contract is the address of the smart contract + string contract = 3; +} + +// MsgClearAdminResponse returns empty data +message MsgClearAdminResponse {} + +// MsgUpdateInstantiateConfig updates instantiate config for a smart contract +message MsgUpdateInstantiateConfig { + // Sender is the that actor that signed the messages + string sender = 1; + // CodeID references the stored WASM code + uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; + // NewInstantiatePermission is the new access control + AccessConfig new_instantiate_permission = 3; +} + +// MsgUpdateInstantiateConfigResponse returns empty data +message MsgUpdateInstantiateConfigResponse {} \ No newline at end of file diff --git a/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto b/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto new file mode 100644 index 000000000..b68179e2e --- /dev/null +++ b/ampd/proto/third_party/cosmwasm/wasm/v1/types.proto @@ -0,0 +1,145 @@ +syntax = "proto3"; +package cosmwasm.wasm.v1; + +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +option go_package = "github.com/CosmWasm/wasmd/x/wasm/types"; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.equal_all) = true; + +// AccessType permission types +enum AccessType { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.goproto_enum_stringer) = false; + // AccessTypeUnspecified placeholder for empty value + ACCESS_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = "AccessTypeUnspecified" ]; + // AccessTypeNobody forbidden + ACCESS_TYPE_NOBODY = 1 + [ (gogoproto.enumvalue_customname) = "AccessTypeNobody" ]; + // AccessTypeOnlyAddress restricted to a single address + // Deprecated: use AccessTypeAnyOfAddresses instead + ACCESS_TYPE_ONLY_ADDRESS = 2 + [ (gogoproto.enumvalue_customname) = "AccessTypeOnlyAddress" ]; + // AccessTypeEverybody unrestricted + ACCESS_TYPE_EVERYBODY = 3 + [ (gogoproto.enumvalue_customname) = "AccessTypeEverybody" ]; + // AccessTypeAnyOfAddresses allow any of the addresses + ACCESS_TYPE_ANY_OF_ADDRESSES = 4 + [ (gogoproto.enumvalue_customname) = "AccessTypeAnyOfAddresses" ]; +} + +// AccessTypeParam +message AccessTypeParam { + option (gogoproto.goproto_stringer) = true; + AccessType value = 1 [ (gogoproto.moretags) = "yaml:\"value\"" ]; +} + +// AccessConfig access control type. +message AccessConfig { + option (gogoproto.goproto_stringer) = true; + AccessType permission = 1 [ (gogoproto.moretags) = "yaml:\"permission\"" ]; + + // Address + // Deprecated: replaced by addresses + string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + repeated string addresses = 3 [ (gogoproto.moretags) = "yaml:\"addresses\"" ]; +} + +// Params defines the set of wasm parameters. +message Params { + option (gogoproto.goproto_stringer) = false; + AccessConfig code_upload_access = 1 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"code_upload_access\"" + ]; + AccessType instantiate_default_permission = 2 + [ (gogoproto.moretags) = "yaml:\"instantiate_default_permission\"" ]; +} + +// CodeInfo is data for the uploaded contract WASM code +message CodeInfo { + // CodeHash is the unique identifier created by wasmvm + bytes code_hash = 1; + // Creator address who initially stored the code + string creator = 2; + // Used in v1beta1 + reserved 3, 4; + // InstantiateConfig access control to apply on contract creation, optional + AccessConfig instantiate_config = 5 [ (gogoproto.nullable) = false ]; +} + +// ContractInfo stores a WASM contract instance +message ContractInfo { + option (gogoproto.equal) = true; + + // CodeID is the reference to the stored Wasm code + uint64 code_id = 1 [ (gogoproto.customname) = "CodeID" ]; + // Creator address who initially instantiated the contract + string creator = 2; + // Admin is an optional address that can execute migrations + string admin = 3; + // Label is optional metadata to be stored with a contract instance. + string label = 4; + // Created Tx position when the contract was instantiated. + AbsoluteTxPosition created = 5; + string ibc_port_id = 6 [ (gogoproto.customname) = "IBCPortID" ]; + + // Extension is an extension point to store custom metadata within the + // persistence model. + google.protobuf.Any extension = 7 + [ (cosmos_proto.accepts_interface) = + "cosmwasm.wasm.v1.ContractInfoExtension" ]; +} + +// ContractCodeHistoryOperationType actions that caused a code change +enum ContractCodeHistoryOperationType { + option (gogoproto.goproto_enum_prefix) = false; + // ContractCodeHistoryOperationTypeUnspecified placeholder for empty value + CONTRACT_CODE_HISTORY_OPERATION_TYPE_UNSPECIFIED = 0 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeUnspecified" ]; + // ContractCodeHistoryOperationTypeInit on chain contract instantiation + CONTRACT_CODE_HISTORY_OPERATION_TYPE_INIT = 1 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeInit" ]; + // ContractCodeHistoryOperationTypeMigrate code migration + CONTRACT_CODE_HISTORY_OPERATION_TYPE_MIGRATE = 2 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeMigrate" ]; + // ContractCodeHistoryOperationTypeGenesis based on genesis data + CONTRACT_CODE_HISTORY_OPERATION_TYPE_GENESIS = 3 + [ (gogoproto.enumvalue_customname) = + "ContractCodeHistoryOperationTypeGenesis" ]; +} + +// ContractCodeHistoryEntry metadata to a contract. +message ContractCodeHistoryEntry { + ContractCodeHistoryOperationType operation = 1; + // CodeID is the reference to the stored WASM code + uint64 code_id = 2 [ (gogoproto.customname) = "CodeID" ]; + // Updated Tx position when the operation was executed. + AbsoluteTxPosition updated = 3; + bytes msg = 4 [ (gogoproto.casttype) = "RawContractMessage" ]; +} + +// AbsoluteTxPosition is a unique transaction position that allows for global +// ordering of transactions. +message AbsoluteTxPosition { + // BlockHeight is the block the contract was created at + uint64 block_height = 1; + // TxIndex is a monotonic counter within the block (actual transaction index, + // or gas consumed) + uint64 tx_index = 2; +} + +// Model is a struct that holds a KV pair +message Model { + // hex-encode key to read it better (this is often ascii) + bytes key = 1 [ (gogoproto.casttype) = + "github.com/tendermint/tendermint/libs/bytes.HexBytes" ]; + // base64-encode raw value + bytes value = 2; +} diff --git a/ampd/proto/third_party/gogoproto/gogo.proto b/ampd/proto/third_party/gogoproto/gogo.proto new file mode 100644 index 000000000..49e78f99f --- /dev/null +++ b/ampd/proto/third_party/gogoproto/gogo.proto @@ -0,0 +1,145 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; +package gogoproto; + +import "google/protobuf/descriptor.proto"; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "GoGoProtos"; +option go_package = "github.com/gogo/protobuf/gogoproto"; + +extend google.protobuf.EnumOptions { + optional bool goproto_enum_prefix = 62001; + optional bool goproto_enum_stringer = 62021; + optional bool enum_stringer = 62022; + optional string enum_customname = 62023; + optional bool enumdecl = 62024; +} + +extend google.protobuf.EnumValueOptions { + optional string enumvalue_customname = 66001; +} + +extend google.protobuf.FileOptions { + optional bool goproto_getters_all = 63001; + optional bool goproto_enum_prefix_all = 63002; + optional bool goproto_stringer_all = 63003; + optional bool verbose_equal_all = 63004; + optional bool face_all = 63005; + optional bool gostring_all = 63006; + optional bool populate_all = 63007; + optional bool stringer_all = 63008; + optional bool onlyone_all = 63009; + + optional bool equal_all = 63013; + optional bool description_all = 63014; + optional bool testgen_all = 63015; + optional bool benchgen_all = 63016; + optional bool marshaler_all = 63017; + optional bool unmarshaler_all = 63018; + optional bool stable_marshaler_all = 63019; + + optional bool sizer_all = 63020; + + optional bool goproto_enum_stringer_all = 63021; + optional bool enum_stringer_all = 63022; + + optional bool unsafe_marshaler_all = 63023; + optional bool unsafe_unmarshaler_all = 63024; + + optional bool goproto_extensions_map_all = 63025; + optional bool goproto_unrecognized_all = 63026; + optional bool gogoproto_import = 63027; + optional bool protosizer_all = 63028; + optional bool compare_all = 63029; + optional bool typedecl_all = 63030; + optional bool enumdecl_all = 63031; + + optional bool goproto_registration = 63032; + optional bool messagename_all = 63033; + + optional bool goproto_sizecache_all = 63034; + optional bool goproto_unkeyed_all = 63035; +} + +extend google.protobuf.MessageOptions { + optional bool goproto_getters = 64001; + optional bool goproto_stringer = 64003; + optional bool verbose_equal = 64004; + optional bool face = 64005; + optional bool gostring = 64006; + optional bool populate = 64007; + optional bool stringer = 67008; + optional bool onlyone = 64009; + + optional bool equal = 64013; + optional bool description = 64014; + optional bool testgen = 64015; + optional bool benchgen = 64016; + optional bool marshaler = 64017; + optional bool unmarshaler = 64018; + optional bool stable_marshaler = 64019; + + optional bool sizer = 64020; + + optional bool unsafe_marshaler = 64023; + optional bool unsafe_unmarshaler = 64024; + + optional bool goproto_extensions_map = 64025; + optional bool goproto_unrecognized = 64026; + + optional bool protosizer = 64028; + optional bool compare = 64029; + + optional bool typedecl = 64030; + + optional bool messagename = 64033; + + optional bool goproto_sizecache = 64034; + optional bool goproto_unkeyed = 64035; +} + +extend google.protobuf.FieldOptions { + optional bool nullable = 65001; + optional bool embed = 65002; + optional string customtype = 65003; + optional string customname = 65004; + optional string jsontag = 65005; + optional string moretags = 65006; + optional string casttype = 65007; + optional string castkey = 65008; + optional string castvalue = 65009; + + optional bool stdtime = 65010; + optional bool stdduration = 65011; + optional bool wktpointer = 65012; + + optional string castrepeated = 65013; +} diff --git a/ampd/proto/third_party/google/api/annotations.proto b/ampd/proto/third_party/google/api/annotations.proto new file mode 100644 index 000000000..efdab3db6 --- /dev/null +++ b/ampd/proto/third_party/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright 2015 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/ampd/proto/third_party/google/api/http.proto b/ampd/proto/third_party/google/api/http.proto new file mode 100644 index 000000000..31d867a27 --- /dev/null +++ b/ampd/proto/third_party/google/api/http.proto @@ -0,0 +1,379 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They +// are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL +// query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP +// request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto new file mode 100644 index 000000000..34672fdeb --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/genesis.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +import "ibc/applications/transfer/v1/transfer.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the ibc-transfer genesis state +message GenesisState { + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + repeated DenomTrace denom_traces = 2 [ + (gogoproto.castrepeated) = "Traces", + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"denom_traces\"" + ]; + Params params = 3 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto new file mode 100644 index 000000000..52f2f2400 --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/query.proto @@ -0,0 +1,105 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/applications/transfer/v1/transfer.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +// Query provides defines the gRPC querier service. +service Query { + // DenomTraces queries all denomination traces. + rpc DenomTraces(QueryDenomTracesRequest) returns (QueryDenomTracesResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces"; + } + + // DenomTrace queries a denomination trace information. + rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; + } + + // Params queries all parameters of the ibc-transfer module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/params"; + } + + // DenomHash queries a denomination hash information. + rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace=**}"; + } + + // EscrowAddress returns the escrow address for a particular port and channel id. + rpc EscrowAddress(QueryEscrowAddressRequest) returns (QueryEscrowAddressResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/channels/{channel_id}/ports/{port_id}/escrow_address"; + } +} + +// QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC +// method +message QueryDenomTraceRequest { + // hash (in hex format) or denom (full denom with ibc prefix) of the denomination trace information. + string hash = 1; +} + +// QueryDenomTraceResponse is the response type for the Query/DenomTrace RPC +// method. +message QueryDenomTraceResponse { + // denom_trace returns the requested denomination trace information. + DenomTrace denom_trace = 1; +} + +// QueryConnectionsRequest is the request type for the Query/DenomTraces RPC +// method +message QueryDenomTracesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryConnectionsResponse is the response type for the Query/DenomTraces RPC +// method. +message QueryDenomTracesResponse { + // denom_traces returns all denominations trace information. + repeated DenomTrace denom_traces = 1 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +// QueryDenomHashRequest is the request type for the Query/DenomHash RPC +// method +message QueryDenomHashRequest { + // The denomination trace ([port_id]/[channel_id])+/[denom] + string trace = 1; +} + +// QueryDenomHashResponse is the response type for the Query/DenomHash RPC +// method. +message QueryDenomHashResponse { + // hash (in hex format) of the denomination trace information. + string hash = 1; +} + +// QueryEscrowAddressRequest is the request type for the EscrowAddress RPC method. +message QueryEscrowAddressRequest { + // unique port identifier + string port_id = 1; + // unique channel identifier + string channel_id = 2; +} + +// QueryEscrowAddressResponse is the response type of the EscrowAddress RPC method. +message QueryEscrowAddressResponse { + // the escrow account address + string escrow_address = 1; +} \ No newline at end of file diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto new file mode 100644 index 000000000..1f92e81a6 --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/transfer.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +import "gogoproto/gogo.proto"; + +// DenomTrace contains the base denomination for ICS20 fungible tokens and the +// source tracing information path. +message DenomTrace { + // path defines the chain of port/channel identifiers used for tracing the + // source of the fungible token. + string path = 1; + // base denomination of the relayed fungible token. + string base_denom = 2; +} + +// Params defines the set of IBC transfer parameters. +// NOTE: To prevent a single token from being transferred, set the +// TransfersEnabled parameter to true and then set the bank module's SendEnabled +// parameter for the denomination to false. +message Params { + // send_enabled enables or disables all cross-chain token transfers from this + // chain. + bool send_enabled = 1 [(gogoproto.moretags) = "yaml:\"send_enabled\""]; + // receive_enabled enables or disables all cross-chain token transfers to this + // chain. + bool receive_enabled = 2 [(gogoproto.moretags) = "yaml:\"receive_enabled\""]; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto b/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto new file mode 100644 index 000000000..44e068d69 --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v1/tx.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "ibc/core/client/v1/client.proto"; + +// Msg defines the ibc/transfer Msg service. +service Msg { + // Transfer defines a rpc handler method for MsgTransfer. + rpc Transfer(MsgTransfer) returns (MsgTransferResponse); +} + +// MsgTransfer defines a msg to transfer fungible tokens (i.e Coins) between +// ICS20 enabled chains. See ICS Spec here: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message MsgTransfer { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // the port on which the packet will be sent + string source_port = 1 [(gogoproto.moretags) = "yaml:\"source_port\""]; + // the channel by which the packet will be sent + string source_channel = 2 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + // the tokens to be transferred + cosmos.base.v1beta1.Coin token = 3 [(gogoproto.nullable) = false]; + // the sender address + string sender = 4; + // the recipient address on the destination chain + string receiver = 5; + // Timeout height relative to the current block height. + // The timeout is disabled when set to 0. + ibc.core.client.v1.Height timeout_height = 6 + [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + // Timeout timestamp in absolute nanoseconds since unix epoch. + // The timeout is disabled when set to 0. + uint64 timeout_timestamp = 7 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; + // optional memo + string memo = 8; +} + +// MsgTransferResponse defines the Msg/Transfer response type. +message MsgTransferResponse { + // sequence number of the transfer packet sent + uint64 sequence = 1; +} diff --git a/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto b/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto new file mode 100644 index 000000000..129815ebc --- /dev/null +++ b/ampd/proto/third_party/ibc/applications/transfer/v2/packet.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v2; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"; + +// FungibleTokenPacketData defines a struct for the packet payload +// See FungibleTokenPacketData spec: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message FungibleTokenPacketData { + // the token denomination to be transferred + string denom = 1; + // the token amount to be transferred + string amount = 2; + // the sender address + string sender = 3; + // the recipient address on the destination chain + string receiver = 4; + // optional memo + string memo = 5; +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/channel.proto b/ampd/proto/third_party/ibc/core/channel/v1/channel.proto new file mode 100644 index 000000000..646884d57 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/channel.proto @@ -0,0 +1,162 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +// Channel defines pipeline for exactly-once packet delivery between specific +// modules on separate blockchains, which has at least one end capable of +// sending packets and one end capable of receiving packets. +message Channel { + option (gogoproto.goproto_getters) = false; + + // current state of the channel end + State state = 1; + // whether the channel is ordered or unordered + Order ordering = 2; + // counterparty channel end + Counterparty counterparty = 3 [(gogoproto.nullable) = false]; + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; + // opaque channel version, which is agreed upon during the handshake + string version = 5; +} + +// IdentifiedChannel defines a channel with additional port and channel +// identifier fields. +message IdentifiedChannel { + option (gogoproto.goproto_getters) = false; + + // current state of the channel end + State state = 1; + // whether the channel is ordered or unordered + Order ordering = 2; + // counterparty channel end + Counterparty counterparty = 3 [(gogoproto.nullable) = false]; + // list of connection identifiers, in order, along which packets sent on + // this channel will travel + repeated string connection_hops = 4 [(gogoproto.moretags) = "yaml:\"connection_hops\""]; + // opaque channel version, which is agreed upon during the handshake + string version = 5; + // port identifier + string port_id = 6; + // channel identifier + string channel_id = 7; +} + +// State defines if a channel is in one of the following states: +// CLOSED, INIT, TRYOPEN, OPEN or UNINITIALIZED. +enum State { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; + // A channel has just started the opening handshake. + STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; + // A channel has acknowledged the handshake step on the counterparty chain. + STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; + // A channel has completed the handshake. Open channels are + // ready to send and receive packets. + STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; + // A channel has been closed and can no longer be used to send or receive + // packets. + STATE_CLOSED = 4 [(gogoproto.enumvalue_customname) = "CLOSED"]; +} + +// Order defines if a channel is ORDERED or UNORDERED +enum Order { + option (gogoproto.goproto_enum_prefix) = false; + + // zero-value for channel ordering + ORDER_NONE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "NONE"]; + // packets can be delivered in any order, which may differ from the order in + // which they were sent. + ORDER_UNORDERED = 1 [(gogoproto.enumvalue_customname) = "UNORDERED"]; + // packets are delivered exactly in the order which they were sent + ORDER_ORDERED = 2 [(gogoproto.enumvalue_customname) = "ORDERED"]; +} + +// Counterparty defines a channel end counterparty +message Counterparty { + option (gogoproto.goproto_getters) = false; + + // port on the counterparty chain which owns the other end of the channel. + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // channel end on the counterparty chain + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; +} + +// Packet defines a type that carries data across different chains through IBC +message Packet { + option (gogoproto.goproto_getters) = false; + + // number corresponds to the order of sends and receives, where a Packet + // with an earlier sequence number must be sent and received before a Packet + // with a later sequence number. + uint64 sequence = 1; + // identifies the port on the sending chain. + string source_port = 2 [(gogoproto.moretags) = "yaml:\"source_port\""]; + // identifies the channel end on the sending chain. + string source_channel = 3 [(gogoproto.moretags) = "yaml:\"source_channel\""]; + // identifies the port on the receiving chain. + string destination_port = 4 [(gogoproto.moretags) = "yaml:\"destination_port\""]; + // identifies the channel end on the receiving chain. + string destination_channel = 5 [(gogoproto.moretags) = "yaml:\"destination_channel\""]; + // actual opaque bytes transferred directly to the application module + bytes data = 6; + // block height after which the packet times out + ibc.core.client.v1.Height timeout_height = 7 + [(gogoproto.moretags) = "yaml:\"timeout_height\"", (gogoproto.nullable) = false]; + // block timestamp (in nanoseconds) after which the packet times out + uint64 timeout_timestamp = 8 [(gogoproto.moretags) = "yaml:\"timeout_timestamp\""]; +} + +// PacketState defines the generic type necessary to retrieve and store +// packet commitments, acknowledgements, and receipts. +// Caller is responsible for knowing the context necessary to interpret this +// state as a commitment, acknowledgement, or a receipt. +message PacketState { + option (gogoproto.goproto_getters) = false; + + // channel port identifier. + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // channel unique identifier. + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + // packet sequence. + uint64 sequence = 3; + // embedded data that represents packet state. + bytes data = 4; +} + +// PacketId is an identifer for a unique Packet +// Source chains refer to packets by source port/channel +// Destination chains refer to packets by destination port/channel +message PacketId { + option (gogoproto.goproto_getters) = false; + + // channel port identifier + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // channel unique identifier + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + // packet sequence + uint64 sequence = 3; +} + +// Acknowledgement is the recommended acknowledgement format to be used by +// app-specific protocols. +// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental +// conflicts with other protobuf message formats used for acknowledgements. +// The first byte of any message with this format will be the non-ASCII values +// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: +// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope +message Acknowledgement { + // response contains either a result or an error and must be non-empty + oneof response { + bytes result = 21; + string error = 22; + } +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto b/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto new file mode 100644 index 000000000..1c0ff6ee8 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/genesis.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// GenesisState defines the ibc channel submodule's genesis state. +message GenesisState { + repeated IdentifiedChannel channels = 1 [(gogoproto.casttype) = "IdentifiedChannel", (gogoproto.nullable) = false]; + repeated PacketState acknowledgements = 2 [(gogoproto.nullable) = false]; + repeated PacketState commitments = 3 [(gogoproto.nullable) = false]; + repeated PacketState receipts = 4 [(gogoproto.nullable) = false]; + repeated PacketSequence send_sequences = 5 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"send_sequences\""]; + repeated PacketSequence recv_sequences = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; + repeated PacketSequence ack_sequences = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; + // the sequence for the next generated channel identifier + uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; +} + +// PacketSequence defines the genesis type necessary to retrieve and store +// next send and receive sequences. +message PacketSequence { + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + uint64 sequence = 3; +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/query.proto b/ampd/proto/third_party/ibc/core/channel/v1/query.proto new file mode 100644 index 000000000..986633173 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/query.proto @@ -0,0 +1,376 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "ibc/core/client/v1/client.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; +import "gogoproto/gogo.proto"; + +// Query provides defines the gRPC querier service +service Query { + // Channel queries an IBC Channel. + rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}"; + } + + // Channels queries all the IBC channels of a chain. + rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels"; + } + + // ConnectionChannels queries all the channels associated with a connection + // end. + rpc ConnectionChannels(QueryConnectionChannelsRequest) returns (QueryConnectionChannelsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/connections/{connection}/channels"; + } + + // ChannelClientState queries for the client state for the channel associated + // with the provided channel identifiers. + rpc ChannelClientState(QueryChannelClientStateRequest) returns (QueryChannelClientStateResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/client_state"; + } + + // ChannelConsensusState queries for the consensus state for the channel + // associated with the provided channel identifiers. + rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/consensus_state/revision/" + "{revision_number}/height/{revision_height}"; + } + + // PacketCommitment queries a stored packet commitment hash. + rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" + "packet_commitments/{sequence}"; + } + + // PacketCommitments returns all the packet commitments hashes associated + // with a channel. + rpc PacketCommitments(QueryPacketCommitmentsRequest) returns (QueryPacketCommitmentsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_commitments"; + } + + // PacketReceipt queries if a given packet sequence has been received on the + // queried chain + rpc PacketReceipt(QueryPacketReceiptRequest) returns (QueryPacketReceiptResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_receipts/{sequence}"; + } + + // PacketAcknowledgement queries a stored packet acknowledgement hash. + rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest) returns (QueryPacketAcknowledgementResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_acks/{sequence}"; + } + + // PacketAcknowledgements returns all the packet acknowledgements associated + // with a channel. + rpc PacketAcknowledgements(QueryPacketAcknowledgementsRequest) returns (QueryPacketAcknowledgementsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_acknowledgements"; + } + + // UnreceivedPackets returns all the unreceived IBC packets associated with a + // channel and sequences. + rpc UnreceivedPackets(QueryUnreceivedPacketsRequest) returns (QueryUnreceivedPacketsResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/" + "packet_commitments/" + "{packet_commitment_sequences}/unreceived_packets"; + } + + // UnreceivedAcks returns all the unreceived IBC acknowledgements associated + // with a channel and sequences. + rpc UnreceivedAcks(QueryUnreceivedAcksRequest) returns (QueryUnreceivedAcksResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/packet_commitments/" + "{packet_ack_sequences}/unreceived_acks"; + } + + // NextSequenceReceive returns the next receive sequence for a given channel. + rpc NextSequenceReceive(QueryNextSequenceReceiveRequest) returns (QueryNextSequenceReceiveResponse) { + option (google.api.http).get = "/ibc/core/channel/v1/channels/{channel_id}/" + "ports/{port_id}/next_sequence"; + } +} + +// QueryChannelRequest is the request type for the Query/Channel RPC method +message QueryChannelRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryChannelResponse is the response type for the Query/Channel RPC method. +// Besides the Channel end, it includes a proof and the height from which the +// proof was retrieved. +message QueryChannelResponse { + // channel associated with the request identifiers + ibc.core.channel.v1.Channel channel = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelsRequest is the request type for the Query/Channels RPC method +message QueryChannelsRequest { + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryChannelsResponse is the response type for the Query/Channels RPC method. +message QueryChannelsResponse { + // list of stored channels of the chain. + repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionChannelsRequest is the request type for the +// Query/QueryConnectionChannels RPC method +message QueryConnectionChannelsRequest { + // connection unique identifier + string connection = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConnectionChannelsResponse is the Response type for the +// Query/QueryConnectionChannels RPC method +message QueryConnectionChannelsResponse { + // list of channels associated with a connection. + repeated ibc.core.channel.v1.IdentifiedChannel channels = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelClientStateRequest is the request type for the Query/ClientState +// RPC method +message QueryChannelClientStateRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QueryChannelClientStateResponse is the Response type for the +// Query/QueryChannelClientState RPC method +message QueryChannelClientStateResponse { + // client state associated with the channel + ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryChannelConsensusStateRequest is the request type for the +// Query/ConsensusState RPC method +message QueryChannelConsensusStateRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // revision number of the consensus state + uint64 revision_number = 3; + // revision height of the consensus state + uint64 revision_height = 4; +} + +// QueryChannelClientStateResponse is the Response type for the +// Query/QueryChannelClientState RPC method +message QueryChannelConsensusStateResponse { + // consensus state associated with the channel + google.protobuf.Any consensus_state = 1; + // client ID associated with the consensus state + string client_id = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryPacketCommitmentRequest is the request type for the +// Query/PacketCommitment RPC method +message QueryPacketCommitmentRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketCommitmentResponse defines the client query response for a packet +// which also includes a proof and the height from which the proof was +// retrieved +message QueryPacketCommitmentResponse { + // packet associated with the request fields + bytes commitment = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketCommitmentsRequest is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketCommitmentsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 3; +} + +// QueryPacketCommitmentsResponse is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketCommitmentsResponse { + repeated ibc.core.channel.v1.PacketState commitments = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketReceiptRequest is the request type for the +// Query/PacketReceipt RPC method +message QueryPacketReceiptRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketReceiptResponse defines the client query response for a packet +// receipt which also includes a proof, and the height from which the proof was +// retrieved +message QueryPacketReceiptResponse { + // success flag for if receipt exists + bool received = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} + +// QueryPacketAcknowledgementRequest is the request type for the +// Query/PacketAcknowledgement RPC method +message QueryPacketAcknowledgementRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // packet sequence + uint64 sequence = 3; +} + +// QueryPacketAcknowledgementResponse defines the client query response for a +// packet which also includes a proof and the height from which the +// proof was retrieved +message QueryPacketAcknowledgementResponse { + // packet associated with the request fields + bytes acknowledgement = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryPacketAcknowledgementsRequest is the request type for the +// Query/QueryPacketCommitments RPC method +message QueryPacketAcknowledgementsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 3; + // list of packet sequences + repeated uint64 packet_commitment_sequences = 4; +} + +// QueryPacketAcknowledgemetsResponse is the request type for the +// Query/QueryPacketAcknowledgements RPC method +message QueryPacketAcknowledgementsResponse { + repeated ibc.core.channel.v1.PacketState acknowledgements = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryUnreceivedPacketsRequest is the request type for the +// Query/UnreceivedPackets RPC method +message QueryUnreceivedPacketsRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // list of packet sequences + repeated uint64 packet_commitment_sequences = 3; +} + +// QueryUnreceivedPacketsResponse is the response type for the +// Query/UnreceivedPacketCommitments RPC method +message QueryUnreceivedPacketsResponse { + // list of unreceived packet sequences + repeated uint64 sequences = 1; + // query block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} + +// QueryUnreceivedAcks is the request type for the +// Query/UnreceivedAcks RPC method +message QueryUnreceivedAcksRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; + // list of acknowledgement sequences + repeated uint64 packet_ack_sequences = 3; +} + +// QueryUnreceivedAcksResponse is the response type for the +// Query/UnreceivedAcks RPC method +message QueryUnreceivedAcksResponse { + // list of unreceived acknowledgement sequences + repeated uint64 sequences = 1; + // query block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} + +// QueryNextSequenceReceiveRequest is the request type for the +// Query/QueryNextSequenceReceiveRequest RPC method +message QueryNextSequenceReceiveRequest { + // port unique identifier + string port_id = 1; + // channel unique identifier + string channel_id = 2; +} + +// QuerySequenceResponse is the request type for the +// Query/QueryNextSequenceReceiveResponse RPC method +message QueryNextSequenceReceiveResponse { + // next sequence receive number + uint64 next_sequence_receive = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/core/channel/v1/tx.proto b/ampd/proto/third_party/ibc/core/channel/v1/tx.proto new file mode 100644 index 000000000..75248aeb5 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/channel/v1/tx.proto @@ -0,0 +1,245 @@ +syntax = "proto3"; + +package ibc.core.channel.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/channel/v1/channel.proto"; + +// Msg defines the ibc/channel Msg service. +service Msg { + // ChannelOpenInit defines a rpc handler method for MsgChannelOpenInit. + rpc ChannelOpenInit(MsgChannelOpenInit) returns (MsgChannelOpenInitResponse); + + // ChannelOpenTry defines a rpc handler method for MsgChannelOpenTry. + rpc ChannelOpenTry(MsgChannelOpenTry) returns (MsgChannelOpenTryResponse); + + // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck. + rpc ChannelOpenAck(MsgChannelOpenAck) returns (MsgChannelOpenAckResponse); + + // ChannelOpenConfirm defines a rpc handler method for MsgChannelOpenConfirm. + rpc ChannelOpenConfirm(MsgChannelOpenConfirm) returns (MsgChannelOpenConfirmResponse); + + // ChannelCloseInit defines a rpc handler method for MsgChannelCloseInit. + rpc ChannelCloseInit(MsgChannelCloseInit) returns (MsgChannelCloseInitResponse); + + // ChannelCloseConfirm defines a rpc handler method for + // MsgChannelCloseConfirm. + rpc ChannelCloseConfirm(MsgChannelCloseConfirm) returns (MsgChannelCloseConfirmResponse); + + // RecvPacket defines a rpc handler method for MsgRecvPacket. + rpc RecvPacket(MsgRecvPacket) returns (MsgRecvPacketResponse); + + // Timeout defines a rpc handler method for MsgTimeout. + rpc Timeout(MsgTimeout) returns (MsgTimeoutResponse); + + // TimeoutOnClose defines a rpc handler method for MsgTimeoutOnClose. + rpc TimeoutOnClose(MsgTimeoutOnClose) returns (MsgTimeoutOnCloseResponse); + + // Acknowledgement defines a rpc handler method for MsgAcknowledgement. + rpc Acknowledgement(MsgAcknowledgement) returns (MsgAcknowledgementResponse); +} + +// ResponseResultType defines the possible outcomes of the execution of a message +enum ResponseResultType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default zero value enumeration + RESPONSE_RESULT_TYPE_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // The message did not call the IBC application callbacks (because, for example, the packet had already been relayed) + RESPONSE_RESULT_TYPE_NOOP = 1 [(gogoproto.enumvalue_customname) = "NOOP"]; + // The message was executed successfully + RESPONSE_RESULT_TYPE_SUCCESS = 2 [(gogoproto.enumvalue_customname) = "SUCCESS"]; +} + +// MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It +// is called by a relayer on Chain A. +message MsgChannelOpenInit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + Channel channel = 2 [(gogoproto.nullable) = false]; + string signer = 3; +} + +// MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. +message MsgChannelOpenInitResponse { + string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string version = 2; +} + +// MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel +// on Chain B. The version field within the Channel field has been deprecated. Its +// value will be ignored by core IBC. +message MsgChannelOpenTry { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // Deprecated: this field is unused. Crossing hello's are no longer supported in core IBC. + string previous_channel_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_channel_id\""]; + // NOTE: the version field within the channel has been deprecated. Its value will be ignored by core IBC. + Channel channel = 3 [(gogoproto.nullable) = false]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 6 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. +message MsgChannelOpenTryResponse { + string version = 1; +} + +// MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge +// the change of channel state to TRYOPEN on Chain B. +message MsgChannelOpenAck { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string counterparty_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_channel_id\""]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_try = 5 [(gogoproto.moretags) = "yaml:\"proof_try\""]; + ibc.core.client.v1.Height proof_height = 6 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 7; +} + +// MsgChannelOpenAckResponse defines the Msg/ChannelOpenAck response type. +message MsgChannelOpenAckResponse {} + +// MsgChannelOpenConfirm defines a msg sent by a Relayer to Chain B to +// acknowledge the change of channel state to OPEN on Chain A. +message MsgChannelOpenConfirm { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + bytes proof_ack = 3 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgChannelOpenConfirmResponse defines the Msg/ChannelOpenConfirm response +// type. +message MsgChannelOpenConfirmResponse {} + +// MsgChannelCloseInit defines a msg sent by a Relayer to Chain A +// to close a channel with Chain B. +message MsgChannelCloseInit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + string signer = 3; +} + +// MsgChannelCloseInitResponse defines the Msg/ChannelCloseInit response type. +message MsgChannelCloseInitResponse {} + +// MsgChannelCloseConfirm defines a msg sent by a Relayer to Chain B +// to acknowledge the change of channel state to CLOSED on Chain A. +message MsgChannelCloseConfirm { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; + bytes proof_init = 3 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgChannelCloseConfirmResponse defines the Msg/ChannelCloseConfirm response +// type. +message MsgChannelCloseConfirmResponse {} + +// MsgRecvPacket receives incoming IBC packet +message MsgRecvPacket { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; + ibc.core.client.v1.Height proof_height = 3 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgRecvPacketResponse defines the Msg/RecvPacket response type. +message MsgRecvPacketResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgTimeout receives timed-out packet +message MsgTimeout { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + ibc.core.client.v1.Height proof_height = 3 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; + string signer = 5; +} + +// MsgTimeoutResponse defines the Msg/Timeout response type. +message MsgTimeoutResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgTimeoutOnClose timed-out packet upon counterparty channel closure. +message MsgTimeoutOnClose { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; + string signer = 6; +} + +// MsgTimeoutOnCloseResponse defines the Msg/TimeoutOnClose response type. +message MsgTimeoutOnCloseResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} + +// MsgAcknowledgement receives incoming IBC acknowledgement +message MsgAcknowledgement { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes acknowledgement = 2; + bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; + ibc.core.client.v1.Height proof_height = 4 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 5; +} + +// MsgAcknowledgementResponse defines the Msg/Acknowledgement response type. +message MsgAcknowledgementResponse { + option (gogoproto.goproto_getters) = false; + + ResponseResultType result = 1; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/client.proto b/ampd/proto/third_party/ibc/core/client/v1/client.proto new file mode 100644 index 000000000..2ec41ed0c --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/client.proto @@ -0,0 +1,103 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "cosmos/upgrade/v1beta1/upgrade.proto"; +import "cosmos_proto/cosmos.proto"; + +// IdentifiedClientState defines a client state with an additional client +// identifier field. +message IdentifiedClientState { + // client identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // client state + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; +} + +// ConsensusStateWithHeight defines a consensus state with an additional height +// field. +message ConsensusStateWithHeight { + // consensus state height + Height height = 1 [(gogoproto.nullable) = false]; + // consensus state + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ClientConsensusStates defines all the stored consensus states for a given +// client. +message ClientConsensusStates { + // client identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // consensus states and their heights associated with the client + repeated ConsensusStateWithHeight consensus_states = 2 + [(gogoproto.moretags) = "yaml:\"consensus_states\"", (gogoproto.nullable) = false]; +} + +// ClientUpdateProposal is a governance proposal. If it passes, the substitute +// client's latest consensus state is copied over to the subject client. The proposal +// handler may fail if the subject and the substitute do not match in client and +// chain parameters (with exception to latest height, frozen height, and chain-id). +message ClientUpdateProposal { + option (gogoproto.goproto_getters) = false; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // the title of the update proposal + string title = 1; + // the description of the proposal + string description = 2; + // the client identifier for the client to be updated if the proposal passes + string subject_client_id = 3 [(gogoproto.moretags) = "yaml:\"subject_client_id\""]; + // the substitute client identifier for the client standing in for the subject + // client + string substitute_client_id = 4 [(gogoproto.moretags) = "yaml:\"substitute_client_id\""]; +} + +// UpgradeProposal is a gov Content type for initiating an IBC breaking +// upgrade. +message UpgradeProposal { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + option (gogoproto.equal) = true; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + + string title = 1; + string description = 2; + cosmos.upgrade.v1beta1.Plan plan = 3 [(gogoproto.nullable) = false]; + + // An UpgradedClientState must be provided to perform an IBC breaking upgrade. + // This will make the chain commit to the correct upgraded (self) client state + // before the upgrade occurs, so that connecting chains can verify that the + // new upgraded client is valid by verifying a proof on the previous version + // of the chain. This will allow IBC connections to persist smoothly across + // planned chain upgrades + google.protobuf.Any upgraded_client_state = 4 [(gogoproto.moretags) = "yaml:\"upgraded_client_state\""]; +} + +// Height is a monotonically increasing data type +// that can be compared against another Height for the purposes of updating and +// freezing clients +// +// Normally the RevisionHeight is incremented at each height while keeping +// RevisionNumber the same. However some consensus algorithms may choose to +// reset the height in certain conditions e.g. hard forks, state-machine +// breaking changes In these cases, the RevisionNumber is incremented so that +// height continues to be monitonically increasing even as the RevisionHeight +// gets reset +message Height { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + // the revision that the client is currently on + uint64 revision_number = 1 [(gogoproto.moretags) = "yaml:\"revision_number\""]; + // the height within the given revision + uint64 revision_height = 2 [(gogoproto.moretags) = "yaml:\"revision_height\""]; +} + +// Params defines the set of IBC light client parameters. +message Params { + // allowed_clients defines the list of allowed client state types. + repeated string allowed_clients = 1 [(gogoproto.moretags) = "yaml:\"allowed_clients\""]; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/genesis.proto b/ampd/proto/third_party/ibc/core/client/v1/genesis.proto new file mode 100644 index 000000000..b2930c484 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/genesis.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "ibc/core/client/v1/client.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the ibc client submodule's genesis state. +message GenesisState { + // client states with their corresponding identifiers + repeated IdentifiedClientState clients = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; + // consensus states from each client + repeated ClientConsensusStates clients_consensus = 2 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "ClientsConsensusStates", + (gogoproto.moretags) = "yaml:\"clients_consensus\"" + ]; + // metadata from each client + repeated IdentifiedGenesisMetadata clients_metadata = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"clients_metadata\""]; + Params params = 4 [(gogoproto.nullable) = false]; + // create localhost on initialization + bool create_localhost = 5 [(gogoproto.moretags) = "yaml:\"create_localhost\""]; + // the sequence for the next generated client identifier + uint64 next_client_sequence = 6 [(gogoproto.moretags) = "yaml:\"next_client_sequence\""]; +} + +// GenesisMetadata defines the genesis type for metadata that clients may return +// with ExportMetadata +message GenesisMetadata { + option (gogoproto.goproto_getters) = false; + + // store key of metadata without clientID-prefix + bytes key = 1; + // metadata value + bytes value = 2; +} + +// IdentifiedGenesisMetadata has the client metadata with the corresponding +// client id. +message IdentifiedGenesisMetadata { + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + repeated GenesisMetadata client_metadata = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_metadata\""]; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/query.proto b/ampd/proto/third_party/ibc/core/client/v1/query.proto new file mode 100644 index 000000000..2c9618bc8 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/query.proto @@ -0,0 +1,207 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/client/v1/client.proto"; +import "google/protobuf/any.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; + +// Query provides defines the gRPC querier service +service Query { + // ClientState queries an IBC light client. + rpc ClientState(QueryClientStateRequest) returns (QueryClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_states/{client_id}"; + } + + // ClientStates queries all the IBC light clients of a chain. + rpc ClientStates(QueryClientStatesRequest) returns (QueryClientStatesResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_states"; + } + + // ConsensusState queries a consensus state associated with a client state at + // a given height. + rpc ConsensusState(QueryConsensusStateRequest) returns (QueryConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/" + "{client_id}/revision/{revision_number}/" + "height/{revision_height}"; + } + + // ConsensusStates queries all the consensus state associated with a given + // client. + rpc ConsensusStates(QueryConsensusStatesRequest) returns (QueryConsensusStatesResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}"; + } + + // ConsensusStateHeights queries the height of every consensus states associated with a given client. + rpc ConsensusStateHeights(QueryConsensusStateHeightsRequest) returns (QueryConsensusStateHeightsResponse) { + option (google.api.http).get = "/ibc/core/client/v1/consensus_states/{client_id}/heights"; + } + + // Status queries the status of an IBC client. + rpc ClientStatus(QueryClientStatusRequest) returns (QueryClientStatusResponse) { + option (google.api.http).get = "/ibc/core/client/v1/client_status/{client_id}"; + } + + // ClientParams queries all parameters of the ibc client. + rpc ClientParams(QueryClientParamsRequest) returns (QueryClientParamsResponse) { + option (google.api.http).get = "/ibc/client/v1/params"; + } + + // UpgradedClientState queries an Upgraded IBC light client. + rpc UpgradedClientState(QueryUpgradedClientStateRequest) returns (QueryUpgradedClientStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_client_states"; + } + + // UpgradedConsensusState queries an Upgraded IBC consensus state. + rpc UpgradedConsensusState(QueryUpgradedConsensusStateRequest) returns (QueryUpgradedConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/client/v1/upgraded_consensus_states"; + } +} + +// QueryClientStateRequest is the request type for the Query/ClientState RPC +// method +message QueryClientStateRequest { + // client state unique identifier + string client_id = 1; +} + +// QueryClientStateResponse is the response type for the Query/ClientState RPC +// method. Besides the client state, it includes a proof and the height from +// which the proof was retrieved. +message QueryClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryClientStatesRequest is the request type for the Query/ClientStates RPC +// method +message QueryClientStatesRequest { + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryClientStatesResponse is the response type for the Query/ClientStates RPC +// method. +message QueryClientStatesResponse { + // list of stored ClientStates of the chain. + repeated IdentifiedClientState client_states = 1 + [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "IdentifiedClientStates"]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryConsensusStateRequest is the request type for the Query/ConsensusState +// RPC method. Besides the consensus state, it includes a proof and the height +// from which the proof was retrieved. +message QueryConsensusStateRequest { + // client identifier + string client_id = 1; + // consensus state revision number + uint64 revision_number = 2; + // consensus state revision height + uint64 revision_height = 3; + // latest_height overrrides the height field and queries the latest stored + // ConsensusState + bool latest_height = 4; +} + +// QueryConsensusStateResponse is the response type for the Query/ConsensusState +// RPC method +message QueryConsensusStateResponse { + // consensus state associated with the client identifier at the given height + google.protobuf.Any consensus_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConsensusStatesRequest is the request type for the Query/ConsensusStates +// RPC method. +message QueryConsensusStatesRequest { + // client identifier + string client_id = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConsensusStatesResponse is the response type for the +// Query/ConsensusStates RPC method +message QueryConsensusStatesResponse { + // consensus states associated with the identifier + repeated ConsensusStateWithHeight consensus_states = 1 [(gogoproto.nullable) = false]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryConsensusStateHeightsRequest is the request type for Query/ConsensusStateHeights +// RPC method. +message QueryConsensusStateHeightsRequest { + // client identifier + string client_id = 1; + // pagination request + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryConsensusStateHeightsResponse is the response type for the +// Query/ConsensusStateHeights RPC method +message QueryConsensusStateHeightsResponse { + // consensus state heights + repeated Height consensus_state_heights = 1 [(gogoproto.nullable) = false]; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryClientStatusRequest is the request type for the Query/ClientStatus RPC +// method +message QueryClientStatusRequest { + // client unique identifier + string client_id = 1; +} + +// QueryClientStatusResponse is the response type for the Query/ClientStatus RPC +// method. It returns the current status of the IBC client. +message QueryClientStatusResponse { + string status = 1; +} + +// QueryClientParamsRequest is the request type for the Query/ClientParams RPC +// method. +message QueryClientParamsRequest {} + +// QueryClientParamsResponse is the response type for the Query/ClientParams RPC +// method. +message QueryClientParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +// QueryUpgradedClientStateRequest is the request type for the +// Query/UpgradedClientState RPC method +message QueryUpgradedClientStateRequest {} + +// QueryUpgradedClientStateResponse is the response type for the +// Query/UpgradedClientState RPC method. +message QueryUpgradedClientStateResponse { + // client state associated with the request identifier + google.protobuf.Any upgraded_client_state = 1; +} + +// QueryUpgradedConsensusStateRequest is the request type for the +// Query/UpgradedConsensusState RPC method +message QueryUpgradedConsensusStateRequest {} + +// QueryUpgradedConsensusStateResponse is the response type for the +// Query/UpgradedConsensusState RPC method. +message QueryUpgradedConsensusStateResponse { + // Consensus state associated with the request identifier + google.protobuf.Any upgraded_consensus_state = 1; +} diff --git a/ampd/proto/third_party/ibc/core/client/v1/tx.proto b/ampd/proto/third_party/ibc/core/client/v1/tx.proto new file mode 100644 index 000000000..11dfdadea --- /dev/null +++ b/ampd/proto/third_party/ibc/core/client/v1/tx.proto @@ -0,0 +1,99 @@ +syntax = "proto3"; + +package ibc.core.client.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// Msg defines the ibc/client Msg service. +service Msg { + // CreateClient defines a rpc handler method for MsgCreateClient. + rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse); + + // UpdateClient defines a rpc handler method for MsgUpdateClient. + rpc UpdateClient(MsgUpdateClient) returns (MsgUpdateClientResponse); + + // UpgradeClient defines a rpc handler method for MsgUpgradeClient. + rpc UpgradeClient(MsgUpgradeClient) returns (MsgUpgradeClientResponse); + + // SubmitMisbehaviour defines a rpc handler method for MsgSubmitMisbehaviour. + rpc SubmitMisbehaviour(MsgSubmitMisbehaviour) returns (MsgSubmitMisbehaviourResponse); +} + +// MsgCreateClient defines a message to create an IBC client +message MsgCreateClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // light client state + google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""]; + // consensus state associated with the client that corresponds to a given + // height. + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // signer address + string signer = 3; +} + +// MsgCreateClientResponse defines the Msg/CreateClient response type. +message MsgCreateClientResponse {} + +// MsgUpdateClient defines an sdk.Msg to update a IBC client state using +// the given header. +message MsgUpdateClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // header to update the light client + google.protobuf.Any header = 2; + // signer address + string signer = 3; +} + +// MsgUpdateClientResponse defines the Msg/UpdateClient response type. +message MsgUpdateClientResponse {} + +// MsgUpgradeClient defines an sdk.Msg to upgrade an IBC client to a new client +// state +message MsgUpgradeClient { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // upgraded client state + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; + // upgraded consensus state, only contains enough information to serve as a + // basis of trust in update logic + google.protobuf.Any consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // proof that old chain committed to new client + bytes proof_upgrade_client = 4 [(gogoproto.moretags) = "yaml:\"proof_upgrade_client\""]; + // proof that old chain committed to new consensus state + bytes proof_upgrade_consensus_state = 5 [(gogoproto.moretags) = "yaml:\"proof_upgrade_consensus_state\""]; + // signer address + string signer = 6; +} + +// MsgUpgradeClientResponse defines the Msg/UpgradeClient response type. +message MsgUpgradeClientResponse {} + +// MsgSubmitMisbehaviour defines an sdk.Msg type that submits Evidence for +// light client misbehaviour. +message MsgSubmitMisbehaviour { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // misbehaviour used for freezing the light client + google.protobuf.Any misbehaviour = 2; + // signer address + string signer = 3; +} + +// MsgSubmitMisbehaviourResponse defines the Msg/SubmitMisbehaviour response +// type. +message MsgSubmitMisbehaviourResponse {} diff --git a/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto b/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto new file mode 100644 index 000000000..b6a68a99f --- /dev/null +++ b/ampd/proto/third_party/ibc/core/commitment/v1/commitment.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; + +package ibc.core.commitment.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/23-commitment/types"; + +import "gogoproto/gogo.proto"; +import "proofs.proto"; + +// MerkleRoot defines a merkle root hash. +// In the Cosmos SDK, the AppHash of a block header becomes the root. +message MerkleRoot { + option (gogoproto.goproto_getters) = false; + + bytes hash = 1; +} + +// MerklePrefix is merkle path prefixed to the key. +// The constructed key from the Path and the key will be append(Path.KeyPath, +// append(Path.KeyPrefix, key...)) +message MerklePrefix { + bytes key_prefix = 1 [(gogoproto.moretags) = "yaml:\"key_prefix\""]; +} + +// MerklePath is the path used to verify commitment proofs, which can be an +// arbitrary structured object (defined by a commitment type). +// MerklePath is represented from root-to-leaf +message MerklePath { + option (gogoproto.goproto_stringer) = false; + + repeated string key_path = 1 [(gogoproto.moretags) = "yaml:\"key_path\""]; +} + +// MerkleProof is a wrapper type over a chain of CommitmentProofs. +// It demonstrates membership or non-membership for an element or set of +// elements, verifiable in conjunction with a known commitment root. Proofs +// should be succinct. +// MerkleProofs are ordered from leaf-to-root +message MerkleProof { + repeated ics23.CommitmentProof proofs = 1; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/connection.proto b/ampd/proto/third_party/ibc/core/connection/v1/connection.proto new file mode 100644 index 000000000..8360af988 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/connection.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/commitment/v1/commitment.proto"; + +// ICS03 - Connection Data Structures as defined in +// https://github.com/cosmos/ibc/blob/master/spec/core/ics-003-connection-semantics#data-structures + +// ConnectionEnd defines a stateful object on a chain connected to another +// separate one. +// NOTE: there must only be 2 defined ConnectionEnds to establish +// a connection between two chains. +message ConnectionEnd { + option (gogoproto.goproto_getters) = false; + // client associated with this connection. + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // IBC version which can be utilised to determine encodings or protocols for + // channels or packets utilising this connection. + repeated Version versions = 2; + // current state of the connection end. + State state = 3; + // counterparty chain associated with this connection. + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + // delay period that must pass before a consensus state can be used for + // packet-verification NOTE: delay period logic is only implemented by some + // clients. + uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; +} + +// IdentifiedConnection defines a connection with additional connection +// identifier field. +message IdentifiedConnection { + option (gogoproto.goproto_getters) = false; + // connection identifier. + string id = 1 [(gogoproto.moretags) = "yaml:\"id\""]; + // client associated with this connection. + string client_id = 2 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // IBC version which can be utilised to determine encodings or protocols for + // channels or packets utilising this connection + repeated Version versions = 3; + // current state of the connection end. + State state = 4; + // counterparty chain associated with this connection. + Counterparty counterparty = 5 [(gogoproto.nullable) = false]; + // delay period associated with this connection. + uint64 delay_period = 6 [(gogoproto.moretags) = "yaml:\"delay_period\""]; +} + +// State defines if a connection is in one of the following states: +// INIT, TRYOPEN, OPEN or UNINITIALIZED. +enum State { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + STATE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNINITIALIZED"]; + // A connection end has just started the opening handshake. + STATE_INIT = 1 [(gogoproto.enumvalue_customname) = "INIT"]; + // A connection end has acknowledged the handshake step on the counterparty + // chain. + STATE_TRYOPEN = 2 [(gogoproto.enumvalue_customname) = "TRYOPEN"]; + // A connection end has completed the handshake. + STATE_OPEN = 3 [(gogoproto.enumvalue_customname) = "OPEN"]; +} + +// Counterparty defines the counterparty chain associated with a connection end. +message Counterparty { + option (gogoproto.goproto_getters) = false; + + // identifies the client on the counterparty chain associated with a given + // connection. + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // identifies the connection end on the counterparty chain associated with a + // given connection. + string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + // commitment merkle prefix of the counterparty chain. + ibc.core.commitment.v1.MerklePrefix prefix = 3 [(gogoproto.nullable) = false]; +} + +// ClientPaths define all the connection paths for a client state. +message ClientPaths { + // list of connection paths + repeated string paths = 1; +} + +// ConnectionPaths define all the connection paths for a given client state. +message ConnectionPaths { + // client state unique identifier + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // list of connection paths + repeated string paths = 2; +} + +// Version defines the versioning scheme used to negotiate the IBC verison in +// the connection handshake. +message Version { + option (gogoproto.goproto_getters) = false; + + // unique version identifier + string identifier = 1; + // list of features compatible with the specified identifier + repeated string features = 2; +} + +// Params defines the set of Connection parameters. +message Params { + // maximum expected time per block (in nanoseconds), used to enforce block delay. This parameter should reflect the + // largest amount of time that the chain might reasonably take to produce the next block under normal operating + // conditions. A safe choice is 3-5x the expected time per block. + uint64 max_expected_time_per_block = 1 [(gogoproto.moretags) = "yaml:\"max_expected_time_per_block\""]; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto b/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto new file mode 100644 index 000000000..f616ae67e --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/genesis.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/connection/v1/connection.proto"; + +// GenesisState defines the ibc connection submodule's genesis state. +message GenesisState { + repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; + repeated ConnectionPaths client_connection_paths = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; + // the sequence for the next generated connection identifier + uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; + Params params = 4 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/query.proto b/ampd/proto/third_party/ibc/core/connection/v1/query.proto new file mode 100644 index 000000000..129f30a71 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/query.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/connection/v1/connection.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; + +// Query provides defines the gRPC querier service +service Query { + // Connection queries an IBC connection end. + rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}"; + } + + // Connections queries all the IBC connections of a chain. + rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections"; + } + + // ClientConnections queries the connection paths associated with a client + // state. + rpc ClientConnections(QueryClientConnectionsRequest) returns (QueryClientConnectionsResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/client_connections/{client_id}"; + } + + // ConnectionClientState queries the client state associated with the + // connection. + rpc ConnectionClientState(QueryConnectionClientStateRequest) returns (QueryConnectionClientStateResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/client_state"; + } + + // ConnectionConsensusState queries the consensus state associated with the + // connection. + rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest) returns (QueryConnectionConsensusStateResponse) { + option (google.api.http).get = "/ibc/core/connection/v1/connections/{connection_id}/consensus_state/" + "revision/{revision_number}/height/{revision_height}"; + } +} + +// QueryConnectionRequest is the request type for the Query/Connection RPC +// method +message QueryConnectionRequest { + // connection unique identifier + string connection_id = 1; +} + +// QueryConnectionResponse is the response type for the Query/Connection RPC +// method. Besides the connection end, it includes a proof and the height from +// which the proof was retrieved. +message QueryConnectionResponse { + // connection associated with the request identifier + ibc.core.connection.v1.ConnectionEnd connection = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionsRequest is the request type for the Query/Connections RPC +// method +message QueryConnectionsRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryConnectionsResponse is the response type for the Query/Connections RPC +// method. +message QueryConnectionsResponse { + // list of stored connections of the chain. + repeated ibc.core.connection.v1.IdentifiedConnection connections = 1; + // pagination response + cosmos.base.query.v1beta1.PageResponse pagination = 2; + // query block height + ibc.core.client.v1.Height height = 3 [(gogoproto.nullable) = false]; +} + +// QueryClientConnectionsRequest is the request type for the +// Query/ClientConnections RPC method +message QueryClientConnectionsRequest { + // client identifier associated with a connection + string client_id = 1; +} + +// QueryClientConnectionsResponse is the response type for the +// Query/ClientConnections RPC method +message QueryClientConnectionsResponse { + // slice of all the connection paths associated with a client. + repeated string connection_paths = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was generated + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionClientStateRequest is the request type for the +// Query/ConnectionClientState RPC method +message QueryConnectionClientStateRequest { + // connection identifier + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; +} + +// QueryConnectionClientStateResponse is the response type for the +// Query/ConnectionClientState RPC method +message QueryConnectionClientStateResponse { + // client state associated with the channel + ibc.core.client.v1.IdentifiedClientState identified_client_state = 1; + // merkle proof of existence + bytes proof = 2; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false]; +} + +// QueryConnectionConsensusStateRequest is the request type for the +// Query/ConnectionConsensusState RPC method +message QueryConnectionConsensusStateRequest { + // connection identifier + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + uint64 revision_number = 2; + uint64 revision_height = 3; +} + +// QueryConnectionConsensusStateResponse is the response type for the +// Query/ConnectionConsensusState RPC method +message QueryConnectionConsensusStateResponse { + // consensus state associated with the channel + google.protobuf.Any consensus_state = 1; + // client ID associated with the consensus state + string client_id = 2; + // merkle proof of existence + bytes proof = 3; + // height at which the proof was retrieved + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/core/connection/v1/tx.proto b/ampd/proto/third_party/ibc/core/connection/v1/tx.proto new file mode 100644 index 000000000..b2fea632c --- /dev/null +++ b/ampd/proto/third_party/ibc/core/connection/v1/tx.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; + +package ibc.core.connection.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/connection/v1/connection.proto"; + +// Msg defines the ibc/connection Msg service. +service Msg { + // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. + rpc ConnectionOpenInit(MsgConnectionOpenInit) returns (MsgConnectionOpenInitResponse); + + // ConnectionOpenTry defines a rpc handler method for MsgConnectionOpenTry. + rpc ConnectionOpenTry(MsgConnectionOpenTry) returns (MsgConnectionOpenTryResponse); + + // ConnectionOpenAck defines a rpc handler method for MsgConnectionOpenAck. + rpc ConnectionOpenAck(MsgConnectionOpenAck) returns (MsgConnectionOpenAckResponse); + + // ConnectionOpenConfirm defines a rpc handler method for + // MsgConnectionOpenConfirm. + rpc ConnectionOpenConfirm(MsgConnectionOpenConfirm) returns (MsgConnectionOpenConfirmResponse); +} + +// MsgConnectionOpenInit defines the msg sent by an account on Chain A to +// initialize a connection with Chain B. +message MsgConnectionOpenInit { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + Version version = 3; + uint64 delay_period = 4 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + string signer = 5; +} + +// MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response +// type. +message MsgConnectionOpenInitResponse {} + +// MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a +// connection on Chain B. +message MsgConnectionOpenTry { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. + string previous_connection_id = 2 [deprecated = true, (gogoproto.moretags) = "yaml:\"previous_connection_id\""]; + google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + uint64 delay_period = 5 [(gogoproto.moretags) = "yaml:\"delay_period\""]; + repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; + ibc.core.client.v1.Height proof_height = 7 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + // proof of the initialization the connection on Chain A: `UNITIALIZED -> + // INIT` + bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + // proof of client state included in message + bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + // proof of client consensus state + bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 11 + [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; + string signer = 12; +} + +// MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. +message MsgConnectionOpenTryResponse {} + +// MsgConnectionOpenAck defines a msg sent by a Relayer to Chain A to +// acknowledge the change of connection state to TRYOPEN on Chain B. +message MsgConnectionOpenAck { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + string counterparty_connection_id = 2 [(gogoproto.moretags) = "yaml:\"counterparty_connection_id\""]; + Version version = 3; + google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; + ibc.core.client.v1.Height proof_height = 5 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + // proof of the initialization the connection on Chain B: `UNITIALIZED -> + // TRYOPEN` + bytes proof_try = 6 [(gogoproto.moretags) = "yaml:\"proof_try\""]; + // proof of client state included in message + bytes proof_client = 7 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + // proof of client consensus state + bytes proof_consensus = 8 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 9 + [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; + string signer = 10; +} + +// MsgConnectionOpenAckResponse defines the Msg/ConnectionOpenAck response type. +message MsgConnectionOpenAckResponse {} + +// MsgConnectionOpenConfirm defines a msg sent by a Relayer to Chain B to +// acknowledge the change of connection state to OPEN on Chain A. +message MsgConnectionOpenConfirm { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string connection_id = 1 [(gogoproto.moretags) = "yaml:\"connection_id\""]; + // proof for the change of the connection state on Chain A: `INIT -> OPEN` + bytes proof_ack = 2 [(gogoproto.moretags) = "yaml:\"proof_ack\""]; + ibc.core.client.v1.Height proof_height = 3 + [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; + string signer = 4; +} + +// MsgConnectionOpenConfirmResponse defines the Msg/ConnectionOpenConfirm +// response type. +message MsgConnectionOpenConfirmResponse {} diff --git a/ampd/proto/third_party/ibc/core/types/v1/genesis.proto b/ampd/proto/third_party/ibc/core/types/v1/genesis.proto new file mode 100644 index 000000000..4cc931d32 --- /dev/null +++ b/ampd/proto/third_party/ibc/core/types/v1/genesis.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package ibc.core.types.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/genesis.proto"; +import "ibc/core/connection/v1/genesis.proto"; +import "ibc/core/channel/v1/genesis.proto"; + +// GenesisState defines the ibc module's genesis state. +message GenesisState { + // ICS002 - Clients genesis state + ibc.core.client.v1.GenesisState client_genesis = 1 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_genesis\""]; + // ICS003 - Connections genesis state + ibc.core.connection.v1.GenesisState connection_genesis = 2 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"connection_genesis\""]; + // ICS004 - Channel genesis state + ibc.core.channel.v1.GenesisState channel_genesis = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"channel_genesis\""]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto b/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto new file mode 100644 index 000000000..9eda835eb --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/localhost/v1/localhost.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package ibc.lightclients.localhost.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/09-localhost/types"; + +import "gogoproto/gogo.proto"; +import "ibc/core/client/v1/client.proto"; + +// ClientState defines a loopback (localhost) client. It requires (read-only) +// access to keys outside the client prefix. +message ClientState { + option (gogoproto.goproto_getters) = false; + // self chain ID + string chain_id = 1 [(gogoproto.moretags) = "yaml:\"chain_id\""]; + // self latest block height + ibc.core.client.v1.Height height = 2 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto b/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto new file mode 100644 index 000000000..37bd81e92 --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/solomachine/v1/solomachine.proto @@ -0,0 +1,189 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/core/02-client/legacy/v100"; + +import "ibc/core/connection/v1/connection.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + uint64 frozen_sequence = 2 [(gogoproto.moretags) = "yaml:\"frozen_sequence\""]; + ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // when set to true, will allow governance to update a solo machine client. + // The client will be unfrozen if it is frozen. + bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + // sequence to update solo machine public key at + uint64 sequence = 1; + uint64 timestamp = 2; + bytes signature = 3; + google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; + string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + bytes signature = 1; + DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + uint64 timestamp = 2; + string diversifier = 3; + // type of the data used + DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; + // marshaled data + bytes data = 5; +} + +// DataType defines the type of solo machine proof being created. This is done +// to preserve uniqueness of different data sign byte encodings. +enum DataType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // Data type for client state verification + DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; + // Data type for consensus state verification + DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; + // Data type for connection state verification + DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; + // Data type for channel state verification + DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; + // Data type for packet commitment verification + DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; + // Data type for packet acknowledgement verification + DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; + // Data type for packet receipt absence verification + DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; + // Data type for next sequence recv verification + DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; + // Data type for header verification + DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + // header diversifier + string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// ClientStateData returns the SignBytes data for client state verification. +message ClientStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; +} + +// ConsensusStateData returns the SignBytes data for consensus state +// verification. +message ConsensusStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ConnectionStateData returns the SignBytes data for connection state +// verification. +message ConnectionStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.connection.v1.ConnectionEnd connection = 2; +} + +// ChannelStateData returns the SignBytes data for channel state +// verification. +message ChannelStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.channel.v1.Channel channel = 2; +} + +// PacketCommitmentData returns the SignBytes data for packet commitment +// verification. +message PacketCommitmentData { + bytes path = 1; + bytes commitment = 2; +} + +// PacketAcknowledgementData returns the SignBytes data for acknowledgement +// verification. +message PacketAcknowledgementData { + bytes path = 1; + bytes acknowledgement = 2; +} + +// PacketReceiptAbsenceData returns the SignBytes data for +// packet receipt absence verification. +message PacketReceiptAbsenceData { + bytes path = 1; +} + +// NextSequenceRecvData returns the SignBytes data for verification of the next +// sequence to be received. +message NextSequenceRecvData { + bytes path = 1; + uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto b/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto new file mode 100644 index 000000000..c735fdddd --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/solomachine/v2/solomachine.proto @@ -0,0 +1,189 @@ +syntax = "proto3"; + +package ibc.lightclients.solomachine.v2; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/06-solomachine/types"; + +import "ibc/core/connection/v1/connection.proto"; +import "ibc/core/channel/v1/channel.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; + +// ClientState defines a solo machine client that tracks the current consensus +// state and if the client is frozen. +message ClientState { + option (gogoproto.goproto_getters) = false; + // latest sequence of the client state + uint64 sequence = 1; + // frozen sequence of the solo machine + bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; + ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; + // when set to true, will allow governance to update a solo machine client. + // The client will be unfrozen if it is frozen. + bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; +} + +// ConsensusState defines a solo machine consensus state. The sequence of a +// consensus state is contained in the "height" key used in storing the +// consensus state. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + // public key of the solo machine + google.protobuf.Any public_key = 1 [(gogoproto.moretags) = "yaml:\"public_key\""]; + // diversifier allows the same public key to be re-used across different solo + // machine clients (potentially on different chains) without being considered + // misbehaviour. + string diversifier = 2; + uint64 timestamp = 3; +} + +// Header defines a solo machine consensus header +message Header { + option (gogoproto.goproto_getters) = false; + // sequence to update solo machine public key at + uint64 sequence = 1; + uint64 timestamp = 2; + bytes signature = 3; + google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; + string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// Misbehaviour defines misbehaviour for a solo machine which consists +// of a sequence and two signatures over different messages at that sequence. +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; +} + +// SignatureAndData contains a signature and the data signed over to create that +// signature. +message SignatureAndData { + option (gogoproto.goproto_getters) = false; + bytes signature = 1; + DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; + bytes data = 3; + uint64 timestamp = 4; +} + +// TimestampedSignatureData contains the signature data and the timestamp of the +// signature. +message TimestampedSignatureData { + option (gogoproto.goproto_getters) = false; + bytes signature_data = 1 [(gogoproto.moretags) = "yaml:\"signature_data\""]; + uint64 timestamp = 2; +} + +// SignBytes defines the signed bytes used for signature verification. +message SignBytes { + option (gogoproto.goproto_getters) = false; + + uint64 sequence = 1; + uint64 timestamp = 2; + string diversifier = 3; + // type of the data used + DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; + // marshaled data + bytes data = 5; +} + +// DataType defines the type of solo machine proof being created. This is done +// to preserve uniqueness of different data sign byte encodings. +enum DataType { + option (gogoproto.goproto_enum_prefix) = false; + + // Default State + DATA_TYPE_UNINITIALIZED_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "UNSPECIFIED"]; + // Data type for client state verification + DATA_TYPE_CLIENT_STATE = 1 [(gogoproto.enumvalue_customname) = "CLIENT"]; + // Data type for consensus state verification + DATA_TYPE_CONSENSUS_STATE = 2 [(gogoproto.enumvalue_customname) = "CONSENSUS"]; + // Data type for connection state verification + DATA_TYPE_CONNECTION_STATE = 3 [(gogoproto.enumvalue_customname) = "CONNECTION"]; + // Data type for channel state verification + DATA_TYPE_CHANNEL_STATE = 4 [(gogoproto.enumvalue_customname) = "CHANNEL"]; + // Data type for packet commitment verification + DATA_TYPE_PACKET_COMMITMENT = 5 [(gogoproto.enumvalue_customname) = "PACKETCOMMITMENT"]; + // Data type for packet acknowledgement verification + DATA_TYPE_PACKET_ACKNOWLEDGEMENT = 6 [(gogoproto.enumvalue_customname) = "PACKETACKNOWLEDGEMENT"]; + // Data type for packet receipt absence verification + DATA_TYPE_PACKET_RECEIPT_ABSENCE = 7 [(gogoproto.enumvalue_customname) = "PACKETRECEIPTABSENCE"]; + // Data type for next sequence recv verification + DATA_TYPE_NEXT_SEQUENCE_RECV = 8 [(gogoproto.enumvalue_customname) = "NEXTSEQUENCERECV"]; + // Data type for header verification + DATA_TYPE_HEADER = 9 [(gogoproto.enumvalue_customname) = "HEADER"]; +} + +// HeaderData returns the SignBytes data for update verification. +message HeaderData { + option (gogoproto.goproto_getters) = false; + + // header public key + google.protobuf.Any new_pub_key = 1 [(gogoproto.moretags) = "yaml:\"new_pub_key\""]; + // header diversifier + string new_diversifier = 2 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; +} + +// ClientStateData returns the SignBytes data for client state verification. +message ClientStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any client_state = 2 [(gogoproto.moretags) = "yaml:\"client_state\""]; +} + +// ConsensusStateData returns the SignBytes data for consensus state +// verification. +message ConsensusStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; +} + +// ConnectionStateData returns the SignBytes data for connection state +// verification. +message ConnectionStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.connection.v1.ConnectionEnd connection = 2; +} + +// ChannelStateData returns the SignBytes data for channel state +// verification. +message ChannelStateData { + option (gogoproto.goproto_getters) = false; + + bytes path = 1; + ibc.core.channel.v1.Channel channel = 2; +} + +// PacketCommitmentData returns the SignBytes data for packet commitment +// verification. +message PacketCommitmentData { + bytes path = 1; + bytes commitment = 2; +} + +// PacketAcknowledgementData returns the SignBytes data for acknowledgement +// verification. +message PacketAcknowledgementData { + bytes path = 1; + bytes acknowledgement = 2; +} + +// PacketReceiptAbsenceData returns the SignBytes data for +// packet receipt absence verification. +message PacketReceiptAbsenceData { + bytes path = 1; +} + +// NextSequenceRecvData returns the SignBytes data for verification of the next +// sequence to be received. +message NextSequenceRecvData { + bytes path = 1; + uint64 next_seq_recv = 2 [(gogoproto.moretags) = "yaml:\"next_seq_recv\""]; +} diff --git a/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto b/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto new file mode 100644 index 000000000..55a4e0690 --- /dev/null +++ b/ampd/proto/third_party/ibc/lightclients/tendermint/v1/tendermint.proto @@ -0,0 +1,114 @@ +syntax = "proto3"; + +package ibc.lightclients.tendermint.v1; + +option go_package = "github.com/cosmos/ibc-go/v4/modules/light-clients/07-tendermint/types"; + +import "tendermint/types/validator.proto"; +import "tendermint/types/types.proto"; +import "proofs.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "ibc/core/client/v1/client.proto"; +import "ibc/core/commitment/v1/commitment.proto"; +import "gogoproto/gogo.proto"; + +// ClientState from Tendermint tracks the current validator set, latest height, +// and a possible frozen height. +message ClientState { + option (gogoproto.goproto_getters) = false; + + string chain_id = 1; + Fraction trust_level = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trust_level\""]; + // duration of the period since the LastestTimestamp during which the + // submitted headers are valid for upgrade + google.protobuf.Duration trusting_period = 3 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"trusting_period\""]; + // duration of the staking unbonding period + google.protobuf.Duration unbonding_period = 4 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true, + (gogoproto.moretags) = "yaml:\"unbonding_period\"" + ]; + // defines how much new (untrusted) header's Time can drift into the future. + google.protobuf.Duration max_clock_drift = 5 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.moretags) = "yaml:\"max_clock_drift\""]; + // Block height when the client was frozen due to a misbehaviour + ibc.core.client.v1.Height frozen_height = 6 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"frozen_height\""]; + // Latest height the client was updated to + ibc.core.client.v1.Height latest_height = 7 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"latest_height\""]; + + // Proof specifications used in verifying counterparty state + repeated ics23.ProofSpec proof_specs = 8 [(gogoproto.moretags) = "yaml:\"proof_specs\""]; + + // Path at which next upgraded client will be committed. + // Each element corresponds to the key for a single CommitmentProof in the + // chained proof. NOTE: ClientState must stored under + // `{upgradePath}/{upgradeHeight}/clientState` ConsensusState must be stored + // under `{upgradepath}/{upgradeHeight}/consensusState` For SDK chains using + // the default upgrade module, upgrade_path should be []string{"upgrade", + // "upgradedIBCState"}` + repeated string upgrade_path = 9 [(gogoproto.moretags) = "yaml:\"upgrade_path\""]; + + // allow_update_after_expiry is deprecated + bool allow_update_after_expiry = 10 [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_expiry\""]; + // allow_update_after_misbehaviour is deprecated + bool allow_update_after_misbehaviour = 11 + [deprecated = true, (gogoproto.moretags) = "yaml:\"allow_update_after_misbehaviour\""]; +} + +// ConsensusState defines the consensus state from Tendermint. +message ConsensusState { + option (gogoproto.goproto_getters) = false; + + // timestamp that corresponds to the block height in which the ConsensusState + // was stored. + google.protobuf.Timestamp timestamp = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + // commitment root (i.e app hash) + ibc.core.commitment.v1.MerkleRoot root = 2 [(gogoproto.nullable) = false]; + bytes next_validators_hash = 3 [ + (gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes", + (gogoproto.moretags) = "yaml:\"next_validators_hash\"" + ]; +} + +// Misbehaviour is a wrapper over two conflicting Headers +// that implements Misbehaviour interface expected by ICS-02 +message Misbehaviour { + option (gogoproto.goproto_getters) = false; + + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; + Header header_2 = 3 [(gogoproto.customname) = "Header2", (gogoproto.moretags) = "yaml:\"header_2\""]; +} + +// Header defines the Tendermint client consensus Header. +// It encapsulates all the information necessary to update from a trusted +// Tendermint ConsensusState. The inclusion of TrustedHeight and +// TrustedValidators allows this update to process correctly, so long as the +// ConsensusState for the TrustedHeight exists, this removes race conditions +// among relayers The SignedHeader and ValidatorSet are the new untrusted update +// fields for the client. The TrustedHeight is the height of a stored +// ConsensusState on the client that will be used to verify the new untrusted +// header. The Trusted ConsensusState must be within the unbonding period of +// current time in order to correctly verify, and the TrustedValidators must +// hash to TrustedConsensusState.NextValidatorsHash since that is the last +// trusted validator set at the TrustedHeight. +message Header { + .tendermint.types.SignedHeader signed_header = 1 + [(gogoproto.embed) = true, (gogoproto.moretags) = "yaml:\"signed_header\""]; + + .tendermint.types.ValidatorSet validator_set = 2 [(gogoproto.moretags) = "yaml:\"validator_set\""]; + ibc.core.client.v1.Height trusted_height = 3 + [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"trusted_height\""]; + .tendermint.types.ValidatorSet trusted_validators = 4 [(gogoproto.moretags) = "yaml:\"trusted_validators\""]; +} + +// Fraction defines the protobuf message type for tmmath.Fraction that only +// supports positive values. +message Fraction { + uint64 numerator = 1; + uint64 denominator = 2; +} diff --git a/ampd/proto/third_party/proofs.proto b/ampd/proto/third_party/proofs.proto new file mode 100644 index 000000000..88b50c1b3 --- /dev/null +++ b/ampd/proto/third_party/proofs.proto @@ -0,0 +1,234 @@ +syntax = "proto3"; + +package ics23; +option go_package = "github.com/confio/ics23/go"; +enum HashOp { + // NO_HASH is the default if no data passed. Note this is an illegal argument some places. + NO_HASH = 0; + SHA256 = 1; + SHA512 = 2; + KECCAK = 3; + RIPEMD160 = 4; + BITCOIN = 5; // ripemd160(sha256(x)) + SHA512_256 = 6; +} + +/** +LengthOp defines how to process the key and value of the LeafOp +to include length information. After encoding the length with the given +algorithm, the length will be prepended to the key and value bytes. +(Each one with it's own encoded length) +*/ +enum LengthOp { + // NO_PREFIX don't include any length info + NO_PREFIX = 0; + // VAR_PROTO uses protobuf (and go-amino) varint encoding of the length + VAR_PROTO = 1; + // VAR_RLP uses rlp int encoding of the length + VAR_RLP = 2; + // FIXED32_BIG uses big-endian encoding of the length as a 32 bit integer + FIXED32_BIG = 3; + // FIXED32_LITTLE uses little-endian encoding of the length as a 32 bit integer + FIXED32_LITTLE = 4; + // FIXED64_BIG uses big-endian encoding of the length as a 64 bit integer + FIXED64_BIG = 5; + // FIXED64_LITTLE uses little-endian encoding of the length as a 64 bit integer + FIXED64_LITTLE = 6; + // REQUIRE_32_BYTES is like NONE, but will fail if the input is not exactly 32 bytes (sha256 output) + REQUIRE_32_BYTES = 7; + // REQUIRE_64_BYTES is like NONE, but will fail if the input is not exactly 64 bytes (sha512 output) + REQUIRE_64_BYTES = 8; +} + +/** +ExistenceProof takes a key and a value and a set of steps to perform on it. +The result of peforming all these steps will provide a "root hash", which can +be compared to the value in a header. + +Since it is computationally infeasible to produce a hash collission for any of the used +cryptographic hash functions, if someone can provide a series of operations to transform +a given key and value into a root hash that matches some trusted root, these key and values +must be in the referenced merkle tree. + +The only possible issue is maliablity in LeafOp, such as providing extra prefix data, +which should be controlled by a spec. Eg. with lengthOp as NONE, + prefix = FOO, key = BAR, value = CHOICE +and + prefix = F, key = OOBAR, value = CHOICE +would produce the same value. + +With LengthOp this is tricker but not impossible. Which is why the "leafPrefixEqual" field +in the ProofSpec is valuable to prevent this mutability. And why all trees should +length-prefix the data before hashing it. +*/ +message ExistenceProof { + bytes key = 1; + bytes value = 2; + LeafOp leaf = 3; + repeated InnerOp path = 4; +} + +/* +NonExistenceProof takes a proof of two neighbors, one left of the desired key, +one right of the desired key. If both proofs are valid AND they are neighbors, +then there is no valid proof for the given key. +*/ +message NonExistenceProof { + bytes key = 1; // TODO: remove this as unnecessary??? we prove a range + ExistenceProof left = 2; + ExistenceProof right = 3; +} + +/* +CommitmentProof is either an ExistenceProof or a NonExistenceProof, or a Batch of such messages +*/ +message CommitmentProof { + oneof proof { + ExistenceProof exist = 1; + NonExistenceProof nonexist = 2; + BatchProof batch = 3; + CompressedBatchProof compressed = 4; + } +} + +/** +LeafOp represents the raw key-value data we wish to prove, and +must be flexible to represent the internal transformation from +the original key-value pairs into the basis hash, for many existing +merkle trees. + +key and value are passed in. So that the signature of this operation is: + leafOp(key, value) -> output + +To process this, first prehash the keys and values if needed (ANY means no hash in this case): + hkey = prehashKey(key) + hvalue = prehashValue(value) + +Then combine the bytes, and hash it + output = hash(prefix || length(hkey) || hkey || length(hvalue) || hvalue) +*/ +message LeafOp { + HashOp hash = 1; + HashOp prehash_key = 2; + HashOp prehash_value = 3; + LengthOp length = 4; + // prefix is a fixed bytes that may optionally be included at the beginning to differentiate + // a leaf node from an inner node. + bytes prefix = 5; +} + +/** +InnerOp represents a merkle-proof step that is not a leaf. +It represents concatenating two children and hashing them to provide the next result. + +The result of the previous step is passed in, so the signature of this op is: + innerOp(child) -> output + +The result of applying InnerOp should be: + output = op.hash(op.prefix || child || op.suffix) + + where the || operator is concatenation of binary data, +and child is the result of hashing all the tree below this step. + +Any special data, like prepending child with the length, or prepending the entire operation with +some value to differentiate from leaf nodes, should be included in prefix and suffix. +If either of prefix or suffix is empty, we just treat it as an empty string +*/ +message InnerOp { + HashOp hash = 1; + bytes prefix = 2; + bytes suffix = 3; +} + + +/** +ProofSpec defines what the expected parameters are for a given proof type. +This can be stored in the client and used to validate any incoming proofs. + + verify(ProofSpec, Proof) -> Proof | Error + +As demonstrated in tests, if we don't fix the algorithm used to calculate the +LeafHash for a given tree, there are many possible key-value pairs that can +generate a given hash (by interpretting the preimage differently). +We need this for proper security, requires client knows a priori what +tree format server uses. But not in code, rather a configuration object. +*/ +message ProofSpec { + // any field in the ExistenceProof must be the same as in this spec. + // except Prefix, which is just the first bytes of prefix (spec can be longer) + LeafOp leaf_spec = 1; + InnerSpec inner_spec = 2; + // max_depth (if > 0) is the maximum number of InnerOps allowed (mainly for fixed-depth tries) + int32 max_depth = 3; + // min_depth (if > 0) is the minimum number of InnerOps allowed (mainly for fixed-depth tries) + int32 min_depth = 4; +} + +/* +InnerSpec contains all store-specific structure info to determine if two proofs from a +given store are neighbors. + +This enables: + + isLeftMost(spec: InnerSpec, op: InnerOp) + isRightMost(spec: InnerSpec, op: InnerOp) + isLeftNeighbor(spec: InnerSpec, left: InnerOp, right: InnerOp) +*/ +message InnerSpec { + // Child order is the ordering of the children node, must count from 0 + // iavl tree is [0, 1] (left then right) + // merk is [0, 2, 1] (left, right, here) + repeated int32 child_order = 1; + int32 child_size = 2; + int32 min_prefix_length = 3; + int32 max_prefix_length = 4; + // empty child is the prehash image that is used when one child is nil (eg. 20 bytes of 0) + bytes empty_child = 5; + // hash is the algorithm that must be used for each InnerOp + HashOp hash = 6; +} + +/* +BatchProof is a group of multiple proof types than can be compressed +*/ +message BatchProof { + repeated BatchEntry entries = 1; +} + +// Use BatchEntry not CommitmentProof, to avoid recursion +message BatchEntry { + oneof proof { + ExistenceProof exist = 1; + NonExistenceProof nonexist = 2; + } +} + + +/****** all items here are compressed forms *******/ + +message CompressedBatchProof { + repeated CompressedBatchEntry entries = 1; + repeated InnerOp lookup_inners = 2; +} + +// Use BatchEntry not CommitmentProof, to avoid recursion +message CompressedBatchEntry { + oneof proof { + CompressedExistenceProof exist = 1; + CompressedNonExistenceProof nonexist = 2; + } +} + +message CompressedExistenceProof { + bytes key = 1; + bytes value = 2; + LeafOp leaf = 3; + // these are indexes into the lookup_inners table in CompressedBatchProof + repeated int32 path = 4; +} + +message CompressedNonExistenceProof { + bytes key = 1; // TODO: remove this as unnecessary??? we prove a range + CompressedExistenceProof left = 2; + CompressedExistenceProof right = 3; +} diff --git a/ampd/proto/third_party/tendermint/abci/types.proto b/ampd/proto/third_party/tendermint/abci/types.proto new file mode 100644 index 000000000..44f861129 --- /dev/null +++ b/ampd/proto/third_party/tendermint/abci/types.proto @@ -0,0 +1,413 @@ +syntax = "proto3"; +package tendermint.abci; + +option go_package = "github.com/tendermint/tendermint/abci/types"; + +// For more information on gogo.proto, see: +// https://github.com/gogo/protobuf/blob/master/extensions.md +import "tendermint/crypto/proof.proto"; +import "tendermint/types/types.proto"; +import "tendermint/crypto/keys.proto"; +import "tendermint/types/params.proto"; +import "google/protobuf/timestamp.proto"; +import "gogoproto/gogo.proto"; + +// This file is copied from http://github.com/tendermint/abci +// NOTE: When using custom types, mind the warnings. +// https://github.com/gogo/protobuf/blob/master/custom_types.md#warnings-and-issues + +//---------------------------------------- +// Request types + +message Request { + oneof value { + RequestEcho echo = 1; + RequestFlush flush = 2; + RequestInfo info = 3; + RequestSetOption set_option = 4; + RequestInitChain init_chain = 5; + RequestQuery query = 6; + RequestBeginBlock begin_block = 7; + RequestCheckTx check_tx = 8; + RequestDeliverTx deliver_tx = 9; + RequestEndBlock end_block = 10; + RequestCommit commit = 11; + RequestListSnapshots list_snapshots = 12; + RequestOfferSnapshot offer_snapshot = 13; + RequestLoadSnapshotChunk load_snapshot_chunk = 14; + RequestApplySnapshotChunk apply_snapshot_chunk = 15; + } +} + +message RequestEcho { + string message = 1; +} + +message RequestFlush {} + +message RequestInfo { + string version = 1; + uint64 block_version = 2; + uint64 p2p_version = 3; +} + +// nondeterministic +message RequestSetOption { + string key = 1; + string value = 2; +} + +message RequestInitChain { + google.protobuf.Timestamp time = 1 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + string chain_id = 2; + ConsensusParams consensus_params = 3; + repeated ValidatorUpdate validators = 4 [(gogoproto.nullable) = false]; + bytes app_state_bytes = 5; + int64 initial_height = 6; +} + +message RequestQuery { + bytes data = 1; + string path = 2; + int64 height = 3; + bool prove = 4; +} + +message RequestBeginBlock { + bytes hash = 1; + tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; + LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; + repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; +} + +enum CheckTxType { + NEW = 0 [(gogoproto.enumvalue_customname) = "New"]; + RECHECK = 1 [(gogoproto.enumvalue_customname) = "Recheck"]; +} + +message RequestCheckTx { + bytes tx = 1; + CheckTxType type = 2; +} + +message RequestDeliverTx { + bytes tx = 1; +} + +message RequestEndBlock { + int64 height = 1; +} + +message RequestCommit {} + +// lists available snapshots +message RequestListSnapshots {} + +// offers a snapshot to the application +message RequestOfferSnapshot { + Snapshot snapshot = 1; // snapshot offered by peers + bytes app_hash = 2; // light client-verified app hash for snapshot height +} + +// loads a snapshot chunk +message RequestLoadSnapshotChunk { + uint64 height = 1; + uint32 format = 2; + uint32 chunk = 3; +} + +// Applies a snapshot chunk +message RequestApplySnapshotChunk { + uint32 index = 1; + bytes chunk = 2; + string sender = 3; +} + +//---------------------------------------- +// Response types + +message Response { + oneof value { + ResponseException exception = 1; + ResponseEcho echo = 2; + ResponseFlush flush = 3; + ResponseInfo info = 4; + ResponseSetOption set_option = 5; + ResponseInitChain init_chain = 6; + ResponseQuery query = 7; + ResponseBeginBlock begin_block = 8; + ResponseCheckTx check_tx = 9; + ResponseDeliverTx deliver_tx = 10; + ResponseEndBlock end_block = 11; + ResponseCommit commit = 12; + ResponseListSnapshots list_snapshots = 13; + ResponseOfferSnapshot offer_snapshot = 14; + ResponseLoadSnapshotChunk load_snapshot_chunk = 15; + ResponseApplySnapshotChunk apply_snapshot_chunk = 16; + } +} + +// nondeterministic +message ResponseException { + string error = 1; +} + +message ResponseEcho { + string message = 1; +} + +message ResponseFlush {} + +message ResponseInfo { + string data = 1; + + string version = 2; + uint64 app_version = 3; + + int64 last_block_height = 4; + bytes last_block_app_hash = 5; +} + +// nondeterministic +message ResponseSetOption { + uint32 code = 1; + // bytes data = 2; + string log = 3; + string info = 4; +} + +message ResponseInitChain { + ConsensusParams consensus_params = 1; + repeated ValidatorUpdate validators = 2 [(gogoproto.nullable) = false]; + bytes app_hash = 3; +} + +message ResponseQuery { + uint32 code = 1; + // bytes data = 2; // use "value" instead. + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 index = 5; + bytes key = 6; + bytes value = 7; + tendermint.crypto.ProofOps proof_ops = 8; + int64 height = 9; + string codespace = 10; +} + +message ResponseBeginBlock { + repeated Event events = 1 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; +} + +message ResponseCheckTx { + uint32 code = 1; + bytes data = 2; + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 gas_wanted = 5 [json_name = "gas_wanted"]; + int64 gas_used = 6 [json_name = "gas_used"]; + repeated Event events = 7 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; + string codespace = 8; + string sender = 9; + int64 priority = 10; + + // mempool_error is set by CometBFT. + // ABCI applictions creating a ResponseCheckTX should not set mempool_error. + string mempool_error = 11; +} + +message ResponseDeliverTx { + uint32 code = 1; + bytes data = 2; + string log = 3; // nondeterministic + string info = 4; // nondeterministic + int64 gas_wanted = 5 [json_name = "gas_wanted"]; + int64 gas_used = 6 [json_name = "gas_used"]; + repeated Event events = 7 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "events,omitempty" + ]; // nondeterministic + string codespace = 8; +} + +message ResponseEndBlock { + repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; + ConsensusParams consensus_param_updates = 2; + repeated Event events = 3 + [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; +} + +message ResponseCommit { + // reserve 1 + bytes data = 2; + int64 retain_height = 3; +} + +message ResponseListSnapshots { + repeated Snapshot snapshots = 1; +} + +message ResponseOfferSnapshot { + Result result = 1; + + enum Result { + UNKNOWN = 0; // Unknown result, abort all snapshot restoration + ACCEPT = 1; // Snapshot accepted, apply chunks + ABORT = 2; // Abort all snapshot restoration + REJECT = 3; // Reject this specific snapshot, try others + REJECT_FORMAT = 4; // Reject all snapshots of this format, try others + REJECT_SENDER = 5; // Reject all snapshots from the sender(s), try others + } +} + +message ResponseLoadSnapshotChunk { + bytes chunk = 1; +} + +message ResponseApplySnapshotChunk { + Result result = 1; + repeated uint32 refetch_chunks = 2; // Chunks to refetch and reapply + repeated string reject_senders = 3; // Chunk senders to reject and ban + + enum Result { + UNKNOWN = 0; // Unknown result, abort all snapshot restoration + ACCEPT = 1; // Chunk successfully accepted + ABORT = 2; // Abort all snapshot restoration + RETRY = 3; // Retry chunk (combine with refetch and reject) + RETRY_SNAPSHOT = 4; // Retry snapshot (combine with refetch and reject) + REJECT_SNAPSHOT = 5; // Reject this snapshot, try others + } +} + +//---------------------------------------- +// Misc. + +// ConsensusParams contains all consensus-relevant parameters +// that can be adjusted by the abci app +message ConsensusParams { + BlockParams block = 1; + tendermint.types.EvidenceParams evidence = 2; + tendermint.types.ValidatorParams validator = 3; + tendermint.types.VersionParams version = 4; +} + +// BlockParams contains limits on the block size. +message BlockParams { + // Note: must be greater than 0 + int64 max_bytes = 1; + // Note: must be greater or equal to -1 + int64 max_gas = 2; +} + +message LastCommitInfo { + int32 round = 1; + repeated VoteInfo votes = 2 [(gogoproto.nullable) = false]; +} + +// Event allows application developers to attach additional information to +// ResponseBeginBlock, ResponseEndBlock, ResponseCheckTx and ResponseDeliverTx. +// Later, transactions may be queried using these events. +message Event { + string type = 1; + repeated EventAttribute attributes = 2 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "attributes,omitempty" + ]; +} + +// EventAttribute is a single key-value pair, associated with an event. +message EventAttribute { + bytes key = 1; + bytes value = 2; + bool index = 3; // nondeterministic +} + +// TxResult contains results of executing the transaction. +// +// One usage is indexing transaction results. +message TxResult { + int64 height = 1; + uint32 index = 2; + bytes tx = 3; + ResponseDeliverTx result = 4 [(gogoproto.nullable) = false]; +} + +//---------------------------------------- +// Blockchain Types + +// Validator +message Validator { + bytes address = 1; // The first 20 bytes of SHA256(public key) + // PubKey pub_key = 2 [(gogoproto.nullable)=false]; + int64 power = 3; // The voting power +} + +// ValidatorUpdate +message ValidatorUpdate { + tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; + int64 power = 2; +} + +// VoteInfo +message VoteInfo { + Validator validator = 1 [(gogoproto.nullable) = false]; + bool signed_last_block = 2; +} + +enum EvidenceType { + UNKNOWN = 0; + DUPLICATE_VOTE = 1; + LIGHT_CLIENT_ATTACK = 2; +} + +message Evidence { + EvidenceType type = 1; + // The offending validator + Validator validator = 2 [(gogoproto.nullable) = false]; + // The height when the offense occurred + int64 height = 3; + // The corresponding time where the offense occurred + google.protobuf.Timestamp time = 4 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + // Total voting power of the validator set in case the ABCI application does + // not store historical validators. + // https://github.com/tendermint/tendermint/issues/4581 + int64 total_voting_power = 5; +} + +//---------------------------------------- +// State Sync Types + +message Snapshot { + uint64 height = 1; // The height at which the snapshot was taken + uint32 format = 2; // The application-specific snapshot format + uint32 chunks = 3; // Number of chunks in the snapshot + bytes hash = 4; // Arbitrary snapshot hash, equal only if identical + bytes metadata = 5; // Arbitrary application metadata +} + +//---------------------------------------- +// Service Definition + +service ABCIApplication { + rpc Echo(RequestEcho) returns (ResponseEcho); + rpc Flush(RequestFlush) returns (ResponseFlush); + rpc Info(RequestInfo) returns (ResponseInfo); + rpc SetOption(RequestSetOption) returns (ResponseSetOption); + rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); + rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); + rpc Query(RequestQuery) returns (ResponseQuery); + rpc Commit(RequestCommit) returns (ResponseCommit); + rpc InitChain(RequestInitChain) returns (ResponseInitChain); + rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); + rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); + rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); + rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); + rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) + returns (ResponseLoadSnapshotChunk); + rpc ApplySnapshotChunk(RequestApplySnapshotChunk) + returns (ResponseApplySnapshotChunk); +} diff --git a/ampd/proto/third_party/tendermint/crypto/keys.proto b/ampd/proto/third_party/tendermint/crypto/keys.proto new file mode 100644 index 000000000..5b94ddaec --- /dev/null +++ b/ampd/proto/third_party/tendermint/crypto/keys.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package tendermint.crypto; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; + +import "gogoproto/gogo.proto"; + +// PublicKey defines the keys available for use with Validators +message PublicKey { + option (gogoproto.compare) = true; + option (gogoproto.equal) = true; + + oneof sum { + bytes ed25519 = 1; + bytes secp256k1 = 2; + } +} diff --git a/ampd/proto/third_party/tendermint/crypto/proof.proto b/ampd/proto/third_party/tendermint/crypto/proof.proto new file mode 100644 index 000000000..975df7685 --- /dev/null +++ b/ampd/proto/third_party/tendermint/crypto/proof.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +package tendermint.crypto; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; + +import "gogoproto/gogo.proto"; + +message Proof { + int64 total = 1; + int64 index = 2; + bytes leaf_hash = 3; + repeated bytes aunts = 4; +} + +message ValueOp { + // Encoded in ProofOp.Key. + bytes key = 1; + + // To encode in ProofOp.Data + Proof proof = 2; +} + +message DominoOp { + string key = 1; + string input = 2; + string output = 3; +} + +// ProofOp defines an operation used for calculating Merkle root +// The data could be arbitrary format, providing nessecary data +// for example neighbouring node hash +message ProofOp { + string type = 1; + bytes key = 2; + bytes data = 3; +} + +// ProofOps is Merkle proof defined by the list of ProofOps +message ProofOps { + repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/tendermint/libs/bits/types.proto b/ampd/proto/third_party/tendermint/libs/bits/types.proto new file mode 100644 index 000000000..3111d113a --- /dev/null +++ b/ampd/proto/third_party/tendermint/libs/bits/types.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package tendermint.libs.bits; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits"; + +message BitArray { + int64 bits = 1; + repeated uint64 elems = 2; +} diff --git a/ampd/proto/third_party/tendermint/p2p/types.proto b/ampd/proto/third_party/tendermint/p2p/types.proto new file mode 100644 index 000000000..0d42ea400 --- /dev/null +++ b/ampd/proto/third_party/tendermint/p2p/types.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package tendermint.p2p; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; + +import "gogoproto/gogo.proto"; + +message NetAddress { + string id = 1 [(gogoproto.customname) = "ID"]; + string ip = 2 [(gogoproto.customname) = "IP"]; + uint32 port = 3; +} + +message ProtocolVersion { + uint64 p2p = 1 [(gogoproto.customname) = "P2P"]; + uint64 block = 2; + uint64 app = 3; +} + +message DefaultNodeInfo { + ProtocolVersion protocol_version = 1 [(gogoproto.nullable) = false]; + string default_node_id = 2 [(gogoproto.customname) = "DefaultNodeID"]; + string listen_addr = 3; + string network = 4; + string version = 5; + bytes channels = 6; + string moniker = 7; + DefaultNodeInfoOther other = 8 [(gogoproto.nullable) = false]; +} + +message DefaultNodeInfoOther { + string tx_index = 1; + string rpc_address = 2 [(gogoproto.customname) = "RPCAddress"]; +} diff --git a/ampd/proto/third_party/tendermint/types/block.proto b/ampd/proto/third_party/tendermint/types/block.proto new file mode 100644 index 000000000..84e9bb15d --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/block.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "tendermint/types/types.proto"; +import "tendermint/types/evidence.proto"; + +message Block { + Header header = 1 [(gogoproto.nullable) = false]; + Data data = 2 [(gogoproto.nullable) = false]; + tendermint.types.EvidenceList evidence = 3 [(gogoproto.nullable) = false]; + Commit last_commit = 4; +} diff --git a/ampd/proto/third_party/tendermint/types/evidence.proto b/ampd/proto/third_party/tendermint/types/evidence.proto new file mode 100644 index 000000000..451b8dca3 --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/evidence.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "tendermint/types/types.proto"; +import "tendermint/types/validator.proto"; + +message Evidence { + oneof sum { + DuplicateVoteEvidence duplicate_vote_evidence = 1; + LightClientAttackEvidence light_client_attack_evidence = 2; + } +} + +// DuplicateVoteEvidence contains evidence of a validator signed two conflicting votes. +message DuplicateVoteEvidence { + tendermint.types.Vote vote_a = 1; + tendermint.types.Vote vote_b = 2; + int64 total_voting_power = 3; + int64 validator_power = 4; + google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +// LightClientAttackEvidence contains evidence of a set of validators attempting to mislead a light client. +message LightClientAttackEvidence { + tendermint.types.LightBlock conflicting_block = 1; + int64 common_height = 2; + repeated tendermint.types.Validator byzantine_validators = 3; + int64 total_voting_power = 4; + google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; +} + +message EvidenceList { + repeated Evidence evidence = 1 [(gogoproto.nullable) = false]; +} diff --git a/ampd/proto/third_party/tendermint/types/params.proto b/ampd/proto/third_party/tendermint/types/params.proto new file mode 100644 index 000000000..0de7d846f --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/params.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/duration.proto"; + +option (gogoproto.equal_all) = true; + +// ConsensusParams contains consensus critical parameters that determine the +// validity of blocks. +message ConsensusParams { + BlockParams block = 1 [(gogoproto.nullable) = false]; + EvidenceParams evidence = 2 [(gogoproto.nullable) = false]; + ValidatorParams validator = 3 [(gogoproto.nullable) = false]; + VersionParams version = 4 [(gogoproto.nullable) = false]; +} + +// BlockParams contains limits on the block size. +message BlockParams { + // Max block size, in bytes. + // Note: must be greater than 0 + int64 max_bytes = 1; + // Max gas per block. + // Note: must be greater or equal to -1 + int64 max_gas = 2; + // Minimum time increment between consecutive blocks (in milliseconds) If the + // block header timestamp is ahead of the system clock, decrease this value. + // + // Not exposed to the application. + int64 time_iota_ms = 3; +} + +// EvidenceParams determine how we handle evidence of malfeasance. +message EvidenceParams { + // Max age of evidence, in blocks. + // + // The basic formula for calculating this is: MaxAgeDuration / {average block + // time}. + int64 max_age_num_blocks = 1; + + // Max age of evidence, in time. + // + // It should correspond with an app's "unbonding period" or other similar + // mechanism for handling [Nothing-At-Stake + // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). + google.protobuf.Duration max_age_duration = 2 + [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + + // This sets the maximum size of total evidence in bytes that can be committed in a single block. + // and should fall comfortably under the max block bytes. + // Default is 1048576 or 1MB + int64 max_bytes = 3; +} + +// ValidatorParams restrict the public key types validators can use. +// NOTE: uses ABCI pubkey naming, not Amino names. +message ValidatorParams { + option (gogoproto.populate) = true; + option (gogoproto.equal) = true; + + repeated string pub_key_types = 1; +} + +// VersionParams contains the ABCI application version. +message VersionParams { + option (gogoproto.populate) = true; + option (gogoproto.equal) = true; + + uint64 app_version = 1; +} + +// HashedParams is a subset of ConsensusParams. +// +// It is hashed into the Header.ConsensusHash. +message HashedParams { + int64 block_max_bytes = 1; + int64 block_max_gas = 2; +} diff --git a/ampd/proto/third_party/tendermint/types/types.proto b/ampd/proto/third_party/tendermint/types/types.proto new file mode 100644 index 000000000..3ce169459 --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/types.proto @@ -0,0 +1,157 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "tendermint/crypto/proof.proto"; +import "tendermint/version/types.proto"; +import "tendermint/types/validator.proto"; + +// BlockIdFlag indicates which BlcokID the signature is for +enum BlockIDFlag { + option (gogoproto.goproto_enum_stringer) = true; + option (gogoproto.goproto_enum_prefix) = false; + + BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; + BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; + BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; + BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; +} + +// SignedMsgType is a type of signed message in the consensus. +enum SignedMsgType { + option (gogoproto.goproto_enum_stringer) = true; + option (gogoproto.goproto_enum_prefix) = false; + + SIGNED_MSG_TYPE_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "UnknownType"]; + // Votes + SIGNED_MSG_TYPE_PREVOTE = 1 [(gogoproto.enumvalue_customname) = "PrevoteType"]; + SIGNED_MSG_TYPE_PRECOMMIT = 2 [(gogoproto.enumvalue_customname) = "PrecommitType"]; + + // Proposals + SIGNED_MSG_TYPE_PROPOSAL = 32 [(gogoproto.enumvalue_customname) = "ProposalType"]; +} + +// PartsetHeader +message PartSetHeader { + uint32 total = 1; + bytes hash = 2; +} + +message Part { + uint32 index = 1; + bytes bytes = 2; + tendermint.crypto.Proof proof = 3 [(gogoproto.nullable) = false]; +} + +// BlockID +message BlockID { + bytes hash = 1; + PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; +} + +// -------------------------------- + +// Header defines the structure of a block header. +message Header { + // basic block info + tendermint.version.Consensus version = 1 [(gogoproto.nullable) = false]; + string chain_id = 2 [(gogoproto.customname) = "ChainID"]; + int64 height = 3; + google.protobuf.Timestamp time = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + + // prev block info + BlockID last_block_id = 5 [(gogoproto.nullable) = false]; + + // hashes of block data + bytes last_commit_hash = 6; // commit from validators from the last block + bytes data_hash = 7; // transactions + + // hashes from the app output from the prev block + bytes validators_hash = 8; // validators for the current block + bytes next_validators_hash = 9; // validators for the next block + bytes consensus_hash = 10; // consensus params for current block + bytes app_hash = 11; // state after txs from the previous block + bytes last_results_hash = 12; // root hash of all results from the txs from the previous block + + // consensus info + bytes evidence_hash = 13; // evidence included in the block + bytes proposer_address = 14; // original proposer of the block +} + +// Data contains the set of transactions included in the block +message Data { + // Txs that will be applied by state @ block.Height+1. + // NOTE: not all txs here are valid. We're just agreeing on the order first. + // This means that block.AppHash does not include these txs. + repeated bytes txs = 1; +} + +// Vote represents a prevote, precommit, or commit vote from validators for +// consensus. +message Vote { + SignedMsgType type = 1; + int64 height = 2; + int32 round = 3; + BlockID block_id = 4 + [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; // zero if vote is nil. + google.protobuf.Timestamp timestamp = 5 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes validator_address = 6; + int32 validator_index = 7; + bytes signature = 8; +} + +// Commit contains the evidence that a block was committed by a set of validators. +message Commit { + int64 height = 1; + int32 round = 2; + BlockID block_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "BlockID"]; + repeated CommitSig signatures = 4 [(gogoproto.nullable) = false]; +} + +// CommitSig is a part of the Vote included in a Commit. +message CommitSig { + BlockIDFlag block_id_flag = 1; + bytes validator_address = 2; + google.protobuf.Timestamp timestamp = 3 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes signature = 4; +} + +message Proposal { + SignedMsgType type = 1; + int64 height = 2; + int32 round = 3; + int32 pol_round = 4; + BlockID block_id = 5 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; + google.protobuf.Timestamp timestamp = 6 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + bytes signature = 7; +} + +message SignedHeader { + Header header = 1; + Commit commit = 2; +} + +message LightBlock { + SignedHeader signed_header = 1; + tendermint.types.ValidatorSet validator_set = 2; +} + +message BlockMeta { + BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false]; + int64 block_size = 2; + Header header = 3 [(gogoproto.nullable) = false]; + int64 num_txs = 4; +} + +// TxProof represents a Merkle proof of the presence of a transaction in the Merkle tree. +message TxProof { + bytes root_hash = 1; + bytes data = 2; + tendermint.crypto.Proof proof = 3; +} diff --git a/ampd/proto/third_party/tendermint/types/validator.proto b/ampd/proto/third_party/tendermint/types/validator.proto new file mode 100644 index 000000000..49860b96d --- /dev/null +++ b/ampd/proto/third_party/tendermint/types/validator.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; +package tendermint.types; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; + +import "gogoproto/gogo.proto"; +import "tendermint/crypto/keys.proto"; + +message ValidatorSet { + repeated Validator validators = 1; + Validator proposer = 2; + int64 total_voting_power = 3; +} + +message Validator { + bytes address = 1; + tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; + int64 voting_power = 3; + int64 proposer_priority = 4; +} + +message SimpleValidator { + tendermint.crypto.PublicKey pub_key = 1; + int64 voting_power = 2; +} diff --git a/ampd/proto/third_party/tendermint/version/types.proto b/ampd/proto/third_party/tendermint/version/types.proto new file mode 100644 index 000000000..6061868bd --- /dev/null +++ b/ampd/proto/third_party/tendermint/version/types.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package tendermint.version; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; + +import "gogoproto/gogo.proto"; + +// App includes the protocol and software version for the application. +// This information is included in ResponseInfo. The App.Protocol can be +// updated in ResponseEndBlock. +message App { + uint64 protocol = 1; + string software = 2; +} + +// Consensus captures the consensus rules for processing a block in the blockchain, +// including all blockchain data structures and the rules of the application's +// state transition machine. +message Consensus { + option (gogoproto.equal) = true; + + uint64 block = 1; + uint64 app = 2; +} diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs new file mode 100644 index 000000000..7499af9e3 --- /dev/null +++ b/ampd/src/broadcaster/confirm_tx.rs @@ -0,0 +1,346 @@ +use std::time::Duration; + +use axelar_wasm_std::FnExt; +use cosmrs::proto::cosmos::tx::v1beta1::{GetTxRequest, GetTxResponse}; +use error_stack::{report, Report, Result}; +use futures::{StreamExt, TryFutureExt}; +use thiserror::Error; +use tokio::sync::{mpsc, Mutex}; +use tokio::time; +use tokio_stream::wrappers::ReceiverStream; +use tonic::Status; +use tracing::error; + +use super::cosmos; + +#[derive(Debug, PartialEq)] +pub enum TxStatus { + Success, + Failure, +} + +impl From for TxStatus { + fn from(code: u32) -> Self { + match code { + 0 => Self::Success, + _ => Self::Failure, + } + } +} + +#[derive(Debug, PartialEq)] +pub struct TxResponse { + pub status: TxStatus, + pub response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse, +} + +impl From for TxResponse { + fn from(response: cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse) -> Self { + Self { + status: response.code.into(), + response, + } + } +} + +#[derive(Error, Debug)] +pub enum Error { + #[error("failed confirming tx due to tx not found: {tx_hash}")] + Confirmation { tx_hash: String }, + #[error("failed confirming tx due to grpc error {status}: {tx_hash}")] + Grpc { status: Status, tx_hash: String }, + #[error("failed sending tx response")] + SendTxRes(#[from] Box>), +} + +enum ConfirmationResult { + Confirmed(Box), + NotFound, + GRPCError(Status), +} + +pub struct TxConfirmer +where + T: cosmos::BroadcastClient, +{ + client: T, + sleep: Duration, + max_attempts: u32, + tx_hash_receiver: mpsc::Receiver, + tx_res_sender: mpsc::Sender, +} + +impl TxConfirmer +where + T: cosmos::BroadcastClient, +{ + pub fn new( + client: T, + sleep: Duration, + max_attempts: u32, + tx_hash_receiver: mpsc::Receiver, + tx_res_sender: mpsc::Sender, + ) -> Self { + Self { + client, + sleep, + max_attempts, + tx_hash_receiver, + tx_res_sender, + } + } + + pub async fn run(self) -> Result<(), Error> { + let Self { + client, + sleep, + max_attempts, + tx_hash_receiver, + tx_res_sender, + } = self; + let limit = tx_hash_receiver.capacity(); + let client = Mutex::new(client); + let mut tx_hash_stream = ReceiverStream::new(tx_hash_receiver) + .map(|tx_hash| { + confirm_tx(&client, tx_hash, sleep, max_attempts).and_then(|tx| async { + tx_res_sender + .send(tx) + .await + .map_err(Box::new) + .map_err(Into::into) + .map_err(Report::new) + }) + }) + .buffer_unordered(limit); + + while let Some(res) = tx_hash_stream.next().await { + res?; + } + + Ok(()) + } +} + +async fn confirm_tx( + client: &Mutex, + tx_hash: String, + sleep: Duration, + attempts: u32, +) -> Result +where + T: cosmos::BroadcastClient, +{ + for i in 0..attempts { + let req = GetTxRequest { + hash: tx_hash.clone(), + }; + + match client.lock().await.tx(req).await.then(evaluate_tx_response) { + ConfirmationResult::Confirmed(tx) => return Ok(*tx), + ConfirmationResult::NotFound if i == attempts.saturating_sub(1) => { + return Err(report!(Error::Confirmation { tx_hash })) + } + ConfirmationResult::GRPCError(status) if i == attempts.saturating_sub(1) => { + return Err(report!(Error::Grpc { status, tx_hash })) + } + _ => time::sleep(sleep).await, + } + } + + unreachable!("confirmation loop should have returned by now") +} + +fn evaluate_tx_response( + response: core::result::Result, +) -> ConfirmationResult { + match response { + Err(status) => ConfirmationResult::GRPCError(status), + Ok(GetTxResponse { + tx_response: None, .. + }) => ConfirmationResult::NotFound, + Ok(GetTxResponse { + tx_response: Some(response), + .. + }) => ConfirmationResult::Confirmed(Box::new(response.into())), + } +} + +#[cfg(test)] +mod test { + use std::time::Duration; + + use cosmrs::proto::cosmos::tx::v1beta1::GetTxRequest; + use mockall::predicate; + use tokio::sync::mpsc; + use tokio::test; + + use super::{Error, TxConfirmer, TxResponse, TxStatus}; + use crate::broadcaster::cosmos::MockBroadcastClient; + + #[test] + async fn should_confirm_successful_tx_and_send_it_back() { + let tx_hash = "tx_hash".to_string(); + let tx_response = cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse { + code: 0, + txhash: tx_hash.clone(), + ..Default::default() + }; + let tx_res = cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse { + tx_response: Some(tx_response.clone()), + ..Default::default() + }; + + let mut client = MockBroadcastClient::new(); + client + .expect_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .return_once(|_| Ok(tx_res)); + + let sleep = Duration::from_secs(5); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, mut tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash).await.unwrap(); + assert_eq!( + tx_res_receiver.recv().await.unwrap(), + TxResponse { + status: TxStatus::Success, + response: tx_response + } + ); + drop(tx_confirmer_sender); + assert!(handle.await.unwrap().is_ok()); + } + + #[test] + async fn should_confirm_failed_tx_and_send_it_back() { + let tx_hash = "tx_hash".to_string(); + let tx_response = cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse { + code: 1, + txhash: tx_hash.clone(), + ..Default::default() + }; + let tx_res = cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse { + tx_response: Some(tx_response.clone()), + ..Default::default() + }; + + let mut client = MockBroadcastClient::new(); + client + .expect_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .return_once(|_| Ok(tx_res)); + + let sleep = Duration::from_secs(5); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, mut tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash).await.unwrap(); + assert_eq!( + tx_res_receiver.recv().await.unwrap(), + TxResponse { + status: TxStatus::Failure, + response: tx_response + } + ); + drop(tx_confirmer_sender); + assert!(handle.await.unwrap().is_ok()); + } + + #[test] + async fn should_retry_when_tx_is_not_found() { + let tx_hash = "tx_hash".to_string(); + + let mut client = MockBroadcastClient::new(); + client + .expect_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .times(3) + .returning(|_| Ok(cosmrs::proto::cosmos::tx::v1beta1::GetTxResponse::default())); + + let sleep = Duration::from_millis(100); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, _tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash.clone()).await.unwrap(); + assert!(matches!( + handle.await.unwrap().unwrap_err().current_context(), + Error::Confirmation { tx_hash: actual } if *actual == tx_hash + )); + } + + #[test] + async fn should_retry_when_grpc_error() { + let tx_hash = "tx_hash".to_string(); + + let mut client = MockBroadcastClient::new(); + client + .expect_tx() + .with(predicate::eq(GetTxRequest { + hash: tx_hash.clone(), + })) + .times(3) + .returning(|_| { + Err(tonic::Status::new( + tonic::Code::Internal, + "internal server error", + )) + }); + + let sleep = Duration::from_millis(100); + let max_attempts = 3; + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(100); + let (tx_res_sender, _tx_res_receiver) = mpsc::channel(100); + + let tx_confirmer = TxConfirmer::new( + client, + sleep, + max_attempts, + tx_confirmer_receiver, + tx_res_sender, + ); + let handle = tokio::spawn(tx_confirmer.run()); + + tx_confirmer_sender.send(tx_hash.clone()).await.unwrap(); + assert!(matches!( + handle.await.unwrap().unwrap_err().current_context(), + Error::Grpc { tx_hash: actual, status } if *actual == tx_hash && status.code() == tonic::Code::Internal + )); + } +} diff --git a/ampd/src/broadcaster/mod.rs b/ampd/src/broadcaster/mod.rs index 27c493fd7..2cd0b0bf1 100644 --- a/ampd/src/broadcaster/mod.rs +++ b/ampd/src/broadcaster/mod.rs @@ -1,7 +1,7 @@ +use std::cmp; use std::convert::TryInto; use std::ops::Mul; use std::time::Duration; -use std::{cmp, thread}; use async_trait::async_trait; use axelar_wasm_std::FnExt; @@ -10,34 +10,32 @@ use cosmrs::proto::cosmos::auth::v1beta1::{ }; use cosmrs::proto::cosmos::bank::v1beta1::QueryBalanceRequest; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; -use cosmrs::proto::cosmos::tx::v1beta1::{ - BroadcastMode, BroadcastTxRequest, GetTxRequest, GetTxResponse, SimulateRequest, -}; +use cosmrs::proto::cosmos::tx::v1beta1::{BroadcastMode, BroadcastTxRequest, SimulateRequest}; use cosmrs::proto::traits::MessageExt; use cosmrs::tendermint::chain::Id; use cosmrs::tx::Fee; use cosmrs::{Amount, Coin, Denom, Gas}; use dec_coin::DecCoin; -use error_stack::{ensure, report, FutureExt, Report, Result, ResultExt}; +use error_stack::{ensure, report, FutureExt, Result, ResultExt}; use futures::TryFutureExt; use k256::sha2::{Digest, Sha256}; use mockall::automock; use num_traits::{cast, Zero}; use prost::Message; use prost_types::Any; -use report::{LoggableError, ResultCompatExt}; +use report::ResultCompatExt; use serde::{Deserialize, Serialize}; use thiserror::Error; use tonic::{Code, Status}; -use tracing::{debug, info}; +use tracing::info; use tx::Tx; use typed_builder::TypedBuilder; -use valuable::Valuable; use crate::tofnd; use crate::tofnd::grpc::Multisig; use crate::types::{PublicKey, TMAddress}; +pub mod confirm_tx; mod cosmos; mod dec_coin; mod tx; @@ -52,10 +50,6 @@ pub enum Error { FeeEstimation, #[error("broadcast failed")] Broadcast, - #[error("failed to confirm inclusion in block for tx with hash '{tx_hash}'")] - TxConfirmation { tx_hash: String }, - #[error("failed to execute tx")] - Execution, #[error("failed to query balance for address '{address}' and denomination '{denom}'")] QueryBalance { address: TMAddress, denom: Denom }, #[error("failed to query account for address '{address}'")] @@ -102,6 +96,7 @@ impl Default for Config { #[automock] #[async_trait] pub trait Broadcaster { + fn sender_address(&self) -> TMAddress; async fn broadcast(&mut self, msgs: Vec) -> Result; async fn estimate_fee(&mut self, msgs: Vec) -> Result; } @@ -215,6 +210,10 @@ where S: Multisig + Send + Sync, Q: cosmos::AccountQueryClient + Send, { + fn sender_address(&self) -> TMAddress { + self.address.clone() + } + async fn broadcast(&mut self, msgs: Vec) -> Result { let (acc_number, acc_sequence) = self.acc_number_and_sequence().await?; let tx = Tx::builder() @@ -259,10 +258,6 @@ where info!(tx_hash, "broadcasted transaction"); - self.confirm_tx(tx_hash).await?; - - info!(tx_hash, "confirmed transaction"); - self.acc_sequence.replace( acc_sequence .checked_add(1) @@ -352,48 +347,6 @@ where }) .await } - - async fn confirm_tx(&mut self, tx_hash: &str) -> Result<(), Error> { - let mut result: Result<(), Status> = Ok(()); - - for i in 0..self.config.tx_fetch_max_retries.saturating_add(1) { - if i > 0 { - thread::sleep(self.config.tx_fetch_interval) - } - - let response = self - .client - .tx(GetTxRequest { - hash: tx_hash.to_string(), - }) - .await; - - match evaluate_tx_response(response) { - ConfirmationResult::Success => { - if let Err(report) = result { - debug!( - err = LoggableError::from(&report).as_value(), - "tx confirmed after {} retries", i - ) - } - - return Ok(()); - } - ConfirmationResult::Critical(err) => return Err(err), - ConfirmationResult::Retriable(err) => { - if let Err(result) = result.as_mut() { - result.extend_one(err); - } else { - result = Err(err); - } - } - }; - } - - result.change_context(Error::TxConfirmation { - tx_hash: tx_hash.to_string(), - }) - } } fn decode_base_account(account: Any) -> Result { @@ -404,27 +357,6 @@ fn decode_base_account(account: Any) -> Result { .attach_printable_lazy(|| format!("{{ value = {:?} }}", account.value)) } -fn evaluate_tx_response( - response: core::result::Result, -) -> ConfirmationResult { - match response { - Err(err) => ConfirmationResult::Retriable(report!(err)), - Ok(GetTxResponse { - tx_response: None, .. - }) => ConfirmationResult::Retriable(Report::new(Status::not_found("tx not found"))), - Ok(GetTxResponse { - tx_response: Some(response), - .. - }) => match response { - TxResponse { code: 0, .. } => ConfirmationResult::Success, - _ => ConfirmationResult::Critical( - report!(Error::Execution) - .attach_printable(format!("{{ response = {response:?} }}")), - ), - }, - } -} - fn remap_account_not_found_error( response: core::result::Result, ) -> core::result::Result { @@ -435,12 +367,6 @@ fn remap_account_not_found_error( } } -enum ConfirmationResult { - Success, - Retriable(Report), - Critical(Report), -} - #[cfg(test)] mod tests { use cosmrs::bank::MsgSend; @@ -564,72 +490,6 @@ mod tests { )); } - #[test] - async fn tx_confirmation_failed() { - let mut client = MockBroadcastClient::new(); - client.expect_simulate().returning(|_| { - Ok(SimulateResponse { - gas_info: Some(GasInfo { - gas_wanted: 0, - gas_used: 0, - }), - result: None, - }) - }); - client - .expect_broadcast_tx() - .returning(|_| Ok(TxResponse::default())); - client - .expect_tx() - .times((Config::default().tx_fetch_max_retries + 1) as usize) - .returning(|_| Err(Status::deadline_exceeded("time out"))); - - let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; - let msgs = vec![dummy_msg()]; - - assert!(matches!( - broadcaster - .broadcast(msgs) - .await - .unwrap_err() - .current_context(), - Error::TxConfirmation { .. } - )); - } - - #[test] - async fn tx_execution_failed() { - let mut client = MockBroadcastClient::new(); - client.expect_simulate().returning(|_| { - Ok(SimulateResponse { - gas_info: Some(GasInfo { - gas_wanted: 0, - gas_used: 0, - }), - result: None, - }) - }); - client - .expect_broadcast_tx() - .returning(|_| Ok(TxResponse::default())); - client.expect_tx().times(1).returning(|_| { - Ok(GetTxResponse { - tx_response: Some(TxResponse { - code: 32, - ..TxResponse::default() - }), - ..GetTxResponse::default() - }) - }); - - let mut broadcaster = init_validated_broadcaster(None, None, Some(client)).await; - let msgs = vec![dummy_msg()]; - - let report = broadcaster.broadcast(msgs).await.unwrap_err(); - - assert!(matches!(report.current_context(), Error::Execution)); - } - #[test] async fn broadcast_confirmed() { let mut broadcaster = init_validated_broadcaster(None, None, None).await; diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 08804d5fb..a134c2fae 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -2,6 +2,7 @@ use std::time::Duration; use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; use block_height_monitor::BlockHeightMonitor; +use broadcaster::confirm_tx::TxConfirmer; use broadcaster::Broadcaster; use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient as AuthQueryClient; use cosmrs::proto::cosmos::bank::v1beta1::query_client::QueryClient as BankQueryClient; @@ -16,8 +17,10 @@ use router_api::ChainName; use thiserror::Error; use tofnd::grpc::{Multisig, MultisigClient}; use tokio::signal::unix::{signal, SignalKind}; +use tokio::sync::mpsc; use tokio::time::interval; use tokio_util::sync::CancellationToken; +use tonic::transport::Channel; use tracing::info; use types::TMAddress; @@ -92,7 +95,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { .auth_query_client(auth_query_client) .bank_query_client(bank_query_client) .address_prefix(PREFIX.to_string()) - .client(service_client) + .client(service_client.clone()) .signer(multisig_client.clone()) .pub_key((tofnd_config.key_uid, pub_key)) .config(broadcast.clone()) @@ -111,6 +114,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { App::new( tm_client, broadcaster, + service_client, multisig_client, broadcast, event_processor.stream_buffer_size, @@ -145,6 +149,7 @@ where event_subscriber: event_sub::EventSubscriber, event_processor: TaskGroup, broadcaster: QueuedBroadcaster, + tx_confirmer: TxConfirmer>, multisig_client: MultisigClient, block_height_monitor: BlockHeightMonitor, health_check_server: health_check::Server, @@ -159,6 +164,7 @@ where fn new( tm_client: tendermint_rpc::HttpClient, broadcaster: T, + service_client: ServiceClient, multisig_client: MultisigClient, broadcast_cfg: broadcaster::Config, event_buffer_cap: usize, @@ -170,12 +176,24 @@ where let (event_publisher, event_subscriber) = event_sub::EventPublisher::new(tm_client, event_buffer_cap); + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); + let event_processor = TaskGroup::new(); let broadcaster = QueuedBroadcaster::new( broadcaster, broadcast_cfg.batch_gas_limit, broadcast_cfg.queue_cap, interval(broadcast_cfg.broadcast_interval), + tx_confirmer_sender, + tx_res_receiver, + ); + let tx_confirmer = TxConfirmer::new( + service_client, + broadcast_cfg.tx_fetch_interval, + broadcast_cfg.tx_fetch_max_retries.saturating_add(1), + tx_confirmer_receiver, + tx_res_sender, ); Self { @@ -183,6 +201,7 @@ where event_subscriber, event_processor, broadcaster, + tx_confirmer, multisig_client, block_height_monitor, health_check_server, @@ -347,6 +366,7 @@ where event_publisher, event_processor, broadcaster, + tx_confirmer, block_height_monitor, health_check_server, token, @@ -389,6 +409,9 @@ where .run(token) .change_context(Error::EventProcessor) })) + .add_task(CancellableTask::create(|_| { + tx_confirmer.run().change_context(Error::TxConfirmer) + })) .add_task(CancellableTask::create(|_| { broadcaster.run().change_context(Error::Broadcaster) })) @@ -405,6 +428,8 @@ pub enum Error { EventProcessor, #[error("broadcaster failed")] Broadcaster, + #[error("tx confirmer failed")] + TxConfirmer, #[error("tofnd failed")] Tofnd, #[error("connection failed")] diff --git a/ampd/src/queue/mod.rs b/ampd/src/queue/mod.rs index 2a6ce0415..d7568b662 100644 --- a/ampd/src/queue/mod.rs +++ b/ampd/src/queue/mod.rs @@ -1,2 +1,3 @@ mod msg_queue; +mod proto; pub mod queued_broadcaster; diff --git a/ampd/src/queue/proto.rs b/ampd/src/queue/proto.rs new file mode 100644 index 000000000..322f2ab62 --- /dev/null +++ b/ampd/src/queue/proto.rs @@ -0,0 +1,42 @@ +use cosmrs::proto::traits::TypeUrl; + +pub mod axelar { + pub mod auxiliary { + pub mod v1beta1 { + tonic::include_proto!("axelar.auxiliary.v1beta1"); + } + } +} + +mod cosmos { + pub mod base { + pub mod abci { + pub mod v1beta1 { + tonic::include_proto!("cosmos.base.abci.v1beta1"); + } + } + } +} + +mod tendermint { + #[allow(clippy::large_enum_variant)] + pub mod abci { + tonic::include_proto!("tendermint.abci"); + } + + pub mod crypto { + tonic::include_proto!("tendermint.crypto"); + } + + pub mod types { + tonic::include_proto!("tendermint.types"); + } + + pub mod version { + tonic::include_proto!("tendermint.version"); + } +} + +impl TypeUrl for axelar::auxiliary::v1beta1::BatchRequest { + const TYPE_URL: &'static str = "/axelar.auxiliary.v1beta1.BatchRequest"; +} diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index cd3feb4ae..88eb83735 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -1,4 +1,5 @@ use async_trait::async_trait; +use cosmrs::tx::MessageExt; use cosmrs::{Any, Gas}; use error_stack::{self, Report, ResultExt}; use mockall::automock; @@ -6,9 +7,11 @@ use thiserror::Error; use tokio::select; use tokio::sync::{mpsc, oneshot}; use tokio::time::Interval; -use tracing::{info, warn}; +use tracing::{debug, info, warn}; use super::msg_queue::MsgQueue; +use super::proto; +use crate::broadcaster::confirm_tx::{TxResponse, TxStatus}; use crate::broadcaster::Broadcaster; type Result = error_stack::Result; @@ -24,6 +27,10 @@ pub enum Error { Client, #[error("failed to queue message")] Queue, + #[error("failed to confirm transaction")] + TxConfirmation, + #[error("failed to decode tx response")] + DecodeTxResponse(#[from] prost::DecodeError), } #[automock] @@ -58,6 +65,8 @@ where batch_gas_limit: Gas, channel: Option<(mpsc::Sender, mpsc::Receiver)>, broadcast_interval: Interval, + tx_confirmer_sender: mpsc::Sender, + tx_confirmer_receiver: mpsc::Receiver, } impl QueuedBroadcaster @@ -69,6 +78,8 @@ where batch_gas_limit: Gas, capacity: usize, broadcast_interval: Interval, + tx_confirmer_sender: mpsc::Sender, + tx_res_receiver: mpsc::Receiver, ) -> Self { Self { broadcaster, @@ -76,6 +87,8 @@ where batch_gas_limit, channel: Some(mpsc::channel(capacity)), broadcast_interval, + tx_confirmer_sender, + tx_confirmer_receiver: tx_res_receiver, } } @@ -95,10 +108,18 @@ where self.broadcast_all().await?; self.broadcast_interval.reset(); }, + Some(tx_res) = self.tx_confirmer_receiver.recv() => self.handle_tx_res(tx_res).await?, } } + self.clean_up().await + } + + async fn clean_up(mut self) -> Result { self.broadcast_all().await?; + while let Some(tx_res) = self.tx_confirmer_receiver.recv().await { + self.handle_tx_res(tx_res).await?; + } Ok(()) } @@ -114,6 +135,30 @@ where } } + async fn handle_tx_res(&self, tx_res: TxResponse) -> Result { + let tx_hash = tx_res.response.txhash; + + match tx_res.status { + TxStatus::Success => { + tx_res.response.logs.iter().for_each(|log| { + let msg_index = log.msg_index; + + log.events + .iter() + .enumerate() + .for_each(|(event_index, event)| { + debug!(tx_hash, msg_index, event_index, "tx event {:?}", event); + }); + }); + } + TxStatus::Failure => { + warn!(tx_hash, "tx failed"); + } + } + + Ok(()) + } + async fn broadcast_all(&mut self) -> Result { let msgs = self.queue.pop_all(); @@ -122,11 +167,25 @@ where n => { info!(message_count = n, "ready to broadcast messages"); - self.broadcaster - .broadcast(msgs) + let batch_req = proto::axelar::auxiliary::v1beta1::BatchRequest { + sender: self.broadcaster.sender_address().as_ref().to_bytes(), + messages: msgs, + } + .to_any() + .expect("failed to serialize proto message for batch request"); + + let tx_hash = self + .broadcaster + .broadcast(vec![batch_req]) + .await + .change_context(Error::Broadcast)? + .txhash; + self.tx_confirmer_sender + .send(tx_hash) .await - .map(|_| ()) - .change_context(Error::Broadcast) + .change_context(Error::TxConfirmation)?; + + Ok(()) } } } @@ -173,16 +232,20 @@ where mod test { use cosmrs::bank::MsgSend; use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; - use cosmrs::tx::{Fee, Msg}; + use cosmrs::tx::{Fee, MessageExt, Msg}; use cosmrs::{AccountId, Any}; use error_stack::Report; + use futures::StreamExt; use tokio::sync::mpsc; use tokio::test; use tokio::time::{interval, timeout, Duration, Instant}; + use tokio_stream::wrappers::ReceiverStream; use super::{Error, QueuedBroadcaster}; use crate::broadcaster::{self, MockBroadcaster}; + use crate::queue::proto; use crate::queue::queued_broadcaster::BroadcasterClient; + use crate::PREFIX; #[test] async fn should_ignore_msg_when_fee_estimation_fails() { @@ -191,8 +254,17 @@ mod test { .expect_estimate_fee() .return_once(|_| Err(Report::new(broadcaster::Error::FeeEstimation))); + let (tx_confirmer_sender, _tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let broadcast_interval = interval(Duration::from_secs(5)); - let queued_broadcaster = QueuedBroadcaster::new(broadcaster, 100, 10, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + 100, + 10, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); @@ -205,6 +277,7 @@ mod test { Error::EstimateFee )); drop(client); + drop(tx_res_sender); assert!(handle.await.unwrap().is_ok()); } @@ -230,24 +303,39 @@ mod test { payer: None, }) }); - + broadcaster + .expect_sender_address() + .once() + .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); broadcaster .expect_broadcast() - .times(1) + .once() .returning(move |msgs| { - assert_eq!(msgs.len(), tx_count); + assert_eq!(msgs.len(), 1); + let msg = msgs.first().unwrap(); + let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); + assert_eq!(msg.messages.len(), tx_count); + tx.try_send(()) .expect("Failed to send broadcast completion signal"); + Ok(TxResponse::default()) }); + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(interval_duration); broadcast_interval.tick().await; - - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + batch_gas_limit, + tx_count, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); - let _handle = tokio::spawn(queued_broadcaster.run()); + let handle = tokio::spawn(queued_broadcaster.run()); let start_time = Instant::now(); @@ -264,8 +352,14 @@ mod test { assert!(elapsed > interval_duration); assert!(elapsed < interval_duration * 2); } - Err(_) => panic!("Broadcast did not occur within the expected timeframe"), + Err(_) => panic!("broadcast did not occur within the expected timeframe"), } + + drop(client); + drop(tx_res_sender); + + assert!(handle.await.unwrap().is_ok()); + assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 1); } #[test(start_paused = true)] @@ -277,52 +371,73 @@ mod test { let interval_duration = Duration::from_secs(5); let mut broadcaster = MockBroadcaster::new(); - broadcaster.expect_estimate_fee().returning(move |_| { - Ok(Fee { - gas_limit, - amount: vec![], - granter: None, - payer: None, - }) - }); broadcaster - .expect_broadcast() - .once() - .returning(move |msgs| { - assert_eq!(msgs.len(), 9); - - Ok(TxResponse::default()) + .expect_estimate_fee() + .times(tx_count) + .returning(move |_| { + Ok(Fee { + gas_limit, + amount: vec![], + granter: None, + payer: None, + }) }); + broadcaster + .expect_sender_address() + .times(3) + .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); + let mut call_count = 0; broadcaster .expect_broadcast() - .once() + .times(3) .returning(move |msgs| { - assert_eq!(msgs.len(), 9); + call_count += 1; + + assert_eq!(msgs.len(), 1); + let msg = msgs.first().unwrap(); + let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); + + if call_count < 3 { + assert_eq!(msg.messages.len(), 9); + } else { + assert_eq!(msg.messages.len(), 2); + } Ok(TxResponse::default()) }); - + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(interval_duration); + // get rid of tick on startup broadcast_interval.tick().await; - - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, batch_size, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + batch_gas_limit, + batch_size, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); - let _handle = tokio::spawn(queued_broadcaster.run()); + let handle = tokio::spawn(queued_broadcaster.run()); let start_time = Instant::now(); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - // Advance time by a small amount to allow processing tokio::time::advance(Duration::from_millis(100)).await; let elapsed = start_time.elapsed(); - // Assert that broadcasts happened faster than the interval assert!(elapsed < interval_duration); + + drop(client); + drop(tx_res_sender); + + assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 3); + assert!(handle.await.unwrap().is_ok()); } #[test(start_paused = true)] @@ -344,35 +459,51 @@ mod test { }) }); broadcaster - .expect_broadcast() - .once() - .returning(move |msgs| { - assert_eq!(msgs.len(), tx_count - 1); - - Ok(TxResponse::default()) - }); + .expect_sender_address() + .times(2) + .returning(|| AccountId::new(PREFIX, &[1, 2, 3]).unwrap().into()); + let mut broadcast_count = 0; broadcaster .expect_broadcast() - .once() + .times(2) .returning(move |msgs| { + broadcast_count += 1; + assert_eq!(msgs.len(), 1); + let msg = msgs.first().unwrap(); + let msg = proto::axelar::auxiliary::v1beta1::BatchRequest::from_any(msg).unwrap(); + + if broadcast_count == 1 { + assert_eq!(msg.messages.len(), tx_count - 1); + } else { + assert_eq!(msg.messages.len(), 1); + } + Ok(TxResponse::default()) }); + let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); + let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); let mut broadcast_interval = interval(Duration::from_secs(5)); // get rid of tick on startup broadcast_interval.tick().await; - - let queued_broadcaster = - QueuedBroadcaster::new(broadcaster, batch_gas_limit, tx_count, broadcast_interval); + let queued_broadcaster = QueuedBroadcaster::new( + broadcaster, + batch_gas_limit, + tx_count, + broadcast_interval, + tx_confirmer_sender, + tx_res_receiver, + ); let client = queued_broadcaster.client(); let handle = tokio::spawn(queued_broadcaster.run()); for _ in 0..tx_count { client.broadcast(dummy_msg()).await.unwrap(); } - drop(client); + drop(tx_res_sender); + assert_eq!(ReceiverStream::new(tx_confirmer_receiver).count().await, 2); assert!(handle.await.unwrap().is_ok()); } From 174681fa155f577af1c6bb4c0055340217e37960 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Mon, 12 Aug 2024 11:27:18 -0400 Subject: [PATCH 149/168] ci: cancel ongoing checks on push (#580) --- .github/workflows/basic.yaml | 6 ++++-- .github/workflows/codecov.yaml | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/basic.yaml b/.github/workflows/basic.yaml index d0df1cd1d..8c5721efe 100644 --- a/.github/workflows/basic.yaml +++ b/.github/workflows/basic.yaml @@ -1,13 +1,15 @@ # Based on https://github.com/actions-rs/example/blob/master/.github/workflows/quickstart.yml +name: Basic on: pull_request: push: branches: - main - - releases/** -name: Basic +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: test: diff --git a/.github/workflows/codecov.yaml b/.github/workflows/codecov.yaml index 51a41df6d..11cf307cc 100644 --- a/.github/workflows/codecov.yaml +++ b/.github/workflows/codecov.yaml @@ -7,6 +7,10 @@ on: - main - releases/** +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: coverage: runs-on: blacksmith-16vcpu-ubuntu-2204 From be07fbcc1d552f4d3fa46a6a5c310a10c71961b4 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 12 Aug 2024 14:57:15 -0400 Subject: [PATCH 150/168] chore: upgrade and unify k256 dependency (#581) --- Cargo.toml | 1 + ampd/Cargo.toml | 2 +- contracts/multisig-prover/Cargo.toml | 8 ++++---- contracts/multisig/Cargo.toml | 2 +- integration-tests/Cargo.toml | 2 +- packages/evm-gateway/Cargo.toml | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 879b4802b..343ef5f38 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ msgs-derive = { version = "^1.0.0", path = "packages/msgs-derive" } multisig-prover = { version = "^1.0.0", path = "contracts/multisig-prover" } num-traits = { version = "0.2.14", default-features = false } service-registry = { version = "^1.0.0", path = "contracts/service-registry" } +k256 = { version = "0.13.1", features = ["ecdsa"] } gateway = { version = "^1.0.0", path = "contracts/gateway" } gateway-api = { version = "^1.0.0", path = "packages/gateway-api" } router-api = { version = "^1.0.0", path = "packages/router-api" } diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index 634aa841a..0d8a08928 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -32,7 +32,7 @@ futures = "0.3.25" hex = { version = "0.4.3", features = ["serde"] } humantime-serde = "1.1.1" itertools = { workspace = true } -k256 = { version = "0.13.1", features = ["ecdsa"] } +k256 = { workspace = true } mockall = "0.11.3" move-core-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.26.2" } multisig = { workspace = true, features = ["library"] } diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 83b386b0f..a6aa1bff2 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -6,9 +6,9 @@ edition = { workspace = true } description = "Multisig prover contract" exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", + # Those files are rust-optimizer artifacts. You might want to commit them for convenience, but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -49,7 +49,7 @@ gateway = { workspace = true } gateway-api = { workspace = true } hex = { version = "0.4.3", default-features = false, features = [] } itertools = "0.11.0" -k256 = { version = "0.13.1", features = ["ecdsa"] } +k256 = { workspace = true } msgs-derive = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 5f1d2f571..2b3058375 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -52,7 +52,7 @@ enum-display-derive = "0.1.1" error-stack = { workspace = true } getrandom = { version = "0.2", default-features = false, features = ["custom"] } itertools = "0.11.0" -k256 = { version = "0.13.1", features = ["ecdsa"] } +k256 = { workspace = true } msgs-derive = { workspace = true } report = { workspace = true } rewards = { workspace = true, features = ["library"] } diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index ad28b08a0..b60cf7729 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -36,7 +36,7 @@ cw-multi-test = "0.15.1" error-stack = { workspace = true } gateway = { workspace = true } gateway-api = { workspace = true } -k256 = { version = "0.13.1", features = ["ecdsa"] } +k256 = { workspace = true } multisig = { workspace = true } multisig-prover = { workspace = true } rand = "0.8.5" diff --git a/packages/evm-gateway/Cargo.toml b/packages/evm-gateway/Cargo.toml index 8aad6ea83..d613723b8 100644 --- a/packages/evm-gateway/Cargo.toml +++ b/packages/evm-gateway/Cargo.toml @@ -11,7 +11,7 @@ cosmwasm-std = { workspace = true } error-stack = { workspace = true } ethers-contract = { workspace = true } ethers-core = { workspace = true } -k256 = { version = "0.13.1", features = ["ecdsa"] } +k256 = { workspace = true } multisig = { workspace = true } router-api = { workspace = true } sha3 = { workspace = true } From 0decfcf387be6d99be92d6b905426e9955462a5b Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 12 Aug 2024 15:37:10 -0400 Subject: [PATCH 151/168] chore(gateway): remove v0.2.3 migration (#568) --- contracts/gateway/src/contract.rs | 6 +- .../gateway/src/contract/migrations/mod.rs | 2 +- .../gateway/src/contract/migrations/v0_2_3.rs | 214 ------------------ 3 files changed, 2 insertions(+), 220 deletions(-) delete mode 100644 contracts/gateway/src/contract/migrations/v0_2_3.rs diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 9787a139d..90fb5c13e 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -8,7 +8,6 @@ use error_stack::ResultExt; use gateway_api::msg::{ExecuteMsg, QueryMsg}; use router_api::client::Router; -use crate::contract::migrations::v0_2_3; use crate::msg::InstantiateMsg; use crate::state; use crate::state::Config; @@ -22,8 +21,6 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("invalid store access")] - InvalidStoreAccess, #[error("batch contains duplicate message ids")] DuplicateMessageIds, #[error("invalid address")] @@ -46,11 +43,10 @@ pub enum Error { #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( - deps: DepsMut, + _deps: DepsMut, _env: Env, _msg: Empty, ) -> Result { - v0_2_3::migrate(deps.storage)?; Ok(Response::default()) } diff --git a/contracts/gateway/src/contract/migrations/mod.rs b/contracts/gateway/src/contract/migrations/mod.rs index 3f8ffb3bd..8b1378917 100644 --- a/contracts/gateway/src/contract/migrations/mod.rs +++ b/contracts/gateway/src/contract/migrations/mod.rs @@ -1 +1 @@ -pub mod v0_2_3; + diff --git a/contracts/gateway/src/contract/migrations/v0_2_3.rs b/contracts/gateway/src/contract/migrations/v0_2_3.rs deleted file mode 100644 index 48ff502c6..000000000 --- a/contracts/gateway/src/contract/migrations/v0_2_3.rs +++ /dev/null @@ -1,214 +0,0 @@ -#![allow(deprecated)] - -use std::any::type_name; - -use axelar_wasm_std::error::ContractError; -use axelar_wasm_std::nonempty; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{StdError, StdResult, Storage}; -use cw_storage_plus::{Key, KeyDeserialize, Map, PrimaryKey}; -use router_api::{Address, ChainName, ChainNameRaw}; - -use crate::contract::{CONTRACT_NAME, CONTRACT_VERSION}; - -const BASE_VERSION: &str = "0.2.3"; - -pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { - cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; - - delete_outgoing_messages(storage); - - cw2::set_contract_version(storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - Ok(()) -} - -fn delete_outgoing_messages(storage: &mut dyn Storage) { - OUTGOING_MESSAGES.clear(storage); -} - -#[deprecated(since = "0.2.3", note = "only used during migration")] -const OUTGOING_MESSAGES_NAME: &str = "outgoing_messages"; - -#[deprecated(since = "0.2.3", note = "only used during migration")] -const OUTGOING_MESSAGES: Map<&CrossChainId, Message> = Map::new(OUTGOING_MESSAGES_NAME); - -#[cw_serde] -#[derive(Eq, Hash)] -#[deprecated(since = "0.2.3", note = "only used during migration")] -pub struct Message { - pub cc_id: CrossChainId, - pub source_address: Address, - pub destination_chain: ChainName, - pub destination_address: Address, - /// for better user experience, the payload hash gets encoded into hex at the edges (input/output), - /// but internally, we treat it as raw bytes to enforce its format. - #[serde(with = "axelar_wasm_std::hex")] - #[schemars(with = "String")] // necessary attribute in conjunction with #[serde(with ...)] - pub payload_hash: [u8; 32], -} - -#[cw_serde] -#[derive(Eq, Hash)] -#[deprecated(since = "0.2.3", note = "only used during migration")] -pub struct CrossChainId { - pub chain: ChainNameRaw, - pub id: nonempty::String, -} - -impl PrimaryKey<'_> for CrossChainId { - type Prefix = ChainNameRaw; - type SubPrefix = (); - type Suffix = String; - type SuperSuffix = (ChainNameRaw, String); - - fn key(&self) -> Vec { - let mut keys = self.chain.key(); - keys.extend(self.id.key()); - keys - } -} - -impl KeyDeserialize for &CrossChainId { - type Output = CrossChainId; - - fn from_vec(value: Vec) -> StdResult { - let (chain, id) = <(ChainNameRaw, String)>::from_vec(value)?; - Ok(CrossChainId { - chain, - id: id - .try_into() - .map_err(|err| StdError::parse_err(type_name::(), err))?, - }) - } -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; - use error_stack::ResultExt; - - use crate::contract::migrations::v0_2_3; - use crate::contract::{Error, CONTRACT_NAME, CONTRACT_VERSION}; - use crate::msg::InstantiateMsg; - use crate::state; - use crate::state::Config; - - #[test] - fn migrate_checks_contract_version() { - let mut deps = mock_dependencies(); - instantiate_contract(deps.as_mut()); - - cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); - - assert!(v0_2_3::migrate(deps.as_mut().storage).is_err()); - - cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_2_3::BASE_VERSION) - .unwrap(); - - assert!(v0_2_3::migrate(deps.as_mut().storage).is_ok()); - } - - #[test] - fn migrate_sets_contract_version() { - let mut deps = mock_dependencies(); - instantiate_contract(deps.as_mut()); - - v0_2_3::migrate(deps.as_mut().storage).unwrap(); - - let contract_version = cw2::get_contract_version(deps.as_mut().storage).unwrap(); - assert_eq!(contract_version.contract, CONTRACT_NAME); - assert_eq!(contract_version.version, CONTRACT_VERSION); - } - - fn instantiate_contract(deps: DepsMut) { - instantiate( - deps, - mock_env(), - mock_info("admin", &[]), - InstantiateMsg { - verifier_address: "verifier".to_string(), - router_address: "router".to_string(), - }, - ) - .unwrap(); - } - - #[test] - fn migrate_outgoing_messages() { - let mut deps = mock_dependencies(); - - instantiate_contract(deps.as_mut()); - - let msgs = vec![ - v0_2_3::Message { - cc_id: v0_2_3::CrossChainId { - id: "id1".try_into().unwrap(), - chain: "chain1".try_into().unwrap(), - }, - source_address: "source-address".parse().unwrap(), - destination_chain: "destination".parse().unwrap(), - destination_address: "destination-address".parse().unwrap(), - payload_hash: [1; 32], - }, - v0_2_3::Message { - cc_id: v0_2_3::CrossChainId { - id: "id2".try_into().unwrap(), - chain: "chain2".try_into().unwrap(), - }, - source_address: "source-address2".parse().unwrap(), - destination_chain: "destination2".parse().unwrap(), - destination_address: "destination-address2".parse().unwrap(), - payload_hash: [2; 32], - }, - v0_2_3::Message { - cc_id: v0_2_3::CrossChainId { - id: "id3".try_into().unwrap(), - chain: "chain3".try_into().unwrap(), - }, - source_address: "source-address3".parse().unwrap(), - destination_chain: "destination3".parse().unwrap(), - destination_address: "destination-address3".parse().unwrap(), - payload_hash: [3; 32], - }, - ]; - - for msg in msgs.iter() { - v0_2_3::OUTGOING_MESSAGES - .save(deps.as_mut().storage, &msg.cc_id, msg) - .unwrap(); - } - - assert!(v0_2_3::migrate(deps.as_mut().storage).is_ok()); - - assert!(v0_2_3::OUTGOING_MESSAGES.is_empty(deps.as_ref().storage)) - } - - #[deprecated(since = "0.2.3", note = "only used to test the migration")] - pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_2_3::BASE_VERSION)?; - - let router = deps - .api - .addr_validate(&msg.router_address) - .change_context(Error::InvalidAddress) - .attach_printable(msg.router_address)?; - - let verifier = deps - .api - .addr_validate(&msg.verifier_address) - .change_context(Error::InvalidAddress) - .attach_printable(msg.verifier_address)?; - - state::save_config(deps.storage, &Config { verifier, router }) - .change_context(Error::InvalidStoreAccess)?; - - Ok(Response::new()) - } -} From 2acf237d4c8cbe20e844436c2b94259408020597 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Mon, 12 Aug 2024 16:54:07 -0400 Subject: [PATCH 152/168] refactor: move cosmwasm address validation into axelar-wasm-std (#567) --- contracts/axelarnet-gateway/src/contract.rs | 7 +- contracts/coordinator/src/contract.rs | 4 +- contracts/gateway/src/contract.rs | 25 ++----- contracts/multisig-prover/src/contract.rs | 32 +++++---- .../multisig-prover/src/contract/execute.rs | 9 ++- contracts/multisig/src/contract.rs | 56 +++++++++------- contracts/nexus-gateway/src/contract.rs | 5 +- contracts/rewards/src/contract.rs | 10 +-- contracts/router/src/contract.rs | 12 ++-- contracts/service-registry/src/contract.rs | 16 +++-- .../service-registry/src/contract/query.rs | 10 ++- contracts/voting-verifier/src/client.rs | 2 +- contracts/voting-verifier/src/contract.rs | 13 ++-- .../voting-verifier/src/contract/execute.rs | 2 +- .../src/contract/migrations/v0_5_0.rs | 2 +- contracts/voting-verifier/src/msg.rs | 2 +- contracts/voting-verifier/src/state.rs | 2 +- .../src/voting_verifier_contract.rs | 2 +- packages/axelar-wasm-std/src/address.rs | 67 +++++++++++++++++++ .../axelar-wasm-std/src/address_format.rs | 23 ------- packages/axelar-wasm-std/src/lib.rs | 2 +- 21 files changed, 182 insertions(+), 121 deletions(-) create mode 100644 packages/axelar-wasm-std/src/address.rs delete mode 100644 packages/axelar-wasm-std/src/address_format.rs diff --git a/contracts/axelarnet-gateway/src/contract.rs b/contracts/axelarnet-gateway/src/contract.rs index 53f0bc44b..3c2fabf32 100644 --- a/contracts/axelarnet-gateway/src/contract.rs +++ b/contracts/axelarnet-gateway/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::FnExt; +use axelar_wasm_std::{address, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; @@ -67,10 +67,7 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let router = deps - .api - .addr_validate(&msg.router_address) - .change_context(Error::InvalidAddress(msg.router_address.clone()))?; + let router = address::validate_cosmwasm_address(deps.api, &msg.router_address)?; let config = Config { chain_name: msg.chain_name, diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index 2199452ee..fb1b7fee6 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -2,7 +2,7 @@ mod execute; mod query; mod migrations; -use axelar_wasm_std::{permission_control, FnExt}; +use axelar_wasm_std::{address, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -42,7 +42,7 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let governance = deps.api.addr_validate(&msg.governance_address)?; + let governance = address::validate_cosmwasm_address(deps.api, &msg.governance_address)?; permission_control::set_governance(deps.storage, &governance)?; Ok(Response::default()) diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 90fb5c13e..a3ec708fd 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use axelar_wasm_std::FnExt; +use axelar_wasm_std::{address, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response}; @@ -23,8 +23,6 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); pub enum Error { #[error("batch contains duplicate message ids")] DuplicateMessageIds, - #[error("invalid address")] - InvalidAddress, #[error("failed to query message status")] MessageStatus, #[error("failed to verify messages")] @@ -59,17 +57,8 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let router = deps - .api - .addr_validate(&msg.router_address) - .change_context(Error::InvalidAddress) - .attach_printable(msg.router_address)?; - - let verifier = deps - .api - .addr_validate(&msg.verifier_address) - .change_context(Error::InvalidAddress) - .attach_printable(msg.verifier_address)?; + let router = address::validate_cosmwasm_address(deps.api, &msg.router_address)?; + let verifier = address::validate_cosmwasm_address(deps.api, &msg.verifier_address)?; state::save_config(deps.storage, &Config { verifier, router })?; Ok(Response::new()) @@ -85,15 +74,15 @@ pub fn execute( let config = state::load_config(deps.storage).change_context(Error::Execute)?; let verifier = client::Client::new(deps.querier, config.verifier).into(); - let router = Router { - address: config.router, - }; - match msg.ensure_permissions(deps.storage, &info.sender)? { ExecuteMsg::VerifyMessages(msgs) => { execute::verify_messages(&verifier, msgs).change_context(Error::VerifyMessages) } ExecuteMsg::RouteMessages(msgs) => { + let router = Router { + address: config.router, + }; + if info.sender == router.address { execute::route_outgoing_messages(deps.storage, msgs) .change_context(Error::RouteOutgoingMessages) diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 068d7d41b..85a5763e9 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::permission_control; +use axelar_wasm_std::{address, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -29,11 +29,17 @@ pub fn instantiate( cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let config = Config { - gateway: deps.api.addr_validate(&msg.gateway_address)?, - multisig: deps.api.addr_validate(&msg.multisig_address)?, - coordinator: deps.api.addr_validate(&msg.coordinator_address)?, - service_registry: deps.api.addr_validate(&msg.service_registry_address)?, - voting_verifier: deps.api.addr_validate(&msg.voting_verifier_address)?, + gateway: address::validate_cosmwasm_address(deps.api, &msg.gateway_address)?, + multisig: address::validate_cosmwasm_address(deps.api, &msg.multisig_address)?, + coordinator: address::validate_cosmwasm_address(deps.api, &msg.coordinator_address)?, + service_registry: address::validate_cosmwasm_address( + deps.api, + &msg.service_registry_address, + )?, + voting_verifier: address::validate_cosmwasm_address( + deps.api, + &msg.voting_verifier_address, + )?, signing_threshold: msg.signing_threshold, service_name: msg.service_name, chain_name: msg.chain_name.parse()?, @@ -44,10 +50,13 @@ pub fn instantiate( }; CONFIG.save(deps.storage, &config)?; - permission_control::set_admin(deps.storage, &deps.api.addr_validate(&msg.admin_address)?)?; + permission_control::set_admin( + deps.storage, + &address::validate_cosmwasm_address(deps.api, &msg.admin_address)?, + )?; permission_control::set_governance( deps.storage, - &deps.api.addr_validate(&msg.governance_address)?, + &address::validate_cosmwasm_address(deps.api, &msg.governance_address)?, )?; Ok(Response::default()) @@ -125,8 +134,7 @@ mod tests { mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; use cosmwasm_std::{ - from_json, Addr, Api, Empty, Fraction, OwnedDeps, SubMsgResponse, SubMsgResult, Uint128, - Uint64, + from_json, Addr, Empty, Fraction, OwnedDeps, SubMsgResponse, SubMsgResult, Uint128, Uint64, }; use multisig::msg::Signer; use multisig::verifier_set::VerifierSet; @@ -339,7 +347,7 @@ mod tests { assert_eq!( permission_control::sender_role( deps.as_ref().storage, - &deps.api.addr_validate(admin).unwrap() + &address::validate_cosmwasm_address(&deps.api, admin).unwrap() ) .unwrap(), Permission::Admin.into() @@ -348,7 +356,7 @@ mod tests { assert_eq!( permission_control::sender_role( deps.as_ref().storage, - &deps.api.addr_validate(governance).unwrap() + &address::validate_cosmwasm_address(&deps.api, governance).unwrap() ) .unwrap(), Permission::Governance.into() diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index 1e9872a09..f49e029c0 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, HashSet}; use axelar_wasm_std::permission_control::Permission; use axelar_wasm_std::snapshot::{Participant, Snapshot}; -use axelar_wasm_std::{permission_control, FnExt, MajorityThreshold, VerificationStatus}; +use axelar_wasm_std::{address, permission_control, FnExt, MajorityThreshold, VerificationStatus}; use cosmwasm_std::{ to_json_binary, wasm_execute, Addr, DepsMut, Env, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, WasmQuery, @@ -412,8 +412,11 @@ pub fn update_signing_threshold( Ok(Response::new()) } -pub fn update_admin(deps: DepsMut, new_admin_address: String) -> Result { - let new_admin = deps.api.addr_validate(&new_admin_address)?; +pub fn update_admin( + deps: DepsMut, + new_admin_address: String, +) -> Result { + let new_admin = address::validate_cosmwasm_address(deps.api, &new_admin_address)?; permission_control::set_admin(deps.storage, &new_admin)?; Ok(Response::new()) } diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 02c70059a..7ef4af54c 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1,13 +1,13 @@ use std::collections::HashMap; -use axelar_wasm_std::{killswitch, permission_control, FnExt}; +use axelar_wasm_std::{address, killswitch, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdError, - StdResult, Storage, Uint64, + to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, + Storage, Uint64, }; -use error_stack::{report, ResultExt}; +use error_stack::{report, Report, ResultExt}; use itertools::Itertools; use router_api::ChainName; @@ -32,13 +32,12 @@ pub fn migrate( _env: Env, msg: MigrationMsg, ) -> Result { - let admin = deps.api.addr_validate(&msg.admin_address)?; + let admin = address::validate_cosmwasm_address(deps.api, &msg.admin_address)?; let authorized_callers = msg .authorized_callers .into_iter() .map(|(contract_address, chain_name)| { - deps.api - .addr_validate(&contract_address) + address::validate_cosmwasm_address(deps.api, &contract_address) .map(|addr| (addr, chain_name)) }) .try_collect()?; @@ -62,8 +61,8 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let admin = deps.api.addr_validate(&msg.admin_address)?; - let governance = deps.api.addr_validate(&msg.governance_address)?; + let admin = address::validate_cosmwasm_address(deps.api, &msg.admin_address)?; + let governance = address::validate_cosmwasm_address(deps.api, &msg.governance_address)?; permission_control::set_admin(deps.storage, &admin)?; permission_control::set_governance(deps.storage, &governance)?; @@ -71,7 +70,7 @@ pub fn instantiate( killswitch::init(deps.storage, killswitch::State::Disengaged)?; let config = Config { - rewards_contract: deps.api.addr_validate(&msg.rewards_address)?, + rewards_contract: address::validate_cosmwasm_address(deps.api, &msg.rewards_address)?, block_expiry: msg.block_expiry, }; CONFIG.save(deps.storage, &config)?; @@ -100,7 +99,7 @@ pub fn execute( sig_verifier, } => { let sig_verifier = sig_verifier - .map(|addr| deps.api.addr_validate(&addr)) + .map(|addr| address::validate_cosmwasm_address(deps.api, &addr)) .transpose()?; execute::start_signing_session( deps, @@ -140,13 +139,14 @@ pub fn execute( fn validate_contract_addresses( deps: &DepsMut, contracts: HashMap, -) -> Result, StdError> { +) -> Result, Report> { contracts .into_iter() .map(|(contract_address, chain_name)| { - deps.api - .addr_validate(&contract_address) - .map(|addr| (addr, chain_name)) + Ok(( + address::validate_cosmwasm_address(deps.api, &contract_address)?, + chain_name, + )) }) .try_collect() } @@ -165,29 +165,34 @@ fn can_start_signing_session( } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { +pub fn query( + deps: Deps, + _env: Env, + msg: QueryMsg, +) -> Result { match msg { - QueryMsg::Multisig { session_id } => to_json_binary(&query::multisig(deps, session_id)?), + QueryMsg::Multisig { session_id } => to_json_binary(&query::multisig(deps, session_id)?)?, QueryMsg::VerifierSet { verifier_set_id } => { - to_json_binary(&query::verifier_set(deps, verifier_set_id)?) + to_json_binary(&query::verifier_set(deps, verifier_set_id)?)? } QueryMsg::PublicKey { verifier_address, key_type, } => to_json_binary(&query::public_key( deps, - deps.api.addr_validate(&verifier_address)?, + address::validate_cosmwasm_address(deps.api, &verifier_address)?, key_type, - )?), + )?)?, QueryMsg::IsCallerAuthorized { contract_address, chain_name, } => to_json_binary(&query::caller_authorized( deps, - deps.api.addr_validate(&contract_address)?, + address::validate_cosmwasm_address(deps.api, &contract_address)?, chain_name, - )?), + )?)?, } + .then(Ok) } #[cfg(feature = "test")] @@ -254,7 +259,10 @@ mod tests { execute(deps, env, info.clone(), msg).map(|res| (res, verifier_set)) } - fn query_verifier_set(verifier_set_id: &str, deps: Deps) -> StdResult { + fn query_verifier_set( + verifier_set_id: &str, + deps: Deps, + ) -> Result { let env = mock_env(); query( deps, @@ -368,7 +376,7 @@ mod tests { deps: Deps, verifier: Addr, key_type: KeyType, - ) -> StdResult { + ) -> Result { let env = mock_env(); query( deps, diff --git a/contracts/nexus-gateway/src/contract.rs b/contracts/nexus-gateway/src/contract.rs index 622d2efa2..5ca6537d1 100644 --- a/contracts/nexus-gateway/src/contract.rs +++ b/contracts/nexus-gateway/src/contract.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::address; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Addr, DepsMut, Empty, Env, MessageInfo, Response, Storage}; @@ -36,8 +37,8 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let nexus = deps.api.addr_validate(&msg.nexus)?; - let router = deps.api.addr_validate(&msg.router)?; + let nexus = address::validate_cosmwasm_address(deps.api, &msg.nexus)?; + let router = address::validate_cosmwasm_address(deps.api, &msg.router)?; state::save_config(deps.storage, Config { nexus, router }).expect("config must be saved"); diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index 142cf5d1a..b5f6e8fdc 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::{nonempty, permission_control}; +use axelar_wasm_std::{address, nonempty, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -43,7 +43,7 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let governance = deps.api.addr_validate(&msg.governance_address)?; + let governance = address::validate_cosmwasm_address(deps.api, &msg.governance_address)?; permission_control::set_governance(deps.storage, &governance)?; CONFIG.save( @@ -80,7 +80,7 @@ pub fn execute( event_id, verifier_address, } => { - let verifier_address = deps.api.addr_validate(&verifier_address)?; + let verifier_address = address::validate_cosmwasm_address(deps.api, &verifier_address)?; let pool_id = PoolId { chain_name, contract: info.sender, @@ -96,7 +96,7 @@ pub fn execute( Ok(Response::new()) } ExecuteMsg::AddRewards { pool_id } => { - deps.api.addr_validate(pool_id.contract.as_str())?; + address::validate_cosmwasm_address(deps.api, pool_id.contract.as_str())?; let amount = info .funds @@ -118,7 +118,7 @@ pub fn execute( pool_id, epoch_count, } => { - deps.api.addr_validate(pool_id.contract.as_str())?; + address::validate_cosmwasm_address(deps.api, pool_id.contract.as_str())?; let rewards = execute::distribute_rewards(deps.storage, pool_id, env.block.height, epoch_count)?; diff --git a/contracts/router/src/contract.rs b/contracts/router/src/contract.rs index ac911eb2d..9c2f7f688 100644 --- a/contracts/router/src/contract.rs +++ b/contracts/router/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::{killswitch, permission_control, FnExt}; +use axelar_wasm_std::{address, killswitch, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -43,9 +43,9 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let admin = deps.api.addr_validate(&msg.admin_address)?; - let governance = deps.api.addr_validate(&msg.governance_address)?; - let nexus_gateway = deps.api.addr_validate(&msg.nexus_gateway)?; + let admin = address::validate_cosmwasm_address(deps.api, &msg.admin_address)?; + let governance = address::validate_cosmwasm_address(deps.api, &msg.governance_address)?; + let nexus_gateway = address::validate_cosmwasm_address(deps.api, &msg.nexus_gateway)?; permission_control::set_admin(deps.storage, &admin)?; permission_control::set_governance(deps.storage, &governance)?; @@ -84,14 +84,14 @@ pub fn execute( gateway_address, msg_id_format, } => { - let gateway_address = deps.api.addr_validate(&gateway_address)?; + let gateway_address = address::validate_cosmwasm_address(deps.api, &gateway_address)?; execute::register_chain(deps.storage, chain, gateway_address, msg_id_format) } ExecuteMsg::UpgradeGateway { chain, contract_address, } => { - let contract_address = deps.api.addr_validate(&contract_address)?; + let contract_address = address::validate_cosmwasm_address(deps.api, &contract_address)?; execute::upgrade_gateway(deps.storage, chain, contract_address) } ExecuteMsg::FreezeChains { chains } => execute::freeze_chains(deps.storage, chains), diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 04899b415..f0cf4def1 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::{permission_control, FnExt}; +use axelar_wasm_std::{address, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -27,7 +27,7 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let governance = deps.api.addr_validate(&msg.governance_account)?; + let governance = address::validate_cosmwasm_address(deps.api, &msg.governance_account)?; permission_control::set_governance(deps.storage, &governance)?; Ok(Response::default()) @@ -67,7 +67,7 @@ pub fn execute( } => { let verifiers = verifiers .into_iter() - .map(|veriier| deps.api.addr_validate(&veriier)) + .map(|verifier| address::validate_cosmwasm_address(deps.api, &verifier)) .collect::, _>>()?; execute::update_verifier_authorization_status( deps, @@ -82,7 +82,7 @@ pub fn execute( } => { let verifiers = verifiers .into_iter() - .map(|verifier| deps.api.addr_validate(&verifier)) + .map(|verifier| address::validate_cosmwasm_address(deps.api, &verifier)) .collect::, _>>()?; execute::update_verifier_authorization_status( deps, @@ -97,7 +97,7 @@ pub fn execute( } => { let verifiers = verifiers .into_iter() - .map(|verifier| deps.api.addr_validate(&verifier)) + .map(|verifier| address::validate_cosmwasm_address(deps.api, &verifier)) .collect::, _>>()?; execute::update_verifier_authorization_status( deps, @@ -145,7 +145,11 @@ fn match_verifier( } #[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::ActiveVerifiers { service_name, diff --git a/contracts/service-registry/src/contract/query.rs b/contracts/service-registry/src/contract/query.rs index 241bfce10..8e48a3b5a 100644 --- a/contracts/service-registry/src/contract/query.rs +++ b/contracts/service-registry/src/contract/query.rs @@ -40,13 +40,17 @@ pub fn verifier( deps: Deps, service_name: String, verifier: String, -) -> Result { +) -> Result { VERIFIERS .may_load( deps.storage, - (&service_name, &deps.api.addr_validate(&verifier)?), + ( + &service_name, + &address::validate_cosmwasm_address(deps.api, &verifier)?, + ), )? - .ok_or(ContractError::VerifierNotFound) + .ok_or(ContractError::VerifierNotFound)? + .then(Ok) } pub fn service(deps: Deps, service_name: String) -> Result { diff --git a/contracts/voting-verifier/src/client.rs b/contracts/voting-verifier/src/client.rs index 1414e7097..a8162ef4d 100644 --- a/contracts/voting-verifier/src/client.rs +++ b/contracts/voting-verifier/src/client.rs @@ -215,7 +215,7 @@ mod test { source_chain: "source-chain".parse().unwrap(), rewards_address: "rewards".try_into().unwrap(), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, - address_format: axelar_wasm_std::address_format::AddressFormat::Eip55, + address_format: axelar_wasm_std::address::AddressFormat::Eip55, }; instantiate(deps, env, info.clone(), msg.clone()).unwrap(); diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index b9acc44fd..3ad247916 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::permission_control; +use axelar_wasm_std::{address, permission_control}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ @@ -26,18 +26,21 @@ pub fn instantiate( ) -> Result { cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let governance = deps.api.addr_validate(&msg.governance_address)?; + let governance = address::validate_cosmwasm_address(deps.api, &msg.governance_address)?; permission_control::set_governance(deps.storage, &governance)?; let config = Config { service_name: msg.service_name, - service_registry_contract: deps.api.addr_validate(&msg.service_registry_address)?, + service_registry_contract: address::validate_cosmwasm_address( + deps.api, + &msg.service_registry_address, + )?, source_gateway_address: msg.source_gateway_address, voting_threshold: msg.voting_threshold, block_expiry: msg.block_expiry, confirmation_height: msg.confirmation_height, source_chain: msg.source_chain, - rewards_contract: deps.api.addr_validate(&msg.rewards_address)?, + rewards_contract: address::validate_cosmwasm_address(deps.api, &msg.rewards_address)?, msg_id_format: msg.msg_id_format, address_format: msg.address_format, }; @@ -106,7 +109,7 @@ pub fn migrate( #[cfg(test)] mod test { - use axelar_wasm_std::address_format::AddressFormat; + use axelar_wasm_std::address::AddressFormat; use axelar_wasm_std::msg_id::{ Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat, diff --git a/contracts/voting-verifier/src/contract/execute.rs b/contracts/voting-verifier/src/contract/execute.rs index 83152fd69..9d48a7eb7 100644 --- a/contracts/voting-verifier/src/contract/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use axelar_wasm_std::address_format::{validate_address, AddressFormat}; +use axelar_wasm_std::address::{validate_address, AddressFormat}; use axelar_wasm_std::utils::TryMapExt; use axelar_wasm_std::voting::{PollId, PollResults, Vote, WeightedPoll}; use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; diff --git a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs index 06085bdcc..90d1313ea 100644 --- a/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs +++ b/contracts/voting-verifier/src/contract/migrations/v0_5_0.rs @@ -1,6 +1,6 @@ #![allow(deprecated)] -use axelar_wasm_std::address_format::AddressFormat; +use axelar_wasm_std::address::AddressFormat; use axelar_wasm_std::error::ContractError; use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::{nonempty, permission_control, MajorityThreshold}; diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index dc6d79455..b85e84234 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::address_format::AddressFormat; +use axelar_wasm_std::address::AddressFormat; use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::voting::{PollId, PollStatus, Vote, WeightedPoll}; use axelar_wasm_std::{nonempty, MajorityThreshold, VerificationStatus}; diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index 471dc0ab0..63f6bfc8b 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -1,4 +1,4 @@ -use axelar_wasm_std::address_format::AddressFormat; +use axelar_wasm_std::address::AddressFormat; use axelar_wasm_std::hash::Hash; use axelar_wasm_std::msg_id::MessageIdFormat; use axelar_wasm_std::voting::{PollId, Vote, WeightedPoll}; diff --git a/integration-tests/src/voting_verifier_contract.rs b/integration-tests/src/voting_verifier_contract.rs index 43d4a2b60..daa53f20e 100644 --- a/integration-tests/src/voting_verifier_contract.rs +++ b/integration-tests/src/voting_verifier_contract.rs @@ -51,7 +51,7 @@ impl VotingVerifierContract { .try_into() .unwrap(), msg_id_format: axelar_wasm_std::msg_id::MessageIdFormat::HexTxHashAndEventIndex, - address_format: axelar_wasm_std::address_format::AddressFormat::Eip55, + address_format: axelar_wasm_std::address::AddressFormat::Eip55, }, &[], "voting_verifier", diff --git a/packages/axelar-wasm-std/src/address.rs b/packages/axelar-wasm-std/src/address.rs new file mode 100644 index 000000000..bf044fc01 --- /dev/null +++ b/packages/axelar-wasm-std/src/address.rs @@ -0,0 +1,67 @@ +use alloy_primitives::Address; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Api}; +use error_stack::{Result, ResultExt}; + +#[derive(thiserror::Error)] +#[cw_serde] +pub enum Error { + #[error("invalid address '{0}'")] + InvalidAddress(String), +} + +#[cw_serde] +pub enum AddressFormat { + Eip55, +} + +pub fn validate_address(address: &str, format: &AddressFormat) -> Result<(), Error> { + match format { + AddressFormat::Eip55 => Address::parse_checksummed(address, None) + .change_context(Error::InvalidAddress(address.to_string()))?, + }; + + Ok(()) +} + +pub fn validate_cosmwasm_address(api: &dyn Api, addr: &str) -> Result { + api.addr_validate(addr) + .change_context(Error::InvalidAddress(addr.to_string())) +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::testing::MockApi; + + use crate::{address, err_contains}; + + #[test] + fn validate_address() { + let addr = "0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5"; + + assert!(address::validate_address(addr, &address::AddressFormat::Eip55).is_ok()); + + let without_prefix = addr.strip_prefix("0x").unwrap(); + assert!(address::validate_address(without_prefix, &address::AddressFormat::Eip55).is_err()); + + let lower_case = addr.to_lowercase(); + assert!(address::validate_address(&lower_case, &address::AddressFormat::Eip55).is_err()); + + let upper_case = addr.to_uppercase(); + assert!(address::validate_address(&upper_case, &address::AddressFormat::Eip55).is_err()); + } + + #[test] + fn validate_cosmwasm_address() { + let api = MockApi::default(); + let addr = "axelar1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v"; + assert!(address::validate_cosmwasm_address(&api, addr).is_ok()); + + let upper_case = addr.to_uppercase(); + assert!(err_contains!( + address::validate_cosmwasm_address(&api, &upper_case).unwrap_err(), + address::Error, + address::Error::InvalidAddress(..) + )); + } +} diff --git a/packages/axelar-wasm-std/src/address_format.rs b/packages/axelar-wasm-std/src/address_format.rs deleted file mode 100644 index b0de28b68..000000000 --- a/packages/axelar-wasm-std/src/address_format.rs +++ /dev/null @@ -1,23 +0,0 @@ -use alloy_primitives::Address; -use cosmwasm_schema::cw_serde; -use error_stack::{Report, ResultExt}; - -#[derive(thiserror::Error)] -#[cw_serde] -pub enum Error { - #[error("invalid address '{0}'")] - InvalidAddress(String), -} - -#[cw_serde] -pub enum AddressFormat { - Eip55, -} - -pub fn validate_address(address: &str, format: &AddressFormat) -> Result<(), Report> { - match format { - AddressFormat::Eip55 => Address::parse_checksummed(address, None) - .change_context(Error::InvalidAddress(address.to_string())) - .map(|_| ()), - } -} diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index 740b86458..43c1f0c77 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -3,7 +3,7 @@ pub use crate::snapshot::{Participant, Snapshot}; pub use crate::threshold::{MajorityThreshold, Threshold}; pub use crate::verification::VerificationStatus; -pub mod address_format; +pub mod address; pub mod counter; pub mod error; pub mod flagset; From 2d03c490780ce56e8f2ec3844113ea2e95e3a8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rare=C8=99?= <6453351+raress96@users.noreply.github.com> Date: Thu, 15 Aug 2024 18:43:25 +0300 Subject: [PATCH 153/168] feat: add only tx hash message id (#528) --- contracts/voting-verifier/src/contract.rs | 10 +- contracts/voting-verifier/src/events.rs | 29 +++- packages/axelar-wasm-std/src/msg_id/mod.rs | 4 + .../axelar-wasm-std/src/msg_id/tx_hash.rs | 138 ++++++++++++++++++ 4 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 packages/axelar-wasm-std/src/msg_id/tx_hash.rs diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 3ad247916..224c49c72 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -111,8 +111,8 @@ pub fn migrate( mod test { use axelar_wasm_std::address::AddressFormat; use axelar_wasm_std::msg_id::{ - Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, - MessageIdFormat, + Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHash, + HexTxHashAndEventIndex, MessageIdFormat, }; use axelar_wasm_std::voting::Vote; use axelar_wasm_std::{ @@ -244,6 +244,12 @@ mod test { .parse() .unwrap() } + MessageIdFormat::HexTxHash => HexTxHash { + tx_hash: Keccak256::digest(id.as_bytes()).into(), + } + .to_string() + .parse() + .unwrap(), } } diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 484171597..61d2cf404 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -2,8 +2,8 @@ use std::str::FromStr; use std::vec::Vec; use axelar_wasm_std::msg_id::{ - Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, - MessageIdFormat, + Base58SolanaTxSignatureAndEventIndex, Base58TxDigestAndEventIndex, HexTxHash, + HexTxHashAndEventIndex, MessageIdFormat, }; use axelar_wasm_std::voting::{PollId, Vote}; use axelar_wasm_std::{nonempty, VerificationStatus}; @@ -164,6 +164,12 @@ fn parse_message_id( Ok((id.signature_as_base58(), id.event_index)) } + MessageIdFormat::HexTxHash => { + let id = HexTxHash::from_str(message_id) + .map_err(|_| ContractError::InvalidMessageID(message_id.into()))?; + + Ok((id.tx_hash_as_hex(), 0)) + } } } @@ -286,7 +292,7 @@ mod test { use std::collections::BTreeMap; use axelar_wasm_std::msg_id::{ - Base58TxDigestAndEventIndex, HexTxHashAndEventIndex, MessageIdFormat, + Base58TxDigestAndEventIndex, HexTxHash, HexTxHashAndEventIndex, MessageIdFormat, }; use axelar_wasm_std::nonempty; use cosmwasm_std::Uint128; @@ -321,7 +327,7 @@ mod test { } #[test] - fn should_make_tx_event_confirmation_with_hex_msg_id() { + fn should_make_tx_event_confirmation_with_hex_event_index_msg_id() { let msg_id = HexTxHashAndEventIndex { tx_hash: random_32_bytes(), event_index: 0, @@ -337,6 +343,21 @@ mod test { compare_event_to_message(event, msg); } + #[test] + fn should_make_tx_event_confirmation_with_hex_msg_id() { + let msg_id = HexTxHash { + tx_hash: random_32_bytes(), + }; + let msg = generate_msg(msg_id.to_string().parse().unwrap()); + + let event = + TxEventConfirmation::try_from((msg.clone(), &MessageIdFormat::HexTxHash)).unwrap(); + + assert_eq!(event.tx_id, msg_id.tx_hash_as_hex()); + assert_eq!(event.event_index, 0); + compare_event_to_message(event, msg); + } + #[test] fn should_make_tx_event_confirmation_with_base58_msg_id() { let msg_id = Base58TxDigestAndEventIndex { diff --git a/packages/axelar-wasm-std/src/msg_id/mod.rs b/packages/axelar-wasm-std/src/msg_id/mod.rs index 26c33de5b..8a0ced623 100644 --- a/packages/axelar-wasm-std/src/msg_id/mod.rs +++ b/packages/axelar-wasm-std/src/msg_id/mod.rs @@ -6,10 +6,12 @@ use error_stack::Report; pub use self::base_58_event_index::Base58TxDigestAndEventIndex; pub use self::base_58_solana_event_index::Base58SolanaTxSignatureAndEventIndex; +pub use self::tx_hash::HexTxHash; pub use self::tx_hash_event_index::HexTxHashAndEventIndex; mod base_58_event_index; mod base_58_solana_event_index; +mod tx_hash; mod tx_hash_event_index; #[derive(thiserror::Error)] @@ -42,6 +44,7 @@ pub enum MessageIdFormat { HexTxHashAndEventIndex, Base58TxDigestAndEventIndex, Base58SolanaTxSignatureAndEventIndex, + HexTxHash, } // function the router calls to verify msg ids @@ -56,6 +59,7 @@ pub fn verify_msg_id(message_id: &str, format: &MessageIdFormat) -> Result<(), R MessageIdFormat::Base58SolanaTxSignatureAndEventIndex => { Base58SolanaTxSignatureAndEventIndex::from_str(message_id).map(|_| ()) } + MessageIdFormat::HexTxHash => HexTxHash::from_str(message_id).map(|_| ()), } } diff --git a/packages/axelar-wasm-std/src/msg_id/tx_hash.rs b/packages/axelar-wasm-std/src/msg_id/tx_hash.rs new file mode 100644 index 000000000..785fa4827 --- /dev/null +++ b/packages/axelar-wasm-std/src/msg_id/tx_hash.rs @@ -0,0 +1,138 @@ +use core::fmt; +use std::fmt::Display; +use std::str::FromStr; + +use cosmwasm_std::HexBinary; +use error_stack::{ensure, Report, ResultExt}; +use lazy_static::lazy_static; +use regex::Regex; + +use super::Error; +use crate::hash::Hash; +use crate::nonempty; + +pub struct HexTxHash { + pub tx_hash: Hash, +} + +impl HexTxHash { + pub fn tx_hash_as_hex(&self) -> nonempty::String { + format!("0x{}", HexBinary::from(self.tx_hash).to_hex()) + .try_into() + .expect("failed to convert tx hash to non-empty string") + } + + pub fn new(tx_id: impl Into<[u8; 32]>) -> Self { + Self { + tx_hash: tx_id.into(), + } + } +} + +const PATTERN: &str = "^0x[0-9a-f]{64}$"; +lazy_static! { + static ref REGEX: Regex = Regex::new(PATTERN).expect("invalid regex"); +} + +impl FromStr for HexTxHash { + type Err = Report; + + fn from_str(message_id: &str) -> Result + where + Self: Sized, + { + // the PATTERN has exactly two capture groups, so the groups can be extracted safely + ensure!( + REGEX.is_match(message_id), + Error::InvalidMessageID { + id: message_id.to_string(), + expected_format: PATTERN.to_string(), + } + ); + Ok(HexTxHash { + tx_hash: HexBinary::from_hex(&message_id[2..]) + .change_context(Error::InvalidTxHash(message_id.to_string()))? + .as_slice() + .try_into() + .map_err(|_| Error::InvalidTxHash(message_id.to_string()))?, + }) + } +} + +impl Display for HexTxHash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "0x{}", HexBinary::from(self.tx_hash).to_hex()) + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + fn random_hash() -> String { + let mut bytes = vec![]; + for _ in 0..32 { + let byte: u8 = rand::random(); + bytes.push(byte) + } + format!("0x{}", HexBinary::from(bytes).to_hex()) + } + + #[test] + fn should_parse_msg_id() { + let res = HexTxHash::from_str( + "0x7cedbb3799cd99636045c84c5c55aef8a138f107ac8ba53a08cad1070ba4385b", + ); + assert!(res.is_ok()); + + for _ in 0..1000 { + let msg_id = random_hash(); + + let res = HexTxHash::from_str(&msg_id); + let parsed = res.unwrap(); + assert_eq!(parsed.tx_hash_as_hex(), msg_id.clone().try_into().unwrap()); + assert_eq!(parsed.to_string(), msg_id); + } + } + + #[test] + fn should_not_parse_msg_id_with_wrong_length_tx_hash() { + let tx_hash = random_hash(); + // too long + let res = HexTxHash::from_str(&format!("{}ff", tx_hash)); + assert!(res.is_err()); + + // too short + let res = HexTxHash::from_str(&tx_hash[..tx_hash.len() - 2]); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_uppercase_tx_hash() { + let tx_hash = &random_hash()[2..]; + let res = HexTxHash::from_str(&format!("0x{}", tx_hash.to_uppercase())); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_non_hex_tx_hash() { + let msg_id = "82GKYvWv5EKm7jnYksHoh3u5M2RxHN2boPreM8Df4ej9"; + let res = HexTxHash::from_str(msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_without_0x() { + let msg_id = "7cedbb3799cd99636045c84c5c55aef8a138f107ac8ba53a08cad1070ba4385b"; + let res = HexTxHash::from_str(msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_event_index() { + let tx_hash = random_hash(); + let res = HexTxHash::from_str(&format!("{}-1", tx_hash)); + assert!(res.is_err()); + } +} From a31ce99f2f49680bb155e7f718bed82617b1c898 Mon Sep 17 00:00:00 2001 From: Milap Sheth Date: Thu, 15 Aug 2024 16:04:45 -0400 Subject: [PATCH 154/168] fix(contracts): restrict crate visibility (#582) --- .../axelarnet-gateway/src/contract/execute.rs | 8 ++-- contracts/axelarnet-gateway/src/executable.rs | 2 +- contracts/axelarnet-gateway/src/lib.rs | 2 +- contracts/axelarnet-gateway/src/state.rs | 22 +++++----- contracts/coordinator/src/contract.rs | 2 +- .../src/contract/migrations/v0_2_0.rs | 8 ++-- contracts/gateway/src/contract/execute.rs | 42 +++++++++++++++++-- contracts/gateway/src/lib.rs | 2 +- contracts/gateway/src/state.rs | 10 ++--- contracts/gateway/tests/contract.rs | 5 +-- contracts/multisig-prover/src/contract.rs | 1 + .../multisig-prover/src/contract/execute.rs | 2 +- .../src/contract/migrations/mod.rs | 2 +- .../src/contract/migrations/v0_6_0.rs | 2 +- contracts/multisig-prover/src/encoding/mod.rs | 4 +- contracts/multisig-prover/src/lib.rs | 9 ++-- .../multisig-prover/src/test/test_utils.rs | 4 +- contracts/multisig/src/lib.rs | 6 +-- contracts/multisig/src/state.rs | 10 ++--- contracts/multisig/src/types.rs | 3 +- contracts/nexus-gateway/src/state.rs | 8 ++-- contracts/rewards/src/contract.rs | 7 ++-- contracts/rewards/src/contract/execute.rs | 8 ++-- contracts/rewards/src/lib.rs | 4 +- contracts/rewards/src/state.rs | 28 ++++++------- contracts/service-registry/src/lib.rs | 6 ++- contracts/voting-verifier/src/contract.rs | 2 +- .../voting-verifier/src/contract/execute.rs | 2 +- contracts/voting-verifier/src/lib.rs | 2 +- .../src/multisig_prover_contract.rs | 2 +- integration-tests/tests/test_utils/mod.rs | 2 +- integration-tests/tests/update_worker_set.rs | 2 +- 32 files changed, 133 insertions(+), 86 deletions(-) diff --git a/contracts/axelarnet-gateway/src/contract/execute.rs b/contracts/axelarnet-gateway/src/contract/execute.rs index 6f442ce28..a8d09f3ab 100644 --- a/contracts/axelarnet-gateway/src/contract/execute.rs +++ b/contracts/axelarnet-gateway/src/contract/execute.rs @@ -13,7 +13,7 @@ use crate::executable::AxelarExecutableClient; use crate::state::{self}; #[allow(clippy::too_many_arguments)] -pub(crate) fn call_contract( +pub fn call_contract( store: &mut dyn Storage, block_height: u64, router: &Router, @@ -59,7 +59,7 @@ pub(crate) fn call_contract( } // Because the messages came from the router, we can assume they are already verified -pub(crate) fn receive_messages( +pub fn receive_messages( store: &mut dyn Storage, chain_name: ChainName, msgs: Vec, @@ -79,7 +79,7 @@ pub(crate) fn receive_messages( )) } -pub(crate) fn send_messages( +pub fn send_messages( store: &mut dyn Storage, router: &Router, msgs: Vec, @@ -113,7 +113,7 @@ fn route( )) } -pub(crate) fn execute( +pub fn execute( store: &mut dyn Storage, api: &dyn Api, querier: QuerierWrapper, diff --git a/contracts/axelarnet-gateway/src/executable.rs b/contracts/axelarnet-gateway/src/executable.rs index 00148a813..7d35f4162 100644 --- a/contracts/axelarnet-gateway/src/executable.rs +++ b/contracts/axelarnet-gateway/src/executable.rs @@ -13,7 +13,7 @@ pub struct AxelarExecutableMsg { /// Crate-specific `ExecuteMsg` type wraps the `AxelarExecutableMsg` for the AxelarExecutable client. #[cw_serde] -pub(crate) enum AxelarExecutableExecuteMsg { +pub enum AxelarExecutableExecuteMsg { /// Execute the message at the destination contract with the corresponding payload. Execute(AxelarExecutableMsg), } diff --git a/contracts/axelarnet-gateway/src/lib.rs b/contracts/axelarnet-gateway/src/lib.rs index c7af4a4da..8b165d551 100644 --- a/contracts/axelarnet-gateway/src/lib.rs +++ b/contracts/axelarnet-gateway/src/lib.rs @@ -1,7 +1,7 @@ pub mod contract; pub mod events; pub mod msg; -pub mod state; +mod state; mod client; pub use client::Client; diff --git a/contracts/axelarnet-gateway/src/state.rs b/contracts/axelarnet-gateway/src/state.rs index 7df260c86..aaec95d3b 100644 --- a/contracts/axelarnet-gateway/src/state.rs +++ b/contracts/axelarnet-gateway/src/state.rs @@ -6,19 +6,19 @@ use cw_storage_plus::{Item, Map}; use router_api::{ChainName, CrossChainId, Message}; #[cw_serde] -pub(crate) struct Config { +pub struct Config { pub chain_name: ChainName, pub router: Addr, } #[cw_serde] -pub(crate) enum MessageStatus { +pub enum MessageStatus { Approved, Executed, } #[cw_serde] -pub(crate) struct MessageWithStatus { +pub struct MessageWithStatus { pub msg: Message, pub status: MessageStatus, } @@ -53,18 +53,18 @@ pub enum Error { MessageAlreadyExists(CrossChainId), } -pub(crate) fn save_config(storage: &mut dyn Storage, value: &Config) -> Result<(), Error> { +pub fn save_config(storage: &mut dyn Storage, value: &Config) -> Result<(), Error> { CONFIG.save(storage, value).map_err(Error::from) } -pub(crate) fn load_config(storage: &dyn Storage) -> Result { +pub fn load_config(storage: &dyn Storage) -> Result { CONFIG .may_load(storage) .map_err(Error::from)? .ok_or(Error::MissingConfig) } -pub(crate) fn save_sent_msg( +pub fn save_sent_msg( storage: &mut dyn Storage, key: CrossChainId, msg: &Message, @@ -75,7 +75,7 @@ pub(crate) fn save_sent_msg( } } -pub(crate) fn may_load_sent_msg( +pub fn may_load_sent_msg( storage: &dyn Storage, id: &CrossChainId, ) -> Result, Error> { @@ -84,7 +84,7 @@ pub(crate) fn may_load_sent_msg( .map_err(Error::from) } -pub(crate) fn may_load_received_msg( +pub fn may_load_received_msg( storage: &dyn Storage, cc_id: &CrossChainId, ) -> Result, Error> { @@ -93,7 +93,7 @@ pub(crate) fn may_load_received_msg( .map_err(Error::from) } -pub(crate) fn save_received_msg( +pub fn save_received_msg( storage: &mut dyn Storage, cc_id: CrossChainId, msg: Message, @@ -122,7 +122,7 @@ pub(crate) fn save_received_msg( } /// Update the status of a message to executed if it is in approved status, error otherwise. -pub(crate) fn set_msg_as_executed( +pub fn set_msg_as_executed( storage: &mut dyn Storage, cc_id: CrossChainId, ) -> Result { @@ -156,7 +156,7 @@ pub(crate) fn set_msg_as_executed( } } -pub(crate) fn increment_msg_counter(storage: &mut dyn Storage) -> Result { +pub fn increment_msg_counter(storage: &mut dyn Storage) -> Result { SENT_MESSAGE_COUNTER.incr(storage).map_err(Error::from) } diff --git a/contracts/coordinator/src/contract.rs b/contracts/coordinator/src/contract.rs index fb1b7fee6..99f994074 100644 --- a/contracts/coordinator/src/contract.rs +++ b/contracts/coordinator/src/contract.rs @@ -1,7 +1,7 @@ mod execute; +mod migrations; mod query; -mod migrations; use axelar_wasm_std::{address, permission_control, FnExt}; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; diff --git a/contracts/coordinator/src/contract/migrations/v0_2_0.rs b/contracts/coordinator/src/contract/migrations/v0_2_0.rs index ae6db4fa0..1e5dba106 100644 --- a/contracts/coordinator/src/contract/migrations/v0_2_0.rs +++ b/contracts/coordinator/src/contract/migrations/v0_2_0.rs @@ -10,7 +10,7 @@ use crate::state::save_prover_for_chain; const BASE_VERSION: &str = "0.2.0"; -pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; migrate_config_to_permission_control(storage)?; @@ -38,15 +38,15 @@ fn migrate_registered_provers(storage: &mut dyn Storage) -> Result<(), ContractE #[cw_serde] #[deprecated(since = "0.2.0", note = "only used to test the migration")] -pub struct Config { +struct Config { pub governance: Addr, } #[deprecated(since = "0.2.0", note = "only used to test the migration")] -pub const CONFIG: Item = Item::new("config"); +const CONFIG: Item = Item::new("config"); #[deprecated(since = "0.2.0", note = "only used to test the migration")] -pub const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); +const PROVER_PER_CHAIN: Map = Map::new("prover_per_chain"); #[cfg(test)] mod tests { diff --git a/contracts/gateway/src/contract/execute.rs b/contracts/gateway/src/contract/execute.rs index d72f98527..0369d96c9 100644 --- a/contracts/gateway/src/contract/execute.rs +++ b/contracts/gateway/src/contract/execute.rs @@ -10,7 +10,7 @@ use crate::contract::Error; use crate::events::GatewayEvent; use crate::state; -pub(crate) fn verify_messages( +pub fn verify_messages( verifier: &voting_verifier::Client, msgs: Vec, ) -> Result { @@ -19,7 +19,7 @@ pub(crate) fn verify_messages( }) } -pub(crate) fn route_incoming_messages( +pub fn route_incoming_messages( verifier: &voting_verifier::Client, router: &Router, msgs: Vec, @@ -30,7 +30,7 @@ pub(crate) fn route_incoming_messages( } // because the messages came from the router, we can assume they are already verified -pub(crate) fn route_outgoing_messages( +pub fn route_outgoing_messages( store: &mut dyn Storage, verified: Vec, ) -> Result { @@ -179,3 +179,39 @@ fn flat_unzip(x: impl Iterator, Vec)>) -> (Vec, Vec, transform: fn(Message) -> GatewayEvent) -> Vec { msgs.into_iter().map(|msg| transform(msg).into()).collect() } + +#[cfg(test)] +mod tests { + use axelar_wasm_std::err_contains; + use cosmwasm_std::testing::mock_dependencies; + use router_api::{CrossChainId, Message}; + + use crate::contract::execute::route_outgoing_messages; + use crate::state; + + #[test] + fn reject_reroute_outgoing_message_with_different_contents() { + let mut msg = Message { + cc_id: CrossChainId::new("source-chain", "0x1234-1").unwrap(), + source_address: "source-address".parse().unwrap(), + destination_chain: "destination-chain".parse().unwrap(), + destination_address: "destination-address".parse().unwrap(), + payload_hash: [1; 32], + }; + + let mut deps = mock_dependencies(); + + let response = route_outgoing_messages(deps.as_mut().storage, vec![msg.clone()]); + assert!(response.is_ok()); + + // re-route with different payload + msg.payload_hash = [2; 32]; + + let response = route_outgoing_messages(deps.as_mut().storage, vec![msg]); + assert!(response.is_err_and(|err| err_contains!( + err, + state::Error, + state::Error::MessageMismatch { .. } + ))); + } +} diff --git a/contracts/gateway/src/lib.rs b/contracts/gateway/src/lib.rs index 5501bc9c7..b376dfa30 100644 --- a/contracts/gateway/src/lib.rs +++ b/contracts/gateway/src/lib.rs @@ -1,4 +1,4 @@ pub mod contract; mod events; pub mod msg; -pub mod state; +mod state; diff --git a/contracts/gateway/src/state.rs b/contracts/gateway/src/state.rs index 445eec117..35f8f8c1b 100644 --- a/contracts/gateway/src/state.rs +++ b/contracts/gateway/src/state.rs @@ -5,7 +5,7 @@ use cw_storage_plus::{Item, Map}; use router_api::{CrossChainId, Message}; #[cw_serde] -pub(crate) struct Config { +pub struct Config { pub verifier: Addr, pub router: Addr, } @@ -25,18 +25,18 @@ pub enum Error { MessageNotFound(CrossChainId), } -pub(crate) fn load_config(storage: &dyn Storage) -> Result { +pub fn load_config(storage: &dyn Storage) -> Result { CONFIG .may_load(storage) .map_err(Error::from)? .ok_or(Error::MissingConfig) } -pub(crate) fn save_config(storage: &mut dyn Storage, config: &Config) -> Result<(), Error> { +pub fn save_config(storage: &mut dyn Storage, config: &Config) -> Result<(), Error> { CONFIG.save(storage, config).map_err(Error::from) } -pub(crate) fn load_outgoing_message( +pub fn load_outgoing_message( storage: &dyn Storage, cc_id: &CrossChainId, ) -> Result { @@ -46,7 +46,7 @@ pub(crate) fn load_outgoing_message( .ok_or_else(|| Error::MessageNotFound(cc_id.clone())) } -pub(crate) fn save_outgoing_message( +pub fn save_outgoing_message( storage: &mut dyn Storage, cc_id: &CrossChainId, msg: &Message, diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index deeb2af49..cb86390aa 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -13,7 +13,6 @@ use cosmwasm_std::{ }; use gateway::contract::*; use gateway::msg::InstantiateMsg; -use gateway::state; use gateway_api::msg::{ExecuteMsg, QueryMsg}; use itertools::Itertools; use rand::{thread_rng, Rng}; @@ -314,8 +313,8 @@ fn reject_reroute_outgoing_message_with_different_contents() { ); assert!(response.is_err_and(|err| err_contains!( err.report, - state::Error, - state::Error::MessageMismatch { .. } + Error, + Error::RouteOutgoingMessages ))); } diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index 85a5763e9..81952e655 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -9,6 +9,7 @@ use error_stack::ResultExt; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{Config, CONFIG}; + mod execute; mod migrations; mod query; diff --git a/contracts/multisig-prover/src/contract/execute.rs b/contracts/multisig-prover/src/contract/execute.rs index f49e029c0..197d78c5a 100644 --- a/contracts/multisig-prover/src/contract/execute.rs +++ b/contracts/multisig-prover/src/contract/execute.rs @@ -12,7 +12,7 @@ use itertools::Itertools; use multisig::msg::Signer; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, CrossChainId, Message}; -use service_registry::state::{Service, WeightedVerifier}; +use service_registry::{Service, WeightedVerifier}; use crate::contract::START_MULTISIG_REPLY_ID; use crate::error::ContractError; diff --git a/contracts/multisig-prover/src/contract/migrations/mod.rs b/contracts/multisig-prover/src/contract/migrations/mod.rs index b29376b44..b9dfdddab 100644 --- a/contracts/multisig-prover/src/contract/migrations/mod.rs +++ b/contracts/multisig-prover/src/contract/migrations/mod.rs @@ -1 +1 @@ -pub(crate) mod v0_6_0; +pub mod v0_6_0; diff --git a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs index 316fab18a..dbf741166 100644 --- a/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs +++ b/contracts/multisig-prover/src/contract/migrations/v0_6_0.rs @@ -15,7 +15,7 @@ use crate::state; const BASE_VERSION: &str = "0.6.0"; -pub(crate) fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; let config = CONFIG.load(storage)?; diff --git a/contracts/multisig-prover/src/encoding/mod.rs b/contracts/multisig-prover/src/encoding/mod.rs index 054cd6ff5..ee545f86e 100644 --- a/contracts/multisig-prover/src/encoding/mod.rs +++ b/contracts/multisig-prover/src/encoding/mod.rs @@ -1,5 +1,5 @@ -pub mod abi; -pub mod bcs; +mod abi; +mod bcs; use axelar_wasm_std::hash::Hash; use cosmwasm_schema::cw_serde; diff --git a/contracts/multisig-prover/src/lib.rs b/contracts/multisig-prover/src/lib.rs index b59c7551a..0fea1d56d 100644 --- a/contracts/multisig-prover/src/lib.rs +++ b/contracts/multisig-prover/src/lib.rs @@ -1,10 +1,13 @@ pub mod contract; -pub mod encoding; +mod encoding; pub mod error; pub mod events; pub mod msg; -pub mod payload; -pub mod state; +mod payload; +mod state; + +pub use encoding::Encoder; +pub use payload::Payload; #[cfg(test)] mod test; diff --git a/contracts/multisig-prover/src/test/test_utils.rs b/contracts/multisig-prover/src/test/test_utils.rs index 1553a98a4..bf827bc60 100644 --- a/contracts/multisig-prover/src/test/test_utils.rs +++ b/contracts/multisig-prover/src/test/test_utils.rs @@ -4,7 +4,7 @@ use multisig::msg::Signer; use multisig::multisig::Multisig; use multisig::types::MultisigState; use multisig::verifier_set::VerifierSet; -use service_registry::state::{ +use service_registry::{ AuthorizationState, BondingState, Verifier, WeightedVerifier, VERIFIER_WEIGHT, }; @@ -118,7 +118,7 @@ fn service_registry_mock_querier_handler( ) -> QuerierResult { let result = match msg { service_registry::msg::QueryMsg::Service { service_name } => { - to_json_binary(&service_registry::state::Service { + to_json_binary(&service_registry::Service { name: service_name.to_string(), coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 1, diff --git a/contracts/multisig/src/lib.rs b/contracts/multisig/src/lib.rs index 189f0ec33..e533db1d9 100644 --- a/contracts/multisig/src/lib.rs +++ b/contracts/multisig/src/lib.rs @@ -4,8 +4,8 @@ pub mod events; pub mod key; pub mod msg; pub mod multisig; -pub mod signing; -pub mod state; +mod signing; +mod state; pub mod types; pub mod verifier_set; @@ -15,7 +15,7 @@ mod secp256k1; #[cfg(feature = "ed25519")] mod ed25519; -#[cfg(feature = "test")] +#[cfg(any(test, feature = "test"))] pub mod test; pub use crate::error::ContractError; diff --git a/contracts/multisig/src/state.rs b/contracts/multisig/src/state.rs index 43979c058..844235418 100644 --- a/contracts/multisig/src/state.rs +++ b/contracts/multisig/src/state.rs @@ -17,9 +17,14 @@ pub struct Config { pub block_expiry: nonempty::Uint64, // number of blocks after which a signing session expires } +type VerifierSetId = str; + pub const CONFIG: Item = Item::new("config"); pub const SIGNING_SESSION_COUNTER: Item = Item::new("signing_session_counter"); pub const SIGNING_SESSIONS: Map = Map::new("signing_sessions"); +// The keys represent the addresses that can start a signing session. +pub const AUTHORIZED_CALLERS: Map<&Addr, ChainName> = Map::new("authorized_callers"); +pub const VERIFIER_SETS: Map<&VerifierSetId, VerifierSet> = Map::new("verifier_sets"); /// Signatures by session id and signer address pub const SIGNATURES: Map<(u64, &str), Signature> = Map::new("signatures"); @@ -55,8 +60,6 @@ pub fn save_signature( ) } -type VerifierSetId = str; -pub const VERIFIER_SETS: Map<&VerifierSetId, VerifierSet> = Map::new("verifier_sets"); pub fn verifier_set( store: &dyn Storage, verifier_set_id: &str, @@ -109,9 +112,6 @@ pub fn save_pub_key( Ok(pub_keys().save(store, (signer, pub_key.key_type()), &pub_key.into())?) } -// The keys represent the addresses that can start a signing session. -pub const AUTHORIZED_CALLERS: Map<&Addr, ChainName> = Map::new("authorized_callers"); - #[cfg(test)] mod tests { diff --git a/contracts/multisig/src/types.rs b/contracts/multisig/src/types.rs index c36c996f0..60091ee4e 100644 --- a/contracts/multisig/src/types.rs +++ b/contracts/multisig/src/types.rs @@ -18,6 +18,7 @@ impl AsRef<[u8]> for MsgToSign { } } +#[cfg(any(test, feature = "test"))] impl MsgToSign { pub fn unchecked(hex: HexBinary) -> Self { Self(hex) @@ -44,7 +45,7 @@ impl TryFrom for MsgToSign { }); } - Ok(MsgToSign::unchecked(other)) + Ok(MsgToSign(other)) } } diff --git a/contracts/nexus-gateway/src/state.rs b/contracts/nexus-gateway/src/state.rs index 77d5daf63..4be51dfe9 100644 --- a/contracts/nexus-gateway/src/state.rs +++ b/contracts/nexus-gateway/src/state.rs @@ -11,25 +11,25 @@ const ROUTED_MESSAGE_IDS: Map<&CrossChainId, ()> = Map::new("routed_message_ids" type Result = error_stack::Result; -pub(crate) fn save_config(storage: &mut dyn Storage, config: Config) -> Result<()> { +pub fn save_config(storage: &mut dyn Storage, config: Config) -> Result<()> { CONFIG .save(storage, &config) .change_context(ContractError::StoreFailure) } -pub(crate) fn load_config(storage: &dyn Storage) -> Result { +pub fn load_config(storage: &dyn Storage) -> Result { CONFIG .load(storage) .change_context(ContractError::StoreFailure) } -pub(crate) fn set_message_routed(storage: &mut dyn Storage, id: &CrossChainId) -> Result<()> { +pub fn set_message_routed(storage: &mut dyn Storage, id: &CrossChainId) -> Result<()> { ROUTED_MESSAGE_IDS .save(storage, id, &()) .change_context(ContractError::StoreFailure) } -pub(crate) fn is_message_routed(storage: &dyn Storage, id: &CrossChainId) -> Result { +pub fn is_message_routed(storage: &dyn Storage, id: &CrossChainId) -> Result { ROUTED_MESSAGE_IDS .may_load(storage, id) .map(|result| result.is_some()) diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index b5f6e8fdc..8eaca607d 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -7,7 +7,6 @@ use cosmwasm_std::{ use error_stack::ResultExt; use itertools::Itertools; -use crate::contract::migrations::v0_4_0; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG, PARAMS}; @@ -25,7 +24,7 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - v0_4_0::migrate(deps.storage)?; + migrations::v0_4_0::migrate(deps.storage)?; // any version checks should be done before here @@ -180,7 +179,9 @@ mod tests { #[test] fn migrate_sets_contract_version() { let mut deps = mock_dependencies(); - v0_4_0::tests::instantiate_contract(deps.as_mut(), "denom"); + + #[allow(deprecated)] + migrations::v0_4_0::tests::instantiate_contract(deps.as_mut(), "denom"); migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index 08eef8eed..4fc8994ea 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -11,7 +11,7 @@ use crate::state::{self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, Stora const DEFAULT_EPOCHS_TO_PROCESS: u64 = 10; const EPOCH_PAYOUT_DELAY: u64 = 2; -pub(crate) fn record_participation( +pub fn record_participation( storage: &mut dyn Storage, event_id: nonempty::String, verifier: Addr, @@ -52,7 +52,7 @@ fn load_or_store_event( } } -pub(crate) fn distribute_rewards( +pub fn distribute_rewards( storage: &mut dyn Storage, pool_id: PoolId, cur_block_height: u64, @@ -114,7 +114,7 @@ fn iterate_epoch_tallies<'a>( }) } -pub(crate) fn update_params( +pub fn update_params( storage: &mut dyn Storage, new_params: Params, block_height: u64, @@ -159,7 +159,7 @@ pub(crate) fn update_params( Ok(()) } -pub(crate) fn add_rewards( +pub fn add_rewards( storage: &mut dyn Storage, pool_id: PoolId, amount: nonempty::Uint128, diff --git a/contracts/rewards/src/lib.rs b/contracts/rewards/src/lib.rs index a5abdbb0f..6a440df29 100644 --- a/contracts/rewards/src/lib.rs +++ b/contracts/rewards/src/lib.rs @@ -1,4 +1,6 @@ pub mod contract; pub mod error; pub mod msg; -pub mod state; +mod state; + +pub use state::{Epoch, PoolId}; diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index e09816885..400774dd5 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -268,15 +268,15 @@ const WATERMARKS: Map = Map::new("rewards_watermarks"); pub const CONFIG: Item = Item::new("config"); -pub(crate) fn load_config(storage: &dyn Storage) -> Config { +pub fn load_config(storage: &dyn Storage) -> Config { CONFIG.load(storage).expect("couldn't load config") } -pub(crate) fn load_params(storage: &dyn Storage) -> ParamsSnapshot { +pub fn load_params(storage: &dyn Storage) -> ParamsSnapshot { PARAMS.load(storage).expect("params should exist") } -pub(crate) fn load_rewards_watermark( +pub fn load_rewards_watermark( storage: &dyn Storage, pool_id: PoolId, ) -> Result, ContractError> { @@ -285,7 +285,7 @@ pub(crate) fn load_rewards_watermark( .change_context(ContractError::LoadRewardsWatermark) } -pub(crate) fn load_event( +pub fn load_event( storage: &dyn Storage, event_id: String, pool_id: PoolId, @@ -295,7 +295,7 @@ pub(crate) fn load_event( .change_context(ContractError::LoadEvent) } -pub(crate) fn load_epoch_tally( +pub fn load_epoch_tally( storage: &dyn Storage, pool_id: PoolId, epoch_num: u64, @@ -305,7 +305,7 @@ pub(crate) fn load_epoch_tally( .change_context(ContractError::LoadEpochTally) } -pub(crate) fn may_load_rewards_pool( +pub fn may_load_rewards_pool( storage: &dyn Storage, pool_id: PoolId, ) -> Result, ContractError> { @@ -314,7 +314,7 @@ pub(crate) fn may_load_rewards_pool( .change_context(ContractError::LoadRewardsPool) } -pub(crate) fn load_rewards_pool_or_new( +pub fn load_rewards_pool_or_new( storage: &dyn Storage, pool_id: PoolId, ) -> Result { @@ -322,7 +322,7 @@ pub(crate) fn load_rewards_pool_or_new( .map(|pool| pool.unwrap_or(RewardsPool::new(pool_id))) } -pub(crate) fn load_rewards_pool( +pub fn load_rewards_pool( storage: &dyn Storage, pool_id: PoolId, ) -> Result { @@ -330,7 +330,7 @@ pub(crate) fn load_rewards_pool( .ok_or(ContractError::RewardsPoolNotFound.into()) } -pub(crate) fn save_params( +pub fn save_params( storage: &mut dyn Storage, params: &ParamsSnapshot, ) -> Result<(), ContractError> { @@ -339,7 +339,7 @@ pub(crate) fn save_params( .change_context(ContractError::SaveParams) } -pub(crate) fn save_rewards_watermark( +pub fn save_rewards_watermark( storage: &mut dyn Storage, pool_id: PoolId, epoch_num: u64, @@ -349,7 +349,7 @@ pub(crate) fn save_rewards_watermark( .change_context(ContractError::SaveRewardsWatermark) } -pub(crate) fn save_event(storage: &mut dyn Storage, event: &Event) -> Result<(), ContractError> { +pub fn save_event(storage: &mut dyn Storage, event: &Event) -> Result<(), ContractError> { EVENTS .save( storage, @@ -359,7 +359,7 @@ pub(crate) fn save_event(storage: &mut dyn Storage, event: &Event) -> Result<(), .change_context(ContractError::SaveEvent) } -pub(crate) fn save_epoch_tally( +pub fn save_epoch_tally( storage: &mut dyn Storage, tally: &EpochTally, ) -> Result<(), ContractError> { @@ -373,7 +373,7 @@ pub(crate) fn save_epoch_tally( .change_context(ContractError::SaveEpochTally) } -pub(crate) fn save_rewards_pool( +pub fn save_rewards_pool( storage: &mut dyn Storage, pool: &RewardsPool, ) -> Result<(), ContractError> { @@ -382,7 +382,7 @@ pub(crate) fn save_rewards_pool( .change_context(ContractError::SaveRewardsPool) } -pub(crate) enum StorageState { +pub enum StorageState { Existing(T), New(T), } diff --git a/contracts/service-registry/src/lib.rs b/contracts/service-registry/src/lib.rs index 98208b782..d439e2a24 100644 --- a/contracts/service-registry/src/lib.rs +++ b/contracts/service-registry/src/lib.rs @@ -2,6 +2,10 @@ pub mod contract; pub mod error; pub mod helpers; pub mod msg; -pub mod state; +mod state; + +pub use state::{ + AuthorizationState, BondingState, Service, Verifier, WeightedVerifier, VERIFIER_WEIGHT, +}; pub use crate::error::ContractError; diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 224c49c72..89601f5fe 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -125,7 +125,7 @@ mod test { use multisig::key::KeyType; use multisig::test::common::{build_verifier_set, ecdsa_test_data}; use router_api::{ChainName, CrossChainId, Message}; - use service_registry::state::{ + use service_registry::{ AuthorizationState, BondingState, Verifier, WeightedVerifier, VERIFIER_WEIGHT, }; use sha3::{Digest, Keccak256, Keccak512}; diff --git a/contracts/voting-verifier/src/contract/execute.rs b/contracts/voting-verifier/src/contract/execute.rs index 9d48a7eb7..5e68eb373 100644 --- a/contracts/voting-verifier/src/contract/execute.rs +++ b/contracts/voting-verifier/src/contract/execute.rs @@ -13,7 +13,7 @@ use itertools::Itertools; use multisig::verifier_set::VerifierSet; use router_api::{ChainName, Message}; use service_registry::msg::QueryMsg; -use service_registry::state::WeightedVerifier; +use service_registry::WeightedVerifier; use crate::contract::query::{message_status, verifier_set_status}; use crate::error::ContractError; diff --git a/contracts/voting-verifier/src/lib.rs b/contracts/voting-verifier/src/lib.rs index f2ab17a66..2cfb800f1 100644 --- a/contracts/voting-verifier/src/lib.rs +++ b/contracts/voting-verifier/src/lib.rs @@ -5,4 +5,4 @@ pub mod contract; pub mod error; pub mod events; pub mod msg; -pub mod state; +mod state; diff --git a/integration-tests/src/multisig_prover_contract.rs b/integration-tests/src/multisig_prover_contract.rs index 75256fb28..8db0da918 100644 --- a/integration-tests/src/multisig_prover_contract.rs +++ b/integration-tests/src/multisig_prover_contract.rs @@ -2,7 +2,7 @@ use axelar_wasm_std::Threshold; use cosmwasm_std::Addr; use cw_multi_test::{ContractWrapper, Executor}; use multisig::key::KeyType; -use multisig_prover::encoding::Encoder; +use multisig_prover::Encoder; use crate::contract::Contract; use crate::protocol::Protocol; diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 0a94de2a4..3b4a976be 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -22,7 +22,7 @@ use k256::ecdsa; use multisig::key::{KeyType, PublicKey}; use multisig::verifier_set::VerifierSet; use multisig_prover::msg::VerifierSetResponse; -use rewards::state::PoolId; +use rewards::PoolId; use router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; use service_registry::msg::ExecuteMsg; use sha3::{Digest, Keccak256}; diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index 4bbdcfe8e..3c0323745 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -3,7 +3,7 @@ use cw_multi_test::Executor; use integration_tests::contract::Contract; use multisig_prover::msg::ExecuteMsg; use service_registry::msg::QueryMsg as ServiceRegistryQueryMsg; -use service_registry::state::WeightedVerifier; +use service_registry::WeightedVerifier; pub mod test_utils; From 6f63cbd609ad754a286a627b13d211c97e5bfba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rare=C8=99?= <6453351+raress96@users.noreply.github.com> Date: Fri, 16 Aug 2024 20:28:09 +0300 Subject: [PATCH 155/168] feat(ampd): add support for multiversx blockchain (#466) --- .gitignore | 2 + Cargo.lock | 360 +++++++++++- ampd/Cargo.toml | 1 + ampd/src/config.rs | 26 +- ampd/src/handlers/config.rs | 42 ++ ampd/src/handlers/mod.rs | 2 + ampd/src/handlers/mvx_verify_msg.rs | 340 +++++++++++ ampd/src/handlers/mvx_verify_verifier_set.rs | 362 ++++++++++++ ampd/src/lib.rs | 28 + ampd/src/mvx/error.rs | 9 + ampd/src/mvx/mod.rs | 85 +++ ampd/src/mvx/proxy.rs | 63 ++ ampd/src/mvx/verifier.rs | 585 +++++++++++++++++++ ampd/src/tests/config_template.toml | 10 + 14 files changed, 1898 insertions(+), 17 deletions(-) create mode 100644 ampd/src/handlers/mvx_verify_msg.rs create mode 100644 ampd/src/handlers/mvx_verify_verifier_set.rs create mode 100644 ampd/src/mvx/error.rs create mode 100644 ampd/src/mvx/mod.rs create mode 100644 ampd/src/mvx/proxy.rs create mode 100644 ampd/src/mvx/verifier.rs diff --git a/.gitignore b/.gitignore index 0944804d6..1c3a92dba 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ *.iml .idea .vscode + +config.toml diff --git a/Cargo.lock b/Cargo.lock index 92d7f7b64..bd078cad3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,13 +254,14 @@ dependencies = [ "mockall 0.11.4", "move-core-types", "multisig", + "multiversx-sdk", "num-traits", "prost 0.11.9", "prost-types", "rand", "random-string", "report", - "reqwest", + "reqwest 0.11.27", "router-api", "serde", "serde_json", @@ -326,7 +327,7 @@ dependencies = [ "rcgen", "ring 0.16.20", "rustls 0.21.12", - "rustls-webpki", + "rustls-webpki 0.101.7", "serde", "serde_json", "socket2", @@ -768,6 +769,12 @@ dependencies = [ "rustc_version 0.4.0", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "auto_impl" version = "1.2.0" @@ -1109,6 +1116,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes 0.11.0", + "rand", + "rand_core 0.6.4", + "serde", + "unicode-normalization", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -1130,6 +1150,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + [[package]] name = "bitcoin_hashes" version = "0.12.0" @@ -2655,7 +2681,7 @@ dependencies = [ "jsonwebtoken", "once_cell", "pin-project", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -2838,7 +2864,7 @@ dependencies = [ "neptune", "num-bigint 0.4.5", "once_cell", - "reqwest", + "reqwest 0.11.27", "schemars", "serde", "serde_json", @@ -2986,6 +3012,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -3281,6 +3322,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3508,7 +3568,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -3531,6 +3591,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -3539,6 +3600,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", ] [[package]] @@ -3608,6 +3670,23 @@ dependencies = [ "tokio-rustls 0.24.1", ] +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.3.1", + "hyper-util", + "rustls 0.23.11", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.4.1" @@ -3620,6 +3699,22 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.3.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.5" @@ -3627,12 +3722,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes", + "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.0", "hyper 1.3.1", "pin-project-lite", + "socket2", "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -4199,7 +4299,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ "base64 0.21.7", - "pem", + "pem 1.1.1", "ring 0.16.20", "serde", "serde_json", @@ -4908,6 +5008,32 @@ dependencies = [ "voting-verifier", ] +[[package]] +name = "multiversx-sdk" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb2f8dd4a17ce9c9fa1ab3d80152929702968be6536499f32bd7e2278c2e0fb" +dependencies = [ + "anyhow", + "base64 0.22.1", + "bech32", + "bip39", + "hex", + "hmac", + "itertools 0.12.1", + "pbkdf2", + "pem 3.0.4", + "rand", + "reqwest 0.12.5", + "serde", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "sha3", + "tokio", + "zeroize", +] + [[package]] name = "mysten-metrics" version = "0.7.0" @@ -5009,6 +5135,23 @@ dependencies = [ "shared-crypto", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "neptune" version = "13.0.0" @@ -5308,12 +5451,50 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.85", + "quote 1.0.36", + "syn 2.0.68", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5542,6 +5723,16 @@ dependencies = [ "base64 0.13.1", ] +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + [[package]] name = "pem-rfc7468" version = "0.6.0" @@ -5747,6 +5938,12 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "polyval" version = "0.6.2" @@ -6264,7 +6461,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ - "pem", + "pem 1.1.1", "ring 0.16.20", "time", "yasna", @@ -6372,7 +6569,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.29", @@ -6385,7 +6582,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.12", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -6399,7 +6596,51 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots 0.25.4", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-rustls 0.27.2", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.2", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", ] [[package]] @@ -6711,10 +6952,23 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct 0.7.1", ] +[[package]] +name = "rustls" +version = "0.23.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.102.5", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.5.0" @@ -6734,7 +6988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -6748,6 +7002,22 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -6758,6 +7028,17 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -6895,7 +7176,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.12.0", "rand", "secp256k1-sys", ] @@ -7708,7 +7989,7 @@ dependencies = [ "fastcrypto", "mime", "rand", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "serde_with 2.3.3", @@ -8231,6 +8512,7 @@ dependencies = [ "libc", "mio", "num_cpus", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -8259,6 +8541,16 @@ dependencies = [ "syn 2.0.68", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.22.0" @@ -8291,6 +8583,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.11", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.15" @@ -8398,7 +8701,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.29", @@ -8425,7 +8728,7 @@ dependencies = [ "axum 0.6.20", "base64 0.21.7", "bytes", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.29", @@ -8726,6 +9029,15 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.13" @@ -8874,6 +9186,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -9286,6 +9604,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "write16" version = "1.0.0" diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index 0d8a08928..6dd31cc18 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -36,6 +36,7 @@ k256 = { workspace = true } mockall = "0.11.3" move-core-types = { git = "https://github.com/mystenlabs/sui", tag = "mainnet-v1.26.2" } multisig = { workspace = true, features = ["library"] } +multiversx-sdk = "0.4.1" num-traits = { workspace = true } prost = "0.11.9" prost-types = "0.11.9" diff --git a/ampd/src/config.rs b/ampd/src/config.rs index dfca06d65..0a1609945 100644 --- a/ampd/src/config.rs +++ b/ampd/src/config.rs @@ -110,6 +110,16 @@ mod tests { [handlers.rpc_timeout] secs = 3 nanos = 0 + + [[handlers]] + type = 'MvxMsgVerifier' + cosmwasm_contract = '{}' + proxy_url = 'http://localhost:7545' + + [[handlers]] + type = 'MvxVerifierSetVerifier' + cosmwasm_contract = '{}' + proxy_url = 'http://localhost:7545' ", TMAddress::random(PREFIX), TMAddress::random(PREFIX), @@ -117,10 +127,12 @@ mod tests { TMAddress::random(PREFIX), TMAddress::random(PREFIX), TMAddress::random(PREFIX), + TMAddress::random(PREFIX), + TMAddress::random(PREFIX), ); let cfg: Config = toml::from_str(config_str.as_str()).unwrap(); - assert_eq!(cfg.handlers.len(), 6); + assert_eq!(cfg.handlers.len(), 8); } #[test] @@ -300,6 +312,18 @@ mod tests { rpc_url: Url::from_str("http://127.0.0.1").unwrap(), rpc_timeout: Some(Duration::from_secs(3)), }, + HandlerConfig::MvxMsgVerifier { + cosmwasm_contract: TMAddress::from( + AccountId::new("axelar", &[0u8; 32]).unwrap(), + ), + proxy_url: Url::from_str("http://127.0.0.1").unwrap(), + }, + HandlerConfig::MvxVerifierSetVerifier { + cosmwasm_contract: TMAddress::from( + AccountId::new("axelar", &[0u8; 32]).unwrap(), + ), + proxy_url: Url::from_str("http://127.0.0.1").unwrap(), + }, ], ..Config::default() } diff --git a/ampd/src/handlers/config.rs b/ampd/src/handlers/config.rs index 598a751a8..6befec34e 100644 --- a/ampd/src/handlers/config.rs +++ b/ampd/src/handlers/config.rs @@ -47,6 +47,14 @@ pub enum Config { rpc_url: Url, rpc_timeout: Option, }, + MvxMsgVerifier { + cosmwasm_contract: TMAddress, + proxy_url: Url, + }, + MvxVerifierSetVerifier { + cosmwasm_contract: TMAddress, + proxy_url: Url, + }, } fn validate_multisig_signer_config<'de, D>(configs: &[Config]) -> Result<(), D::Error> @@ -142,6 +150,38 @@ where } } +fn validate_mvx_msg_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error> +where + D: Deserializer<'de>, +{ + match configs + .iter() + .filter(|config| matches!(config, Config::MvxMsgVerifier { .. })) + .count() + { + count if count > 1 => Err(de::Error::custom( + "only one Mvx msg verifier config is allowed", + )), + _ => Ok(()), + } +} + +fn validate_mvx_worker_set_verifier_config<'de, D>(configs: &[Config]) -> Result<(), D::Error> +where + D: Deserializer<'de>, +{ + match configs + .iter() + .filter(|config| matches!(config, Config::MvxVerifierSetVerifier { .. })) + .count() + { + count if count > 1 => Err(de::Error::custom( + "only one Mvx worker set verifier config is allowed", + )), + _ => Ok(()), + } +} + pub fn deserialize_handler_configs<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -153,6 +193,8 @@ where validate_multisig_signer_config::(&configs)?; validate_sui_msg_verifier_config::(&configs)?; validate_sui_verifier_set_verifier_config::(&configs)?; + validate_mvx_msg_verifier_config::(&configs)?; + validate_mvx_worker_set_verifier_config::(&configs)?; Ok(configs) } diff --git a/ampd/src/handlers/mod.rs b/ampd/src/handlers/mod.rs index 8a15b92fd..1a01f197b 100644 --- a/ampd/src/handlers/mod.rs +++ b/ampd/src/handlers/mod.rs @@ -3,6 +3,8 @@ mod errors; pub mod evm_verify_msg; pub mod evm_verify_verifier_set; pub mod multisig; +pub mod mvx_verify_msg; +pub mod mvx_verify_verifier_set; pub mod sui_verify_msg; pub mod sui_verify_verifier_set; diff --git a/ampd/src/handlers/mvx_verify_msg.rs b/ampd/src/handlers/mvx_verify_msg.rs new file mode 100644 index 000000000..a836ef40e --- /dev/null +++ b/ampd/src/handlers/mvx_verify_msg.rs @@ -0,0 +1,340 @@ +use std::collections::HashSet; +use std::convert::TryInto; + +use async_trait::async_trait; +use axelar_wasm_std::voting::{PollId, Vote}; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; +use cosmrs::Any; +use error_stack::ResultExt; +use events::Error::EventTypeMismatch; +use events::Event; +use events_derive::try_from; +use multiversx_sdk::data::address::Address; +use serde::Deserialize; +use tokio::sync::watch::Receiver; +use tracing::info; +use voting_verifier::msg::ExecuteMsg; + +use crate::event_processor::EventHandler; +use crate::handlers::errors::Error; +use crate::mvx::proxy::MvxProxy; +use crate::mvx::verifier::verify_message; +use crate::types::{Hash, TMAddress}; + +type Result = error_stack::Result; + +#[derive(Deserialize, Debug)] +pub struct Message { + pub tx_id: Hash, + pub event_index: u32, + pub destination_address: String, + pub destination_chain: router_api::ChainName, + pub source_address: Address, + pub payload_hash: Hash, +} + +#[derive(Deserialize, Debug)] +#[try_from("wasm-messages_poll_started")] +struct PollStartedEvent { + poll_id: PollId, + source_gateway_address: Address, + messages: Vec, + participants: Vec, + expires_at: u64, +} + +pub struct Handler

+where + P: MvxProxy + Send + Sync, +{ + verifier: TMAddress, + voting_verifier_contract: TMAddress, + blockchain: P, + latest_block_height: Receiver, +} + +impl

Handler

+where + P: MvxProxy + Send + Sync, +{ + pub fn new( + verifier: TMAddress, + voting_verifier_contract: TMAddress, + blockchain: P, + latest_block_height: Receiver, + ) -> Self { + Self { + verifier, + voting_verifier_contract, + blockchain, + latest_block_height, + } + } + + fn vote_msg(&self, poll_id: PollId, votes: Vec) -> MsgExecuteContract { + MsgExecuteContract { + sender: self.verifier.as_ref().clone(), + contract: self.voting_verifier_contract.as_ref().clone(), + msg: serde_json::to_vec(&ExecuteMsg::Vote { poll_id, votes }) + .expect("vote msg should serialize"), + funds: vec![], + } + } +} + +#[async_trait] +impl

EventHandler for Handler

+where + P: MvxProxy + Send + Sync, +{ + type Err = Error; + + async fn handle(&self, event: &Event) -> Result> { + if !event.is_from_contract(self.voting_verifier_contract.as_ref()) { + return Ok(vec![]); + } + + let PollStartedEvent { + poll_id, + source_gateway_address, + messages, + participants, + expires_at, + .. + } = match event.try_into() as error_stack::Result<_, _> { + Err(report) if matches!(report.current_context(), EventTypeMismatch(_)) => { + return Ok(vec![]); + } + event => event.change_context(Error::DeserializeEvent)?, + }; + + if !participants.contains(&self.verifier) { + return Ok(vec![]); + } + + let latest_block_height = *self.latest_block_height.borrow(); + if latest_block_height >= expires_at { + info!(poll_id = poll_id.to_string(), "skipping expired poll"); + + return Ok(vec![]); + } + + let tx_hashes: HashSet<_> = messages.iter().map(|message| message.tx_id).collect(); + let transactions_info = self + .blockchain + .transactions_info_with_results(tx_hashes) + .await; + + let votes: Vec = messages + .iter() + .map(|msg| { + transactions_info + .get(&msg.tx_id) + .map_or(Vote::NotFound, |transaction| { + verify_message(&source_gateway_address, transaction, msg) + }) + }) + .collect(); + + Ok(vec![self + .vote_msg(poll_id, votes) + .into_any() + .expect("vote msg should serialize")]) + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + use std::convert::TryInto; + + use cosmrs::cosmwasm::MsgExecuteContract; + use cosmrs::tx::Msg; + use cosmwasm_std; + use error_stack::Result; + use hex::ToHex; + use tokio::sync::watch; + use tokio::test as async_test; + use voting_verifier::events::{PollMetadata, PollStarted, TxEventConfirmation}; + + use super::PollStartedEvent; + use crate::event_processor::EventHandler; + use crate::handlers::tests::into_structured_event; + use crate::mvx::proxy::MockMvxProxy; + use crate::types::{EVMAddress, Hash, TMAddress}; + use crate::PREFIX; + + #[test] + fn should_deserialize_poll_started_event() { + let event: Result = into_structured_event( + poll_started_event(participants(5, None)), + &TMAddress::random(PREFIX), + ) + .try_into(); + + assert!(event.is_ok()); + + let event = event.unwrap(); + + assert!(event.poll_id == 100u64.into()); + assert!( + event.source_gateway_address.to_bech32_string().unwrap() + == "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx" + ); + + let message = event.messages.first().unwrap(); + + assert!( + message.tx_id.encode_hex::() + == "dfaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47312", + ); + assert!(message.event_index == 1u32); + assert!(message.destination_chain == "ethereum"); + assert!( + message.source_address.to_bech32_string().unwrap() + == "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7" + ); + } + + // Should not handle event if it is not a poll started event + #[async_test] + async fn not_poll_started_event() { + let event = into_structured_event( + cosmwasm_std::Event::new("transfer"), + &TMAddress::random(PREFIX), + ); + + let handler = super::Handler::new( + TMAddress::random(PREFIX), + TMAddress::random(PREFIX), + MockMvxProxy::new(), + watch::channel(0).1, + ); + + assert!(handler.handle(&event).await.is_ok()); + } + + // Should not handle event if it is not emitted from voting verifier + #[async_test] + async fn contract_is_not_voting_verifier() { + let event = into_structured_event( + poll_started_event(participants(5, None)), + &TMAddress::random(PREFIX), + ); + + let handler = super::Handler::new( + TMAddress::random(PREFIX), + TMAddress::random(PREFIX), + MockMvxProxy::new(), + watch::channel(0).1, + ); + + assert!(handler.handle(&event).await.is_ok()); + } + + // Should not handle event if worker is not a poll participant + #[async_test] + async fn verifier_is_not_a_participant() { + let voting_verifier = TMAddress::random(PREFIX); + let event = + into_structured_event(poll_started_event(participants(5, None)), &voting_verifier); + + let handler = super::Handler::new( + TMAddress::random(PREFIX), + voting_verifier, + MockMvxProxy::new(), + watch::channel(0).1, + ); + + assert!(handler.handle(&event).await.is_ok()); + } + + #[async_test] + async fn should_vote_correctly() { + let mut proxy = MockMvxProxy::new(); + proxy + .expect_transactions_info_with_results() + .returning(|_| HashMap::new()); + + let voting_verifier = TMAddress::random(PREFIX); + let worker = TMAddress::random(PREFIX); + let event = into_structured_event( + poll_started_event(participants(5, Some(worker.clone()))), + &voting_verifier, + ); + + let handler = super::Handler::new(worker, voting_verifier, proxy, watch::channel(0).1); + + let actual = handler.handle(&event).await.unwrap(); + assert_eq!(actual.len(), 1); + assert!(MsgExecuteContract::from_any(actual.first().unwrap()).is_ok()); + } + + #[async_test] + async fn should_skip_expired_poll() { + let mut proxy = MockMvxProxy::new(); + proxy + .expect_transactions_info_with_results() + .returning(|_| HashMap::new()); + + let voting_verifier = TMAddress::random(PREFIX); + let worker = TMAddress::random(PREFIX); + let expiration = 100u64; + let event = into_structured_event( + poll_started_event(participants(5, Some(worker.clone()))), + &voting_verifier, + ); + + let (tx, rx) = watch::channel(expiration - 1); + + let handler = super::Handler::new(worker, voting_verifier, proxy, rx); + + // poll is not expired yet, should hit proxy + let actual = handler.handle(&event).await.unwrap(); + assert_eq!(actual.len(), 1); + + let _ = tx.send(expiration + 1); + + // poll is expired + assert_eq!(handler.handle(&event).await.unwrap(), vec![]); + } + + fn poll_started_event(participants: Vec) -> PollStarted { + PollStarted::Messages { + metadata: PollMetadata { + poll_id: "100".parse().unwrap(), + source_chain: "multiversx".parse().unwrap(), + source_gateway_address: + "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx" + .parse() + .unwrap(), + confirmation_height: 15, + expires_at: 100, + participants: participants + .into_iter() + .map(|addr| cosmwasm_std::Addr::unchecked(addr.to_string())) + .collect(), + }, + messages: vec![TxEventConfirmation { + tx_id: "dfaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47312" + .parse() + .unwrap(), + event_index: 1, + source_address: "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7" + .parse() + .unwrap(), + destination_chain: "ethereum".parse().unwrap(), + destination_address: format!("0x{:x}", EVMAddress::random()).parse().unwrap(), + payload_hash: Hash::random().to_fixed_bytes(), + }], + } + } + + fn participants(n: u8, worker: Option) -> Vec { + (0..n) + .map(|_| TMAddress::random(PREFIX)) + .chain(worker) + .collect() + } +} diff --git a/ampd/src/handlers/mvx_verify_verifier_set.rs b/ampd/src/handlers/mvx_verify_verifier_set.rs new file mode 100644 index 000000000..1953ee000 --- /dev/null +++ b/ampd/src/handlers/mvx_verify_verifier_set.rs @@ -0,0 +1,362 @@ +use std::convert::TryInto; + +use async_trait::async_trait; +use axelar_wasm_std::voting::{PollId, Vote}; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; +use cosmrs::Any; +use error_stack::ResultExt; +use events::Error::EventTypeMismatch; +use events::Event; +use events_derive::try_from; +use multisig::verifier_set::VerifierSet; +use multiversx_sdk::data::address::Address; +use serde::Deserialize; +use tokio::sync::watch::Receiver; +use tracing::{info, info_span}; +use valuable::Valuable; +use voting_verifier::msg::ExecuteMsg; + +use crate::event_processor::EventHandler; +use crate::handlers::errors::Error; +use crate::mvx::proxy::MvxProxy; +use crate::mvx::verifier::verify_verifier_set; +use crate::types::{Hash, TMAddress}; + +#[derive(Deserialize, Debug)] +pub struct VerifierSetConfirmation { + pub tx_id: Hash, + pub event_index: u32, + pub verifier_set: VerifierSet, +} + +#[derive(Deserialize, Debug)] +#[try_from("wasm-verifier_set_poll_started")] +struct PollStartedEvent { + poll_id: PollId, + source_gateway_address: Address, + verifier_set: VerifierSetConfirmation, + participants: Vec, + expires_at: u64, +} + +pub struct Handler

+where + P: MvxProxy + Send + Sync, +{ + verifier: TMAddress, + voting_verifier_contract: TMAddress, + blockchain: P, + latest_block_height: Receiver, +} + +impl

Handler

+where + P: MvxProxy + Send + Sync, +{ + pub fn new( + verifier: TMAddress, + voting_verifier_contract: TMAddress, + blockchain: P, + latest_block_height: Receiver, + ) -> Self { + Self { + verifier, + voting_verifier_contract, + blockchain, + latest_block_height, + } + } + + fn vote_msg(&self, poll_id: PollId, vote: Vote) -> MsgExecuteContract { + MsgExecuteContract { + sender: self.verifier.as_ref().clone(), + contract: self.voting_verifier_contract.as_ref().clone(), + msg: serde_json::to_vec(&ExecuteMsg::Vote { + poll_id, + votes: vec![vote], + }) + .expect("vote msg should serialize"), + funds: vec![], + } + } +} + +#[async_trait] +impl

EventHandler for Handler

+where + P: MvxProxy + Send + Sync, +{ + type Err = Error; + + async fn handle(&self, event: &Event) -> error_stack::Result, Error> { + if !event.is_from_contract(self.voting_verifier_contract.as_ref()) { + return Ok(vec![]); + } + + let PollStartedEvent { + poll_id, + source_gateway_address, + verifier_set, + participants, + expires_at, + .. + } = match event.try_into() as error_stack::Result<_, _> { + Err(report) if matches!(report.current_context(), EventTypeMismatch(_)) => { + return Ok(vec![]); + } + event => event.change_context(Error::DeserializeEvent)?, + }; + + if !participants.contains(&self.verifier) { + return Ok(vec![]); + } + + let latest_block_height = *self.latest_block_height.borrow(); + if latest_block_height >= expires_at { + info!(poll_id = poll_id.to_string(), "skipping expired poll"); + return Ok(vec![]); + } + + let transaction_info = self + .blockchain + .transaction_info_with_results(&verifier_set.tx_id) + .await; + + let vote = info_span!( + "verify a new verifier set for MultiversX", + poll_id = poll_id.to_string(), + id = format!("{}_{}", verifier_set.tx_id, verifier_set.event_index) + ) + .in_scope(|| { + info!("ready to verify a new worker set in poll"); + + let vote = transaction_info.map_or(Vote::NotFound, |transaction| { + verify_verifier_set(&source_gateway_address, &transaction, verifier_set) + }); + info!( + vote = vote.as_value(), + "ready to vote for a new worker set in poll" + ); + + vote + }); + + Ok(vec![self + .vote_msg(poll_id, vote) + .into_any() + .expect("vote msg should serialize")]) + } +} + +#[cfg(test)] +mod tests { + use std::convert::TryInto; + + use cosmrs::cosmwasm::MsgExecuteContract; + use cosmrs::tx::Msg; + use cosmwasm_std; + use cosmwasm_std::{HexBinary, Uint128}; + use error_stack::Result; + use events::Event; + use hex::ToHex; + use multisig::key::KeyType; + use multisig::test::common::{build_verifier_set, ed25519_test_data}; + use tokio::sync::watch; + use tokio::test as async_test; + use voting_verifier::events::{PollMetadata, PollStarted, VerifierSetConfirmation}; + + use super::PollStartedEvent; + use crate::event_processor::EventHandler; + use crate::handlers::tests::into_structured_event; + use crate::mvx::proxy::MockMvxProxy; + use crate::types::TMAddress; + use crate::PREFIX; + + #[test] + fn should_deserialize_verifier_set_poll_started_event() { + let event: Result = into_structured_event( + verifier_set_poll_started_event(participants(5, None), 100), + &TMAddress::random(PREFIX), + ) + .try_into(); + + assert!(event.is_ok()); + + let event = event.unwrap(); + + assert!(event.poll_id == 100u64.into()); + assert!( + event.source_gateway_address.to_bech32_string().unwrap() + == "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx" + ); + + let verifier_set = event.verifier_set; + + assert!( + verifier_set.tx_id.encode_hex::() + == "dfaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47312" + ); + assert!(verifier_set.event_index == 1u32); + assert!(verifier_set.verifier_set.signers.len() == 3); + assert_eq!(verifier_set.verifier_set.threshold, Uint128::from(2u128)); + + let mut signers = verifier_set.verifier_set.signers.values(); + let signer1 = signers.next().unwrap(); + let signer2 = signers.next().unwrap(); + + assert_eq!(signer1.pub_key.as_ref(), HexBinary::from_hex( + "45e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f", + ) + .unwrap().as_ref()); + assert_eq!(signer1.weight, Uint128::from(1u128)); + + assert_eq!(signer2.pub_key.as_ref(), HexBinary::from_hex( + "dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b", + ) + .unwrap().as_ref()); + assert_eq!(signer2.weight, Uint128::from(1u128)); + } + + #[async_test] + async fn not_poll_started_event() { + let event = into_structured_event( + cosmwasm_std::Event::new("transfer"), + &TMAddress::random(PREFIX), + ); + + let handler = super::Handler::new( + TMAddress::random(PREFIX), + TMAddress::random(PREFIX), + MockMvxProxy::new(), + watch::channel(0).1, + ); + + assert_eq!(handler.handle(&event).await.unwrap(), vec![]); + } + + #[async_test] + async fn contract_is_not_voting_verifier() { + let event = into_structured_event( + verifier_set_poll_started_event(participants(5, None), 100), + &TMAddress::random(PREFIX), + ); + + let handler = super::Handler::new( + TMAddress::random(PREFIX), + TMAddress::random(PREFIX), + MockMvxProxy::new(), + watch::channel(0).1, + ); + + assert_eq!(handler.handle(&event).await.unwrap(), vec![]); + } + + #[async_test] + async fn verifier_is_not_a_participant() { + let voting_verifier = TMAddress::random(PREFIX); + let event = into_structured_event( + verifier_set_poll_started_event(participants(5, None), 100), + &voting_verifier, + ); + + let handler = super::Handler::new( + TMAddress::random(PREFIX), + voting_verifier, + MockMvxProxy::new(), + watch::channel(0).1, + ); + + assert_eq!(handler.handle(&event).await.unwrap(), vec![]); + } + + #[async_test] + async fn should_skip_expired_poll() { + let mut proxy = MockMvxProxy::new(); + proxy + .expect_transaction_info_with_results() + .returning(|_| None); + + let voting_verifier = TMAddress::random(PREFIX); + let verifier = TMAddress::random(PREFIX); + let expiration = 100u64; + let event: Event = into_structured_event( + verifier_set_poll_started_event( + vec![verifier.clone()].into_iter().collect(), + expiration, + ), + &voting_verifier, + ); + + let (tx, rx) = watch::channel(expiration - 1); + + let handler = super::Handler::new(verifier, voting_verifier, proxy, rx); + + // poll is not expired yet, should hit proxy + let actual = handler.handle(&event).await.unwrap(); + assert_eq!(actual.len(), 1); + + let _ = tx.send(expiration + 1); + + // poll is expired + assert_eq!(handler.handle(&event).await.unwrap(), vec![]); + } + + #[async_test] + async fn should_vote_correctly() { + let mut proxy = MockMvxProxy::new(); + proxy + .expect_transaction_info_with_results() + .returning(|_| None); + + let voting_verifier = TMAddress::random(PREFIX); + let worker = TMAddress::random(PREFIX); + + let event = into_structured_event( + verifier_set_poll_started_event(participants(5, Some(worker.clone())), 100), + &voting_verifier, + ); + + let handler = super::Handler::new(worker, voting_verifier, proxy, watch::channel(0).1); + + let actual = handler.handle(&event).await.unwrap(); + assert_eq!(actual.len(), 1); + assert!(MsgExecuteContract::from_any(actual.first().unwrap()).is_ok()); + } + + fn verifier_set_poll_started_event( + participants: Vec, + expires_at: u64, + ) -> PollStarted { + PollStarted::VerifierSet { + metadata: PollMetadata { + poll_id: "100".parse().unwrap(), + source_chain: "multiversx".parse().unwrap(), + source_gateway_address: + "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx" + .parse() + .unwrap(), + confirmation_height: 15, + expires_at, + participants: participants + .into_iter() + .map(|addr| cosmwasm_std::Addr::unchecked(addr.to_string())) + .collect(), + }, + verifier_set: VerifierSetConfirmation { + tx_id: "dfaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47312" + .parse() + .unwrap(), + event_index: 1, + verifier_set: build_verifier_set(KeyType::Ed25519, &ed25519_test_data::signers()), + }, + } + } + + fn participants(n: u8, worker: Option) -> Vec { + (0..n) + .map(|_| TMAddress::random(PREFIX)) + .chain(worker) + .collect() + } +} diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index a134c2fae..79182420e 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -12,6 +12,7 @@ use event_processor::EventHandler; use event_sub::EventSub; use evm::finalizer::{pick, Finalization}; use evm::json_rpc::EthereumClient; +use multiversx_sdk::blockchain::CommunicationProxy; use queue::queued_broadcaster::QueuedBroadcaster; use router_api::ChainName; use thiserror::Error; @@ -39,6 +40,7 @@ mod grpc; mod handlers; mod health_check; mod json_rpc; +mod mvx; mod queue; mod sui; mod tm_client; @@ -328,6 +330,32 @@ where ), event_processor_config.clone(), ), + handlers::config::Config::MvxMsgVerifier { + cosmwasm_contract, + proxy_url, + } => self.create_handler_task( + "mvx-msg-verifier", + handlers::mvx_verify_msg::Handler::new( + verifier.clone(), + cosmwasm_contract, + CommunicationProxy::new(proxy_url.to_string().trim_end_matches('/').into()), + self.block_height_monitor.latest_block_height(), + ), + event_processor_config.clone(), + ), + handlers::config::Config::MvxVerifierSetVerifier { + cosmwasm_contract, + proxy_url, + } => self.create_handler_task( + "mvx-worker-set-verifier", + handlers::mvx_verify_verifier_set::Handler::new( + verifier.clone(), + cosmwasm_contract, + CommunicationProxy::new(proxy_url.to_string().trim_end_matches('/').into()), + self.block_height_monitor.latest_block_height(), + ), + event_processor_config.clone(), + ), }; self.event_processor = self.event_processor.add_task(task); } diff --git a/ampd/src/mvx/error.rs b/ampd/src/mvx/error.rs new file mode 100644 index 000000000..4a22a59d9 --- /dev/null +++ b/ampd/src/mvx/error.rs @@ -0,0 +1,9 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("provided key is not ed25519")] + NotEd25519Key, + #[error("required property is empty")] + PropertyEmpty, +} diff --git a/ampd/src/mvx/mod.rs b/ampd/src/mvx/mod.rs new file mode 100644 index 000000000..6bc2ad9c5 --- /dev/null +++ b/ampd/src/mvx/mod.rs @@ -0,0 +1,85 @@ +use axelar_wasm_std::hash::Hash; +use cosmwasm_std::Uint256; +use multisig::key::PublicKey; +use multisig::msg::Signer; +use multisig::verifier_set::VerifierSet; +use sha3::{Digest, Keccak256}; + +use crate::mvx::error::Error; + +pub mod error; +pub mod proxy; +pub mod verifier; + +pub struct WeightedSigner { + pub signer: [u8; 32], + pub weight: Vec, +} + +pub struct WeightedSigners { + pub signers: Vec, + pub threshold: Vec, + pub nonce: [u8; 32], +} + +impl WeightedSigners { + pub fn hash(&self) -> Hash { + let mut encoded = Vec::new(); + + for signer in self.signers.iter() { + encoded.push(signer.signer.as_slice()); + encoded.push(signer.weight.as_slice()); + } + + encoded.push(self.threshold.as_slice()); + encoded.push(self.nonce.as_slice()); + + Keccak256::digest(encoded.concat()).into() + } +} + +impl From<&Signer> for WeightedSigner { + fn from(signer: &Signer) -> Self { + WeightedSigner { + signer: ed25519_key(&signer.pub_key).expect("not ed25519 key"), + weight: uint256_to_compact_vec(signer.weight.into()), + } + } +} + +impl From<&VerifierSet> for WeightedSigners { + fn from(verifier_set: &VerifierSet) -> Self { + let mut signers = verifier_set + .signers + .values() + .map(WeightedSigner::from) + .collect::>(); + + signers.sort_by_key(|weighted_signer| weighted_signer.signer); + + WeightedSigners { + signers, + threshold: uint256_to_compact_vec(verifier_set.threshold.into()), + nonce: Keccak256::digest(Uint256::from(verifier_set.created_at).to_be_bytes()).into(), + } + } +} + +fn uint256_to_compact_vec(value: Uint256) -> Vec { + if value.is_zero() { + return Vec::new(); + } + + let bytes = value.to_be_bytes(); + let slice_from = bytes.iter().position(|byte| *byte != 0).unwrap_or(0); + + bytes[slice_from..].to_vec() +} + +pub fn ed25519_key(pub_key: &PublicKey) -> Result<[u8; 32], Error> { + return match pub_key { + PublicKey::Ed25519(ed25519_key) => Ok(<[u8; 32]>::try_from(ed25519_key.as_ref()) + .expect("couldn't convert pubkey to ed25519 public key")), + _ => Err(Error::NotEd25519Key), + }; +} diff --git a/ampd/src/mvx/proxy.rs b/ampd/src/mvx/proxy.rs new file mode 100644 index 000000000..de5299c4e --- /dev/null +++ b/ampd/src/mvx/proxy.rs @@ -0,0 +1,63 @@ +use std::collections::{HashMap, HashSet}; + +use async_trait::async_trait; +use futures::future::join_all; +use hex::ToHex; +use mockall::automock; +use multiversx_sdk::blockchain::CommunicationProxy; +use multiversx_sdk::data::transaction::TransactionOnNetwork; + +use crate::types::Hash; + +const STATUS_SUCCESS: &str = "success"; + +#[automock] +#[async_trait] +pub trait MvxProxy { + async fn transactions_info_with_results( + &self, + tx_hashes: HashSet, + ) -> HashMap; + + async fn transaction_info_with_results(&self, tx_hash: &Hash) -> Option; + + fn is_valid_transaction(tx: &TransactionOnNetwork) -> bool; +} + +#[async_trait] +impl MvxProxy for CommunicationProxy { + async fn transactions_info_with_results( + &self, + tx_hashes: HashSet, + ) -> HashMap { + let tx_hashes = Vec::from_iter(tx_hashes); + + let txs = join_all( + tx_hashes + .iter() + .map(|tx_hash| self.transaction_info_with_results(tx_hash)), + ) + .await; + + tx_hashes + .into_iter() + .zip(txs) + .filter_map(|(hash, tx)| { + tx.as_ref()?; + + Some((hash, tx.unwrap())) + }) + .collect() + } + + async fn transaction_info_with_results(&self, tx_hash: &Hash) -> Option { + self.get_transaction_info_with_results(tx_hash.encode_hex::().as_str()) + .await + .ok() + .filter(Self::is_valid_transaction) + } + + fn is_valid_transaction(tx: &TransactionOnNetwork) -> bool { + tx.hash.is_some() && tx.logs.is_some() && tx.status == *STATUS_SUCCESS + } +} diff --git a/ampd/src/mvx/verifier.rs b/ampd/src/mvx/verifier.rs new file mode 100644 index 000000000..d158240fc --- /dev/null +++ b/ampd/src/mvx/verifier.rs @@ -0,0 +1,585 @@ +use axelar_wasm_std::voting::Vote; +use base64::engine::general_purpose::STANDARD; +use base64::Engine; +use hex::ToHex; +use multiversx_sdk::data::address::Address; +use multiversx_sdk::data::transaction::{Events, TransactionOnNetwork}; +use num_traits::cast; + +use crate::handlers::mvx_verify_msg::Message; +use crate::handlers::mvx_verify_verifier_set::VerifierSetConfirmation; +use crate::mvx::error::Error; +use crate::mvx::WeightedSigners; +use crate::types::Hash; + +const CONTRACT_CALL_IDENTIFIER: &str = "callContract"; +const CONTRACT_CALL_EVENT: &str = "contract_call_event"; + +const ROTATE_SIGNERS_IDENTIFIER: &str = "rotateSigners"; +const SIGNERS_ROTATED_EVENT: &str = "signers_rotated_event"; + +impl Message { + fn eq_event(&self, event: &Events) -> Result> { + if event.identifier != CONTRACT_CALL_IDENTIFIER { + return Ok(false); + } + + let topics = event.topics.as_ref().ok_or(Error::PropertyEmpty)?; + + let event_name = topics.first().ok_or(Error::PropertyEmpty)?; + let event_name = STANDARD.decode(event_name)?; + if event_name.as_slice() != CONTRACT_CALL_EVENT.as_bytes() { + return Ok(false); + } + + let sender = topics.get(1).ok_or(Error::PropertyEmpty)?; + let sender = STANDARD.decode(sender)?; + if sender.len() != 32 || sender[0..32] != self.source_address.to_bytes() { + return Ok(false); + } + + let destination_chain = topics.get(2).ok_or(Error::PropertyEmpty)?; + let destination_chain = STANDARD.decode(destination_chain)?; + let destination_chain = String::from_utf8(destination_chain)?; + if destination_chain != self.destination_chain.as_ref() { + return Ok(false); + } + + let destination_address = topics.get(3).ok_or(Error::PropertyEmpty)?; + let destination_address = STANDARD.decode(destination_address)?; + let destination_address = String::from_utf8(destination_address)?; + if destination_address != self.destination_address { + return Ok(false); + } + + let payload_hash = topics.get(4).ok_or(Error::PropertyEmpty)?; + let payload_hash = STANDARD.decode(payload_hash)?; + if payload_hash.len() != 32 + || Hash::from_slice(payload_hash.as_slice()) != self.payload_hash + { + return Ok(false); + } + + Ok(true) + } +} + +impl VerifierSetConfirmation { + fn eq_event(&self, event: &Events) -> Result> { + if event.identifier != ROTATE_SIGNERS_IDENTIFIER { + return Ok(false); + } + + let topics = event.topics.as_ref().ok_or(Error::PropertyEmpty)?; + + let event_name = topics.first().ok_or(Error::PropertyEmpty)?; + let event_name = STANDARD.decode(event_name)?; + if event_name.as_slice() != SIGNERS_ROTATED_EVENT.as_bytes() { + return Ok(false); + } + + let signers_hash = topics.get(2).ok_or(Error::PropertyEmpty)?; + let signers_hash = STANDARD.decode(signers_hash)?; + + let weighted_signers = WeightedSigners::from(&self.verifier_set); + + if signers_hash.len() != 32 || signers_hash.as_slice() != weighted_signers.hash().as_slice() + { + return Ok(false); + } + + Ok(true) + } +} + +fn find_event<'a>( + transaction: &'a TransactionOnNetwork, + gateway_address: &Address, + log_index: u32, +) -> Option<&'a Events> { + let log_index: usize = cast(log_index).expect("log_index must be a valid usize"); + + let event = transaction.logs.as_ref()?.events.get(log_index)?; + + if event.address.to_bytes() != gateway_address.to_bytes() { + return None; + } + + Some(event) +} + +pub fn verify_message( + gateway_address: &Address, + transaction: &TransactionOnNetwork, + message: &Message, +) -> Vote { + let hash = transaction.hash.as_deref().unwrap_or_default(); + + if hash.is_empty() { + return Vote::NotFound; + } + + match find_event(transaction, gateway_address, message.event_index) { + Some(event) + if hash == message.tx_id.encode_hex::().as_str() + && message.eq_event(event).unwrap_or(false) => + { + Vote::SucceededOnChain + } + _ => Vote::NotFound, + } +} + +pub fn verify_verifier_set( + gateway_address: &Address, + transaction: &TransactionOnNetwork, + verifier_set: VerifierSetConfirmation, +) -> Vote { + let hash = transaction.hash.as_deref().unwrap_or_default(); + + if hash.is_empty() { + return Vote::NotFound; + } + + match find_event(transaction, gateway_address, verifier_set.event_index) { + Some(event) + if hash == verifier_set.tx_id.encode_hex::().as_str() + && verifier_set.eq_event(event).unwrap_or(false) => + { + Vote::SucceededOnChain + } + _ => Vote::NotFound, + } +} + +#[cfg(test)] +mod tests { + use axelar_wasm_std::voting::Vote; + use base64::engine::general_purpose::STANDARD; + use base64::Engine; + use cosmwasm_std::{HexBinary, Uint128}; + use hex::ToHex; + use multisig::key::KeyType; + use multisig::test::common::{build_verifier_set, ed25519_test_data}; + use multiversx_sdk::data::address::Address; + use multiversx_sdk::data::transaction::{ApiLogs, Events, TransactionOnNetwork}; + + use crate::handlers::mvx_verify_msg::Message; + use crate::handlers::mvx_verify_verifier_set::VerifierSetConfirmation; + use crate::mvx::verifier::{ + verify_message, verify_verifier_set, CONTRACT_CALL_EVENT, CONTRACT_CALL_IDENTIFIER, + ROTATE_SIGNERS_IDENTIFIER, SIGNERS_ROTATED_EVENT, + }; + use crate::types::{EVMAddress, Hash}; + + // test verify message + #[test] + fn should_not_verify_msg_if_tx_id_does_not_match() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.tx_id = "ffaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47313" + .parse() + .unwrap(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_no_logs() { + let (gateway_address, mut tx, msg) = get_matching_msg_and_tx(); + + tx.logs = None; + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_no_log_for_event_index() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.event_index = 2; + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_event_index_does_not_match() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.event_index = 0; + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_not_from_gateway() { + let (gateway_address, mut tx, msg) = get_matching_msg_and_tx(); + + let events = &mut tx.logs.as_mut().unwrap().events; + let event = events.get_mut(1).unwrap(); + event.address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7", + ) + .unwrap(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_not_call_contract_identifier() { + let (gateway_address, mut tx, msg) = get_matching_msg_and_tx(); + + let events = &mut tx.logs.as_mut().unwrap().events; + let event = events.get_mut(1).unwrap(); + event.identifier = "other".into(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_not_call_contract_event() { + let (gateway_address, mut tx, msg) = get_matching_msg_and_tx(); + + let events = &mut tx.logs.as_mut().unwrap().events; + let event = events.get_mut(1).unwrap(); + + let topics = event.topics.as_mut().unwrap(); + let topic = topics.get_mut(0).unwrap(); + *topic = "other".into(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_source_address_does_not_match() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.source_address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx", + ) + .unwrap(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_destination_chain_does_not_match() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.destination_chain = "otherchain".parse().unwrap(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_destination_address_does_not_match() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.destination_address = EVMAddress::random().to_string(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_not_verify_msg_if_payload_hash_does_not_match() { + let (gateway_address, tx, mut msg) = get_matching_msg_and_tx(); + + msg.payload_hash = Hash::random(); + assert_eq!(verify_message(&gateway_address, &tx, &msg), Vote::NotFound); + } + + #[test] + fn should_verify_msg() { + let (gateway_address, tx, msg) = get_matching_msg_and_tx(); + + assert_eq!( + verify_message(&gateway_address, &tx, &msg), + Vote::SucceededOnChain + ); + } + + // test verify worker set + #[test] + fn should_not_verify_verifier_set_if_tx_id_does_not_match() { + let (gateway_address, tx, mut verifier_set) = get_matching_verifier_set_and_tx(); + + verifier_set.tx_id = "ffaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47313" + .parse() + .unwrap(); + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_no_logs() { + let (gateway_address, mut tx, verifier_set) = get_matching_verifier_set_and_tx(); + + tx.logs = None; + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_no_log_for_event_index() { + let (gateway_address, tx, mut verifier_set) = get_matching_verifier_set_and_tx(); + + verifier_set.event_index = 2; + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_event_index_does_not_match() { + let (gateway_address, tx, mut verifier_set) = get_matching_verifier_set_and_tx(); + + verifier_set.event_index = 0; + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_not_from_gateway() { + let (gateway_address, mut tx, verifier_set) = get_matching_verifier_set_and_tx(); + + let events = &mut tx.logs.as_mut().unwrap().events; + let event = events.get_mut(1).unwrap(); + event.address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7", + ) + .unwrap(); + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_not_rotate_signers_identifier() { + let (gateway_address, mut tx, verifier_set) = get_matching_verifier_set_and_tx(); + + let events = &mut tx.logs.as_mut().unwrap().events; + let event = events.get_mut(1).unwrap(); + event.identifier = "callContract".into(); + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_verifier_set_if_not_signers_rotated_event() { + let (gateway_address, mut tx, verifier_set) = get_matching_verifier_set_and_tx(); + + let events = &mut tx.logs.as_mut().unwrap().events; + let event = events.get_mut(1).unwrap(); + + let topics = event.topics.as_mut().unwrap(); + let topic = topics.get_mut(0).unwrap(); + *topic = "otherEvent".into(); + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_not_verify_worker_set_if_verifier_set_does_not_match() { + let (gateway_address, tx, mut verifier_set) = get_matching_verifier_set_and_tx(); + + verifier_set.verifier_set.threshold = Uint128::from(10u128); + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::NotFound + ); + } + + #[test] + fn should_verify_verifier() { + let (gateway_address, tx, verifier_set) = get_matching_verifier_set_and_tx(); + + assert_eq!( + verify_verifier_set(&gateway_address, &tx, verifier_set), + Vote::SucceededOnChain + ); + } + + fn get_matching_msg_and_tx() -> (Address, TransactionOnNetwork, Message) { + let gateway_address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx", + ) + .unwrap(); + let source_address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7", + ) + .unwrap(); + let tx_id = "dfaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47312" + .parse() + .unwrap(); + + let msg = Message { + tx_id, + event_index: 1, + source_address, + destination_chain: "ethereum".parse().unwrap(), + destination_address: format!("0x{:x}", EVMAddress::random()).parse().unwrap(), + payload_hash: Hash::random(), + }; + + // Only the first 32 bytes matter for data + let payload_hash = msg.payload_hash; + + let wrong_event = Events { + address: gateway_address.clone(), + identifier: CONTRACT_CALL_IDENTIFIER.into(), + topics: Some(vec![STANDARD.encode(SIGNERS_ROTATED_EVENT)]), // wrong event name + data: None, + }; + + // On MultiversX, topics and data are base64 encoded + let event = Events { + address: gateway_address.clone(), + identifier: CONTRACT_CALL_IDENTIFIER.into(), + topics: Some(vec![ + STANDARD.encode(CONTRACT_CALL_EVENT), + STANDARD.encode(msg.source_address.clone().to_bytes()), + STANDARD.encode(msg.destination_chain.to_string()), + STANDARD.encode(msg.destination_address.clone()), + STANDARD.encode(payload_hash), + ]), + data: Some("".into()), // data is irrelevant here since it contains only the offchain payload + }; + + let other_address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7", + ) + .unwrap(); + let tx_block = TransactionOnNetwork { + hash: Some(msg.tx_id.encode_hex::()), + logs: Some(ApiLogs { + address: other_address.clone(), + events: vec![wrong_event, event], + }), + status: "success".into(), + // The rest are irrelevant but there is no default + kind: "".into(), + nonce: 1, + round: 1, + epoch: 1, + value: "".into(), + receiver: other_address.clone(), + sender: other_address, + gas_price: 0, + gas_limit: 0, + signature: "".into(), + source_shard: 1, + destination_shard: 1, + block_nonce: 1, + block_hash: "".into(), + notarized_at_source_in_meta_nonce: Some(0), + notarized_at_source_in_meta_hash: Some("".into()), + notarized_at_destination_in_meta_nonce: Some(0), + notarized_at_destination_in_meta_hash: Some("".into()), + miniblock_type: "".into(), + miniblock_hash: "".into(), + timestamp: 1, + data: None, + hyperblock_nonce: Some(1), + hyperblock_hash: Some("".into()), + smart_contract_results: None, + processing_type_on_destination: "".into(), + }; + + (gateway_address, tx_block, msg) + } + + fn get_matching_verifier_set_and_tx() -> (Address, TransactionOnNetwork, VerifierSetConfirmation) + { + let gateway_address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqsvzyz88e8v8j6x3wquatxuztnxjwnw92kkls6rdtzx", + ) + .unwrap(); + let tx_id = "dfaf64de66510723f2efbacd7ead3c4f8c856aed1afc2cb30254552aeda47312" + .parse() + .unwrap(); + + let verifier_set_confirmation = VerifierSetConfirmation { + tx_id, + event_index: 1, + verifier_set: build_verifier_set(KeyType::Ed25519, &ed25519_test_data::signers()), + }; + + // 00000003 - length of new signers + // 45e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f - first new signer + // 00000001 01 - length of biguint weight followed by 1 as hex + // c387253d29085a8036d6ae2cafb1b14699751417c0ce302cfe03da279e6b5c04 - second new signer + // 00000001 01 - length of biguint weight followed by 1 as hex + // dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b - third new signer + // 00000001 01 - length of biguint weight followed by 1 as hex + // 00000001 02 - length of biguint threshold followed by 2 as hex + // 290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 - the nonce (keccak256 hash of Uin256 number 0, created_at date) + let data = HexBinary::from_hex("0000000345e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f0000000101c387253d29085a8036d6ae2cafb1b14699751417c0ce302cfe03da279e6b5c040000000101dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b00000001010000000102290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") + .unwrap(); + let signers_hash = + HexBinary::from_hex("acc61d8597eaf76375dd9e34c50baab3c110d508ed4bd99c8d6000af503bf770") + .unwrap(); + + let wrong_event = Events { + address: gateway_address.clone(), + identifier: ROTATE_SIGNERS_IDENTIFIER.into(), + topics: Some(vec![STANDARD.encode(CONTRACT_CALL_EVENT)]), // wrong event name + data: None, + }; + + // On MultiversX, topics and data are base64 encoded + let event = Events { + address: gateway_address.clone(), + identifier: ROTATE_SIGNERS_IDENTIFIER.into(), + topics: Some(vec![ + STANDARD.encode(SIGNERS_ROTATED_EVENT), + STANDARD.encode("0"), // epoch (irrelevant here) + STANDARD.encode(signers_hash), // signers hash + ]), + data: Some(STANDARD.encode(data)), + }; + + let other_address = Address::from_bech32_string( + "erd1qqqqqqqqqqqqqpgqzqvm5ywqqf524efwrhr039tjs29w0qltkklsa05pk7", + ) + .unwrap(); + let tx_block = TransactionOnNetwork { + hash: Some(tx_id.encode_hex::()), + logs: Some(ApiLogs { + address: other_address.clone(), + events: vec![wrong_event, event], + }), + status: "success".into(), + // The rest are irrelevant but there is no default + kind: "".into(), + nonce: 1, + round: 1, + epoch: 1, + value: "".into(), + receiver: other_address.clone(), + sender: other_address, + gas_price: 0, + gas_limit: 0, + signature: "".into(), + source_shard: 1, + destination_shard: 1, + block_nonce: 1, + block_hash: "".into(), + notarized_at_source_in_meta_nonce: Some(0), + notarized_at_source_in_meta_hash: Some("".into()), + notarized_at_destination_in_meta_nonce: Some(0), + notarized_at_destination_in_meta_hash: Some("".into()), + miniblock_type: "".into(), + miniblock_hash: "".into(), + timestamp: 1, + data: None, + hyperblock_nonce: Some(1), + hyperblock_hash: Some("".into()), + smart_contract_results: None, + processing_type_on_destination: "".into(), + }; + + (gateway_address, tx_block, verifier_set_confirmation) + } +} diff --git a/ampd/src/tests/config_template.toml b/ampd/src/tests/config_template.toml index 30865dbd9..c50c2b107 100644 --- a/ampd/src/tests/config_template.toml +++ b/ampd/src/tests/config_template.toml @@ -62,6 +62,16 @@ rpc_url = 'http://127.0.0.1/' secs = 3 nanos = 0 +[[handlers]] +type = 'MvxMsgVerifier' +cosmwasm_contract = 'axelar1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqecnww6' +proxy_url = 'http://127.0.0.1/' + +[[handlers]] +type = 'MvxVerifierSetVerifier' +cosmwasm_contract = 'axelar1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqecnww6' +proxy_url = 'http://127.0.0.1/' + [tofnd_config] url = 'http://localhost:50051/' party_uid = 'ampd' From ff214c375f3e257527ec28a61f11b3102b1eb639 Mon Sep 17 00:00:00 2001 From: Sammy Date: Fri, 16 Aug 2024 14:27:16 -0400 Subject: [PATCH 156/168] feat: integrate address format with SuiAddress (#585) --- Cargo.lock | 23 ++- Cargo.toml | 2 + ampd/src/sui/verifier.rs | 8 +- contracts/multisig-prover/src/encoding/bcs.rs | 4 +- packages/axelar-wasm-std/Cargo.toml | 1 + packages/axelar-wasm-std/src/address.rs | 48 ++++- packages/sui-gateway/Cargo.toml | 3 +- packages/sui-gateway/src/error.rs | 6 +- .../sui-gateway/src/{gateway => }/events.rs | 4 +- packages/sui-gateway/src/gateway/mod.rs | 180 ----------------- packages/sui-gateway/src/lib.rs | 185 +++++++++++++++++- packages/sui-types/Cargo.toml | 17 ++ .../base_types.rs => sui-types/src/lib.rs} | 35 ++-- 13 files changed, 300 insertions(+), 216 deletions(-) rename packages/sui-gateway/src/{gateway => }/events.rs (94%) delete mode 100644 packages/sui-gateway/src/gateway/mod.rs create mode 100644 packages/sui-types/Cargo.toml rename packages/{sui-gateway/src/base_types.rs => sui-types/src/lib.rs} (76%) diff --git a/Cargo.lock b/Cargo.lock index bd078cad3..12c73bb4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,7 @@ dependencies = [ "sha3", "sui-gateway", "sui-json-rpc-types", - "sui-types", + "sui-types 0.1.0", "tendermint 0.33.0", "tendermint-rpc", "thiserror", @@ -824,6 +824,7 @@ dependencies = [ "serde_json", "sha3", "strum 0.25.0", + "sui-types 1.0.0", "thiserror", "valuable", ] @@ -7861,6 +7862,7 @@ dependencies = [ "serde", "serde_json", "sha3", + "sui-types 1.0.0", "thiserror", ] @@ -7878,7 +7880,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "sui-types", + "sui-types 0.1.0", ] [[package]] @@ -7906,7 +7908,7 @@ dependencies = [ "sui-macros", "sui-package-resolver", "sui-protocol-config", - "sui-types", + "sui-types 0.1.0", "tabled", "tracing", ] @@ -7936,7 +7938,7 @@ dependencies = [ "move-core-types", "serde", "sui-rest-api", - "sui-types", + "sui-types 0.1.0", "thiserror", "tokio", ] @@ -7993,7 +7995,7 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", - "sui-types", + "sui-types 0.1.0", "tap", "thiserror", ] @@ -8067,6 +8069,17 @@ dependencies = [ "typed-store-error", ] +[[package]] +name = "sui-types" +version = "1.0.0" +dependencies = [ + "error-stack", + "hex", + "rand", + "serde", + "thiserror", +] + [[package]] name = "syn" version = "0.15.44" diff --git a/Cargo.toml b/Cargo.toml index 343ef5f38..ebca95c66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,11 @@ error-stack = { version = "0.4.0", features = ["eyre"] } events = { version = "^1.0.0", path = "packages/events" } events-derive = { version = "^1.0.0", path = "packages/events-derive" } evm-gateway = { version = "^1.0.0", path = "packages/evm-gateway" } +sui-types = { version = "^1.0.0", path = "packages/sui-types" } sui-gateway = { version = "^1.0.0", path = "packages/sui-gateway" } axelar-wasm-std = { version = "^1.0.0", path = "packages/axelar-wasm-std" } axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std-derive" } +hex = "0.4.3" integration-tests = { version = "^1.0.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^1.0.0", path = "contracts/voting-verifier" } diff --git a/ampd/src/sui/verifier.rs b/ampd/src/sui/verifier.rs index 26d85b366..5b04dcd40 100644 --- a/ampd/src/sui/verifier.rs +++ b/ampd/src/sui/verifier.rs @@ -2,8 +2,8 @@ use axelar_wasm_std::voting::Vote; use axelar_wasm_std::{self}; use cosmwasm_std::HexBinary; use move_core_types::language_storage::StructTag; -use sui_gateway::gateway::events::{ContractCall, SignersRotated}; -use sui_gateway::gateway::{WeightedSigner, WeightedSigners}; +use sui_gateway::events::{ContractCall, SignersRotated}; +use sui_gateway::{WeightedSigner, WeightedSigners}; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockResponse}; use sui_types::base_types::SuiAddress; @@ -154,8 +154,8 @@ mod tests { use random_string::generate; use router_api::ChainName; use serde_json::json; - use sui_gateway::gateway::events::{ContractCall, SignersRotated}; - use sui_gateway::gateway::{WeightedSigner, WeightedSigners}; + use sui_gateway::events::{ContractCall, SignersRotated}; + use sui_gateway::{WeightedSigner, WeightedSigners}; use sui_json_rpc_types::{SuiEvent, SuiTransactionBlockEvents, SuiTransactionBlockResponse}; use sui_types::base_types::{SuiAddress, TransactionDigest}; use sui_types::event::EventID; diff --git a/contracts/multisig-prover/src/encoding/bcs.rs b/contracts/multisig-prover/src/encoding/bcs.rs index 80ba60ed6..b56c35746 100644 --- a/contracts/multisig-prover/src/encoding/bcs.rs +++ b/contracts/multisig-prover/src/encoding/bcs.rs @@ -6,9 +6,7 @@ use error_stack::{Result, ResultExt}; use multisig::msg::SignerWithSig; use multisig::verifier_set::VerifierSet; use sha3::{Digest, Keccak256}; -use sui_gateway::gateway::{ - CommandType, ExecuteData, Message, MessageToSign, Proof, WeightedSigners, -}; +use sui_gateway::{CommandType, ExecuteData, Message, MessageToSign, Proof, WeightedSigners}; use crate::encoding::{to_recoverable, Encoder}; use crate::error::ContractError; diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index f6d74fad5..f2e02b5db 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -47,6 +47,7 @@ serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" sha3 = { workspace = true } strum = { workspace = true } +sui-types = { workspace = true } thiserror = { workspace = true } valuable = { version = "0.1.0", features = ["derive"] } diff --git a/packages/axelar-wasm-std/src/address.rs b/packages/axelar-wasm-std/src/address.rs index bf044fc01..69162ca30 100644 --- a/packages/axelar-wasm-std/src/address.rs +++ b/packages/axelar-wasm-std/src/address.rs @@ -1,7 +1,10 @@ +use std::str::FromStr; + use alloy_primitives::Address; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Api}; use error_stack::{Result, ResultExt}; +use sui_types::SuiAddress; #[derive(thiserror::Error)] #[cw_serde] @@ -13,13 +16,20 @@ pub enum Error { #[cw_serde] pub enum AddressFormat { Eip55, + Sui, } pub fn validate_address(address: &str, format: &AddressFormat) -> Result<(), Error> { match format { - AddressFormat::Eip55 => Address::parse_checksummed(address, None) - .change_context(Error::InvalidAddress(address.to_string()))?, - }; + AddressFormat::Eip55 => { + Address::parse_checksummed(address, None) + .change_context(Error::InvalidAddress(address.to_string()))?; + } + AddressFormat::Sui => { + SuiAddress::from_str(address) + .change_context(Error::InvalidAddress(address.to_string()))?; + } + } Ok(()) } @@ -36,7 +46,7 @@ mod tests { use crate::{address, err_contains}; #[test] - fn validate_address() { + fn validate_eip55_address() { let addr = "0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5"; assert!(address::validate_address(addr, &address::AddressFormat::Eip55).is_ok()); @@ -51,6 +61,36 @@ mod tests { assert!(address::validate_address(&upper_case, &address::AddressFormat::Eip55).is_err()); } + #[test] + fn validate_sui_address() { + let addr = "0x8cc8d18733a4bf98de8f861d356e2191918733e3afff29f327a01b5ba2997a4d"; + + assert!(address::validate_address(addr, &address::AddressFormat::Sui).is_ok()); + + let without_prefix = addr.strip_prefix("0x").unwrap(); + assert!(address::validate_address(without_prefix, &address::AddressFormat::Sui).is_err()); + + let upper_case = addr.to_uppercase(); + assert!(address::validate_address(&upper_case, &address::AddressFormat::Sui).is_err()); + + let mixed_case = addr + .chars() + .enumerate() + .map(|(i, c)| { + if i % 2 == 0 { + c.to_uppercase().next().unwrap() + } else { + c + } + .to_string() + }) + .collect::(); + assert!(address::validate_address(&mixed_case, &address::AddressFormat::Sui).is_err()); + + let invalid_length = format!("{}5f", addr); + assert!(address::validate_address(&invalid_length, &address::AddressFormat::Sui).is_err()); + } + #[test] fn validate_cosmwasm_address() { let api = MockApi::default(); diff --git a/packages/sui-gateway/Cargo.toml b/packages/sui-gateway/Cargo.toml index f2d152ab9..b7cb5c160 100644 --- a/packages/sui-gateway/Cargo.toml +++ b/packages/sui-gateway/Cargo.toml @@ -8,12 +8,13 @@ rust-version = { workspace = true } bcs = { workspace = true } cosmwasm-std = { workspace = true } error-stack = { workspace = true } -hex = "0.4.3" +hex = { workspace = true } multisig = { workspace = true, features = ["library"] } router-api = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } sha3 = { workspace = true } +sui-types = { workspace = true } thiserror = { workspace = true } [lints] diff --git a/packages/sui-gateway/src/error.rs b/packages/sui-gateway/src/error.rs index 7d85c08bd..4437a9540 100644 --- a/packages/sui-gateway/src/error.rs +++ b/packages/sui-gateway/src/error.rs @@ -2,10 +2,8 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum Error { - #[error("invalid address bytes: {:?}", .0)] - InvalidAddressBytes(Vec), - #[error("invalid address hex: {0}")] - InvalidAddressHex(String), + #[error("invalid address: {0}")] + InvalidAddress(String), #[error("unsupported type of public key")] UnsupportedPublicKey, #[error("unsupported type of signature")] diff --git a/packages/sui-gateway/src/gateway/events.rs b/packages/sui-gateway/src/events.rs similarity index 94% rename from packages/sui-gateway/src/gateway/events.rs rename to packages/sui-gateway/src/events.rs index 83b4008fa..2ef5d086a 100644 --- a/packages/sui-gateway/src/gateway/events.rs +++ b/packages/sui-gateway/src/events.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; +use sui_types::SuiAddress; -use crate::base_types::SuiAddress; -use crate::gateway::{Bytes32, WeightedSigners}; +use super::{Bytes32, WeightedSigners}; #[derive(Serialize, Deserialize, Debug)] pub struct SignersRotated { diff --git a/packages/sui-gateway/src/gateway/mod.rs b/packages/sui-gateway/src/gateway/mod.rs deleted file mode 100644 index f24212b15..000000000 --- a/packages/sui-gateway/src/gateway/mod.rs +++ /dev/null @@ -1,180 +0,0 @@ -use cosmwasm_std::Uint256; -use error_stack::{report, Report}; -use multisig::key::PublicKey; -use multisig::msg::SignerWithSig; -use multisig::verifier_set::VerifierSet; -use serde::{Deserialize, Serialize}; -use sha3::{Digest, Keccak256}; - -use crate::base_types::SuiAddress; -use crate::error::Error; - -pub mod events; - -#[repr(u8)] -pub enum CommandType { - ApproveMessages = 0, - RotateSigners = 1, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Bytes32 { - bytes: [u8; 32], -} - -impl AsRef<[u8]> for Bytes32 { - fn as_ref(&self) -> &[u8] { - &self.bytes - } -} - -impl From<[u8; 32]> for Bytes32 { - fn from(bytes: [u8; 32]) -> Self { - Self { bytes } - } -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct WeightedSigner { - pub pub_key: Vec, - pub weight: u128, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WeightedSigners { - pub signers: Vec, - pub threshold: u128, - pub nonce: Bytes32, -} - -impl TryFrom for WeightedSigners { - type Error = Report; - - fn try_from(verifier_set: VerifierSet) -> Result { - let mut signers = verifier_set - .signers - .values() - .map(|signer| match &signer.pub_key { - PublicKey::Ecdsa(key) => Ok(WeightedSigner { - pub_key: key.to_vec(), - weight: signer.weight.into(), - }), - PublicKey::Ed25519(_) => Err(Report::new(Error::UnsupportedPublicKey)), - }) - .collect::, _>>()?; - signers.sort_by(|signer1, signer2| signer1.pub_key.cmp(&signer2.pub_key)); - - let nonce = Uint256::from(verifier_set.created_at).to_be_bytes().into(); - - Ok(Self { - signers, - threshold: verifier_set.threshold.into(), - nonce, - }) - } -} - -impl WeightedSigners { - pub fn hash(&self) -> [u8; 32] { - let hash = - Keccak256::digest(bcs::to_bytes(&self).expect("failed to serialize WeightedSigners")); - - hash.into() - } -} - -#[derive(Serialize)] -pub struct MessageToSign { - pub domain_separator: Bytes32, - pub signers_hash: Bytes32, - pub data_hash: Bytes32, -} - -impl MessageToSign { - pub fn hash(&self) -> [u8; 32] { - let hash = - Keccak256::digest(bcs::to_bytes(&self).expect("failed to serialize MessageToSign")); - - hash.into() - } -} - -#[derive(Serialize)] -pub struct Message { - source_chain: String, - message_id: String, - source_address: String, - destination_id: SuiAddress, - payload_hash: Bytes32, -} - -impl TryFrom<&router_api::Message> for Message { - type Error = Report; - - fn try_from(value: &router_api::Message) -> Result { - Ok(Self { - source_chain: value.cc_id.source_chain.to_string(), - message_id: value.cc_id.message_id.to_string(), - source_address: value.source_address.to_string(), - destination_id: value.destination_address.parse()?, - payload_hash: value.payload_hash.into(), - }) - } -} - -#[derive(Serialize)] -pub struct Signature { - bytes: Vec, -} - -impl TryFrom for Signature { - type Error = Report; - - fn try_from(signature: multisig::key::Signature) -> Result { - match signature { - // The move contracts require recoverable signatures. This should - // only be called after the proper conversion during encoding. - multisig::key::Signature::EcdsaRecoverable(signature) => Ok(Self { - bytes: signature.as_ref().to_vec(), - }), - _ => Err(report!(Error::UnsupportedSignature)), - } - } -} - -#[derive(Serialize)] -pub struct Proof { - signers: WeightedSigners, - signatures: Vec, -} - -impl TryFrom<(VerifierSet, Vec)> for Proof { - type Error = Report; - - fn try_from( - (verifier_set, mut signatures): (VerifierSet, Vec), - ) -> Result { - signatures.sort_by(|signer1, signer2| signer1.signer.pub_key.cmp(&signer2.signer.pub_key)); - - Ok(Self { - signers: verifier_set.try_into()?, - signatures: signatures - .into_iter() - .map(|signer| signer.signature) - .map(TryInto::try_into) - .collect::, _>>()?, - }) - } -} - -#[derive(Serialize, Deserialize)] -pub struct ExecuteData { - pub payload: Vec, - pub proof: Vec, -} - -impl ExecuteData { - pub fn new(payload: Vec, proof: Vec) -> Self { - Self { payload, proof } - } -} diff --git a/packages/sui-gateway/src/lib.rs b/packages/sui-gateway/src/lib.rs index 2f5f7b253..a0b2b7ff8 100644 --- a/packages/sui-gateway/src/lib.rs +++ b/packages/sui-gateway/src/lib.rs @@ -1,3 +1,184 @@ -pub mod base_types; +use std::str::FromStr; + +use cosmwasm_std::Uint256; +use error_stack::{report, Report, ResultExt}; +use multisig::key::PublicKey; +use multisig::msg::SignerWithSig; +use multisig::verifier_set::VerifierSet; +use serde::{Deserialize, Serialize}; +use sha3::{Digest, Keccak256}; +use sui_types::SuiAddress; + pub mod error; -pub mod gateway; +pub mod events; + +use error::Error; + +#[repr(u8)] +pub enum CommandType { + ApproveMessages = 0, + RotateSigners = 1, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Bytes32 { + bytes: [u8; 32], +} + +impl AsRef<[u8]> for Bytes32 { + fn as_ref(&self) -> &[u8] { + &self.bytes + } +} + +impl From<[u8; 32]> for Bytes32 { + fn from(bytes: [u8; 32]) -> Self { + Self { bytes } + } +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct WeightedSigner { + pub pub_key: Vec, + pub weight: u128, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WeightedSigners { + pub signers: Vec, + pub threshold: u128, + pub nonce: Bytes32, +} + +impl TryFrom for WeightedSigners { + type Error = Report; + + fn try_from(verifier_set: VerifierSet) -> Result { + let mut signers = verifier_set + .signers + .values() + .map(|signer| match &signer.pub_key { + PublicKey::Ecdsa(key) => Ok(WeightedSigner { + pub_key: key.to_vec(), + weight: signer.weight.into(), + }), + PublicKey::Ed25519(_) => Err(Report::new(Error::UnsupportedPublicKey)), + }) + .collect::, _>>()?; + signers.sort_by(|signer1, signer2| signer1.pub_key.cmp(&signer2.pub_key)); + + let nonce = Uint256::from(verifier_set.created_at).to_be_bytes().into(); + + Ok(Self { + signers, + threshold: verifier_set.threshold.into(), + nonce, + }) + } +} + +impl WeightedSigners { + pub fn hash(&self) -> [u8; 32] { + let hash = + Keccak256::digest(bcs::to_bytes(&self).expect("failed to serialize WeightedSigners")); + + hash.into() + } +} + +#[derive(Serialize)] +pub struct MessageToSign { + pub domain_separator: Bytes32, + pub signers_hash: Bytes32, + pub data_hash: Bytes32, +} + +impl MessageToSign { + pub fn hash(&self) -> [u8; 32] { + let hash = + Keccak256::digest(bcs::to_bytes(&self).expect("failed to serialize MessageToSign")); + + hash.into() + } +} + +#[derive(Serialize)] +pub struct Message { + source_chain: String, + message_id: String, + source_address: String, + destination_id: SuiAddress, + payload_hash: Bytes32, +} + +impl TryFrom<&router_api::Message> for Message { + type Error = Report; + + fn try_from(value: &router_api::Message) -> Result { + Ok(Self { + source_chain: value.cc_id.source_chain.to_string(), + message_id: value.cc_id.message_id.to_string(), + source_address: value.source_address.to_string(), + destination_id: SuiAddress::from_str(&value.destination_address) + .change_context(Error::InvalidAddress(value.destination_address.to_string()))?, + payload_hash: value.payload_hash.into(), + }) + } +} + +#[derive(Serialize)] +pub struct Signature { + bytes: Vec, +} + +impl TryFrom for Signature { + type Error = Report; + + fn try_from(signature: multisig::key::Signature) -> Result { + match signature { + // The move contracts require recoverable signatures. This should + // only be called after the proper conversion during encoding. + multisig::key::Signature::EcdsaRecoverable(signature) => Ok(Self { + bytes: signature.as_ref().to_vec(), + }), + _ => Err(report!(Error::UnsupportedSignature)), + } + } +} + +#[derive(Serialize)] +pub struct Proof { + signers: WeightedSigners, + signatures: Vec, +} + +impl TryFrom<(VerifierSet, Vec)> for Proof { + type Error = Report; + + fn try_from( + (verifier_set, mut signatures): (VerifierSet, Vec), + ) -> Result { + signatures.sort_by(|signer1, signer2| signer1.signer.pub_key.cmp(&signer2.signer.pub_key)); + + Ok(Self { + signers: verifier_set.try_into()?, + signatures: signatures + .into_iter() + .map(|signer| signer.signature) + .map(TryInto::try_into) + .collect::, _>>()?, + }) + } +} + +#[derive(Serialize, Deserialize)] +pub struct ExecuteData { + pub payload: Vec, + pub proof: Vec, +} + +impl ExecuteData { + pub fn new(payload: Vec, proof: Vec) -> Self { + Self { payload, proof } + } +} diff --git a/packages/sui-types/Cargo.toml b/packages/sui-types/Cargo.toml new file mode 100644 index 000000000..f5744a8f4 --- /dev/null +++ b/packages/sui-types/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "sui-types" +version = "1.0.0" +edition = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +error-stack = { workspace = true } +hex = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } + +[dev-dependencies] +rand = "0.8.5" + +[lints] +workspace = true diff --git a/packages/sui-gateway/src/base_types.rs b/packages/sui-types/src/lib.rs similarity index 76% rename from packages/sui-gateway/src/base_types.rs rename to packages/sui-types/src/lib.rs index fc7e0e5db..baa6b7aa1 100644 --- a/packages/sui-gateway/src/base_types.rs +++ b/packages/sui-types/src/lib.rs @@ -1,13 +1,20 @@ use std::str::FromStr; -use error_stack::{report, Report, Result, ResultExt}; +use error_stack::{ensure, report, Report, Result, ResultExt}; use serde::{Deserialize, Serialize}; - -use crate::error::Error; +use thiserror::Error; const ADDRESS_PREFIX: &str = "0x"; const SUI_ADDRESS_LENGTH: usize = 32; +#[derive(Error, Debug)] +pub enum Error { + #[error("invalid address length: {:?}", .0)] + InvalidAddressLength(Vec), + #[error("invalid address: {0}")] + InvalidAddress(String), +} + #[derive(Serialize, Deserialize, Debug)] pub struct SuiAddress([u8; SUI_ADDRESS_LENGTH]); @@ -24,7 +31,7 @@ impl TryFrom<&[u8]> for SuiAddress { bytes .try_into() .map(Self) - .change_context(Error::InvalidAddressBytes(bytes.to_vec())) + .change_context(Error::InvalidAddressLength(bytes.to_vec())) } } @@ -32,13 +39,19 @@ impl FromStr for SuiAddress { type Err = Report; fn from_str(s: &str) -> Result { - hex::decode( - s.strip_prefix(ADDRESS_PREFIX) - .ok_or(report!(Error::InvalidAddressHex(s.to_string())))?, - ) - .change_context(Error::InvalidAddressHex(s.to_string()))? - .as_slice() - .try_into() + let hex = s + .strip_prefix(ADDRESS_PREFIX) + .ok_or(report!(Error::InvalidAddress(s.to_string())))?; + // disallow uppercase characters for the sui addresses + ensure!( + hex.to_lowercase() == hex, + Error::InvalidAddress(s.to_string()) + ); + + hex::decode(hex) + .change_context(Error::InvalidAddress(s.to_string()))? + .as_slice() + .try_into() } } From 45df3dfc1247be1cb5afcdb1de16d1dc808abdfa Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:40:14 -0600 Subject: [PATCH 157/168] feat(minor-rewards)!: set params per pool (#576) --- contracts/rewards/src/contract.rs | 42 +- contracts/rewards/src/contract/execute.rs | 725 ++++++++++++++++-- .../rewards/src/contract/migrations/mod.rs | 2 +- .../rewards/src/contract/migrations/v0_4_0.rs | 153 ---- .../rewards/src/contract/migrations/v1_0_0.rs | 175 +++++ contracts/rewards/src/contract/query.rs | 6 +- contracts/rewards/src/error.rs | 11 +- contracts/rewards/src/msg.rs | 15 +- contracts/rewards/src/state.rs | 180 +++-- integration-tests/src/rewards_contract.rs | 8 +- integration-tests/tests/test_utils/mod.rs | 33 +- 11 files changed, 993 insertions(+), 357 deletions(-) delete mode 100644 contracts/rewards/src/contract/migrations/v0_4_0.rs create mode 100644 contracts/rewards/src/contract/migrations/v1_0_0.rs diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index 8eaca607d..b97df9dc2 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -9,7 +9,7 @@ use itertools::Itertools; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG, PARAMS}; +use crate::state::{self, Config, PoolId, CONFIG}; mod execute; mod migrations; @@ -24,7 +24,7 @@ pub fn migrate( _env: Env, _msg: Empty, ) -> Result { - migrations::v0_4_0::migrate(deps.storage)?; + migrations::v1_0_0::migrate(deps.storage)?; // any version checks should be done before here @@ -36,7 +36,7 @@ pub fn migrate( #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, - env: Env, + _env: Env, _info: MessageInfo, msg: InstantiateMsg, ) -> Result { @@ -52,17 +52,6 @@ pub fn instantiate( }, )?; - PARAMS.save( - deps.storage, - &ParamsSnapshot { - params: msg.params, - created_at: Epoch { - epoch_num: 0, - block_height_started: env.block.height, - }, - }, - )?; - Ok(Response::new()) } @@ -135,11 +124,15 @@ pub fn execute( Ok(Response::new().add_messages(msgs)) } - ExecuteMsg::UpdateParams { params } => { - execute::update_params(deps.storage, params, env.block.height)?; + ExecuteMsg::UpdatePoolParams { params, pool_id } => { + execute::update_pool_params(deps.storage, &pool_id, params, env.block.height)?; Ok(Response::new()) } + ExecuteMsg::CreatePool { params, pool_id } => { + execute::create_pool(deps.storage, params, env.block.height, &pool_id)?; + Ok(Response::new()) + } } } @@ -181,7 +174,7 @@ mod tests { let mut deps = mock_dependencies(); #[allow(deprecated)] - migrations::v0_4_0::tests::instantiate_contract(deps.as_mut(), "denom"); + migrations::v1_0_0::tests::instantiate_contract(deps.as_mut(), "denom"); migrate(deps.as_mut(), mock_env(), Empty {}).unwrap(); @@ -224,7 +217,6 @@ mod tests { &InstantiateMsg { governance_address: governance_address.to_string(), rewards_denom: AXL_DENOMINATION.to_string(), - params: initial_params.clone(), }, &[], "Contract", @@ -237,6 +229,17 @@ mod tests { contract: pool_contract.clone(), }; + let res = app.execute_contract( + governance_address.clone(), + contract_address.clone(), + &ExecuteMsg::CreatePool { + params: initial_params.clone(), + pool_id: pool_id.clone(), + }, + &[], + ); + assert!(res.is_ok()); + let rewards = 200; let res = app.execute_contract( user.clone(), @@ -255,8 +258,9 @@ mod tests { let res = app.execute_contract( governance_address, contract_address.clone(), - &ExecuteMsg::UpdateParams { + &ExecuteMsg::UpdatePoolParams { params: updated_params.clone(), + pool_id: pool_id.clone(), }, &[], ); diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index 4fc8994ea..ead843cae 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -2,11 +2,13 @@ use std::collections::HashMap; use axelar_wasm_std::{nonempty, FnExt}; use cosmwasm_std::{Addr, OverflowError, OverflowOperation, Storage, Uint128}; -use error_stack::{Report, Result}; +use error_stack::{ensure, Report, Result}; use crate::error::ContractError; use crate::msg::Params; -use crate::state::{self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, StorageState}; +use crate::state::{ + self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, RewardsPool, StorageState, +}; const DEFAULT_EPOCHS_TO_PROCESS: u64 = 10; const EPOCH_PAYOUT_DELAY: u64 = 2; @@ -18,7 +20,7 @@ pub fn record_participation( pool_id: PoolId, block_height: u64, ) -> Result<(), ContractError> { - let current_params = state::load_params(storage); + let current_params = state::load_rewards_pool_params(storage, pool_id.clone())?; let cur_epoch = Epoch::current(¤t_params, block_height)?; let event = load_or_store_event(storage, event_id, pool_id.clone(), cur_epoch.epoch_num)?; @@ -59,7 +61,7 @@ pub fn distribute_rewards( epoch_process_limit: Option, ) -> Result, ContractError> { let epoch_process_limit = epoch_process_limit.unwrap_or(DEFAULT_EPOCHS_TO_PROCESS); - let cur_epoch = Epoch::current(&state::load_params(storage), cur_block_height)?; + let cur_epoch = state::current_epoch(storage, &pool_id, cur_block_height)?; let from = state::load_rewards_watermark(storage, pool_id.clone())? .map_or(0, |last_processed| last_processed.saturating_add(1)); @@ -85,7 +87,7 @@ fn process_rewards_for_epochs( to: u64, ) -> Result, ContractError> { let rewards = cumulate_rewards(storage, &pool_id, from, to)?; - state::load_rewards_pool_or_new(storage, pool_id.clone())? + state::load_rewards_pool(storage, pool_id.clone())? .sub_reward(rewards.values().sum())? .then(|pool| state::save_rewards_pool(storage, &pool))?; @@ -114,12 +116,43 @@ fn iterate_epoch_tallies<'a>( }) } -pub fn update_params( +pub fn create_pool( storage: &mut dyn Storage, + params: Params, + block_height: u64, + pool_id: &PoolId, +) -> Result<(), ContractError> { + ensure!( + !state::pool_exists(storage, pool_id)?, + ContractError::RewardsPoolAlreadyExists + ); + + let cur_epoch = Epoch { + epoch_num: 0, + block_height_started: block_height, + }; + + let params_snapshot = ParamsSnapshot { + params, + created_at: cur_epoch, + }; + + let pool = RewardsPool { + id: pool_id.clone(), + balance: Uint128::zero(), + params: params_snapshot, + }; + + state::save_rewards_pool(storage, &pool) +} + +pub fn update_pool_params( + storage: &mut dyn Storage, + pool_id: &PoolId, new_params: Params, block_height: u64, ) -> Result<(), ContractError> { - let cur_epoch = Epoch::current(&state::load_params(storage), block_height)?; + let cur_epoch = state::current_epoch(storage, pool_id, block_height)?; // If the param update reduces the epoch duration such that the current epoch immediately ends, // start a new epoch at this block, incrementing the current epoch number by 1. // This prevents us from jumping forward an arbitrary number of epochs, and maintains consistency for past events. @@ -149,13 +182,13 @@ pub fn update_params( } else { cur_epoch }; - state::save_params( - storage, - &ParamsSnapshot { - params: new_params, - created_at: cur_epoch, - }, - )?; + let new_params_snapshot = ParamsSnapshot { + params: new_params, + created_at: cur_epoch, + }; + + state::update_pool_params(storage, pool_id, &new_params_snapshot)?; + Ok(()) } @@ -164,7 +197,7 @@ pub fn add_rewards( pool_id: PoolId, amount: nonempty::Uint128, ) -> Result<(), ContractError> { - let mut pool = state::load_rewards_pool_or_new(storage, pool_id)?; + let mut pool = state::load_rewards_pool(storage, pool_id)?; pool.balance = pool .balance .checked_add(Uint128::from(amount)) @@ -221,8 +254,19 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - let mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); - let current_params = state::load_params(mock_deps.as_ref().storage); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; + let mock_deps = setup( + cur_epoch_num, + block_height_started, + epoch_duration, + pool_id.clone(), + ); + let current_params = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id) + .unwrap() + .params; let new_epoch = Epoch::current(¤t_params, block_height_started).unwrap(); assert_eq!(new_epoch.epoch_num, cur_epoch_num); @@ -245,8 +289,19 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - let mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); - let current_params = state::load_params(mock_deps.as_ref().storage); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; + let mock_deps = setup( + cur_epoch_num, + block_height_started, + epoch_duration, + pool_id.clone(), + ); + let current_params = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; assert!(Epoch::current(¤t_params, block_height_started - 1).is_err()); assert!(Epoch::current(¤t_params, block_height_started - epoch_duration).is_err()); @@ -258,7 +313,16 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - let mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; + let mock_deps = setup( + cur_epoch_num, + block_height_started, + epoch_duration, + pool_id.clone(), + ); // elements are (height, expected epoch number, expected epoch start) let test_cases = vec![ @@ -285,8 +349,13 @@ mod test { ]; for (height, expected_epoch_num, expected_block_start) in test_cases { - let new_epoch = - Epoch::current(&state::load_params(mock_deps.as_ref().storage), height).unwrap(); + let new_epoch = Epoch::current( + &state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params, + height, + ) + .unwrap(); assert_eq!(new_epoch.epoch_num, expected_epoch_num); assert_eq!(new_epoch.block_height_started, expected_block_start); @@ -300,12 +369,16 @@ mod test { let epoch_block_start = 250u64; let epoch_duration = 100u64; - let mut mock_deps = setup(cur_epoch_num, epoch_block_start, epoch_duration); - let pool_id = PoolId { chain_name: "mock-chain".parse().unwrap(), contract: Addr::unchecked("some contract"), }; + let mut mock_deps = setup( + cur_epoch_num, + epoch_block_start, + epoch_duration, + pool_id.clone(), + ); let mut simulated_participation = HashMap::new(); simulated_participation.insert(Addr::unchecked("verifier_1"), 10); @@ -354,12 +427,16 @@ mod test { let block_height_started = 250u64; let epoch_duration = 100u64; - let mut mock_deps = setup(starting_epoch_num, block_height_started, epoch_duration); - let pool_id = PoolId { chain_name: "mock-chain".parse().unwrap(), contract: Addr::unchecked("some contract"), }; + let mut mock_deps = setup( + starting_epoch_num, + block_height_started, + epoch_duration, + pool_id.clone(), + ); let verifiers = vec![ Addr::unchecked("verifier_1"), @@ -381,7 +458,9 @@ mod test { } let cur_epoch = Epoch::current( - &state::load_params(mock_deps.as_ref().storage), + &state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params, height_at_epoch_end, ) .unwrap(); @@ -414,9 +493,6 @@ mod test { fn record_participation_multiple_contracts() { let cur_epoch_num = 1u64; let block_height_started = 250u64; - let epoch_duration = 100u64; - - let mut mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); let mut simulated_participation = HashMap::new(); simulated_participation.insert( @@ -450,6 +526,20 @@ mod test { ), ); + let params = Params { + participation_threshold: (1, 2).try_into().unwrap(), + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: 100u128.try_into().unwrap(), + }; + let mut mock_deps = setup_multiple_pools_with_params( + cur_epoch_num, + block_height_started, + simulated_participation + .iter() + .map(|(_, (pool_id, _))| (pool_id.clone(), params.clone())) + .collect(), + ); + for (verifier, (pool_contract, events_participated)) in &simulated_participation { for i in 0..*events_participated { let event_id = i.to_string().try_into().unwrap(); @@ -482,6 +572,7 @@ mod test { ); } } + /// Test that rewards parameters are updated correctly. In this test we don't change the epoch duration, so /// that computation of the current epoch is unaffected. #[test] @@ -491,12 +582,17 @@ mod test { let initial_rewards_per_epoch = 100u128; let initial_participation_threshold = (1, 2); let epoch_duration = 100u64; + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; let mut mock_deps = setup_with_params( initial_epoch_num, initial_epoch_start, epoch_duration, initial_rewards_per_epoch, initial_participation_threshold, + pool_id.clone(), ); // simulate the below tests running at this block height @@ -511,16 +607,34 @@ mod test { }; // the epoch shouldn't change when the params are updated, since we are not changing the epoch duration - let expected_epoch = - Epoch::current(&state::load_params(mock_deps.as_ref().storage), cur_height).unwrap(); + let expected_epoch = Epoch::current( + &state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params, + cur_height, + ) + .unwrap(); - update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); - let stored = state::load_params(mock_deps.as_ref().storage); + update_pool_params( + mock_deps.as_mut().storage, + &pool_id, + new_params.clone(), + cur_height, + ) + .unwrap(); + let stored = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; assert_eq!(stored.params, new_params); // current epoch shouldn't have changed - let cur_epoch = - Epoch::current(&state::load_params(mock_deps.as_ref().storage), cur_height).unwrap(); + let cur_epoch = Epoch::current( + &state::load_rewards_pool(mock_deps.as_ref().storage, pool_id) + .unwrap() + .params, + cur_height, + ) + .unwrap(); assert_eq!(expected_epoch.epoch_num, cur_epoch.epoch_num); assert_eq!( expected_epoch.block_height_started, @@ -537,10 +651,15 @@ mod test { let initial_epoch_num = 1u64; let initial_epoch_start = 250u64; let initial_epoch_duration = 100u64; + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; let mut mock_deps = setup( initial_epoch_num, initial_epoch_start, initial_epoch_duration, + pool_id.clone(), ); // simulate the tests running after 5 epochs have passed @@ -548,7 +667,10 @@ mod test { let cur_height = initial_epoch_start + initial_epoch_duration * epochs_elapsed + 10; // add 10 here just to be a little past the epoch boundary // epoch shouldn't change if we are extending the duration - let initial_params_snapshot = state::load_params(mock_deps.as_ref().storage); + let initial_params_snapshot = + state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; let epoch_prior_to_update = Epoch::current(&initial_params_snapshot, cur_height).unwrap(); let new_epoch_duration = initial_epoch_duration * 2; @@ -557,9 +679,17 @@ mod test { ..initial_params_snapshot.params // keep everything besides epoch duration the same }; - update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); + update_pool_params( + mock_deps.as_mut().storage, + &pool_id.clone(), + new_params.clone(), + cur_height, + ) + .unwrap(); - let updated_params_snapshot = state::load_params(mock_deps.as_ref().storage); + let updated_params_snapshot = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id) + .unwrap() + .params; // current epoch shouldn't change let epoch = Epoch::current(&updated_params_snapshot, cur_height).unwrap(); @@ -590,10 +720,15 @@ mod test { let initial_epoch_num = 1u64; let initial_epoch_start = 256u64; let initial_epoch_duration = 100u64; + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; let mut mock_deps = setup( initial_epoch_num, initial_epoch_start, initial_epoch_duration, + pool_id.clone(), ); // simulate the tests running after 10 epochs have passed @@ -602,7 +737,10 @@ mod test { let new_epoch_duration = initial_epoch_duration / 2; - let initial_params_snapshot = state::load_params(mock_deps.as_ref().storage); + let initial_params_snapshot = + state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; let epoch_prior_to_update = Epoch::current(&initial_params_snapshot, cur_height).unwrap(); // we are shortening the epoch, but not so much it causes the epoch number to change. We want to remain in the same epoch assert!(cur_height - epoch_prior_to_update.block_height_started < new_epoch_duration); @@ -611,9 +749,18 @@ mod test { epoch_duration: new_epoch_duration.try_into().unwrap(), ..initial_params_snapshot.params }; - update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); + update_pool_params( + mock_deps.as_mut().storage, + &pool_id, + new_params.clone(), + cur_height, + ) + .unwrap(); - let updated_params_snapshot = state::load_params(mock_deps.as_ref().storage); + let updated_params_snapshot = + state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; // current epoch shouldn't have changed let epoch = Epoch::current(&updated_params_snapshot, cur_height).unwrap(); @@ -636,10 +783,15 @@ mod test { let initial_epoch_num = 1u64; let initial_epoch_start = 250u64; let initial_epoch_duration = 100u64; + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; let mut mock_deps = setup( initial_epoch_num, initial_epoch_start, initial_epoch_duration, + pool_id.clone(), ); // simulate running the test after 100 epochs have elapsed @@ -650,16 +802,28 @@ mod test { let cur_height = initial_epoch_start + initial_epoch_duration * epochs_elapsed + new_epoch_duration * 2; - let initial_params_snapshot = state::load_params(mock_deps.as_ref().storage); + let initial_params_snapshot = + state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; let epoch_prior_to_update = Epoch::current(&initial_params_snapshot, cur_height).unwrap(); let new_params = Params { epoch_duration: 10.try_into().unwrap(), ..initial_params_snapshot.params }; - update_params(mock_deps.as_mut().storage, new_params.clone(), cur_height).unwrap(); + update_pool_params( + mock_deps.as_mut().storage, + &pool_id.clone(), + new_params.clone(), + cur_height, + ) + .unwrap(); - let updated_params_snapshot = state::load_params(mock_deps.as_ref().storage); + let updated_params_snapshot = + state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()) + .unwrap() + .params; // should be in new epoch now let epoch = Epoch::current(&updated_params_snapshot, cur_height).unwrap(); @@ -679,15 +843,19 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; - - let mut mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); - let pool_id = PoolId { chain_name: "mock-chain".parse().unwrap(), contract: Addr::unchecked("some contract"), }; - let pool = - state::load_rewards_pool_or_new(mock_deps.as_ref().storage, pool_id.clone()).unwrap(); + + let mut mock_deps = setup( + cur_epoch_num, + block_height_started, + epoch_duration, + pool_id.clone(), + ); + + let pool = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()).unwrap(); assert!(pool.balance.is_zero()); let initial_amount = Uint128::from(100u128); @@ -698,8 +866,7 @@ mod test { ) .unwrap(); - let pool = - state::load_rewards_pool_or_new(mock_deps.as_ref().storage, pool_id.clone()).unwrap(); + let pool = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id.clone()).unwrap(); assert_eq!(pool.balance, initial_amount); let added_amount = Uint128::from(500u128); @@ -710,7 +877,7 @@ mod test { ) .unwrap(); - let pool = state::load_rewards_pool_or_new(mock_deps.as_ref().storage, pool_id).unwrap(); + let pool = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id).unwrap(); assert_eq!(pool.balance, initial_amount + added_amount); } @@ -720,8 +887,17 @@ mod test { let cur_epoch_num = 1u64; let block_height_started = 250u64; let epoch_duration = 100u64; + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("some contract"), + }; - let mut mock_deps = setup(cur_epoch_num, block_height_started, epoch_duration); + let mut mock_deps = setup( + cur_epoch_num, + block_height_started, + epoch_duration, + pool_id.clone(), + ); // a vector of (contract, rewards amounts) pairs let test_data = vec![ (Addr::unchecked("contract_1"), vec![100, 200, 50]), @@ -736,6 +912,19 @@ mod test { chain_name: chain_name.clone(), contract: pool_contract.clone(), }; + let participation_threshold = (1, 2); + let rewards_per_epoch = 100u128; + create_pool( + mock_deps.as_mut().storage, + Params { + epoch_duration: epoch_duration.try_into().unwrap(), + rewards_per_epoch: rewards_per_epoch.try_into().unwrap(), + participation_threshold: participation_threshold.try_into().unwrap(), + }, + block_height_started, + &pool_id, + ) + .unwrap(); for amount in rewards { add_rewards( @@ -753,8 +942,7 @@ mod test { contract: pool_contract.clone(), }; - let pool = - state::load_rewards_pool_or_new(mock_deps.as_ref().storage, pool_id).unwrap(); + let pool = state::load_rewards_pool(mock_deps.as_ref().storage, pool_id).unwrap(); assert_eq!( pool.balance, cosmwasm_std::Uint128::from(rewards.iter().sum::()) @@ -762,6 +950,276 @@ mod test { } } + /// Tests that pools can have different reward amounts + #[test] + fn multiple_pools_different_rewards_amount() { + let cur_epoch_num = 1u64; + let block_height_started = 250u64; + let epoch_duration = 100u64; + + let mut simulated_participation = HashMap::new(); + simulated_participation.insert( + Addr::unchecked("verifier-1"), + ( + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + 3, + ), + ); + simulated_participation.insert( + Addr::unchecked("verifier-2"), + ( + PoolId { + chain_name: "mock-chain-2".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + 4, + ), + ); + simulated_participation.insert( + Addr::unchecked("verifier-3"), + ( + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract-3"), + }, + 2, + ), + ); + let base_params = Params { + participation_threshold: (1, 2).try_into().unwrap(), + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: 100u128.try_into().unwrap(), // this is overwritten below + }; + let rewards_per_epoch = vec![50u128, 100u128, 200u128]; + let pool_params: Vec<(PoolId, Params)> = simulated_participation + .values() + .map(|(pool_id, _)| pool_id.clone()) + .zip(rewards_per_epoch.into_iter().map(|r| Params { + rewards_per_epoch: r.try_into().unwrap(), + ..base_params.clone() + })) + .collect(); + + let mut mock_deps = setup_multiple_pools_with_params( + cur_epoch_num, + block_height_started, + pool_params.clone(), + ); + + for (verifier, (pool_contract, events_participated)) in &simulated_participation { + for i in 0..*events_participated { + let event_id = i.to_string().try_into().unwrap(); + record_participation( + mock_deps.as_mut().storage, + event_id, + verifier.clone(), + pool_contract.clone(), + block_height_started, + ) + .unwrap(); + } + } + + for (pool_id, params) in pool_params { + let rewards_to_add = params.rewards_per_epoch; + let _ = add_rewards( + mock_deps.as_mut().storage, + pool_id.clone(), + Uint128::from(rewards_to_add).try_into().unwrap(), + ); + + let rewards_claimed = distribute_rewards( + mock_deps.as_mut().storage, + pool_id, + block_height_started + epoch_duration * 2, + None, + ) + .unwrap(); + assert_eq!( + rewards_claimed.values().sum::(), + Uint128::from(params.rewards_per_epoch) + ); + } + } + + /// Tests that pools can have different participation thresholds + #[test] + fn multiple_pools_different_threshold() { + let cur_epoch_num = 1u64; + let block_height_started = 250u64; + let epoch_duration = 100u64; + let pools = vec![ + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + PoolId { + chain_name: "mock-chain-2".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + ]; + + let verifiers = [Addr::unchecked("verifier-1"), Addr::unchecked("verifier-2")]; + + // simulate two verifiers each participating in two pools + // the first verifier participates in 2 events, and the second in 3 events (out of a total of 3 events) + let simulated_participation = vec![ + (verifiers[0].clone(), (pools[0].clone(), 2)), + (verifiers[0].clone(), (pools[1].clone(), 2)), + (verifiers[1].clone(), (pools[0].clone(), 3)), + (verifiers[1].clone(), (pools[1].clone(), 3)), + ]; + let base_params = Params { + participation_threshold: (1, 2).try_into().unwrap(), // this is overwritten below + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: 100u128.try_into().unwrap(), + }; + // the first pool has a 2/3 threshold, the second 3/4 threshold + let participation_thresholds = vec![(2, 3), (3, 4)]; + let pool_params: Vec<(PoolId, Params)> = pools + .clone() + .into_iter() + .zip(participation_thresholds.into_iter().map(|p| Params { + participation_threshold: p.try_into().unwrap(), + ..base_params.clone() + })) + .collect(); + + let mut mock_deps = setup_multiple_pools_with_params( + cur_epoch_num, + block_height_started, + pool_params.clone(), + ); + + for (verifier, (pool_contract, events_participated)) in &simulated_participation { + for i in 0..*events_participated { + let event_id = i.to_string().try_into().unwrap(); + record_participation( + mock_deps.as_mut().storage, + event_id, + verifier.clone(), + pool_contract.clone(), + block_height_started, + ) + .unwrap(); + } + } + + for (pool_id, params) in pool_params { + let rewards_to_add = params.rewards_per_epoch; + let _ = add_rewards(mock_deps.as_mut().storage, pool_id.clone(), rewards_to_add); + + let rewards_claimed = distribute_rewards( + mock_deps.as_mut().storage, + pool_id.clone(), + block_height_started + epoch_duration * 2, + None, + ) + .unwrap(); + + if pool_id == pools[0] { + // the first pool has a 2/3 threshold, which both verifiers meet + assert_eq!( + rewards_claimed, + HashMap::from_iter(verifiers.iter().map(|v| ( + v.clone(), + Uint128::from(Uint128::from(rewards_to_add).u128() / 2) + ))) + ); + } else { + // the second pool has 3/4 threshold, which only the second verifier meets + assert_eq!( + rewards_claimed, + HashMap::from([(verifiers[1].clone(), Uint128::from(rewards_to_add))]) + ); + } + } + } + + /// Tests that pools can have different epoch lengths + #[test] + fn multiple_pools_different_epoch_length() { + let cur_epoch_num = 1u64; + let block_height_started = 250u64; + let base_epoch_duration = 100u64; + let pools = vec![ + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + PoolId { + chain_name: "mock-chain-2".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + ]; + + let verifier = Addr::unchecked("verifier-1"); + + // simulate one verifier participating in two events in each pool + let simulated_participation = vec![ + (verifier.clone(), (pools[0].clone(), 2)), + (verifier.clone(), (pools[1].clone(), 2)), + ]; + + let base_params = Params { + participation_threshold: (1, 2).try_into().unwrap(), + epoch_duration: 100u64.try_into().unwrap(), // this is overwritten below + rewards_per_epoch: 100u128.try_into().unwrap(), + }; + // one pool has twice the epoch duration as the other + let epoch_durations = vec![base_epoch_duration, base_epoch_duration * 2]; + let pool_params: Vec<(PoolId, Params)> = pools + .clone() + .into_iter() + .zip(epoch_durations.into_iter().map(|e| Params { + epoch_duration: e.try_into().unwrap(), + ..base_params.clone() + })) + .collect(); + + let mut mock_deps = setup_multiple_pools_with_params( + cur_epoch_num, + block_height_started, + pool_params.clone(), + ); + + for (verifier, (pool_contract, events_participated)) in &simulated_participation { + for i in 0..*events_participated { + let event_id = i.to_string().try_into().unwrap(); + record_participation( + mock_deps.as_mut().storage, + event_id, + verifier.clone(), + pool_contract.clone(), + block_height_started, + ) + .unwrap(); + } + } + + for (pool_id, params) in pool_params { + let rewards_to_add = params.rewards_per_epoch; + add_rewards(mock_deps.as_mut().storage, pool_id.clone(), rewards_to_add).unwrap(); + + let rewards = distribute_rewards( + mock_deps.as_mut().storage, + pool_id.clone(), + block_height_started + base_epoch_duration * EPOCH_PAYOUT_DELAY, // this is long enough for the first pool to pay out, but not the second + None, + ) + .unwrap(); + + if pool_id == pools[0] { + assert_eq!(rewards.len(), 1); + } else { + assert_eq!(rewards.len(), 0); + } + } + } + /// Tests that rewards are distributed correctly based on participation #[test] fn successfully_distribute_rewards() { @@ -770,6 +1228,10 @@ mod test { let epoch_duration = 1000u64; let rewards_per_epoch = 100u128; let participation_threshold = (2, 3); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("pool_contract"), + }; let mut mock_deps = setup_with_params( cur_epoch_num, @@ -777,6 +1239,7 @@ mod test { epoch_duration, rewards_per_epoch, participation_threshold, + pool_id.clone(), ); let verifier1 = Addr::unchecked("verifier1"); let verifier2 = Addr::unchecked("verifier2"); @@ -812,11 +1275,6 @@ mod test { (verifier4.clone(), rewards_per_epoch / 4), ]); - let pool_id = PoolId { - chain_name: "mock-chain".parse().unwrap(), - contract: Addr::unchecked("pool_contract"), - }; - for (verifier, events_participated) in verifier_participation_per_epoch.clone() { for (epoch, events) in events_participated.iter().enumerate().take(epoch_count) { for event in events { @@ -832,8 +1290,8 @@ mod test { } } - // we add 2 epochs worth of rewards. There were 2 epochs of participation, but only 2 epochs where rewards should be given out - // These tests we are accounting correctly, and only removing from the pool when we actually give out rewards + // we add 2 epochs worth of rewards. There were 4 epochs of participation, but only 2 epochs where rewards should be given out + // This tests we are accounting correctly, and only removing from the pool when we actually give out rewards let rewards_added = 2 * rewards_per_epoch; let _ = add_rewards( mock_deps.as_mut().storage, @@ -870,6 +1328,10 @@ mod test { let epoch_duration = 1000u64; let rewards_per_epoch = 100u128; let participation_threshold = (1, 2); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("pool_contract"), + }; let mut mock_deps = setup_with_params( cur_epoch_num, @@ -877,12 +1339,9 @@ mod test { epoch_duration, rewards_per_epoch, participation_threshold, + pool_id.clone(), ); let verifier = Addr::unchecked("verifier"); - let pool_id = PoolId { - chain_name: "mock-chain".parse().unwrap(), - contract: Addr::unchecked("pool_contract"), - }; for height in block_height_started..block_height_started + epoch_duration * 9 { let event_id = height.to_string() + "event"; @@ -949,6 +1408,10 @@ mod test { let epoch_duration = 1000u64; let rewards_per_epoch = 100u128; let participation_threshold = (8, 10); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("pool_contract"), + }; let mut mock_deps = setup_with_params( cur_epoch_num, @@ -956,6 +1419,7 @@ mod test { epoch_duration, rewards_per_epoch, participation_threshold, + pool_id.clone(), ); let verifier = Addr::unchecked("verifier"); let pool_id = PoolId { @@ -1028,6 +1492,10 @@ mod test { let epoch_duration = 1000u64; let rewards_per_epoch = 100u128; let participation_threshold = (8, 10); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("pool_contract"), + }; let mut mock_deps = setup_with_params( cur_epoch_num, @@ -1035,6 +1503,7 @@ mod test { epoch_duration, rewards_per_epoch, participation_threshold, + pool_id.clone(), ); let verifier = Addr::unchecked("verifier"); let pool_id = PoolId { @@ -1095,6 +1564,10 @@ mod test { let epoch_duration = 1000u64; let rewards_per_epoch = 100u128; let participation_threshold = (8, 10); + let pool_id = PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("pool_contract"), + }; let mut mock_deps = setup_with_params( cur_epoch_num, @@ -1102,12 +1575,9 @@ mod test { epoch_duration, rewards_per_epoch, participation_threshold, + pool_id.clone(), ); let verifier = Addr::unchecked("verifier"); - let pool_id = PoolId { - chain_name: "mock-chain".parse().unwrap(), - contract: Addr::unchecked("pool_contract"), - }; let _ = record_participation( mock_deps.as_mut().storage, @@ -1144,14 +1614,108 @@ mod test { assert_eq!(err.current_context(), &ContractError::NoRewardsToDistribute); } + #[test] + fn cannot_record_participation_before_pool_is_created() { + let cur_epoch_num = 1u64; + let block_height_started = 250u64; + let mut mock_deps = + setup_multiple_pools_with_params(cur_epoch_num, block_height_started, vec![]); + + assert!(record_participation( + mock_deps.as_mut().storage, + "some-event".parse().unwrap(), + Addr::unchecked("verifier"), + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract") + }, + block_height_started + ) + .is_err()); + } + + #[test] + fn cannot_add_rewards_before_pool_is_created() { + let cur_epoch_num = 1u64; + let block_height_started = 250u64; + let mut mock_deps = + setup_multiple_pools_with_params(cur_epoch_num, block_height_started, vec![]); + assert!(add_rewards( + mock_deps.as_mut().storage, + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract") + }, + 100u128.try_into().unwrap(), + ) + .is_err()); + } + + #[test] + fn cannot_distribute_rewards_before_pool_is_created() { + let cur_epoch_num = 1u64; + let block_height_started = 250u64; + let mut mock_deps = + setup_multiple_pools_with_params(cur_epoch_num, block_height_started, vec![]); + assert!(distribute_rewards( + mock_deps.as_mut().storage, + PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract") + }, + block_height_started, + None + ) + .is_err()); + } + type MockDeps = OwnedDeps; + fn setup_multiple_pools_with_params( + cur_epoch_num: u64, + block_height_started: u64, + pools: Vec<(PoolId, Params)>, + ) -> MockDeps { + let current_epoch = Epoch { + epoch_num: cur_epoch_num, + block_height_started, + }; + + let mut deps = mock_dependencies(); + let storage = deps.as_mut().storage; + for (pool_id, params) in pools { + let params_snapshot = ParamsSnapshot { + params, + created_at: current_epoch.clone(), + }; + + state::save_rewards_pool( + storage, + &RewardsPool { + id: pool_id, + params: params_snapshot, + balance: Uint128::zero(), + }, + ) + .unwrap(); + } + + let config = Config { + rewards_denom: "AXL".to_string(), + }; + + CONFIG.save(storage, &config).unwrap(); + + deps + } + fn setup_with_params( cur_epoch_num: u64, block_height_started: u64, epoch_duration: u64, rewards_per_epoch: u128, participation_threshold: (u64, u64), + pool_id: PoolId, ) -> MockDeps { let rewards_per_epoch: nonempty::Uint128 = cosmwasm_std::Uint128::from(rewards_per_epoch) .try_into() @@ -1172,8 +1736,15 @@ mod test { let mut deps = mock_dependencies(); let storage = deps.as_mut().storage; - - state::save_params(storage, ¶ms_snapshot).unwrap(); + state::save_rewards_pool( + storage, + &RewardsPool { + id: pool_id, + params: params_snapshot, + balance: Uint128::zero(), + }, + ) + .unwrap(); let config = Config { rewards_denom: "AXL".to_string(), @@ -1184,7 +1755,12 @@ mod test { deps } - fn setup(cur_epoch_num: u64, block_height_started: u64, epoch_duration: u64) -> MockDeps { + fn setup( + cur_epoch_num: u64, + block_height_started: u64, + epoch_duration: u64, + pool_id: PoolId, + ) -> MockDeps { let participation_threshold = (1, 2); let rewards_per_epoch = 100u128; setup_with_params( @@ -1193,6 +1769,7 @@ mod test { epoch_duration, rewards_per_epoch, participation_threshold, + pool_id, ) } } diff --git a/contracts/rewards/src/contract/migrations/mod.rs b/contracts/rewards/src/contract/migrations/mod.rs index a73cc4eb4..1d185e9d7 100644 --- a/contracts/rewards/src/contract/migrations/mod.rs +++ b/contracts/rewards/src/contract/migrations/mod.rs @@ -1 +1 @@ -pub mod v0_4_0; +pub mod v1_0_0; diff --git a/contracts/rewards/src/contract/migrations/v0_4_0.rs b/contracts/rewards/src/contract/migrations/v0_4_0.rs deleted file mode 100644 index 115da34ae..000000000 --- a/contracts/rewards/src/contract/migrations/v0_4_0.rs +++ /dev/null @@ -1,153 +0,0 @@ -#![allow(deprecated)] - -use axelar_wasm_std::error::ContractError; -use axelar_wasm_std::permission_control; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Storage}; -use cw_storage_plus::Item; -use router_api::error::Error; - -use crate::contract::CONTRACT_NAME; -use crate::state; - -const BASE_VERSION: &str = "0.4.0"; - -pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { - cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; - - set_generalized_permission_control(storage)?; - Ok(()) -} - -fn set_generalized_permission_control(storage: &mut dyn Storage) -> Result<(), Error> { - let old_config = CONFIG.load(storage)?; - - permission_control::set_governance(storage, &old_config.governance).map_err(Error::from)?; - - let new_config = &state::Config { - rewards_denom: old_config.rewards_denom, - }; - state::CONFIG.save(storage, new_config)?; - Ok(()) -} - -#[cw_serde] -#[deprecated(since = "0.4.0", note = "only used during migration")] -pub struct Config { - pub governance: Addr, - pub rewards_denom: String, -} - -#[deprecated(since = "0.4.0", note = "only used during migration")] -pub const CONFIG: Item = Item::new("config"); - -#[cfg(test)] -pub mod tests { - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; - - use crate::contract::migrations::v0_4_0; - use crate::contract::{execute, CONTRACT_NAME}; - use crate::msg::{ExecuteMsg, InstantiateMsg, Params}; - use crate::state; - use crate::state::{Epoch, ParamsSnapshot, PARAMS}; - - #[deprecated(since = "0.4.0", note = "only used during migration tests")] - fn instantiate( - deps: DepsMut, - env: Env, - _info: MessageInfo, - msg: InstantiateMsg, - ) -> Result { - cw2::set_contract_version(deps.storage, CONTRACT_NAME, v0_4_0::BASE_VERSION)?; - - let governance = deps.api.addr_validate(&msg.governance_address)?; - - v0_4_0::CONFIG.save( - deps.storage, - &v0_4_0::Config { - governance, - rewards_denom: msg.rewards_denom, - }, - )?; - - PARAMS.save( - deps.storage, - &ParamsSnapshot { - params: msg.params, - created_at: Epoch { - epoch_num: 0, - block_height_started: env.block.height, - }, - }, - )?; - - Ok(Response::new()) - } - - #[test] - fn migrate_checks_contract_version() { - let mut deps = mock_dependencies(); - instantiate_contract(deps.as_mut(), "denom"); - cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); - - assert!(v0_4_0::migrate(deps.as_mut().storage).is_err()); - - cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v0_4_0::BASE_VERSION) - .unwrap(); - - assert!(v0_4_0::migrate(deps.as_mut().storage).is_ok()); - } - - #[test] - fn migrate_config() { - let mut deps = mock_dependencies(); - let denom = "denom".to_string(); - instantiate_contract(deps.as_mut(), &denom); - - v0_4_0::migrate(&mut deps.storage).unwrap(); - - let new_config = state::CONFIG.load(&deps.storage).unwrap(); - assert_eq!(denom, new_config.rewards_denom); - } - - #[test] - fn migrate_governance_permission() { - let mut deps = mock_dependencies(); - - instantiate_contract(deps.as_mut(), "denom"); - - v0_4_0::migrate(&mut deps.storage).unwrap(); - - let msg = ExecuteMsg::UpdateParams { - params: Params { - epoch_duration: 100u64.try_into().unwrap(), - rewards_per_epoch: 1000u128.try_into().unwrap(), - participation_threshold: (1, 2).try_into().unwrap(), - }, - }; - assert!(execute( - deps.as_mut(), - mock_env(), - mock_info("anyone", &[]), - msg.clone(), - ) - .is_err()); - - assert!(execute(deps.as_mut(), mock_env(), mock_info("governance", &[]), msg).is_ok()); - } - - #[deprecated(since = "0.4.0", note = "only used during migration tests")] - pub fn instantiate_contract(deps: DepsMut, denom: impl Into) { - let msg = InstantiateMsg { - governance_address: "governance".to_string(), - rewards_denom: denom.into(), - params: Params { - epoch_duration: 100u64.try_into().unwrap(), - rewards_per_epoch: 1000u128.try_into().unwrap(), - participation_threshold: (1, 2).try_into().unwrap(), - }, - }; - instantiate(deps, mock_env(), mock_info("anyone", &[]), msg).unwrap(); - } -} diff --git a/contracts/rewards/src/contract/migrations/v1_0_0.rs b/contracts/rewards/src/contract/migrations/v1_0_0.rs new file mode 100644 index 000000000..3db5b8312 --- /dev/null +++ b/contracts/rewards/src/contract/migrations/v1_0_0.rs @@ -0,0 +1,175 @@ +#![allow(deprecated)] + +use axelar_wasm_std::error::ContractError; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Order, Storage, Uint128}; +use cw_storage_plus::{Item, Map}; + +use crate::contract::CONTRACT_NAME; +use crate::state::{self, ParamsSnapshot, PoolId}; + +const BASE_VERSION: &str = "1.0.0"; + +pub fn migrate(storage: &mut dyn Storage) -> Result<(), ContractError> { + cw2::assert_contract_version(storage, CONTRACT_NAME, BASE_VERSION)?; + + migrate_params(storage)?; + Ok(()) +} + +fn migrate_params(storage: &mut dyn Storage) -> Result<(), ContractError> { + let params = PARAMS.load(storage)?; + let pools = get_all_pools(storage)?; + + for pool in pools { + state::save_rewards_pool( + storage, + &state::RewardsPool { + params: params.to_owned(), + id: pool.id, + balance: pool.balance, + }, + )?; + } + PARAMS.remove(storage); + + Ok(()) +} + +const POOLS: Map = Map::new("pools"); + +fn get_all_pools(storage: &mut dyn Storage) -> Result, ContractError> { + POOLS + .range(storage, None, None, Order::Ascending) + .map(|res| res.map(|(_, pool)| pool).map_err(|err| err.into())) + .collect::, _>>() +} + +#[deprecated(since = "1.0.0", note = "only used during migration")] +const PARAMS: Item = Item::new("params"); + +#[cw_serde] +#[deprecated(since = "1.0.0", note = "only used during migration")] +struct RewardsPool { + pub id: PoolId, + pub balance: Uint128, +} + +#[cfg(test)] +pub mod tests { + use axelar_wasm_std::permission_control; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response, Uint128}; + + use super::{RewardsPool, PARAMS, POOLS}; + use crate::contract::migrations::v1_0_0; + use crate::contract::CONTRACT_NAME; + use crate::msg::{InstantiateMsg, Params}; + use crate::state::{self, Config, Epoch, ParamsSnapshot, PoolId, CONFIG}; + + #[test] + fn migrate_rewards_pools() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut(), "denom"); + + let test_pools = vec![ + RewardsPool { + id: PoolId { + chain_name: "mock-chain".parse().unwrap(), + contract: Addr::unchecked("contract-1"), + }, + balance: Uint128::from(250u128), + }, + RewardsPool { + id: PoolId { + chain_name: "mock-chain-2".parse().unwrap(), + contract: Addr::unchecked("contract-2"), + }, + balance: Uint128::from(100u128), + }, + ]; + + for pool in &test_pools { + POOLS + .save(deps.as_mut().storage, pool.id.to_owned(), pool) + .unwrap(); + } + let params = PARAMS.load(deps.as_mut().storage).unwrap(); + + v1_0_0::migrate(deps.as_mut().storage).unwrap(); + + for pool in &test_pools { + let new_pool = + state::load_rewards_pool(deps.as_mut().storage, pool.id.to_owned()).unwrap(); + assert_eq!( + new_pool, + state::RewardsPool { + id: pool.id.to_owned(), + balance: pool.balance, + params: params.clone() + } + ); + } + } + + #[test] + fn migrate_checks_contract_version() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut(), "denom"); + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, "something wrong").unwrap(); + + assert!(v1_0_0::migrate(deps.as_mut().storage).is_err()); + + cw2::set_contract_version(deps.as_mut().storage, CONTRACT_NAME, v1_0_0::BASE_VERSION) + .unwrap(); + + assert!(v1_0_0::migrate(deps.as_mut().storage).is_ok()); + } + + #[deprecated(since = "0.4.0", note = "only used during migration tests")] + pub fn instantiate_contract(deps: DepsMut, denom: impl Into) { + let msg = InstantiateMsg { + governance_address: "governance".to_string(), + rewards_denom: denom.into(), + }; + instantiate(deps, mock_env(), mock_info("anyone", &[]), msg).unwrap(); + } + + #[deprecated(since = "0.4.0", note = "only used during migration tests")] + fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: InstantiateMsg, + ) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, v1_0_0::BASE_VERSION)?; + + let governance = deps.api.addr_validate(&msg.governance_address)?; + permission_control::set_governance(deps.storage, &governance)?; + + CONFIG.save( + deps.storage, + &Config { + rewards_denom: msg.rewards_denom, + }, + )?; + + let params = Params { + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: 1000u128.try_into().unwrap(), + participation_threshold: (1, 2).try_into().unwrap(), + }; + PARAMS.save( + deps.storage, + &ParamsSnapshot { + params, + created_at: Epoch { + epoch_num: 0, + block_height_started: env.block.height, + }, + }, + )?; + + Ok(Response::new()) + } +} diff --git a/contracts/rewards/src/contract/query.rs b/contracts/rewards/src/contract/query.rs index 9da88e320..998770ce2 100644 --- a/contracts/rewards/src/contract/query.rs +++ b/contracts/rewards/src/contract/query.rs @@ -11,7 +11,7 @@ pub fn rewards_pool( block_height: u64, ) -> Result { let pool = state::load_rewards_pool(storage, pool_id.clone())?; - let current_params = state::load_params(storage); + let current_params = pool.params; let cur_epoch = Epoch::current(¤t_params, block_height)?; // the params could have been updated since the tally was created. Therefore we use the params from the @@ -42,7 +42,7 @@ pub fn participation( let epoch_num = match epoch_num { Some(num) => num, None => { - let current_params = state::load_params(storage); + let current_params = state::load_rewards_pool_params(storage, pool_id.clone())?; Epoch::current(¤t_params, block_height)?.epoch_num } }; @@ -94,9 +94,9 @@ mod tests { let rewards_pool = RewardsPool { id: pool_id.clone(), balance: initial_balance, + params: params_snapshot.clone(), }; - state::save_params(storage, ¶ms_snapshot).unwrap(); state::save_rewards_pool(storage, &rewards_pool).unwrap(); (params_snapshot, pool_id) diff --git a/contracts/rewards/src/error.rs b/contracts/rewards/src/error.rs index 169222898..11aaf4de3 100644 --- a/contracts/rewards/src/error.rs +++ b/contracts/rewards/src/error.rs @@ -1,9 +1,12 @@ use axelar_wasm_std::IntoContractError; -use cosmwasm_std::OverflowError; +use cosmwasm_std::{OverflowError, StdError}; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] pub enum ContractError { + #[error(transparent)] + Std(#[from] StdError), + #[error("error saving params")] SaveParams, @@ -16,6 +19,9 @@ pub enum ContractError { #[error("error saving rewards pool")] SaveRewardsPool, + #[error("error updating rewards pool")] + UpdateRewardsPool, + #[error("error saving rewards watermark")] SaveRewardsWatermark, @@ -31,6 +37,9 @@ pub enum ContractError { #[error("rewards pool not found")] RewardsPoolNotFound, + #[error("rewards pool already exists")] + RewardsPoolAlreadyExists, + #[error("error loading rewards watermark")] LoadRewardsWatermark, diff --git a/contracts/rewards/src/msg.rs b/contracts/rewards/src/msg.rs index 64d46a317..be31741f3 100644 --- a/contracts/rewards/src/msg.rs +++ b/contracts/rewards/src/msg.rs @@ -12,7 +12,6 @@ use crate::state::{Epoch, PoolId}; pub struct InstantiateMsg { pub governance_address: String, pub rewards_denom: String, - pub params: Params, } #[cw_serde] @@ -35,6 +34,7 @@ pub struct Params { #[derive(EnsurePermissions)] pub enum ExecuteMsg { /// Log a specific verifier as participating in a specific event. Verifier weights are ignored + /// This call will error if the pool does not yet exist. /// /// TODO: For batched voting, treating the entire batch as a single event can be problematic. /// A verifier may vote correctly for 9 out of 10 messages in a batch, but the verifier's participation @@ -50,6 +50,7 @@ pub enum ExecuteMsg { }, /// Distribute rewards up to epoch T - 2 (i.e. if we are currently in epoch 10, distribute all undistributed rewards for epochs 0-8) and send the required number of tokens to each verifier + /// This call will error if the pool does not yet exist. #[permission(Any)] DistributeRewards { pool_id: PoolId, @@ -57,14 +58,20 @@ pub enum ExecuteMsg { epoch_count: Option, }, - /// Start a new reward pool for the given contract if none exists. Otherwise, add tokens to an existing reward pool. + /// Add tokens to an existing rewards pool. /// Any attached funds with a denom matching the rewards denom are added to the pool. + /// This call will error if the pool does not yet exist. #[permission(Any)] AddRewards { pool_id: PoolId }, - /// Overwrites the currently stored params. Callable only by governance. + /// Overwrites the currently stored params for the specified pool. Callable only by governance. + /// This call will error if the pool does not yet exist. + #[permission(Governance)] + UpdatePoolParams { params: Params, pool_id: PoolId }, + + /// Creates a rewards pool with the specified pool ID and parameters. Callable only by governance. #[permission(Governance)] - UpdateParams { params: Params }, + CreatePool { params: Params, pool_id: PoolId }, } #[cw_serde] diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index 400774dd5..159898b26 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -11,6 +11,21 @@ use router_api::ChainName; use crate::error::ContractError; use crate::msg::Params; +/// Maps a (pool id, epoch number) pair to a tally for that epoch and rewards pool +const TALLIES: Map = Map::new("tallies"); + +/// Maps an (event id, pool id) pair to an Event +const EVENTS: Map<(String, PoolId), Event> = Map::new("events"); + +/// Maps the id to the rewards pool for given chain and contract +const POOLS: Map = Map::new("pools"); + +/// Maps a rewards pool to the epoch number of the most recent epoch for which rewards were distributed. All epochs prior +/// have had rewards distributed already and all epochs after have not yet had rewards distributed for this pool +const WATERMARKS: Map = Map::new("rewards_watermarks"); + +pub const CONFIG: Item = Item::new("config"); + #[cw_serde] pub struct Config { pub rewards_denom: String, @@ -230,16 +245,10 @@ impl Epoch { pub struct RewardsPool { pub id: PoolId, pub balance: Uint128, + pub params: ParamsSnapshot, } impl RewardsPool { - pub fn new(id: PoolId) -> Self { - RewardsPool { - id, - balance: Uint128::zero(), - } - } - pub fn sub_reward(mut self, reward: Uint128) -> Result { self.balance = self .balance @@ -250,32 +259,10 @@ impl RewardsPool { } } -/// Current rewards parameters, along with when the params were updated -pub const PARAMS: Item = Item::new("params"); - -/// Maps a (pool id, epoch number) pair to a tally for that epoch and rewards pool -const TALLIES: Map = Map::new("tallies"); - -/// Maps an (event id, pool id) pair to an Event -const EVENTS: Map<(String, PoolId), Event> = Map::new("events"); - -/// Maps the id to the rewards pool for given chain and contract -const POOLS: Map = Map::new("pools"); - -/// Maps a rewards pool to the epoch number of the most recent epoch for which rewards were distributed. All epochs prior -/// have had rewards distributed already and all epochs after have not yet had rewards distributed for this pool -const WATERMARKS: Map = Map::new("rewards_watermarks"); - -pub const CONFIG: Item = Item::new("config"); - pub fn load_config(storage: &dyn Storage) -> Config { CONFIG.load(storage).expect("couldn't load config") } -pub fn load_params(storage: &dyn Storage) -> ParamsSnapshot { - PARAMS.load(storage).expect("params should exist") -} - pub fn load_rewards_watermark( storage: &dyn Storage, pool_id: PoolId, @@ -314,29 +301,21 @@ pub fn may_load_rewards_pool( .change_context(ContractError::LoadRewardsPool) } -pub fn load_rewards_pool_or_new( +pub fn load_rewards_pool( storage: &dyn Storage, pool_id: PoolId, ) -> Result { - may_load_rewards_pool(storage, pool_id.clone()) - .map(|pool| pool.unwrap_or(RewardsPool::new(pool_id))) + may_load_rewards_pool(storage, pool_id.clone())? + .ok_or(ContractError::RewardsPoolNotFound.into()) } -pub fn load_rewards_pool( +pub fn load_rewards_pool_params( storage: &dyn Storage, pool_id: PoolId, -) -> Result { +) -> Result { may_load_rewards_pool(storage, pool_id.clone())? .ok_or(ContractError::RewardsPoolNotFound.into()) -} - -pub fn save_params( - storage: &mut dyn Storage, - params: &ParamsSnapshot, -) -> Result<(), ContractError> { - PARAMS - .save(storage, params) - .change_context(ContractError::SaveParams) + .map(|pool| pool.params) } pub fn save_rewards_watermark( @@ -382,6 +361,41 @@ pub fn save_rewards_pool( .change_context(ContractError::SaveRewardsPool) } +pub fn update_pool_params( + storage: &mut dyn Storage, + pool_id: &PoolId, + updated_params: &ParamsSnapshot, +) -> Result { + POOLS + .update(storage, pool_id.clone(), |pool| match pool { + None => Err(ContractError::RewardsPoolNotFound), + Some(pool) => Ok(RewardsPool { + id: pool_id.to_owned(), + balance: pool.balance, + params: updated_params.to_owned(), + }), + }) + .change_context(ContractError::UpdateRewardsPool) +} + +pub fn pool_exists(storage: &mut dyn Storage, pool_id: &PoolId) -> Result { + POOLS + .may_load(storage, pool_id.to_owned()) + .change_context(ContractError::LoadRewardsPool) + .map(|pool| pool.is_some()) +} + +pub fn current_epoch( + storage: &mut dyn Storage, + pool_id: &PoolId, + cur_block_height: u64, +) -> Result { + Epoch::current( + &load_rewards_pool_params(storage, pool_id.to_owned())?, + cur_block_height, + ) +} + pub enum StorageState { Existing(T), New(T), @@ -477,12 +491,24 @@ mod test { #[test] fn sub_reward_from_pool() { + let params = ParamsSnapshot { + params: Params { + participation_threshold: (Uint64::new(1), Uint64::new(2)).try_into().unwrap(), + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: Uint128::from(1000u128).try_into().unwrap(), + }, + created_at: Epoch { + epoch_num: 1, + block_height_started: 1, + }, + }; let pool = RewardsPool { id: PoolId { chain_name: "mock-chain".parse().unwrap(), contract: Addr::unchecked("pool_contract"), }, balance: Uint128::from(100u128), + params, }; let new_pool = pool.sub_reward(Uint128::from(50u128)).unwrap(); assert_eq!(new_pool.balance, Uint128::from(50u128)); @@ -494,41 +520,6 @@ mod test { )); } - #[test] - fn save_and_load_params() { - let mut mock_deps = mock_dependencies(); - let params = ParamsSnapshot { - params: Params { - participation_threshold: (Uint64::new(1), Uint64::new(2)).try_into().unwrap(), - epoch_duration: 100u64.try_into().unwrap(), - rewards_per_epoch: Uint128::from(1000u128).try_into().unwrap(), - }, - created_at: Epoch { - epoch_num: 1, - block_height_started: 1, - }, - }; - // save an initial params, then load it - assert!(save_params(mock_deps.as_mut().storage, ¶ms).is_ok()); - let loaded = load_params(mock_deps.as_ref().storage); - assert_eq!(loaded, params); - - // now store a new params, and check that it was updated - let new_params = ParamsSnapshot { - params: Params { - epoch_duration: 200u64.try_into().unwrap(), - ..params.params - }, - created_at: Epoch { - epoch_num: 2, - block_height_started: 101, - }, - }; - assert!(save_params(mock_deps.as_mut().storage, &new_params).is_ok()); - let loaded = load_params(mock_deps.as_mut().storage); - assert_eq!(loaded, new_params); - } - #[test] fn save_and_load_rewards_watermark() { let mut mock_deps = mock_dependencies(); @@ -711,30 +702,31 @@ mod test { #[test] fn save_and_load_rewards_pool() { + let params = ParamsSnapshot { + params: Params { + participation_threshold: (Uint64::new(1), Uint64::new(2)).try_into().unwrap(), + epoch_duration: 100u64.try_into().unwrap(), + rewards_per_epoch: Uint128::from(1000u128).try_into().unwrap(), + }, + created_at: Epoch { + epoch_num: 1, + block_height_started: 1, + }, + }; let mut mock_deps = mock_dependencies(); let chain_name: ChainName = "mock-chain".parse().unwrap(); - let pool = RewardsPool::new(PoolId::new( - chain_name.clone(), - Addr::unchecked("some contract"), - )); + let pool = RewardsPool { + id: PoolId::new(chain_name.clone(), Addr::unchecked("some contract")), + params, + balance: Uint128::zero(), + }; let res = save_rewards_pool(mock_deps.as_mut().storage, &pool); assert!(res.is_ok()); - let loaded = load_rewards_pool_or_new(mock_deps.as_ref().storage, pool.id.clone()); + let loaded = load_rewards_pool(mock_deps.as_ref().storage, pool.id.clone()); assert!(loaded.is_ok()); assert_eq!(loaded.unwrap(), pool); - - // return new pool when pool is not found - let loaded = load_rewards_pool_or_new( - mock_deps.as_ref().storage, - PoolId { - chain_name: chain_name.clone(), - contract: Addr::unchecked("a different contract"), - }, - ); - assert!(loaded.is_ok()); - assert!(loaded.as_ref().unwrap().balance.is_zero()); } } diff --git a/integration-tests/src/rewards_contract.rs b/integration-tests/src/rewards_contract.rs index 0e0118739..fb8572b1b 100644 --- a/integration-tests/src/rewards_contract.rs +++ b/integration-tests/src/rewards_contract.rs @@ -9,12 +9,7 @@ pub struct RewardsContract { } impl RewardsContract { - pub fn instantiate_contract( - app: &mut App, - governance: Addr, - rewards_denom: String, - params: rewards::msg::Params, - ) -> Self { + pub fn instantiate_contract(app: &mut App, governance: Addr, rewards_denom: String) -> Self { let code = ContractWrapper::new( rewards::contract::execute, rewards::contract::instantiate, @@ -29,7 +24,6 @@ impl RewardsContract { &rewards::msg::InstantiateMsg { governance_address: governance.to_string(), rewards_denom, - params, }, &[], "rewards", diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 3b4a976be..ace32837b 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -375,7 +375,6 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { &mut app, governance_address.clone(), AXL_DENOMINATION.to_string(), - rewards_params.clone(), ); let multisig = MultisigContract::instantiate_contract( @@ -696,6 +695,38 @@ pub fn setup_chain( ); assert!(response.is_ok()); + let rewards_params = rewards::msg::Params { + epoch_duration: nonempty::Uint64::try_from(10u64).unwrap(), + rewards_per_epoch: Uint128::from(100u128).try_into().unwrap(), + participation_threshold: (1, 2).try_into().unwrap(), + }; + + let response = protocol.rewards.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &rewards::msg::ExecuteMsg::CreatePool { + pool_id: PoolId { + chain_name: chain_name.clone(), + contract: voting_verifier.contract_addr.clone(), + }, + params: rewards_params.clone(), + }, + ); + assert!(response.is_ok()); + + let response = protocol.rewards.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &rewards::msg::ExecuteMsg::CreatePool { + pool_id: PoolId { + chain_name: chain_name.clone(), + contract: protocol.multisig.contract_addr.clone(), + }, + params: rewards_params, + }, + ); + assert!(response.is_ok()); + let response = protocol.rewards.execute_with_funds( &mut protocol.app, protocol.genesis_address.clone(), From e66af901a8c2c8b11483d47ee76d02531c462300 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:42:26 -0600 Subject: [PATCH 158/168] feat(minor-ampd): add command to send tokens from verifier address (#586) --- ampd/src/commands/mod.rs | 3 +++ ampd/src/commands/send_tokens.rs | 41 ++++++++++++++++++++++++++++++++ ampd/src/main.rs | 3 ++- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 ampd/src/commands/send_tokens.rs diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 5f4d091d2..15d6f80be 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -20,6 +20,7 @@ pub mod daemon; pub mod deregister_chain_support; pub mod register_chain_support; pub mod register_public_key; +pub mod send_tokens; pub mod verifier_address; #[derive(Debug, Subcommand, Valuable)] @@ -36,6 +37,8 @@ pub enum SubCommand { RegisterPublicKey(register_public_key::Args), /// Query the verifier address VerifierAddress, + /// Send tokens from the verifier account to a specified address + SendTokens(send_tokens::Args), } #[derive(Debug, Deserialize, Serialize, PartialEq)] diff --git a/ampd/src/commands/send_tokens.rs b/ampd/src/commands/send_tokens.rs new file mode 100644 index 000000000..c89fa6ddb --- /dev/null +++ b/ampd/src/commands/send_tokens.rs @@ -0,0 +1,41 @@ +use axelar_wasm_std::nonempty; +use cosmrs::bank::MsgSend; +use cosmrs::tx::Msg; +use cosmrs::{AccountId, Coin}; +use error_stack::Result; +use report::ResultCompatExt; +use valuable::Valuable; + +use crate::commands::{broadcast_tx, verifier_pub_key}; +use crate::config::Config; +use crate::{Error, PREFIX}; + +#[derive(clap::Args, Debug, Valuable)] +pub struct Args { + pub to_address: nonempty::String, + pub amount: u128, + pub denom: nonempty::String, +} + +pub async fn run(config: Config, args: Args) -> Result, Error> { + let coin = Coin::new(args.amount, args.denom.as_str()).change_context(Error::InvalidInput)?; + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; + + let tx = MsgSend { + to_address: args + .to_address + .parse::() + .change_context(Error::InvalidInput)?, + from_address: pub_key.account_id(PREFIX).change_context(Error::Tofnd)?, + amount: vec![coin], + } + .into_any() + .expect("failed to serialize proto message"); + + let tx_hash = broadcast_tx(config, tx, pub_key).await?.txhash; + + Ok(Some(format!( + "successfully broadcast send transaction, tx hash: {}", + tx_hash + ))) +} diff --git a/ampd/src/main.rs b/ampd/src/main.rs index d5881bfb5..916beed6e 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -6,7 +6,7 @@ use std::process::ExitCode; use ::config::{Config as cfg, Environment, File, FileFormat, FileSourceFile}; use ampd::commands::{ bond_verifier, daemon, deregister_chain_support, register_chain_support, register_public_key, - verifier_address, SubCommand, + send_tokens, verifier_address, SubCommand, }; use ampd::config::Config; use ampd::Error; @@ -64,6 +64,7 @@ async fn main() -> ExitCode { } Some(SubCommand::RegisterPublicKey(args)) => register_public_key::run(cfg, args).await, Some(SubCommand::VerifierAddress) => verifier_address::run(cfg.tofnd_config).await, + Some(SubCommand::SendTokens(args)) => send_tokens::run(cfg, args).await, }; match result { From 8bb895d7e8d8d47dd3db602278576dc5737ea252 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:14:45 -0600 Subject: [PATCH 159/168] feat(rewards): add event for rewards distribution (#584) --- Cargo.lock | 1 + contracts/rewards/Cargo.toml | 1 + contracts/rewards/src/contract.rs | 17 +++-- contracts/rewards/src/contract/execute.rs | 83 ++++++++++++++++------- contracts/rewards/src/events.rs | 53 +++++++++++++++ contracts/rewards/src/lib.rs | 1 + contracts/rewards/src/state.rs | 11 +++ 7 files changed, 139 insertions(+), 28 deletions(-) create mode 100644 contracts/rewards/src/events.rs diff --git a/Cargo.lock b/Cargo.lock index 12c73bb4f..962288514 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6659,6 +6659,7 @@ dependencies = [ "msgs-derive", "report", "router-api", + "serde_json", "thiserror", ] diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index a9248e38b..29d0dd41b 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -43,6 +43,7 @@ itertools = "0.11.0" msgs-derive = { workspace = true } report = { workspace = true } router-api = { workspace = true } +serde_json = { workspace = true } thiserror = { workspace = true } [dev-dependencies] diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index b97df9dc2..cca76834f 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -8,6 +8,7 @@ use error_stack::ResultExt; use itertools::Itertools; use crate::error::ContractError; +use crate::events; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; use crate::state::{self, Config, PoolId, CONFIG}; @@ -108,10 +109,16 @@ pub fn execute( } => { address::validate_cosmwasm_address(deps.api, pool_id.contract.as_str())?; - let rewards = - execute::distribute_rewards(deps.storage, pool_id, env.block.height, epoch_count)?; + let rewards_distribution = execute::distribute_rewards( + deps.storage, + pool_id.clone(), + env.block.height, + epoch_count, + )?; - let msgs = rewards + let msgs = rewards_distribution + .rewards + .clone() .into_iter() .sorted() .map(|(addr, amount)| BankMsg::Send { @@ -122,7 +129,9 @@ pub fn execute( }], }); - Ok(Response::new().add_messages(msgs)) + Ok(Response::new() + .add_messages(msgs) + .add_event(events::Event::from(rewards_distribution).into())) } ExecuteMsg::UpdatePoolParams { params, pool_id } => { execute::update_pool_params(deps.storage, &pool_id, params, env.block.height)?; diff --git a/contracts/rewards/src/contract/execute.rs b/contracts/rewards/src/contract/execute.rs index ead843cae..382afdeba 100644 --- a/contracts/rewards/src/contract/execute.rs +++ b/contracts/rewards/src/contract/execute.rs @@ -7,7 +7,8 @@ use error_stack::{ensure, Report, Result}; use crate::error::ContractError; use crate::msg::Params; use crate::state::{ - self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, RewardsPool, StorageState, + self, Epoch, EpochTally, Event, ParamsSnapshot, PoolId, RewardsDistribution, RewardsPool, + StorageState, }; const DEFAULT_EPOCHS_TO_PROCESS: u64 = 10; @@ -59,7 +60,7 @@ pub fn distribute_rewards( pool_id: PoolId, cur_block_height: u64, epoch_process_limit: Option, -) -> Result, ContractError> { +) -> Result { let epoch_process_limit = epoch_process_limit.unwrap_or(DEFAULT_EPOCHS_TO_PROCESS); let cur_epoch = state::current_epoch(storage, &pool_id, cur_block_height)?; @@ -77,7 +78,12 @@ pub fn distribute_rewards( let rewards = process_rewards_for_epochs(storage, pool_id.clone(), from, to)?; state::save_rewards_watermark(storage, pool_id, to)?; - Ok(rewards) + Ok(RewardsDistribution { + rewards, + epochs_processed: (from..=to).collect(), + current_epoch: cur_epoch.clone(), + can_distribute_more: to < cur_epoch.epoch_num.saturating_sub(EPOCH_PAYOUT_DELAY), + }) } fn process_rewards_for_epochs( @@ -1031,7 +1037,7 @@ mod test { Uint128::from(rewards_to_add).try_into().unwrap(), ); - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id, block_height_started + epoch_duration * 2, @@ -1039,7 +1045,7 @@ mod test { ) .unwrap(); assert_eq!( - rewards_claimed.values().sum::(), + distribution.rewards.values().sum::(), Uint128::from(params.rewards_per_epoch) ); } @@ -1112,7 +1118,7 @@ mod test { let rewards_to_add = params.rewards_per_epoch; let _ = add_rewards(mock_deps.as_mut().storage, pool_id.clone(), rewards_to_add); - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id.clone(), block_height_started + epoch_duration * 2, @@ -1123,7 +1129,7 @@ mod test { if pool_id == pools[0] { // the first pool has a 2/3 threshold, which both verifiers meet assert_eq!( - rewards_claimed, + distribution.rewards, HashMap::from_iter(verifiers.iter().map(|v| ( v.clone(), Uint128::from(Uint128::from(rewards_to_add).u128() / 2) @@ -1132,7 +1138,7 @@ mod test { } else { // the second pool has 3/4 threshold, which only the second verifier meets assert_eq!( - rewards_claimed, + distribution.rewards, HashMap::from([(verifiers[1].clone(), Uint128::from(rewards_to_add))]) ); } @@ -1204,7 +1210,7 @@ mod test { let rewards_to_add = params.rewards_per_epoch; add_rewards(mock_deps.as_mut().storage, pool_id.clone(), rewards_to_add).unwrap(); - let rewards = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id.clone(), block_height_started + base_epoch_duration * EPOCH_PAYOUT_DELAY, // this is long enough for the first pool to pay out, but not the second @@ -1213,9 +1219,9 @@ mod test { .unwrap(); if pool_id == pools[0] { - assert_eq!(rewards.len(), 1); + assert_eq!(distribution.rewards.len(), 1); } else { - assert_eq!(rewards.len(), 0); + assert_eq!(distribution.rewards.len(), 0); } } } @@ -1299,14 +1305,16 @@ mod test { Uint128::from(rewards_added).try_into().unwrap(), ); - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id, - block_height_started + epoch_duration * (epoch_count as u64 + 2), + block_height_started + epoch_duration * (epoch_count as u64 + 1), None, ) .unwrap(); + let rewards_claimed = distribution.rewards; + assert_eq!( rewards_claimed.len(), verifier_participation_per_epoch.len() @@ -1318,6 +1326,11 @@ mod test { Some(&Uint128::from(rewards)) ); } + + assert_eq!( + distribution.epochs_processed, + Vec::from_iter(0u64..epoch_count as u64) + ); } /// Tests that rewards are distributed correctly for a specified number of epochs, and that pagination works correctly @@ -1361,34 +1374,45 @@ mod test { Uint128::from(rewards_added).try_into().unwrap(), ); - // this puts us in epoch 10 + // this puts us in epoch 9 let cur_height = block_height_started + epoch_duration * 9; let total_epochs_with_rewards = (cur_height / epoch_duration) - 1; // distribute 5 epochs worth of rewards let epochs_to_process = 5; - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id.clone(), cur_height, Some(epochs_to_process), ) .unwrap(); + let rewards_claimed = distribution.rewards; assert_eq!(rewards_claimed.len(), 1); assert!(rewards_claimed.contains_key(&verifier)); assert_eq!( rewards_claimed.get(&verifier), Some(&(rewards_per_epoch * epochs_to_process as u128).into()) ); + assert_eq!( + distribution.epochs_processed, + Vec::from_iter(0u64..epochs_to_process) + ); + assert_eq!( + distribution.current_epoch.epoch_num, + cur_height / epoch_duration + ); + assert!(distribution.can_distribute_more); // distribute the remaining epochs worth of rewards - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id.clone(), cur_height, None, ) .unwrap(); + let rewards_claimed = distribution.rewards; assert_eq!(rewards_claimed.len(), 1); assert!(rewards_claimed.contains_key(&verifier)); assert_eq!( @@ -1398,6 +1422,15 @@ mod test { .into() ) ); + assert_eq!( + distribution.epochs_processed, + Vec::from_iter(epochs_to_process..total_epochs_with_rewards) + ); + assert_eq!( + distribution.current_epoch.epoch_num, + cur_height / epoch_duration + ); + assert!(!distribution.can_distribute_more); } /// Tests that we do not distribute rewards for a given epoch until two epochs later @@ -1463,14 +1496,15 @@ mod test { assert_eq!(err.current_context(), &ContractError::NoRewardsToDistribute); // can claim now, two epochs after participation - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id.clone(), block_height_started + epoch_duration * 2, None, ) .unwrap(); - assert_eq!(rewards_claimed.len(), 1); + assert_eq!(distribution.rewards.len(), 1); + assert!(!distribution.can_distribute_more); // should error if we try again let err = distribute_rewards( @@ -1546,14 +1580,14 @@ mod test { Uint128::from(rewards_added).try_into().unwrap(), ); - let result = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id, block_height_started + epoch_duration * 2, None, - ); - assert!(result.is_ok()); - assert_eq!(result.unwrap().len(), 1); + ) + .unwrap(); + assert_eq!(distribution.rewards.len(), 1); } /// Tests that an error is returned from distribute_rewards when trying to claim rewards for the same epoch more than once @@ -1594,14 +1628,15 @@ mod test { Uint128::from(rewards_added).try_into().unwrap(), ); - let rewards_claimed = distribute_rewards( + let distribution = distribute_rewards( mock_deps.as_mut().storage, pool_id.clone(), block_height_started + epoch_duration * 2, None, ) .unwrap(); - assert_eq!(rewards_claimed.len(), 1); + assert_eq!(distribution.rewards.len(), 1); + assert_eq!(distribution.epochs_processed, vec![cur_epoch_num]); // try to claim again, shouldn't get an error let err = distribute_rewards( diff --git a/contracts/rewards/src/events.rs b/contracts/rewards/src/events.rs new file mode 100644 index 000000000..4bd221422 --- /dev/null +++ b/contracts/rewards/src/events.rs @@ -0,0 +1,53 @@ +use std::collections::HashMap; + +use cosmwasm_std::{Addr, Uint128}; + +use crate::state::{Epoch, RewardsDistribution}; + +pub enum Event { + RewardsDistributed { + rewards: HashMap, + epochs_processed: Vec, + current_epoch: Epoch, + can_distribute_more: bool, + }, +} + +impl From for Event { + fn from(value: RewardsDistribution) -> Self { + Event::RewardsDistributed { + rewards: value.rewards, + epochs_processed: value.epochs_processed, + current_epoch: value.current_epoch, + can_distribute_more: value.can_distribute_more, + } + } +} + +impl From for cosmwasm_std::Event { + fn from(other: Event) -> Self { + match other { + Event::RewardsDistributed { + rewards, + epochs_processed, + current_epoch, + can_distribute_more: more_epochs_to_distribute, + } => cosmwasm_std::Event::new("rewards_distributed") + .add_attribute( + "rewards", + serde_json::to_string(&rewards).expect("failed to serialize rewards"), + ) + .add_attribute( + "epochs_processed", + serde_json::to_string(&epochs_processed) + .expect("failed to serialize epochs processed"), + ) + .add_attribute( + "current_epoch", + serde_json::to_string(¤t_epoch) + .expect("failed to serialize current epoch"), + ) + .add_attribute("can_distribute_more", more_epochs_to_distribute.to_string()), + } + } +} diff --git a/contracts/rewards/src/lib.rs b/contracts/rewards/src/lib.rs index 6a440df29..bf0cc0a11 100644 --- a/contracts/rewards/src/lib.rs +++ b/contracts/rewards/src/lib.rs @@ -1,5 +1,6 @@ pub mod contract; pub mod error; +pub mod events; pub mod msg; mod state; diff --git a/contracts/rewards/src/state.rs b/contracts/rewards/src/state.rs index 159898b26..e043d1321 100644 --- a/contracts/rewards/src/state.rs +++ b/contracts/rewards/src/state.rs @@ -259,6 +259,17 @@ impl RewardsPool { } } +#[cw_serde] +pub struct RewardsDistribution { + /// Amount of rewards denom each verifier received + pub rewards: HashMap, + /// List of epochs processed for this distribution + pub epochs_processed: Vec, + /// Epoch in which rewards were distributed + pub current_epoch: Epoch, + /// True if there are more rewards to distribute (later epochs that have not yet been distributed but are ready for distribution at the time of calling) + pub can_distribute_more: bool, +} pub fn load_config(storage: &dyn Storage) -> Config { CONFIG.load(storage).expect("couldn't load config") } From ddddd803870dc40477c73d5cc93c0e9f5045a9c1 Mon Sep 17 00:00:00 2001 From: jcs47 <11947034+jcs47@users.noreply.github.com> Date: Tue, 20 Aug 2024 02:35:20 +0100 Subject: [PATCH 160/168] chore(ampd): include libssl3 in docker image (#592) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Sousa --- ampd/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/ampd/Dockerfile b/ampd/Dockerfile index 2adea51e4..8a542a4fd 100644 --- a/ampd/Dockerfile +++ b/ampd/Dockerfile @@ -22,6 +22,7 @@ COPY ./ampd/build.rs ./ampd/build.rs RUN cargo install --locked --path ./ampd FROM debian:bookworm-slim AS runner +RUN apt update && apt install libssl3 RUN addgroup --system --gid 1001 axelard && adduser --home /home/axelard --system --uid 1000 --ingroup axelard axelard WORKDIR /home/axelard RUN mkdir /.ampd && chown axelard /.ampd From e2278d2c56f1bf548529813ce3566167474d1330 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:58:33 -0600 Subject: [PATCH 161/168] feat(minor-ampd): add commands to unbond and claim stake (#587) --- Cargo.lock | 40 +++++++++++++-------------- ampd/src/commands/claim_stake.rs | 41 ++++++++++++++++++++++++++++ ampd/src/commands/mod.rs | 6 ++++ ampd/src/commands/unbond_verifier.rs | 41 ++++++++++++++++++++++++++++ ampd/src/main.rs | 6 ++-- 5 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 ampd/src/commands/claim_stake.rs create mode 100644 ampd/src/commands/unbond_verifier.rs diff --git a/Cargo.lock b/Cargo.lock index 962288514..84f9339c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3325,9 +3325,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", @@ -3592,7 +3592,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -3681,7 +3681,7 @@ dependencies = [ "http 1.1.0", "hyper 1.3.1", "hyper-util", - "rustls 0.23.11", + "rustls 0.23.12", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -5454,9 +5454,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.5.0", "cfg-if", @@ -5486,9 +5486,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -6612,7 +6612,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.0", "http-body-util", @@ -6628,7 +6628,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile 2.1.2", + "rustls-pemfile 2.1.3", "serde", "serde_json", "serde_urlencoded", @@ -6960,13 +6960,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.11" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "once_cell", "rustls-pki-types", - "rustls-webpki 0.102.5", + "rustls-webpki 0.102.6", "subtle", "zeroize", ] @@ -7006,9 +7006,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -7016,9 +7016,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" @@ -7032,9 +7032,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.5" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -8603,7 +8603,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.11", + "rustls 0.23.12", "rustls-pki-types", "tokio", ] diff --git a/ampd/src/commands/claim_stake.rs b/ampd/src/commands/claim_stake.rs new file mode 100644 index 000000000..918c1e90a --- /dev/null +++ b/ampd/src/commands/claim_stake.rs @@ -0,0 +1,41 @@ +use axelar_wasm_std::nonempty; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; +use error_stack::Result; +use report::ResultCompatExt; +use service_registry::msg::ExecuteMsg; +use valuable::Valuable; + +use crate::commands::{broadcast_tx, verifier_pub_key}; +use crate::config::Config; +use crate::{Error, PREFIX}; + +#[derive(clap::Args, Debug, Valuable)] +pub struct Args { + pub service_name: nonempty::String, +} + +pub async fn run(config: Config, args: Args) -> Result, Error> { + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; + + let msg = serde_json::to_vec(&ExecuteMsg::ClaimStake { + service_name: args.service_name.into(), + }) + .expect("claim stake msg should be serializable"); + + let tx = MsgExecuteContract { + sender: pub_key.account_id(PREFIX).change_context(Error::Tofnd)?, + contract: config.service_registry.cosmwasm_contract.as_ref().clone(), + msg, + funds: vec![], + } + .into_any() + .expect("failed to serialize proto message"); + + let tx_hash = broadcast_tx(config, tx, pub_key).await?.txhash; + + Ok(Some(format!( + "successfully broadcast claim stake transaction, tx hash: {}", + tx_hash + ))) +} diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 15d6f80be..5d07d1681 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -16,11 +16,13 @@ use crate::types::{PublicKey, TMAddress}; use crate::{broadcaster, tofnd, Error, PREFIX}; pub mod bond_verifier; +pub mod claim_stake; pub mod daemon; pub mod deregister_chain_support; pub mod register_chain_support; pub mod register_public_key; pub mod send_tokens; +pub mod unbond_verifier; pub mod verifier_address; #[derive(Debug, Subcommand, Valuable)] @@ -29,6 +31,10 @@ pub enum SubCommand { Daemon, /// Bond the verifier to the service registry contract BondVerifier(bond_verifier::Args), + /// Unbond the verifier from the service registry contract + UnbondVerifier(unbond_verifier::Args), + /// Claim unbonded stake from the service registry contract + ClaimStake(claim_stake::Args), /// Register chain support to the service registry contract RegisterChainSupport(register_chain_support::Args), /// Deregister chain support to the service registry contract diff --git a/ampd/src/commands/unbond_verifier.rs b/ampd/src/commands/unbond_verifier.rs new file mode 100644 index 000000000..f17f4919f --- /dev/null +++ b/ampd/src/commands/unbond_verifier.rs @@ -0,0 +1,41 @@ +use axelar_wasm_std::nonempty; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; +use error_stack::Result; +use report::ResultCompatExt; +use service_registry::msg::ExecuteMsg; +use valuable::Valuable; + +use crate::commands::{broadcast_tx, verifier_pub_key}; +use crate::config::Config; +use crate::{Error, PREFIX}; + +#[derive(clap::Args, Debug, Valuable)] +pub struct Args { + pub service_name: nonempty::String, +} + +pub async fn run(config: Config, args: Args) -> Result, Error> { + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; + + let msg = serde_json::to_vec(&ExecuteMsg::UnbondVerifier { + service_name: args.service_name.into(), + }) + .expect("unbond verifier msg should be serializable"); + + let tx = MsgExecuteContract { + sender: pub_key.account_id(PREFIX).change_context(Error::Tofnd)?, + contract: config.service_registry.cosmwasm_contract.as_ref().clone(), + msg, + funds: vec![], + } + .into_any() + .expect("failed to serialize proto message"); + + let tx_hash = broadcast_tx(config, tx, pub_key).await?.txhash; + + Ok(Some(format!( + "successfully broadcast unbond verifier transaction, tx hash: {}", + tx_hash + ))) +} diff --git a/ampd/src/main.rs b/ampd/src/main.rs index 916beed6e..5445cca7a 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -5,8 +5,8 @@ use std::process::ExitCode; use ::config::{Config as cfg, Environment, File, FileFormat, FileSourceFile}; use ampd::commands::{ - bond_verifier, daemon, deregister_chain_support, register_chain_support, register_public_key, - send_tokens, verifier_address, SubCommand, + bond_verifier, claim_stake, daemon, deregister_chain_support, register_chain_support, + register_public_key, send_tokens, unbond_verifier, verifier_address, SubCommand, }; use ampd::config::Config; use ampd::Error; @@ -64,6 +64,8 @@ async fn main() -> ExitCode { } Some(SubCommand::RegisterPublicKey(args)) => register_public_key::run(cfg, args).await, Some(SubCommand::VerifierAddress) => verifier_address::run(cfg.tofnd_config).await, + Some(SubCommand::UnbondVerifier(args)) => unbond_verifier::run(cfg, args).await, + Some(SubCommand::ClaimStake(args)) => claim_stake::run(cfg, args).await, Some(SubCommand::SendTokens(args)) => send_tokens::run(cfg, args).await, }; From 2b49ac8321161433e3a29cfb7f6eec7271818aa0 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Wed, 21 Aug 2024 15:45:14 -0400 Subject: [PATCH 162/168] feat(ampd): add uri to connection errors (#590) --- ampd/src/commands/mod.rs | 19 ++++++++++++------- ampd/src/commands/register_public_key.rs | 5 +++-- ampd/src/error.rs | 24 ------------------------ ampd/src/lib.rs | 21 +++++++++++++-------- 4 files changed, 28 insertions(+), 41 deletions(-) delete mode 100644 ampd/src/error.rs diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 5d07d1681..3ed6b3276 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -61,9 +61,10 @@ impl Default for ServiceRegistryConfig { } async fn verifier_pub_key(config: tofnd::Config) -> Result { - MultisigClient::new(config.party_uid, config.url) + MultisigClient::new(config.party_uid, config.url.clone()) .await - .change_context(Error::Connection)? + .change_context(Error::Connection) + .attach_printable(config.url.clone())? .keygen(&config.key_uid, tofnd::Algorithm::Ecdsa) .await .change_context(Error::Tofnd) @@ -83,16 +84,20 @@ async fn broadcast_tx( let service_client = ServiceClient::connect(tm_grpc.to_string()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tm_grpc.clone())?; let auth_query_client = AuthQueryClient::connect(tm_grpc.to_string()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tm_grpc.clone())?; let bank_query_client = BankQueryClient::connect(tm_grpc.to_string()) .await - .change_context(Error::Connection)?; - let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) + .change_context(Error::Connection) + .attach_printable(tm_grpc)?; + let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url.clone()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tofnd_config.url)?; broadcaster::UnvalidatedBasicBroadcaster::builder() .client(service_client) diff --git a/ampd/src/commands/register_public_key.rs b/ampd/src/commands/register_public_key.rs index b31f45f1a..b68ee6edc 100644 --- a/ampd/src/commands/register_public_key.rs +++ b/ampd/src/commands/register_public_key.rs @@ -53,9 +53,10 @@ pub async fn run(config: Config, args: Args) -> Result, Error> { let tofnd_config = config.tofnd_config.clone(); - let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) + let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url.clone()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tofnd_config.url)?; let multisig_key = multisig_client .keygen(&multisig_address.to_string(), args.key_type.into()) .await diff --git a/ampd/src/error.rs b/ampd/src/error.rs deleted file mode 100644 index 61562ca35..000000000 --- a/ampd/src/error.rs +++ /dev/null @@ -1,24 +0,0 @@ -use thiserror::Error; -use tracing::error; - -#[derive(Error, Debug)] -pub enum Error { - #[error("failed to load config, falling back on default")] - LoadConfig, - #[error("{0} is not a valid location to persist state")] - StateLocation(String), - #[error("event sub failed")] - EventSub, - #[error("event processor failed")] - EventProcessor, - #[error("broadcaster failed")] - Broadcaster, - #[error("state updater failed")] - StateUpdater, - #[error("tofnd failed")] - Tofnd, - #[error("connection failed")] - Connection, - #[error("task execution failed")] - Task, -} diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 79182420e..e409a658c 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -32,7 +32,6 @@ mod block_height_monitor; mod broadcaster; pub mod commands; pub mod config; -pub mod error; mod event_processor; mod event_sub; mod evm; @@ -70,23 +69,29 @@ async fn prepare_app(cfg: Config) -> Result, Error> { } = cfg; let tm_client = tendermint_rpc::HttpClient::new(tm_jsonrpc.to_string().as_str()) - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tm_jsonrpc.clone())?; let service_client = ServiceClient::connect(tm_grpc.to_string()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tm_grpc.clone())?; let auth_query_client = AuthQueryClient::connect(tm_grpc.to_string()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tm_grpc.clone())?; let bank_query_client = BankQueryClient::connect(tm_grpc.to_string()) .await - .change_context(Error::Connection)?; - let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url) + .change_context(Error::Connection) + .attach_printable(tm_grpc.clone())?; + let multisig_client = MultisigClient::new(tofnd_config.party_uid, tofnd_config.url.clone()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tofnd_config.url)?; let block_height_monitor = BlockHeightMonitor::connect(tm_client.clone()) .await - .change_context(Error::Connection)?; + .change_context(Error::Connection) + .attach_printable(tm_jsonrpc)?; let pub_key = multisig_client .keygen(&tofnd_config.key_uid, tofnd::Algorithm::Ecdsa) From a085d77c395ac2c8d6f25bae4ee11f287dede2a4 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Wed, 21 Aug 2024 15:52:20 -0400 Subject: [PATCH 163/168] feat(minor-multisig-prover): stellar xdr encoding message to sign (#589) --- Cargo.lock | 67 ++++ Cargo.toml | 3 +- contracts/multisig-prover/Cargo.toml | 1 + contracts/multisig-prover/src/encoding/mod.rs | 7 + .../src/encoding/stellar_xdr.rs | 196 ++++++++++ .../stellar_messages_payload_digest.golden | 1 + ...stellar_verifier_set_payload_digest.golden | 1 + contracts/multisig-prover/src/error.rs | 3 + external-gateways/stellar/Cargo.toml | 26 ++ external-gateways/stellar/release.toml | 1 + external-gateways/stellar/src/error.rs | 11 + external-gateways/stellar/src/lib.rs | 341 ++++++++++++++++++ .../src/testdata/command_type_encode.golden | 4 + .../testdata/messages_approval_hash.golden | 1 + .../src/testdata/signers_rotation_hash.golden | 1 + 15 files changed, 663 insertions(+), 1 deletion(-) create mode 100644 contracts/multisig-prover/src/encoding/stellar_xdr.rs create mode 100644 contracts/multisig-prover/src/encoding/testdata/stellar_messages_payload_digest.golden create mode 100644 contracts/multisig-prover/src/encoding/testdata/stellar_verifier_set_payload_digest.golden create mode 100644 external-gateways/stellar/Cargo.toml create mode 100644 external-gateways/stellar/release.toml create mode 100644 external-gateways/stellar/src/error.rs create mode 100644 external-gateways/stellar/src/lib.rs create mode 100644 external-gateways/stellar/src/testdata/command_type_encode.golden create mode 100644 external-gateways/stellar/src/testdata/messages_approval_hash.golden create mode 100644 external-gateways/stellar/src/testdata/signers_rotation_hash.golden diff --git a/Cargo.lock b/Cargo.lock index 84f9339c3..46cd7b101 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -997,6 +997,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" + [[package]] name = "base64" version = "0.13.1" @@ -1794,6 +1800,17 @@ dependencies = [ "libc", ] +[[package]] +name = "crate-git-revision" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c521bf1f43d31ed2f73441775ed31935d77901cb3451e44b38a1c1612fcbaf98" +dependencies = [ + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -2526,6 +2543,12 @@ dependencies = [ "rustc_version 0.4.0", ] +[[package]] +name = "escape-bytes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfcf67fea2815c2fc3b90873fae90957be12ff417335dfadc7f52927feb03b2" + [[package]] name = "ethabi" version = "18.0.0" @@ -5004,6 +5027,7 @@ dependencies = [ "serde_json", "service-registry", "sha3", + "stellar", "sui-gateway", "thiserror", "voting-verifier", @@ -7741,6 +7765,49 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stellar" +version = "1.0.0" +dependencies = [ + "axelar-wasm-std", + "cosmwasm-std", + "error-stack", + "goldie", + "hex", + "multisig", + "rand", + "router-api", + "serde", + "serde_json", + "sha3", + "stellar-strkey", + "stellar-xdr", + "thiserror", +] + +[[package]] +name = "stellar-strkey" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12d2bf45e114117ea91d820a846fd1afbe3ba7d717988fee094ce8227a3bf8bd" +dependencies = [ + "base32", + "crate-git-revision", + "thiserror", +] + +[[package]] +name = "stellar-xdr" +version = "21.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2675a71212ed39a806e415b0dbf4702879ff288ec7f5ee996dda42a135512b50" +dependencies = [ + "crate-git-revision", + "escape-bytes", + "hex", + "stellar-strkey", +] + [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index ebca95c66..a44a4558f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["ampd", "contracts/*", "integration-tests", "interchain-token-service", "packages/*"] +members = ["ampd", "contracts/*", "external-gateways/*", "integration-tests", "interchain-token-service", "packages/*"] resolver = "2" [workspace.package] @@ -19,6 +19,7 @@ events-derive = { version = "^1.0.0", path = "packages/events-derive" } evm-gateway = { version = "^1.0.0", path = "packages/evm-gateway" } sui-types = { version = "^1.0.0", path = "packages/sui-types" } sui-gateway = { version = "^1.0.0", path = "packages/sui-gateway" } +stellar = { version = "^1.0.0", path = "external-gateways/stellar" } axelar-wasm-std = { version = "^1.0.0", path = "packages/axelar-wasm-std" } axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std-derive" } hex = "0.4.3" diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index a6aa1bff2..396f28f74 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -57,6 +57,7 @@ router-api = { workspace = true } serde_json = "1.0.89" service-registry = { workspace = true } sha3 = { workspace = true } +stellar = { workspace = true } sui-gateway = { workspace = true } thiserror = { workspace = true } voting-verifier = { workspace = true, features = ["library"] } diff --git a/contracts/multisig-prover/src/encoding/mod.rs b/contracts/multisig-prover/src/encoding/mod.rs index ee545f86e..25941cd67 100644 --- a/contracts/multisig-prover/src/encoding/mod.rs +++ b/contracts/multisig-prover/src/encoding/mod.rs @@ -1,5 +1,6 @@ mod abi; mod bcs; +mod stellar_xdr; use axelar_wasm_std::hash::Hash; use cosmwasm_schema::cw_serde; @@ -17,6 +18,7 @@ use crate::payload::Payload; pub enum Encoder { Abi, Bcs, + StellarXdr, } impl Encoder { @@ -29,6 +31,9 @@ impl Encoder { match self { Encoder::Abi => abi::payload_digest(domain_separator, verifier_set, payload), Encoder::Bcs => bcs::payload_digest(domain_separator, verifier_set, payload), + Encoder::StellarXdr => { + stellar_xdr::payload_digest(domain_separator, verifier_set, payload) + } } } @@ -52,6 +57,7 @@ impl Encoder { &self.digest(domain_separator, verifier_set, payload)?, payload, ), + Encoder::StellarXdr => todo!(), } } } @@ -64,6 +70,7 @@ where let recovery_transform = match encoder { Encoder::Abi => add_27, Encoder::Bcs => no_op, + Encoder::StellarXdr => no_op, }; signers .into_iter() diff --git a/contracts/multisig-prover/src/encoding/stellar_xdr.rs b/contracts/multisig-prover/src/encoding/stellar_xdr.rs new file mode 100644 index 000000000..ffb0c55f0 --- /dev/null +++ b/contracts/multisig-prover/src/encoding/stellar_xdr.rs @@ -0,0 +1,196 @@ +use axelar_wasm_std::hash::Hash; +use axelar_wasm_std::FnExt; +use error_stack::{Result, ResultExt}; +use multisig::verifier_set::VerifierSet; +use sha3::{Digest, Keccak256}; +use stellar::{Message, Messages, WeightedSigners}; + +use crate::error::ContractError; +use crate::payload::Payload; + +pub fn payload_digest( + domain_separator: &Hash, + verifier_set: &VerifierSet, + payload: &Payload, +) -> Result { + let data_hash = match payload { + Payload::Messages(messages) => messages + .iter() + .map(Message::try_from) + .collect::, _>>() + .change_context(ContractError::InvalidMessage)? + .then(Messages::from) + .messages_approval_hash(), + Payload::VerifierSet(verifier_set) => WeightedSigners::try_from(verifier_set) + .change_context(ContractError::InvalidVerifierSet)? + .signers_rotation_hash(), + } + .change_context(ContractError::SerializeData)?; + + let signers_hash = WeightedSigners::try_from(verifier_set) + .change_context(ContractError::InvalidVerifierSet)? + .hash() + .change_context(ContractError::SerializeData)?; + + let unsigned = [ + domain_separator, + signers_hash.as_slice(), + data_hash.as_slice(), + ] + .concat(); + + Ok(Keccak256::digest(unsigned).into()) +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::{Addr, HexBinary, Uint128}; + use multisig::key::KeyType; + use multisig::msg::Signer; + use multisig::verifier_set::VerifierSet; + use router_api::{CrossChainId, Message}; + + use crate::encoding::stellar_xdr::payload_digest; + use crate::payload::Payload; + + #[test] + fn stellar_messages_payload_digest() { + let signers_data = vec![ + ( + "addr_1", + "508bcac3df50837e0b093aebc549211ba72bd1e7c1830a288b816b677d62a046", + 9u128, + ), + ( + "addr_2", + "5c186341e6392ff06b35b2b80a05f99cdd1dd7d5b436f2eef1a6dd08c07c9463", + 4u128, + ), + ( + "addr_3", + "78c860cbba0b74a728bdc2ae05feef5a14c8903f59d59525ed5bea9b52027d0e", + 3u128, + ), + ( + "addr_4", + "ac1276368dab35ecc413c5008f184df4005e8773ea44ce3c980bc3dbe45f7521", + 3u128, + ), + ( + "addr_4", + "856d2aedc159b543f3150fd9e013ed5cc4d5d32659595e7bedbec279c28ccbe0", + 5u128, + ), + ( + "addr_5", + "e2a6a040c4a31f8131651fb669d514066963e2fde91feb86350d494a6e02f0fa", + 6u128, + ), + ]; + let verifier_set = gen_veifier_set(signers_data, 22, 2024); + + let payload = Payload::Messages(vec![Message { + cc_id: CrossChainId { + source_chain: "source".parse().unwrap(), + message_id: "test".parse().unwrap(), + }, + source_address: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + .parse() + .unwrap(), + destination_chain: "stellar".parse().unwrap(), + destination_address: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + .parse() + .unwrap(), + payload_hash: HexBinary::from_hex( + "65ad329dc342a82bd1daedc42e183e6e2c272b8e2e3fd7c8f81d089736d0bc3c", + ) + .unwrap() + .to_array() + .unwrap(), + }]); + let domain_separator: [u8; 32] = + HexBinary::from_hex("2a15376c1277252b1bcce5a6ecd781bfbc2697dfd969ff58d8e2e116018b501e") + .unwrap() + .to_array() + .unwrap(); + goldie::assert!(hex::encode( + payload_digest(&domain_separator, &verifier_set, &payload).unwrap() + )); + } + + #[test] + fn stellar_verifier_set_payload_digest() { + let verifier_set = gen_veifier_set( + vec![( + "addr_1", + "bf95c447eb2e694974ee2cf5f17e7165bc884a0cb676bb4de50c604bb7a6ea77", + 4u128, + )], + 1, + 2024, + ); + let signers_data = vec![ + ( + "addr_1", + "5086d25f94b8c42faf7ef4325516864e179fcb2a1a9321720f0fc2b249105106", + 5u128, + ), + ( + "addr_2", + "57a446f70d8243b7d5e08edcd9c5774f3f0257940df7aa84bca5b1acfc0f3ba3", + 7u128, + ), + ( + "addr_3", + "5a3211139cca5cee83096e8009aadf6405d84f5137706bc1db68f53cbb202054", + 9u128, + ), + ( + "addr_4", + "9d8774a24acce628658dc93e41c56972ded010c07b731306b54282890113d60f", + 7u128, + ), + ( + "addr_5", + "a99083342953620013c9c61f8000a8778915337632ac601458c6c93387d963f5", + 7u128, + ), + ]; + let payload = Payload::VerifierSet(gen_veifier_set(signers_data, 27, 2024)); + let domain_separator: [u8; 32] = + HexBinary::from_hex("6773bd037510492f863cba62a0f3c55ac846883f33cae7266aff8be5eb9681e8") + .unwrap() + .to_array() + .unwrap(); + + goldie::assert!(hex::encode( + payload_digest(&domain_separator, &verifier_set, &payload).unwrap() + )); + } + + fn gen_veifier_set( + signers_data: Vec<(&str, &str, u128)>, + threshold: u128, + created_at: u64, + ) -> VerifierSet { + VerifierSet { + signers: signers_data + .into_iter() + .map(|(addr, pub_key, weight)| { + ( + addr.to_string(), + Signer { + address: Addr::unchecked(addr), + pub_key: (KeyType::Ed25519, HexBinary::from_hex(pub_key).unwrap()) + .try_into() + .unwrap(), + weight: Uint128::from(weight), + }, + ) + }) + .collect(), + threshold: threshold.into(), + created_at, + } + } +} diff --git a/contracts/multisig-prover/src/encoding/testdata/stellar_messages_payload_digest.golden b/contracts/multisig-prover/src/encoding/testdata/stellar_messages_payload_digest.golden new file mode 100644 index 000000000..82b3f830f --- /dev/null +++ b/contracts/multisig-prover/src/encoding/testdata/stellar_messages_payload_digest.golden @@ -0,0 +1 @@ +0d29098e3f5a7ead5c97c0f8e74051e1de9cb601105551f8d4a898187e0f4f0d \ No newline at end of file diff --git a/contracts/multisig-prover/src/encoding/testdata/stellar_verifier_set_payload_digest.golden b/contracts/multisig-prover/src/encoding/testdata/stellar_verifier_set_payload_digest.golden new file mode 100644 index 000000000..c10388061 --- /dev/null +++ b/contracts/multisig-prover/src/encoding/testdata/stellar_verifier_set_payload_digest.golden @@ -0,0 +1 @@ +80097627445437998d5e4b6689ec9b5dcba64cdd5f4580e490f173cefe78609f \ No newline at end of file diff --git a/contracts/multisig-prover/src/error.rs b/contracts/multisig-prover/src/error.rs index 4ed88fea3..cafef424e 100644 --- a/contracts/multisig-prover/src/error.rs +++ b/contracts/multisig-prover/src/error.rs @@ -74,4 +74,7 @@ pub enum ContractError { #[error("payload does not match the stored value")] PayloadMismatch, + + #[error("failed to serialize data for the external gateway")] + SerializeData, } diff --git a/external-gateways/stellar/Cargo.toml b/external-gateways/stellar/Cargo.toml new file mode 100644 index 000000000..3efc2cb84 --- /dev/null +++ b/external-gateways/stellar/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "stellar" +version = "1.0.0" +edition = { workspace = true } +rust-version = { workspace = true } + +[dependencies] +axelar-wasm-std = { workspace = true } +cosmwasm-std = { workspace = true } +error-stack = { workspace = true } +hex = "0.4.3" +multisig = { workspace = true, features = ["library"] } +router-api = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sha3 = { workspace = true } +stellar-strkey = { version = "0.0.8" } +stellar-xdr = { version = "21.2.0" } +thiserror = { workspace = true } + +[lints] +workspace = true + +[dev-dependencies] +goldie = { workspace = true } +rand = "0.8.5" diff --git a/external-gateways/stellar/release.toml b/external-gateways/stellar/release.toml new file mode 100644 index 000000000..954564097 --- /dev/null +++ b/external-gateways/stellar/release.toml @@ -0,0 +1 @@ +release = false diff --git a/external-gateways/stellar/src/error.rs b/external-gateways/stellar/src/error.rs new file mode 100644 index 000000000..3722a04fe --- /dev/null +++ b/external-gateways/stellar/src/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("unsupported type of public key")] + UnsupportedPublicKey, + #[error("invalid public key")] + InvalidPublicKey, + #[error("invalid destination address")] + InvalidDestinationAddress, +} diff --git a/external-gateways/stellar/src/lib.rs b/external-gateways/stellar/src/lib.rs new file mode 100644 index 000000000..279629793 --- /dev/null +++ b/external-gateways/stellar/src/lib.rs @@ -0,0 +1,341 @@ +pub mod error; + +use std::str::FromStr; + +use axelar_wasm_std::utils::TryMapExt; +use cosmwasm_std::Uint256; +use error_stack::{Report, ResultExt}; +use multisig::key::PublicKey; +use multisig::verifier_set::VerifierSet; +use sha3::{Digest, Keccak256}; +use stellar_strkey::Contract; +use stellar_xdr::curr::{ + BytesM, Error as XdrError, Hash, Limits, ScAddress, ScMapEntry, ScVal, StringM, VecM, WriteXdr, +}; + +use crate::error::Error; + +#[derive(Debug, Clone)] +pub enum CommandType { + ApproveMessages, + RotateSigners, +} + +impl CommandType { + pub fn as_str(&self) -> &'static str { + match self { + CommandType::ApproveMessages => "ApproveMessages", + CommandType::RotateSigners => "RotateSigners", + } + } +} + +impl TryFrom for ScVal { + type Error = XdrError; + + fn try_from(value: CommandType) -> Result { + let val: VecM = + vec![ScVal::Symbol(StringM::from_str(value.as_str())?.into())].try_into()?; + + Ok(ScVal::Vec(Some(val.into()))) + } +} + +#[derive(Debug, Clone)] +pub struct Message { + pub message_id: String, + pub source_chain: String, + pub source_address: String, + pub contract_address: Contract, + pub payload_hash: Hash, +} + +impl TryFrom<&router_api::Message> for Message { + type Error = Report; + + fn try_from(value: &router_api::Message) -> Result { + Ok(Self { + source_chain: value.cc_id.source_chain.to_string(), + message_id: value.cc_id.message_id.to_string(), + source_address: value.source_address.to_string(), + contract_address: Contract::from_string(value.destination_address.as_str()) + .change_context(Error::InvalidDestinationAddress) + .attach_printable(value.destination_address.to_string())?, + payload_hash: value.payload_hash.into(), + }) + } +} + +impl TryFrom for ScVal { + type Error = XdrError; + + fn try_from(value: Message) -> Result { + let keys: [&'static str; 5] = [ + "contract_address", + "message_id", + "payload_hash", + "source_address", + "source_chain", + ]; + + let vals: [ScVal; 5] = [ + ScVal::Address(ScAddress::Contract(Hash(value.contract_address.0))), + ScVal::String(StringM::from_str(&value.message_id)?.into()), + ScVal::Bytes(BytesM::try_from(AsRef::<[u8; 32]>::as_ref(&value.payload_hash))?.into()), + ScVal::String(StringM::from_str(&value.source_address)?.into()), + ScVal::String(StringM::from_str(&value.source_chain)?.into()), + ]; + + sc_map_from_slices(&keys, &vals) + } +} + +pub struct Messages(Vec); + +impl From> for Messages { + fn from(v: Vec) -> Self { + Messages(v) + } +} + +impl Messages { + pub fn messages_approval_hash(&self) -> Result<[u8; 32], XdrError> { + let messages = self + .0 + .iter() + .map(|message| message.clone().try_into()) + .collect::, _>>()?; + + let val: ScVal = (CommandType::ApproveMessages, messages) + .try_into() + .expect("must convert tuple of size 2 to ScVec"); + + let hash = Keccak256::digest(val.to_xdr(Limits::none())?); + + Ok(hash.into()) + } +} + +#[derive(Clone, Debug)] +pub struct WeightedSigner { + pub signer: BytesM<32>, + pub weight: u128, +} + +impl TryFrom for ScVal { + type Error = XdrError; + + fn try_from(value: WeightedSigner) -> Result { + let keys: [&'static str; 2] = ["signer", "weight"]; + + let vals: [ScVal; 2] = [ + ScVal::Bytes(value.signer.to_vec().try_into()?), + value.weight.into(), + ]; + + sc_map_from_slices(&keys, &vals) + } +} + +#[derive(Debug, Clone)] +pub struct WeightedSigners { + pub signers: Vec, + pub threshold: u128, + pub nonce: BytesM<32>, +} + +impl WeightedSigners { + pub fn hash(&self) -> Result<[u8; 32], XdrError> { + let val: ScVal = self.clone().try_into()?; + let hash = Keccak256::digest(val.to_xdr(Limits::none())?); + + Ok(hash.into()) + } + + pub fn signers_rotation_hash(&self) -> Result<[u8; 32], XdrError> { + let val: ScVal = (CommandType::RotateSigners, self.clone()) + .try_into() + .expect("must convert tuple of size 2 to ScVec"); + + let hash = Keccak256::digest(val.to_xdr(Limits::none())?); + + Ok(hash.into()) + } +} + +impl TryFrom for ScVal { + type Error = XdrError; + + fn try_from(value: WeightedSigners) -> Result { + let signers = value.signers.clone().try_map(|signer| signer.try_into())?; + + let keys: [&'static str; 3] = ["nonce", "signers", "threshold"]; + + let vals: [ScVal; 3] = [ + ScVal::Bytes(value.nonce.to_vec().try_into()?), + ScVal::Vec(Some(signers.try_into()?)), + value.threshold.into(), + ]; + + sc_map_from_slices(&keys, &vals) + } +} + +impl TryFrom<&VerifierSet> for WeightedSigners { + type Error = Report; + + fn try_from(value: &VerifierSet) -> Result { + let mut signers = value + .signers + .values() + .map(|signer| match &signer.pub_key { + PublicKey::Ed25519(key) => Ok(WeightedSigner { + signer: BytesM::try_from(key.as_ref()) + .change_context(Error::InvalidPublicKey) + .attach_printable(key.to_hex())?, + weight: signer.weight.into(), + }), + PublicKey::Ecdsa(_) => Err(Report::new(Error::UnsupportedPublicKey)), + }) + .collect::, _>>()?; + + signers.sort_by(|signer1, signer2| signer1.signer.cmp(&signer2.signer)); + + let nonce = Uint256::from(value.created_at) + .to_be_bytes() + .try_into() + .expect("must convert from 32 bytes"); + + Ok(Self { + signers, + threshold: value.threshold.into(), + nonce, + }) + } +} + +/// Form a new Map from a slice of symbol-names and a slice of values. Keys must be in sorted order. +fn sc_map_from_slices(keys: &[&str], vals: &[ScVal]) -> Result { + let vec: VecM = keys + .iter() + .zip(vals.iter()) + .map(|(key, val)| { + Ok(ScMapEntry { + key: ScVal::Symbol(StringM::from_str(key)?.into()), + val: val.clone(), + }) + }) + .collect::, XdrError>>()? + .try_into()?; + + Ok(ScVal::Map(Some(vec.into()))) +} + +#[cfg(test)] +mod test { + use axelar_wasm_std::FnExt; + use cosmwasm_std::HexBinary; + use serde::Serialize; + use stellar_xdr::curr::{Limits, ScVal, WriteXdr}; + + use crate::{CommandType, Message, Messages, WeightedSigner, WeightedSigners}; + + #[test] + fn command_type_encode() { + #[derive(Serialize)] + struct Encoded { + approve_messages: String, + rotate_signers: String, + } + let approve_messages = ScVal::try_from(CommandType::ApproveMessages) + .unwrap() + .to_xdr(Limits::none()) + .unwrap() + .then(HexBinary::from) + .to_hex(); + let rotate_signers = ScVal::try_from(CommandType::RotateSigners) + .unwrap() + .to_xdr(Limits::none()) + .unwrap() + .then(HexBinary::from) + .to_hex(); + + let encoded = Encoded { + approve_messages, + rotate_signers, + }; + + goldie::assert_json!(&encoded); + } + + #[test] + fn messages_approval_hash() { + let payload_hashes = [ + "cfa347779c9b646ddf628c4da721976ceb998f1ab2c097b52e66a575c3975a6c", + "fb5eb8245e3b8eb9d44f228ee142a3378f57d49fc95fa78d437ff8aa5dd564ba", + "90e3761c0794fbbd8b563a0d05d83395e7f88f64f30eebb7c5533329f6653e84", + "60e146cb9c548ba6e614a87910d8172c9d21279a3f8f4da256ff36e15b80ea30", + ]; + + let messages: Messages = (1..=4) + .map(|i| Message { + message_id: format!("test-{}", i), + source_chain: format!("source-{}", i), + source_address: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" + .to_string(), + contract_address: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" + .parse() + .unwrap(), + payload_hash: payload_hashes[i - 1].parse().expect("invalid hash"), + }) + .collect::>() + .into(); + goldie::assert!(HexBinary::from(messages.messages_approval_hash().unwrap()).to_hex()); + } + + #[test] + fn signers_rotation_hash() { + let weighted_signers = WeightedSigners { + signers: vec![ + WeightedSigner { + signer: "0a245a2a2a5e8ec439d1377579a08fc78ea55647ba6fcb1f5d8a360218e8a985" + .parse() + .unwrap(), + weight: 3, + }, + WeightedSigner { + signer: "0b422cf449d900f6f8eb97f62e35811c62eb75feb84dfccef44a5c1c3dbac2ad" + .parse() + .unwrap(), + weight: 2, + }, + WeightedSigner { + signer: "18c34bf01a11b5ba21ea11b1678f3035ef753f0bdb1d5014ec21037e8f99e2a2" + .parse() + .unwrap(), + weight: 4, + }, + WeightedSigner { + signer: "f683ca8a6d7fe55f25599bb64b01edcc5eeb85fe5b63d3a4f0b3c32405005518" + .parse() + .unwrap(), + weight: 4, + }, + WeightedSigner { + signer: "fbb4b870e800038f1379697fae3058938c59b696f38dd0fdf2659c0cf3a5b663" + .parse() + .unwrap(), + weight: 2, + }, + ], + threshold: 8, + nonce: "8784bf7be5a9baaeea47e12d9e8ad0dec29afcbc3617d97f771e3c24fa945dce" + .parse() + .unwrap(), + }; + + goldie::assert!( + HexBinary::from(weighted_signers.signers_rotation_hash().unwrap()).to_hex() + ); + } +} diff --git a/external-gateways/stellar/src/testdata/command_type_encode.golden b/external-gateways/stellar/src/testdata/command_type_encode.golden new file mode 100644 index 000000000..6db86d933 --- /dev/null +++ b/external-gateways/stellar/src/testdata/command_type_encode.golden @@ -0,0 +1,4 @@ +{ + "approve_messages": "0000001000000001000000010000000f0000000f417070726f76654d6573736167657300", + "rotate_signers": "0000001000000001000000010000000f0000000d526f746174655369676e657273000000" +} \ No newline at end of file diff --git a/external-gateways/stellar/src/testdata/messages_approval_hash.golden b/external-gateways/stellar/src/testdata/messages_approval_hash.golden new file mode 100644 index 000000000..4512173fc --- /dev/null +++ b/external-gateways/stellar/src/testdata/messages_approval_hash.golden @@ -0,0 +1 @@ +49f6a85aec4b4f72c667f2ba7950a692a59f462007abdbce0181e2982c0b602e \ No newline at end of file diff --git a/external-gateways/stellar/src/testdata/signers_rotation_hash.golden b/external-gateways/stellar/src/testdata/signers_rotation_hash.golden new file mode 100644 index 000000000..774e8446b --- /dev/null +++ b/external-gateways/stellar/src/testdata/signers_rotation_hash.golden @@ -0,0 +1 @@ +4ad8f3015146ac68334fd405f90e6ca75fbf2c276b333a8747c9ba83d9c3f1f6 \ No newline at end of file From f752c6a72fe77f8786134cfd426a2c302c9188f0 Mon Sep 17 00:00:00 2001 From: haiyizxx Date: Wed, 21 Aug 2024 16:16:46 -0400 Subject: [PATCH 164/168] fix(ampd): copy external-gateways folder to dockerfile (#594) --- ampd/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/ampd/Dockerfile b/ampd/Dockerfile index 8a542a4fd..e778c783f 100644 --- a/ampd/Dockerfile +++ b/ampd/Dockerfile @@ -9,6 +9,7 @@ COPY ./packages ./packages COPY ./contracts ./contracts COPY ./interchain-token-service ./interchain-token-service COPY ./integration-tests ./integration-tests +COPY ./external-gateways ./external-gateways COPY ./.cargo ./.cargo # build dependencies separately From b87368f201d4e331b63b9f42a8d9227e514ecde5 Mon Sep 17 00:00:00 2001 From: CJ Cobb <46455409+cjcobb23@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:37:47 -0600 Subject: [PATCH 165/168] fix(minor-service-registry): prevent zero bond (#588) --- Cargo.lock | 13 ++ Cargo.toml | 1 + .../multisig-prover/src/test/test_utils.rs | 6 +- contracts/service-registry/src/contract.rs | 126 ++++++++++++------ .../service-registry/src/contract/execute.rs | 28 ++-- contracts/service-registry/src/error.rs | 2 + contracts/service-registry/src/msg.rs | 5 +- contracts/service-registry/src/state.rs | 115 +++++++++------- contracts/voting-verifier/src/contract.rs | 2 +- integration-tests/tests/bond_unbond.rs | 5 +- integration-tests/tests/test_utils/mod.rs | 16 +-- packages/axelar-wasm-std/Cargo.toml | 1 + .../axelar-wasm-std/src/nonempty/string.rs | 3 +- .../axelar-wasm-std/src/nonempty/timestamp.rs | 2 + packages/axelar-wasm-std/src/nonempty/uint.rs | 20 +-- packages/into-inner-derive/Cargo.toml | 22 +++ packages/into-inner-derive/release.toml | 1 + packages/into-inner-derive/src/lib.rs | 31 +++++ packages/into-inner-derive/tests/derive.rs | 11 ++ 19 files changed, 279 insertions(+), 131 deletions(-) create mode 100644 packages/into-inner-derive/Cargo.toml create mode 100644 packages/into-inner-derive/release.toml create mode 100644 packages/into-inner-derive/src/lib.rs create mode 100644 packages/into-inner-derive/tests/derive.rs diff --git a/Cargo.lock b/Cargo.lock index 46cd7b101..dd3e9a85a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -813,6 +813,7 @@ dependencies = [ "error-stack", "flagset", "hex", + "into-inner-derive", "itertools 0.11.0", "lazy_static", "num-traits", @@ -4097,6 +4098,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "into-inner-derive" +version = "1.0.0" +dependencies = [ + "axelar-wasm-std", + "error-stack", + "quote 1.0.36", + "report", + "syn 2.0.68", + "thiserror", +] + [[package]] name = "ipnet" version = "2.9.0" diff --git a/Cargo.toml b/Cargo.toml index a44a4558f..f8833bb3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ axelar-wasm-std = { version = "^1.0.0", path = "packages/axelar-wasm-std" } axelar-wasm-std-derive = { version = "^1.0.0", path = "packages/axelar-wasm-std-derive" } hex = "0.4.3" integration-tests = { version = "^1.0.0", path = "integration-tests" } +into-inner-derive = { version = "^1.0.0", path = "packages/into-inner-derive" } itertools = "0.11.0" voting-verifier = { version = "^1.0.0", path = "contracts/voting-verifier" } coordinator = { version = "^1.0.0", path = "contracts/coordinator" } diff --git a/contracts/multisig-prover/src/test/test_utils.rs b/contracts/multisig-prover/src/test/test_utils.rs index bf827bc60..a177365dc 100644 --- a/contracts/multisig-prover/src/test/test_utils.rs +++ b/contracts/multisig-prover/src/test/test_utils.rs @@ -123,7 +123,7 @@ fn service_registry_mock_querier_handler( coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 1, max_num_verifiers: Some(100), - min_verifier_bond: Uint128::new(1), + min_verifier_bond: Uint128::new(1).try_into().unwrap(), bond_denom: "uaxl".to_string(), unbonding_period_days: 1, description: "verifiers".to_string(), @@ -139,7 +139,9 @@ fn service_registry_mock_querier_handler( .map(|op| WeightedVerifier { verifier_info: Verifier { address: op.address, - bonding_state: BondingState::Bonded { amount: op.weight }, + bonding_state: BondingState::Bonded { + amount: op.weight.try_into().unwrap(), + }, authorization_state: AuthorizationState::Authorized, service_name: SERVICE_NAME.to_string(), }, diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index f0cf4def1..3cd025cec 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -3,7 +3,7 @@ use axelar_wasm_std::{address, permission_control, FnExt}; use cosmwasm_std::entry_point; use cosmwasm_std::{ to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, Order, - QueryRequest, Response, Storage, Uint128, WasmQuery, + QueryRequest, Response, Storage, WasmQuery, }; use error_stack::{bail, Report, ResultExt}; @@ -185,10 +185,11 @@ mod test { use std::str::FromStr; use axelar_wasm_std::error::err_contains; + use axelar_wasm_std::nonempty; use cosmwasm_std::testing::{ mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, }; - use cosmwasm_std::{coins, from_json, CosmosMsg, Empty, OwnedDeps, StdResult}; + use cosmwasm_std::{coins, from_json, CosmosMsg, Empty, OwnedDeps, StdResult, Uint128}; use router_api::ChainName; use super::*; @@ -236,7 +237,7 @@ mod test { coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond: Uint128::zero(), + min_verifier_bond: Uint128::one().try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -253,7 +254,7 @@ mod test { coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond: Uint128::zero(), + min_verifier_bond: Uint128::one().try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -281,7 +282,7 @@ mod test { coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond: Uint128::zero(), + min_verifier_bond: Uint128::one().try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -332,7 +333,7 @@ mod test { coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond, + min_verifier_bond: min_verifier_bond.try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -365,6 +366,51 @@ mod test { assert!(res.is_ok()); } + #[test] + fn bond_verifier_zero_bond_should_fail() { + let mut deps = setup(); + + let service_name = "validators"; + let min_verifier_bond = Uint128::new(100); + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::RegisterService { + service_name: service_name.into(), + coordinator_contract: Addr::unchecked("nowhere"), + min_num_verifiers: 0, + max_num_verifiers: Some(100), + min_verifier_bond: min_verifier_bond.try_into().unwrap(), + bond_denom: AXL_DENOMINATION.into(), + unbonding_period_days: 10, + description: "Some service".into(), + }, + ); + assert!(res.is_ok()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::AuthorizeVerifiers { + verifiers: vec![VERIFIER_ADDRESS.into()], + service_name: service_name.into(), + }, + ); + assert!(res.is_ok()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(VERIFIER_ADDRESS, &[]), + ExecuteMsg::BondVerifier { + service_name: service_name.into(), + }, + ); + assert!(res.is_err()); + } + #[test] fn register_chain_support() { let mut deps = setup(); @@ -380,7 +426,7 @@ mod test { coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond, + min_verifier_bond: min_verifier_bond.try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -442,7 +488,7 @@ mod test { verifier_info: Verifier { address: Addr::unchecked(VERIFIER_ADDRESS), bonding_state: BondingState::Bonded { - amount: min_verifier_bond + amount: min_verifier_bond.try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: service_name.into() @@ -483,7 +529,7 @@ mod test { coordinator_contract: Addr::unchecked("nowhere"), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond, + min_verifier_bond: min_verifier_bond.try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -570,7 +616,7 @@ mod test { coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond, + min_verifier_bond: min_verifier_bond.try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -664,7 +710,7 @@ mod test { coordinator_contract: Addr::unchecked(COORDINATOR_ADDRESS), min_num_verifiers: 0, max_num_verifiers: Some(100), - min_verifier_bond, + min_verifier_bond: min_verifier_bond.try_into().unwrap(), bond_denom: AXL_DENOMINATION.into(), unbonding_period_days: 10, description: "Some service".into(), @@ -761,7 +807,7 @@ mod test { verifier_info: Verifier { address: Addr::unchecked(VERIFIER_ADDRESS), bonding_state: BondingState::Bonded { - amount: min_verifier_bond + amount: min_verifier_bond.try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: service_name.into() @@ -779,7 +825,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -813,7 +859,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -881,7 +927,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -915,7 +961,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -993,7 +1039,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1027,7 +1073,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1069,7 +1115,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1143,7 +1189,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1225,7 +1271,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1259,7 +1305,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1309,7 +1355,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1332,7 +1378,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), "funnydenom"), + &coins(min_verifier_bond.into_inner().u128(), "funnydenom"), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1352,7 +1398,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1375,7 +1421,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1415,7 +1461,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1449,7 +1495,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128() / 2, AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128() / 2, AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1489,7 +1535,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1512,7 +1558,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1576,7 +1622,7 @@ mod test { let mut deps = setup(); let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let res = execute( deps.as_mut(), mock_env(), @@ -1610,7 +1656,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1682,7 +1728,7 @@ mod test { fn unbonding_period() { let mut deps = setup(); - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let service_name = "validators"; let unbonding_period_days = 1; @@ -1719,7 +1765,7 @@ mod test { mock_env(), mock_info( VERIFIER_ADDRESS, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1793,7 +1839,7 @@ mod test { res.messages[0].msg, CosmosMsg::Bank(BankMsg::Send { to_address: VERIFIER_ADDRESS.into(), - amount: coins(min_verifier_bond.u128(), AXL_DENOMINATION) + amount: coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION) }) ) } @@ -1807,7 +1853,7 @@ mod test { let min_num_verifiers = verifiers.len() as u16; let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let _ = execute( deps.as_mut(), mock_env(), @@ -1855,7 +1901,7 @@ mod test { mock_env(), mock_info( verifier.as_str(), - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1917,7 +1963,7 @@ mod test { // register a service let service_name = "validators"; - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond: nonempty::Uint128 = Uint128::new(100).try_into().unwrap(); let unbonding_period_days = 10; let res = execute( deps.as_mut(), @@ -1943,7 +1989,7 @@ mod test { mock_env(), mock_info( verifier1.as_str(), - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), @@ -1988,7 +2034,7 @@ mod test { mock_env(), mock_info( verifier2.as_str(), - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ), ExecuteMsg::BondVerifier { service_name: service_name.into(), diff --git a/contracts/service-registry/src/contract/execute.rs b/contracts/service-registry/src/contract/execute.rs index 65ee8b542..eb3bba305 100644 --- a/contracts/service-registry/src/contract/execute.rs +++ b/contracts/service-registry/src/contract/execute.rs @@ -1,3 +1,4 @@ +use axelar_wasm_std::nonempty; use router_api::ChainName; use super::*; @@ -10,7 +11,7 @@ pub fn register_service( coordinator_contract: Addr, min_num_verifiers: u16, max_num_verifiers: Option, - min_verifier_bond: Uint128, + min_verifier_bond: nonempty::Uint128, bond_denom: String, unbonding_period_days: u16, description: String, @@ -84,14 +85,17 @@ pub fn bond_verifier( .may_load(deps.storage, &service_name)? .ok_or(ContractError::ServiceNotFound)?; - let bond = if !info.funds.is_empty() { - info.funds - .iter() - .find(|coin| coin.denom == service.bond_denom) - .ok_or(ContractError::WrongDenom)? - .amount + let bond: Option = if !info.funds.is_empty() { + Some( + info.funds + .iter() + .find(|coin| coin.denom == service.bond_denom) + .ok_or(ContractError::WrongDenom)? + .amount + .try_into()?, + ) } else { - Uint128::zero() // sender can rebond currently unbonding funds by just sending no new funds + None // sender can rebond currently unbonding funds by just sending no new funds }; VERIFIERS.update( @@ -99,10 +103,12 @@ pub fn bond_verifier( (&service_name.clone(), &info.sender.clone()), |sw| -> Result { match sw { - Some(verifier) => Ok(verifier.add_bond(bond)?), + Some(verifier) => Ok(verifier.bond(bond)?), None => Ok(Verifier { address: info.sender, - bonding_state: BondingState::Bonded { amount: bond }, + bonding_state: BondingState::Bonded { + amount: bond.ok_or(ContractError::NoFundsToBond)?, + }, authorization_state: AuthorizationState::NotAuthorized, service_name, }), @@ -200,7 +206,7 @@ pub fn claim_stake( to_address: info.sender.into(), amount: [Coin { denom: service.bond_denom, - amount: released_bond, + amount: released_bond.into(), }] .to_vec(), })) diff --git a/contracts/service-registry/src/error.rs b/contracts/service-registry/src/error.rs index 0c45576d9..2a524370a 100644 --- a/contracts/service-registry/src/error.rs +++ b/contracts/service-registry/src/error.rs @@ -29,6 +29,8 @@ pub enum ContractError { VerifierNotFound, #[error("invalid bonding state `{0:?}` for this operation")] InvalidBondingState(BondingState), + #[error("no attached funds to bond")] + NoFundsToBond, #[error("not enough verifiers")] NotEnoughVerifiers, #[error("verifier is jailed")] diff --git a/contracts/service-registry/src/msg.rs b/contracts/service-registry/src/msg.rs index 934e07bab..e3c6b2ed6 100644 --- a/contracts/service-registry/src/msg.rs +++ b/contracts/service-registry/src/msg.rs @@ -1,5 +1,6 @@ +use axelar_wasm_std::nonempty; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Uint128}; +use cosmwasm_std::Addr; use msgs_derive::EnsurePermissions; use router_api::ChainName; @@ -18,7 +19,7 @@ pub enum ExecuteMsg { coordinator_contract: Addr, min_num_verifiers: u16, max_num_verifiers: Option, - min_verifier_bond: Uint128, + min_verifier_bond: nonempty::Uint128, bond_denom: String, unbonding_period_days: u16, // number of days to wait after starting unbonding before allowed to claim stake description: String, diff --git a/contracts/service-registry/src/state.rs b/contracts/service-registry/src/state.rs index 974241b53..cf1de2cd4 100644 --- a/contracts/service-registry/src/state.rs +++ b/contracts/service-registry/src/state.rs @@ -15,7 +15,7 @@ pub struct Service { pub coordinator_contract: Addr, pub min_num_verifiers: u16, pub max_num_verifiers: Option, - pub min_verifier_bond: Uint128, + pub min_verifier_bond: nonempty::Uint128, pub bond_denom: String, // should be set to a duration longer than the voting period for governance proposals, // otherwise a verifier could bail before they get penalized @@ -32,27 +32,25 @@ pub struct Verifier { } impl Verifier { - pub fn add_bond(self, to_add: Uint128) -> Result { - let amount = match self.bonding_state { + pub fn bond(self, to_add: Option) -> Result { + let amount: nonempty::Uint128 = match self.bonding_state { BondingState::Bonded { amount } | BondingState::RequestedUnbonding { amount } | BondingState::Unbonding { amount, unbonded_at: _, } => amount - .checked_add(to_add) - .map_err(ContractError::Overflow)?, - BondingState::Unbonded => to_add, + .into_inner() + .checked_add(to_add.map(Uint128::from).unwrap_or(Uint128::zero())) + .map_err(ContractError::Overflow)? + .try_into()?, + BondingState::Unbonded => to_add.ok_or(ContractError::NoFundsToBond)?, }; - if amount.is_zero() { - Err(ContractError::InvalidBondingState(self.bonding_state)) - } else { - Ok(Self { - bonding_state: BondingState::Bonded { amount }, - ..self - }) - } + Ok(Self { + bonding_state: BondingState::Bonded { amount }, + ..self + }) } pub fn unbond(self, can_unbond: bool, time: Timestamp) -> Result { @@ -84,7 +82,7 @@ impl Verifier { self, time: Timestamp, unbonding_period_days: u64, - ) -> Result<(Self, Uint128), ContractError> { + ) -> Result<(Self, nonempty::Uint128), ContractError> { if self.authorization_state == AuthorizationState::Jailed { return Err(ContractError::VerifierJailed); } @@ -126,13 +124,13 @@ impl From for Participant { #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub enum BondingState { Bonded { - amount: Uint128, + amount: nonempty::Uint128, }, RequestedUnbonding { - amount: Uint128, + amount: nonempty::Uint128, }, Unbonding { - amount: Uint128, + amount: nonempty::Uint128, unbonded_at: Timestamp, }, Unbonded, @@ -322,18 +320,18 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::Bonded { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), }; - let res = verifier.add_bond(Uint128::from(200u32)); + let res = verifier.bond(Some(Uint128::from(200u32).try_into().unwrap())); assert!(res.is_ok()); assert_eq!( res.unwrap().bonding_state, BondingState::Bonded { - amount: Uint128::from(300u32) + amount: Uint128::from(300u32).try_into().unwrap() } ); } @@ -343,18 +341,18 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), }; - let res = verifier.add_bond(Uint128::from(200u32)); + let res = verifier.bond(Some(Uint128::from(200u32).try_into().unwrap())); assert!(res.is_ok()); assert_eq!( res.unwrap().bonding_state, BondingState::Bonded { - amount: Uint128::from(300u32) + amount: Uint128::from(300u32).try_into().unwrap() } ); } @@ -364,19 +362,19 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::Unbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), unbonded_at: Timestamp::from_nanos(0), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), }; - let res = verifier.add_bond(Uint128::from(200u32)); + let res = verifier.bond(Some(Uint128::from(200u32).try_into().unwrap())); assert!(res.is_ok()); assert_eq!( res.unwrap().bonding_state, BondingState::Bonded { - amount: Uint128::from(300u32) + amount: Uint128::from(300u32).try_into().unwrap() } ); } @@ -390,12 +388,12 @@ mod tests { service_name: "validators".to_string(), }; - let res = verifier.add_bond(Uint128::from(200u32)); + let res = verifier.bond(Some(Uint128::from(200u32).try_into().unwrap())); assert!(res.is_ok()); assert_eq!( res.unwrap().bonding_state, BondingState::Bonded { - amount: Uint128::from(200u32) + amount: Uint128::from(200u32).try_into().unwrap() } ); } @@ -411,12 +409,28 @@ mod tests { service_name: "validators".to_string(), }; - let res = verifier.add_bond(Uint128::from(0u32)); + let res = verifier.bond(None); assert!(res.is_err()); - assert_eq!( - res.unwrap_err(), - ContractError::InvalidBondingState(bonding_state) - ); + assert_eq!(res.unwrap_err(), ContractError::NoFundsToBond); + } + #[test] + fn test_zero_bond_rebond() { + let amount = nonempty::Uint128::try_from(100u128).unwrap(); + let bonding_state = BondingState::Unbonding { + amount, + unbonded_at: Timestamp::from_nanos(0), + }; + + let verifier = Verifier { + address: Addr::unchecked("verifier"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = verifier.bond(None); + assert!(res.is_ok()); + assert_eq!(res.unwrap().bonding_state, BondingState::Bonded { amount }); } #[test] @@ -424,7 +438,7 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::Bonded { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), @@ -436,7 +450,7 @@ mod tests { assert_eq!( res.unwrap().bonding_state, BondingState::Unbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), unbonded_at } ); @@ -447,7 +461,7 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::Bonded { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), @@ -459,7 +473,7 @@ mod tests { assert_eq!( res.unwrap().bonding_state, BondingState::RequestedUnbonding { - amount: Uint128::from(100u32) + amount: Uint128::from(100u32).try_into().unwrap() } ); } @@ -469,7 +483,7 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), @@ -481,7 +495,7 @@ mod tests { assert_eq!( res.unwrap().bonding_state, BondingState::Unbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), unbonded_at } ); @@ -492,7 +506,7 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: "validators".to_string(), @@ -504,7 +518,7 @@ mod tests { assert_eq!( res.unwrap().bonding_state, BondingState::RequestedUnbonding { - amount: Uint128::from(100u32) + amount: Uint128::from(100u32).try_into().unwrap(), } ); } @@ -512,7 +526,7 @@ mod tests { #[test] fn test_unbonding_unbond() { let bonding_state = BondingState::Unbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), unbonded_at: Timestamp::from_nanos(0), }; @@ -567,7 +581,7 @@ mod tests { #[test] fn test_bonded_claim_stake() { let bonding_state = BondingState::Bonded { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }; let verifier = Verifier { address: Addr::unchecked("verifier"), @@ -594,7 +608,7 @@ mod tests { #[test] fn test_requested_unbonding_claim_stake() { let bonding_state = BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }; let verifier = Verifier { address: Addr::unchecked("verifier"), @@ -621,7 +635,7 @@ mod tests { #[test] fn test_unbonding_claim_stake() { let bonding_state = BondingState::Unbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), unbonded_at: Timestamp::from_nanos(0), }; let verifier = Verifier { @@ -644,7 +658,10 @@ mod tests { let (verifier, amount) = res.unwrap(); assert_eq!( (verifier.bonding_state, amount), - (BondingState::Unbonded, Uint128::from(100u32)) + ( + BondingState::Unbonded, + Uint128::from(100u32).try_into().unwrap() + ) ); } @@ -678,7 +695,7 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::Bonded { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), }, authorization_state: AuthorizationState::Jailed, service_name: "validators".to_string(), @@ -694,7 +711,7 @@ mod tests { let verifier = Verifier { address: Addr::unchecked("verifier"), bonding_state: BondingState::Unbonding { - amount: Uint128::from(100u32), + amount: Uint128::from(100u32).try_into().unwrap(), unbonded_at: Timestamp::from_nanos(0), }, authorization_state: AuthorizationState::Jailed, diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 89601f5fe..a7f8ccaab 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -163,7 +163,7 @@ mod test { verifiers.push(Verifier { address: Addr::unchecked(format!("addr{}", i)), bonding_state: BondingState::Bonded { - amount: Uint128::from(100u128), + amount: Uint128::from(100u128).try_into().unwrap(), }, authorization_state: AuthorizationState::Authorized, service_name: SERVICE_NAME.parse().unwrap(), diff --git a/integration-tests/tests/bond_unbond.rs b/integration-tests/tests/bond_unbond.rs index b3f27638d..257b39e35 100644 --- a/integration-tests/tests/bond_unbond.rs +++ b/integration-tests/tests/bond_unbond.rs @@ -71,7 +71,10 @@ fn claim_stake_after_rotation_success() { let after_balances = test_utils::query_balances(&protocol.app, &verifiers); for (before_balance, after_balance) in before_balances.into_iter().zip(after_balances) { - assert_eq!(after_balance, before_balance + min_verifier_bond); + assert_eq!( + after_balance, + before_balance + min_verifier_bond.into_inner() + ); } } diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index ace32837b..7f1676482 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -251,7 +251,7 @@ pub fn sign_proof( pub fn register_service( protocol: &mut Protocol, - min_verifier_bond: Uint128, + min_verifier_bond: nonempty::Uint128, unbonding_period_days: u16, ) { let response = protocol.service_registry.execute( @@ -424,7 +424,7 @@ pub struct Verifier { pub fn register_verifiers( protocol: &mut Protocol, verifiers: &Vec, - min_verifier_bond: Uint128, + min_verifier_bond: nonempty::Uint128, ) { register_in_service_registry(protocol, verifiers, min_verifier_bond); submit_pubkeys(protocol, verifiers); @@ -586,7 +586,7 @@ pub fn update_registry_and_construct_verifier_set_update_proof( verifiers_to_remove: &Vec, current_verifiers: &Vec, chain_multisig_prover: &MultisigProverContract, - min_verifier_bond: Uint128, + min_verifier_bond: nonempty::Uint128, ) -> Uint64 { // Register new verifiers register_verifiers(protocol, new_verifiers, min_verifier_bond); @@ -850,7 +850,7 @@ pub struct TestCase { pub chain1: Chain, pub chain2: Chain, pub verifiers: Vec, - pub min_verifier_bond: Uint128, + pub min_verifier_bond: nonempty::Uint128, pub unbonding_period_days: u16, } @@ -866,7 +866,7 @@ pub fn setup_test_case() -> TestCase { vec![("verifier1".to_string(), 0), ("verifier2".to_string(), 1)], ); - let min_verifier_bond = Uint128::new(100); + let min_verifier_bond = nonempty::Uint128::try_from(100).unwrap(); let unbonding_period_days = 10; register_service(&mut protocol, min_verifier_bond, unbonding_period_days); @@ -893,7 +893,7 @@ pub fn assert_contract_err_strings_equal( pub fn register_in_service_registry( protocol: &mut Protocol, verifiers: &Vec, - min_verifier_bond: Uint128, + min_verifier_bond: nonempty::Uint128, ) { let response = protocol.service_registry.execute( &mut protocol.app, @@ -912,7 +912,7 @@ pub fn register_in_service_registry( let response = protocol.app.send_tokens( protocol.genesis_address.clone(), verifier.addr.clone(), - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ); assert!(response.is_ok()); @@ -922,7 +922,7 @@ pub fn register_in_service_registry( &ExecuteMsg::BondVerifier { service_name: protocol.service_name.to_string(), }, - &coins(min_verifier_bond.u128(), AXL_DENOMINATION), + &coins(min_verifier_bond.into_inner().u128(), AXL_DENOMINATION), ); assert!(response.is_ok()); diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index f2e02b5db..05c32e53a 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -37,6 +37,7 @@ cw-storage-plus = { workspace = true } cw2 = { workspace = true } error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } +into-inner-derive = { workspace = true } itertools = { workspace = true } lazy_static = "1.4.0" num-traits = { workspace = true } diff --git a/packages/axelar-wasm-std/src/nonempty/string.rs b/packages/axelar-wasm-std/src/nonempty/string.rs index b891b3326..2de06f2ea 100644 --- a/packages/axelar-wasm-std/src/nonempty/string.rs +++ b/packages/axelar-wasm-std/src/nonempty/string.rs @@ -2,13 +2,14 @@ use std::ops::Deref; use std::str::FromStr; use cosmwasm_schema::cw_serde; +use into_inner_derive::IntoInner; use valuable::Valuable; use crate::nonempty::Error; #[cw_serde] #[serde(try_from = "std::string::String")] -#[derive(Eq, Hash, Valuable)] +#[derive(Eq, Hash, Valuable, IntoInner)] pub struct String(std::string::String); impl TryFrom for String { diff --git a/packages/axelar-wasm-std/src/nonempty/timestamp.rs b/packages/axelar-wasm-std/src/nonempty/timestamp.rs index 2b1ec1ce4..6a8f201ea 100644 --- a/packages/axelar-wasm-std/src/nonempty/timestamp.rs +++ b/packages/axelar-wasm-std/src/nonempty/timestamp.rs @@ -1,8 +1,10 @@ use cosmwasm_schema::cw_serde; +use into_inner_derive::IntoInner; use crate::nonempty::Error; #[cw_serde] +#[derive(IntoInner)] pub struct Timestamp(cosmwasm_std::Timestamp); impl TryFrom for Timestamp { diff --git a/packages/axelar-wasm-std/src/nonempty/uint.rs b/packages/axelar-wasm-std/src/nonempty/uint.rs index de9eba31a..3af6af52a 100644 --- a/packages/axelar-wasm-std/src/nonempty/uint.rs +++ b/packages/axelar-wasm-std/src/nonempty/uint.rs @@ -1,13 +1,14 @@ use std::fmt; use cosmwasm_schema::cw_serde; +use into_inner_derive::IntoInner; use crate::nonempty::Error; #[cw_serde] #[serde(try_from = "cosmwasm_std::Uint64")] #[serde(into = "cosmwasm_std::Uint64")] -#[derive(Copy, PartialOrd)] +#[derive(Copy, PartialOrd, IntoInner)] pub struct Uint64(cosmwasm_std::Uint64); impl TryFrom for Uint64 { @@ -50,7 +51,7 @@ impl fmt::Display for Uint64 { // TODO: consider using macro for these types #[cw_serde] -#[derive(Copy, PartialOrd, Eq)] +#[derive(Copy, PartialOrd, Eq, IntoInner)] pub struct Uint256(cosmwasm_std::Uint256); impl TryFrom for Uint256 { @@ -83,14 +84,8 @@ impl TryFrom for Uint256 { } } -impl AsRef for Uint256 { - fn as_ref(&self) -> &cosmwasm_std::Uint256 { - &self.0 - } -} - #[cw_serde] -#[derive(Copy, PartialOrd, Eq)] +#[derive(Copy, PartialOrd, Eq, IntoInner)] pub struct Uint128(cosmwasm_std::Uint128); impl TryFrom for Uint128 { @@ -192,13 +187,6 @@ mod tests { assert!(Uint256::try_from(cosmwasm_std::Uint128::one()).is_ok()); } - #[test] - fn convert_from_uint256_to_reference_cosmwasm_uint256() { - let val = Uint256(cosmwasm_std::Uint256::one()); - let converted: &cosmwasm_std::Uint256 = val.as_ref(); - assert_eq!(&val.0, converted); - } - #[test] fn convert_from_uint128_to_non_empty_uint128() { assert!(Uint128::try_from(0u128).is_err()); diff --git a/packages/into-inner-derive/Cargo.toml b/packages/into-inner-derive/Cargo.toml new file mode 100644 index 000000000..dc0cbb606 --- /dev/null +++ b/packages/into-inner-derive/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "into-inner-derive" +version = "1.0.0" +rust-version = { workspace = true } +edition = { workspace = true } +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +proc-macro = true + +[dependencies] +error-stack = { workspace = true } +quote = "1.0.33" +report = { workspace = true } +syn = "2.0.29" +thiserror = { workspace = true } + +[dev-dependencies] +axelar-wasm-std = { workspace = true } + +[lints] +workspace = true diff --git a/packages/into-inner-derive/release.toml b/packages/into-inner-derive/release.toml new file mode 100644 index 000000000..954564097 --- /dev/null +++ b/packages/into-inner-derive/release.toml @@ -0,0 +1 @@ +release = false diff --git a/packages/into-inner-derive/src/lib.rs b/packages/into-inner-derive/src/lib.rs new file mode 100644 index 000000000..6a108e74e --- /dev/null +++ b/packages/into-inner-derive/src/lib.rs @@ -0,0 +1,31 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{DeriveInput, Fields}; + +#[proc_macro_derive(IntoInner)] +pub fn into_inner_derive(input: TokenStream) -> TokenStream { + let ast: DeriveInput = syn::parse(input).unwrap(); + + let name = &ast.ident; + let ty = match ast.data { + syn::Data::Struct(val) => match val.fields { + Fields::Unnamed(fields) if fields.unnamed.len() == 1 => { + fields.unnamed.first().map(|field| field.ty.to_owned()) + } + _ => None, + }, + _ => None, + }; + + match ty { + Some(ty) => quote! { + impl #name { + pub fn into_inner(self) -> #ty { + self.0 + } + } + } + .into(), + None => panic!("only newtype structs are supported"), + } +} diff --git a/packages/into-inner-derive/tests/derive.rs b/packages/into-inner-derive/tests/derive.rs new file mode 100644 index 000000000..52e9f99d7 --- /dev/null +++ b/packages/into-inner-derive/tests/derive.rs @@ -0,0 +1,11 @@ +use into_inner_derive::IntoInner; + +#[derive(IntoInner)] +struct Test(u128); + +#[test] +fn can_into_inner() { + let expected_inner = 32; + let actual_inner = Test(expected_inner).into_inner(); + assert_eq!(actual_inner, expected_inner); +} From 347cd15e987c7637646311f1dd7fbf8b0cd6a773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rare=C8=99?= <6453351+raress96@users.noreply.github.com> Date: Fri, 23 Aug 2024 08:44:30 +0300 Subject: [PATCH 166/168] fix(ampd): fix nonce for multiversx being keccak256 hash instead of created at (#593) --- ampd/src/mvx/mod.rs | 2 +- ampd/src/mvx/verifier.rs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ampd/src/mvx/mod.rs b/ampd/src/mvx/mod.rs index 6bc2ad9c5..331b66aa9 100644 --- a/ampd/src/mvx/mod.rs +++ b/ampd/src/mvx/mod.rs @@ -60,7 +60,7 @@ impl From<&VerifierSet> for WeightedSigners { WeightedSigners { signers, threshold: uint256_to_compact_vec(verifier_set.threshold.into()), - nonce: Keccak256::digest(Uint256::from(verifier_set.created_at).to_be_bytes()).into(), + nonce: Uint256::from(verifier_set.created_at).to_be_bytes(), } } } diff --git a/ampd/src/mvx/verifier.rs b/ampd/src/mvx/verifier.rs index d158240fc..3b201471a 100644 --- a/ampd/src/mvx/verifier.rs +++ b/ampd/src/mvx/verifier.rs @@ -500,11 +500,12 @@ mod tests { .parse() .unwrap(); - let verifier_set_confirmation = VerifierSetConfirmation { + let mut verifier_set_confirmation = VerifierSetConfirmation { tx_id, event_index: 1, verifier_set: build_verifier_set(KeyType::Ed25519, &ed25519_test_data::signers()), }; + verifier_set_confirmation.verifier_set.created_at = 5; // 00000003 - length of new signers // 45e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f - first new signer @@ -514,11 +515,11 @@ mod tests { // dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b - third new signer // 00000001 01 - length of biguint weight followed by 1 as hex // 00000001 02 - length of biguint threshold followed by 2 as hex - // 290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 - the nonce (keccak256 hash of Uin256 number 0, created_at date) - let data = HexBinary::from_hex("0000000345e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f0000000101c387253d29085a8036d6ae2cafb1b14699751417c0ce302cfe03da279e6b5c040000000101dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b00000001010000000102290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") + // 0000000000000000000000000000000000000000000000000000000000000005 - the nonce (created_at date as uint256) + let data = HexBinary::from_hex("0000000345e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f0000000101c387253d29085a8036d6ae2cafb1b14699751417c0ce302cfe03da279e6b5c040000000101dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b000000010100000001020000000000000000000000000000000000000000000000000000000000000005") .unwrap(); let signers_hash = - HexBinary::from_hex("acc61d8597eaf76375dd9e34c50baab3c110d508ed4bd99c8d6000af503bf770") + HexBinary::from_hex("29f81aa379fa1f5973d05dd25e5ae4bc1afa2aa30156b1db5ec437a46ba4fd28") .unwrap(); let wrong_event = Events { From 490f6f21d39b7c4f2b7c54394cccb7fcdb503e05 Mon Sep 17 00:00:00 2001 From: Christian Gorenflo Date: Fri, 23 Aug 2024 17:59:23 -0400 Subject: [PATCH 167/168] fix(ampd): ensure that txs get confirmed when broadcast with an ampd subcommand (#597) --- ampd/src/asyncutil/future.rs | 117 ++++++------------ ampd/src/broadcaster/confirm_tx.rs | 139 ++++++++++++---------- ampd/src/commands/mod.rs | 63 ++++++++-- ampd/src/event_processor.rs | 19 +-- ampd/src/lib.rs | 28 +++-- contracts/multisig/src/contract.rs | 4 +- contracts/nexus-gateway/Cargo.toml | 3 + contracts/voting-verifier/src/contract.rs | 2 +- 8 files changed, 191 insertions(+), 184 deletions(-) diff --git a/ampd/src/asyncutil/future.rs b/ampd/src/asyncutil/future.rs index a90b4c4b4..645ff6b43 100644 --- a/ampd/src/asyncutil/future.rs +++ b/ampd/src/asyncutil/future.rs @@ -1,102 +1,53 @@ -use std::pin::Pin; -use std::task::{Context, Poll}; use std::time::Duration; -use futures::{Future, FutureExt}; +use futures::Future; use tokio::time; -pub fn with_retry( - future: F, - policy: RetryPolicy, -) -> impl Future> +pub async fn with_retry(mut future: F, policy: RetryPolicy) -> Result where - F: Fn() -> Fut, + F: FnMut() -> Fut, Fut: Future>, { - RetriableFuture::new(future, policy) -} - -pub enum RetryPolicy { - RepeatConstant { sleep: Duration, max_attempts: u64 }, -} - -struct RetriableFuture -where - F: Fn() -> Fut, - Fut: Future>, -{ - future: F, - inner: Pin>, - policy: RetryPolicy, - err_count: u64, -} - -impl Unpin for RetriableFuture -where - F: Fn() -> Fut, - Fut: Future>, -{ -} - -impl RetriableFuture -where - F: Fn() -> Fut, - Fut: Future>, -{ - fn new(get_future: F, policy: RetryPolicy) -> Self { - let future = get_future(); - - Self { - future: get_future, - inner: Box::pin(future), - policy, - err_count: 0, + let mut attempt_count = 0u64; + loop { + match future().await { + Ok(result) => return Ok(result), + Err(err) => { + attempt_count = attempt_count.saturating_add(1); + + match enact_policy(attempt_count, policy).await { + PolicyAction::Retry => continue, + PolicyAction::Abort => return Err(err), + } + } } } +} - fn handle_err( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - error: Err, - ) -> Poll> { - self.err_count = self.err_count.saturating_add(1); - - match self.policy { - RetryPolicy::RepeatConstant { - sleep, - max_attempts, - } => { - if self.err_count >= max_attempts { - return Poll::Ready(Err(error)); - } - - self.inner = Box::pin((self.future)()); - - let waker = cx.waker().clone(); - tokio::spawn(time::sleep(sleep).then(|_| async { - waker.wake(); - })); - - Poll::Pending +async fn enact_policy(attempt_count: u64, policy: RetryPolicy) -> PolicyAction { + match policy { + RetryPolicy::RepeatConstant { + sleep, + max_attempts, + } => { + if attempt_count >= max_attempts { + PolicyAction::Abort + } else { + time::sleep(sleep).await; + PolicyAction::Retry } } } } -impl Future for RetriableFuture -where - F: Fn() -> Fut, - Fut: Future>, -{ - type Output = Result; +enum PolicyAction { + Retry, + Abort, +} - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - match self.inner.as_mut().poll(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(Ok(result)) => Poll::Ready(Ok(result)), - Poll::Ready(Err(error)) => self.handle_err(cx, error), - } - } +#[derive(Copy, Clone)] +pub enum RetryPolicy { + RepeatConstant { sleep: Duration, max_attempts: u64 }, } #[cfg(test)] diff --git a/ampd/src/broadcaster/confirm_tx.rs b/ampd/src/broadcaster/confirm_tx.rs index 7499af9e3..a0d0c8fdc 100644 --- a/ampd/src/broadcaster/confirm_tx.rs +++ b/ampd/src/broadcaster/confirm_tx.rs @@ -1,17 +1,17 @@ -use std::time::Duration; +use std::sync::Arc; use axelar_wasm_std::FnExt; use cosmrs::proto::cosmos::tx::v1beta1::{GetTxRequest, GetTxResponse}; -use error_stack::{report, Report, Result}; +use error_stack::{bail, Report, Result}; use futures::{StreamExt, TryFutureExt}; use thiserror::Error; use tokio::sync::{mpsc, Mutex}; -use tokio::time; use tokio_stream::wrappers::ReceiverStream; use tonic::Status; use tracing::error; use super::cosmos; +use crate::asyncutil::future::{with_retry, RetryPolicy}; #[derive(Debug, PartialEq)] pub enum TxStatus { @@ -53,19 +53,12 @@ pub enum Error { SendTxRes(#[from] Box>), } -enum ConfirmationResult { - Confirmed(Box), - NotFound, - GRPCError(Status), -} - pub struct TxConfirmer where T: cosmos::BroadcastClient, { client: T, - sleep: Duration, - max_attempts: u32, + retry_policy: RetryPolicy, tx_hash_receiver: mpsc::Receiver, tx_res_sender: mpsc::Sender, } @@ -76,15 +69,13 @@ where { pub fn new( client: T, - sleep: Duration, - max_attempts: u32, + retry_policy: RetryPolicy, tx_hash_receiver: mpsc::Receiver, tx_res_sender: mpsc::Sender, ) -> Self { Self { client, - sleep, - max_attempts, + retry_policy, tx_hash_receiver, tx_res_sender, } @@ -93,23 +84,19 @@ where pub async fn run(self) -> Result<(), Error> { let Self { client, - sleep, - max_attempts, + retry_policy, tx_hash_receiver, tx_res_sender, } = self; let limit = tx_hash_receiver.capacity(); - let client = Mutex::new(client); + let client = Arc::new(Mutex::new(client)); + let mut tx_hash_stream = ReceiverStream::new(tx_hash_receiver) .map(|tx_hash| { - confirm_tx(&client, tx_hash, sleep, max_attempts).and_then(|tx| async { - tx_res_sender - .send(tx) - .await - .map_err(Box::new) - .map_err(Into::into) - .map_err(Report::new) - }) + // multiple instances of confirm_tx can be spawned due to buffer_unordered, + // so we need to clone the client to avoid a deadlock + confirm_tx_with_retry(client.clone(), tx_hash, retry_policy) + .and_then(|tx| async { send_response(&tx_res_sender, tx).await }) }) .buffer_unordered(limit); @@ -121,50 +108,63 @@ where } } -async fn confirm_tx( - client: &Mutex, +async fn confirm_tx_with_retry( + client: Arc>, tx_hash: String, - sleep: Duration, - attempts: u32, -) -> Result -where - T: cosmos::BroadcastClient, -{ - for i in 0..attempts { - let req = GetTxRequest { - hash: tx_hash.clone(), - }; - - match client.lock().await.tx(req).await.then(evaluate_tx_response) { - ConfirmationResult::Confirmed(tx) => return Ok(*tx), - ConfirmationResult::NotFound if i == attempts.saturating_sub(1) => { - return Err(report!(Error::Confirmation { tx_hash })) - } - ConfirmationResult::GRPCError(status) if i == attempts.saturating_sub(1) => { - return Err(report!(Error::Grpc { status, tx_hash })) - } - _ => time::sleep(sleep).await, - } - } + retry_policy: RetryPolicy, +) -> Result { + with_retry(|| confirm_tx(client.clone(), tx_hash.clone()), retry_policy).await +} - unreachable!("confirmation loop should have returned by now") +// do to limitations of lambdas and lifetime issues this needs to be a separate function +async fn confirm_tx( + client: Arc>, + tx_hash: String, +) -> Result { + let req = GetTxRequest { + hash: tx_hash.clone(), + }; + + client + .lock() + .await + .tx(req) + .await + .then(evaluate_tx_response(tx_hash)) } fn evaluate_tx_response( - response: core::result::Result, -) -> ConfirmationResult { - match response { - Err(status) => ConfirmationResult::GRPCError(status), + tx_hash: String, +) -> impl Fn(core::result::Result) -> Result { + move |response| match response { + Err(status) => bail!(Error::Grpc { + status, + tx_hash: tx_hash.clone() + }), Ok(GetTxResponse { tx_response: None, .. - }) => ConfirmationResult::NotFound, + }) => bail!(Error::Confirmation { + tx_hash: tx_hash.clone() + }), Ok(GetTxResponse { tx_response: Some(response), .. - }) => ConfirmationResult::Confirmed(Box::new(response.into())), + }) => Ok(response.into()), } } +async fn send_response( + tx_res_sender: &mpsc::Sender, + tx: TxResponse, +) -> Result<(), Error> { + tx_res_sender + .send(tx) + .await + .map_err(Box::new) + .map_err(Into::into) + .map_err(Report::new) +} + #[cfg(test)] mod test { use std::time::Duration; @@ -175,6 +175,7 @@ mod test { use tokio::test; use super::{Error, TxConfirmer, TxResponse, TxStatus}; + use crate::asyncutil::future::RetryPolicy; use crate::broadcaster::cosmos::MockBroadcastClient; #[test] @@ -205,8 +206,10 @@ mod test { let tx_confirmer = TxConfirmer::new( client, - sleep, - max_attempts, + RetryPolicy::RepeatConstant { + sleep, + max_attempts, + }, tx_confirmer_receiver, tx_res_sender, ); @@ -252,8 +255,10 @@ mod test { let tx_confirmer = TxConfirmer::new( client, - sleep, - max_attempts, + RetryPolicy::RepeatConstant { + sleep, + max_attempts, + }, tx_confirmer_receiver, tx_res_sender, ); @@ -291,8 +296,10 @@ mod test { let tx_confirmer = TxConfirmer::new( client, - sleep, - max_attempts, + RetryPolicy::RepeatConstant { + sleep, + max_attempts, + }, tx_confirmer_receiver, tx_res_sender, ); @@ -330,8 +337,10 @@ mod test { let tx_confirmer = TxConfirmer::new( client, - sleep, - max_attempts, + RetryPolicy::RepeatConstant { + sleep, + max_attempts, + }, tx_confirmer_receiver, tx_res_sender, ); diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index 3ed6b3276..257946ded 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -5,12 +5,15 @@ use cosmrs::proto::cosmos::base::abci::v1beta1::TxResponse; use cosmrs::proto::cosmos::tx::v1beta1::service_client::ServiceClient; use cosmrs::proto::Any; use cosmrs::AccountId; -use error_stack::{Result, ResultExt}; +use error_stack::{report, FutureExt, Result, ResultExt}; +use futures::TryFutureExt; use serde::{Deserialize, Serialize}; +use tokio::sync::mpsc::{Receiver, Sender}; use valuable::Valuable; +use crate::asyncutil::future::RetryPolicy; use crate::broadcaster::Broadcaster; -use crate::config::Config as AmpdConfig; +use crate::config::{Config as AmpdConfig, Config}; use crate::tofnd::grpc::{Multisig, MultisigClient}; use crate::types::{PublicKey, TMAddress}; use crate::{broadcaster, tofnd, Error, PREFIX}; @@ -75,13 +78,46 @@ async fn broadcast_tx( tx: Any, pub_key: PublicKey, ) -> Result { + let (confirmation_sender, mut confirmation_receiver) = tokio::sync::mpsc::channel(1); + let (hash_to_confirm_sender, hash_to_confirm_receiver) = tokio::sync::mpsc::channel(1); + + let mut broadcaster = instantiate_broadcaster( + config, + pub_key, + hash_to_confirm_receiver, + confirmation_sender, + ) + .await?; + + broadcaster + .broadcast(vec![tx]) + .change_context(Error::Broadcaster) + .and_then(|response| { + hash_to_confirm_sender + .send(response.txhash) + .change_context(Error::Broadcaster) + }) + .await?; + + confirmation_receiver + .recv() + .await + .ok_or(report!(Error::TxConfirmation)) + .map(|tx| tx.response) +} + +async fn instantiate_broadcaster( + config: Config, + pub_key: PublicKey, + tx_hashes_to_confirm: Receiver, + confirmed_txs: Sender, +) -> Result { let AmpdConfig { tm_grpc, broadcast, tofnd_config, .. } = config; - let service_client = ServiceClient::connect(tm_grpc.to_string()) .await .change_context(Error::Connection) @@ -99,7 +135,20 @@ async fn broadcast_tx( .change_context(Error::Connection) .attach_printable(tofnd_config.url)?; - broadcaster::UnvalidatedBasicBroadcaster::builder() + broadcaster::confirm_tx::TxConfirmer::new( + service_client.clone(), + RetryPolicy::RepeatConstant { + sleep: broadcast.tx_fetch_interval, + max_attempts: broadcast.tx_fetch_max_retries.saturating_add(1).into(), + }, + tx_hashes_to_confirm, + confirmed_txs, + ) + .run() + .await + .change_context(Error::TxConfirmation)?; + + let basic_broadcaster = broadcaster::UnvalidatedBasicBroadcaster::builder() .client(service_client) .signer(multisig_client) .auth_query_client(auth_query_client) @@ -110,8 +159,6 @@ async fn broadcast_tx( .build() .validate_fee_denomination() .await - .change_context(Error::Broadcaster)? - .broadcast(vec![tx]) - .await - .change_context(Error::Broadcaster) + .change_context(Error::Broadcaster)?; + Ok(basic_broadcaster) } diff --git a/ampd/src/event_processor.rs b/ampd/src/event_processor.rs index 204b0c64f..c0d3e3437 100644 --- a/ampd/src/event_processor.rs +++ b/ampd/src/event_processor.rs @@ -86,8 +86,10 @@ where &handler, &broadcaster, event, - event_processor_config.retry_delay, - event_processor_config.retry_max_attempts, + RetryPolicy::RepeatConstant { + sleep: event_processor_config.retry_delay, + max_attempts: event_processor_config.retry_max_attempts, + }, ) .await?; } @@ -110,23 +112,14 @@ async fn handle_event( handler: &H, broadcaster: &B, event: &Event, - handle_sleep_duration: Duration, - handle_max_attempts: u64, + retry_policy: RetryPolicy, ) -> Result<(), Error> where H: EventHandler, B: BroadcasterClient, { // if handlers run into errors we log them and then move on to the next event - match future::with_retry( - || handler.handle(event), - RetryPolicy::RepeatConstant { - sleep: handle_sleep_duration, - max_attempts: handle_max_attempts, - }, - ) - .await - { + match future::with_retry(|| handler.handle(event), retry_policy).await { Ok(msgs) => { for msg in msgs { broadcaster diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index e409a658c..89ca29a83 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -2,7 +2,6 @@ use std::time::Duration; use asyncutil::task::{CancellableTask, TaskError, TaskGroup}; use block_height_monitor::BlockHeightMonitor; -use broadcaster::confirm_tx::TxConfirmer; use broadcaster::Broadcaster; use cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient as AuthQueryClient; use cosmrs::proto::cosmos::bank::v1beta1::query_client::QueryClient as BankQueryClient; @@ -49,6 +48,9 @@ mod url; pub use grpc::{client, proto}; +use crate::asyncutil::future::RetryPolicy; +use crate::broadcaster::confirm_tx::TxConfirmer; + const PREFIX: &str = "axelar"; const DEFAULT_RPC_TIMEOUT: Duration = Duration::from_secs(3); @@ -183,8 +185,8 @@ where let (event_publisher, event_subscriber) = event_sub::EventPublisher::new(tm_client, event_buffer_cap); - let (tx_confirmer_sender, tx_confirmer_receiver) = mpsc::channel(1000); - let (tx_res_sender, tx_res_receiver) = mpsc::channel(1000); + let (tx_hash_sender, tx_hash_receiver) = mpsc::channel(1000); + let (tx_response_sender, tx_response_receiver) = mpsc::channel(1000); let event_processor = TaskGroup::new(); let broadcaster = QueuedBroadcaster::new( @@ -192,15 +194,17 @@ where broadcast_cfg.batch_gas_limit, broadcast_cfg.queue_cap, interval(broadcast_cfg.broadcast_interval), - tx_confirmer_sender, - tx_res_receiver, + tx_hash_sender, + tx_response_receiver, ); let tx_confirmer = TxConfirmer::new( service_client, - broadcast_cfg.tx_fetch_interval, - broadcast_cfg.tx_fetch_max_retries.saturating_add(1), - tx_confirmer_receiver, - tx_res_sender, + RetryPolicy::RepeatConstant { + sleep: broadcast_cfg.tx_fetch_interval, + max_attempts: broadcast_cfg.tx_fetch_max_retries.saturating_add(1).into(), + }, + tx_hash_receiver, + tx_response_sender, ); Self { @@ -443,7 +447,7 @@ where .change_context(Error::EventProcessor) })) .add_task(CancellableTask::create(|_| { - tx_confirmer.run().change_context(Error::TxConfirmer) + tx_confirmer.run().change_context(Error::TxConfirmation) })) .add_task(CancellableTask::create(|_| { broadcaster.run().change_context(Error::Broadcaster) @@ -461,8 +465,8 @@ pub enum Error { EventProcessor, #[error("broadcaster failed")] Broadcaster, - #[error("tx confirmer failed")] - TxConfirmer, + #[error("tx confirmation failed")] + TxConfirmation, #[error("tofnd failed")] Tofnd, #[error("connection failed")] diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 7ef4af54c..b30683d52 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -857,7 +857,7 @@ mod tests { let res = query(deps.as_ref(), mock_env(), msg); assert!(res.is_ok()); - let query_res: Multisig = from_json(&res.unwrap()).unwrap(); + let query_res: Multisig = from_json(res.unwrap()).unwrap(); let session = SIGNING_SESSIONS .load(deps.as_ref().storage, session_id.into()) .unwrap(); @@ -939,7 +939,7 @@ mod tests { for (addr, _, _) in &expected_pub_keys { let res = query_registered_public_key(deps.as_ref(), addr.clone(), key_type); assert!(res.is_ok()); - ret_pub_keys.push(from_json(&res.unwrap()).unwrap()); + ret_pub_keys.push(from_json(res.unwrap()).unwrap()); } assert_eq!( expected_pub_keys diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index 04ca59083..2e7d7ca53 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -12,6 +12,9 @@ crate-type = ["cdylib", "rlib"] name = "nexus-gateway-schema" path = "src/bin/schema.rs" +[features] +library = [] + [dependencies] axelar-wasm-std = { workspace = true, features = ["derive"] } cosmwasm-schema = { workspace = true } diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index a7f8ccaab..805b4f423 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -764,7 +764,7 @@ mod test { // check status corresponds to votes let statuses: Vec = from_json( - &query( + query( deps.as_ref(), mock_env(), QueryMsg::MessagesStatus(messages.clone()), From 8308c8d18276e3538987a98674fc6ffab2fecb7d Mon Sep 17 00:00:00 2001 From: Sammy Date: Wed, 28 Aug 2024 14:50:39 -0400 Subject: [PATCH 168/168] feat(nexus-gateway)!: call contract with token (#599) --- Cargo.lock | 3 + contracts/axelarnet-gateway/src/client.rs | 42 +++++- contracts/axelarnet-gateway/src/contract.rs | 1 + .../axelarnet-gateway/src/contract/execute.rs | 2 +- contracts/axelarnet-gateway/src/lib.rs | 2 +- contracts/axelarnet-gateway/src/msg.rs | 4 + contracts/nexus-gateway/Cargo.toml | 3 + contracts/nexus-gateway/src/contract.rs | 122 ++++++++++++++++-- .../nexus-gateway/src/contract/execute.rs | 76 +++++++++-- contracts/nexus-gateway/src/error.rs | 10 +- contracts/nexus-gateway/src/msg.rs | 13 ++ contracts/nexus-gateway/src/nexus.rs | 5 +- contracts/nexus-gateway/src/state.rs | 1 + 13 files changed, 249 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd3e9a85a..fc55f41ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5214,6 +5214,8 @@ name = "nexus-gateway" version = "1.0.0" dependencies = [ "axelar-wasm-std", + "axelarnet-gateway", + "client", "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", @@ -5226,6 +5228,7 @@ dependencies = [ "router-api", "schemars", "serde", + "sha3", "thiserror", "voting-verifier", ] diff --git a/contracts/axelarnet-gateway/src/client.rs b/contracts/axelarnet-gateway/src/client.rs index 558078971..29ea04f8e 100644 --- a/contracts/axelarnet-gateway/src/client.rs +++ b/contracts/axelarnet-gateway/src/client.rs @@ -1,9 +1,16 @@ use axelar_wasm_std::vec::VecExt; -use cosmwasm_std::{HexBinary, WasmMsg}; +use cosmwasm_std::{Addr, HexBinary, WasmMsg}; +use error_stack::{Result, ResultExt}; use router_api::{Address, ChainName, CrossChainId, Message}; use crate::msg::{ExecuteMsg, QueryMsg}; +#[derive(thiserror::Error, Debug, PartialEq)] +pub enum Error { + #[error("failed to query the chain name at gateway contract {0}")] + QueryChainName(Addr), +} + impl<'a> From> for Client<'a> { fn from(client: client::Client<'a, ExecuteMsg, QueryMsg>) -> Self { Client { client } @@ -36,17 +43,37 @@ impl<'a> Client<'a> { msgs.to_none_if_empty() .map(|messages| self.client.execute(&ExecuteMsg::RouteMessages(messages))) } + + pub fn chain_name(&self) -> Result { + self.client + .query(&QueryMsg::ChainName) + .change_context_lazy(|| Error::QueryChainName(self.client.address.clone())) + } } #[cfg(test)] mod test { + use std::str::FromStr; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier}; - use cosmwasm_std::{to_json_binary, Addr, DepsMut, QuerierWrapper}; + use cosmwasm_std::{from_json, to_json_binary, Addr, DepsMut, QuerierWrapper, WasmQuery}; use super::*; - use crate::contract::instantiate; + use crate::contract::{instantiate, query}; use crate::msg::InstantiateMsg; + #[test] + fn chain_name() { + let (querier, _, addr) = setup(); + let client: Client = + client::Client::new(QuerierWrapper::new(&querier), addr.clone()).into(); + + assert_eq!( + client.chain_name().unwrap(), + ChainName::from_str("source-chain").unwrap() + ); + } + #[test] fn call_contract() { let (querier, _, addr) = setup(); @@ -104,7 +131,14 @@ mod test { let mut deps = mock_dependencies(); let instantiate_msg = instantiate_contract(deps.as_mut()); - let querier = MockQuerier::default(); + let mut querier = MockQuerier::default(); + querier.update_wasm(move |msg| match msg { + WasmQuery::Smart { contract_addr, msg } if contract_addr == addr => { + let msg = from_json::(msg).unwrap(); + Ok(query(deps.as_ref(), mock_env(), msg).into()).into() + } + _ => panic!("unexpected query: {:?}", msg), + }); (querier, instantiate_msg, Addr::unchecked(addr)) } diff --git a/contracts/axelarnet-gateway/src/contract.rs b/contracts/axelarnet-gateway/src/contract.rs index 3c2fabf32..a0655f142 100644 --- a/contracts/axelarnet-gateway/src/contract.rs +++ b/contracts/axelarnet-gateway/src/contract.rs @@ -136,6 +136,7 @@ pub fn query( QueryMsg::ReceivedMessages { cc_ids } => { to_json_binary(&query::received_messages(deps, cc_ids)?) } + QueryMsg::ChainName => to_json_binary(&state::load_config(deps.storage)?.chain_name), } .map_err(axelar_wasm_std::error::ContractError::from) } diff --git a/contracts/axelarnet-gateway/src/contract/execute.rs b/contracts/axelarnet-gateway/src/contract/execute.rs index a8d09f3ab..dca3271ce 100644 --- a/contracts/axelarnet-gateway/src/contract/execute.rs +++ b/contracts/axelarnet-gateway/src/contract/execute.rs @@ -41,7 +41,7 @@ pub fn call_contract( let msg = Message { cc_id: cc_id.clone(), - source_address: Address::try_from(sender.clone().into_string()) + source_address: Address::try_from(sender.into_string()) .expect("failed to convert sender address"), destination_chain, destination_address, diff --git a/contracts/axelarnet-gateway/src/lib.rs b/contracts/axelarnet-gateway/src/lib.rs index 8b165d551..c089ff750 100644 --- a/contracts/axelarnet-gateway/src/lib.rs +++ b/contracts/axelarnet-gateway/src/lib.rs @@ -4,7 +4,7 @@ pub mod msg; mod state; mod client; -pub use client::Client; +pub use client::{Client, Error}; mod executable; pub use executable::AxelarExecutableMsg; diff --git a/contracts/axelarnet-gateway/src/msg.rs b/contracts/axelarnet-gateway/src/msg.rs index a28ef14e6..f5a55820f 100644 --- a/contracts/axelarnet-gateway/src/msg.rs +++ b/contracts/axelarnet-gateway/src/msg.rs @@ -50,4 +50,8 @@ pub enum QueryMsg { /// Returns the received messages with their status for the given cross-chain ids. #[returns(Vec)] ReceivedMessages { cc_ids: Vec }, + + /// Returns the chain name for this gateway. + #[returns(ChainName)] + ChainName, } diff --git a/contracts/nexus-gateway/Cargo.toml b/contracts/nexus-gateway/Cargo.toml index 2e7d7ca53..409087cce 100644 --- a/contracts/nexus-gateway/Cargo.toml +++ b/contracts/nexus-gateway/Cargo.toml @@ -17,6 +17,8 @@ library = [] [dependencies] axelar-wasm-std = { workspace = true, features = ["derive"] } +axelarnet-gateway = { workspace = true, features = ["library"] } +client = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } @@ -29,6 +31,7 @@ report = { workspace = true } router-api = { workspace = true } schemars = "0.8.15" serde = { version = "1.0.188", features = ["derive"] } +sha3 = { workspace = true } thiserror = { workspace = true } voting-verifier = { workspace = true, features = ["library"] } diff --git a/contracts/nexus-gateway/src/contract.rs b/contracts/nexus-gateway/src/contract.rs index 5ca6537d1..0fbf6d312 100644 --- a/contracts/nexus-gateway/src/contract.rs +++ b/contracts/nexus-gateway/src/contract.rs @@ -2,9 +2,9 @@ use axelar_wasm_std::address; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Addr, DepsMut, Empty, Env, MessageInfo, Response, Storage}; -use error_stack::{Report, ResultExt}; +use error_stack::Report; -use crate::contract::execute::{route_to_nexus, route_to_router}; +use crate::contract::execute::{call_contract_with_token, route_to_nexus, route_to_router}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg}; use crate::state::Config; @@ -39,8 +39,17 @@ pub fn instantiate( let nexus = address::validate_cosmwasm_address(deps.api, &msg.nexus)?; let router = address::validate_cosmwasm_address(deps.api, &msg.router)?; - - state::save_config(deps.storage, Config { nexus, router }).expect("config must be saved"); + let axelar_gateway = address::validate_cosmwasm_address(deps.api, &msg.axelar_gateway)?; + + state::save_config( + deps.storage, + Config { + nexus, + router, + axelar_gateway, + }, + ) + .expect("config must be saved"); Ok(Response::default()) } @@ -48,17 +57,25 @@ pub fn instantiate( #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, - _env: Env, + _: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result, axelar_wasm_std::error::ContractError> { let res = match msg.ensure_permissions(deps.storage, &info.sender, match_router, match_nexus)? { - ExecuteMsg::RouteMessages(msgs) => { - route_to_nexus(deps.storage, msgs).change_context(ContractError::RouteToNexus)? - } - ExecuteMsg::RouteMessagesFromNexus(msgs) => { - route_to_router(deps.storage, msgs).change_context(ContractError::RouteToRouter)? - } + ExecuteMsg::CallContractWithToken { + destination_chain, + destination_address, + payload, + } => call_contract_with_token( + deps.storage, + deps.querier, + info, + destination_chain, + destination_address, + payload, + )?, + ExecuteMsg::RouteMessages(msgs) => route_to_nexus(deps.storage, msgs)?, + ExecuteMsg::RouteMessagesFromNexus(msgs) => route_to_router(deps.storage, msgs)?, }; Ok(res) @@ -77,7 +94,10 @@ mod tests { use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::{err_contains, permission_control}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_json, Addr, CosmosMsg, WasmMsg}; + use cosmwasm_std::{ + from_json, to_json_binary, Addr, BankMsg, Coin, CosmosMsg, QuerierResult, SubMsg, WasmMsg, + WasmQuery, + }; use hex::decode; use router_api::CrossChainId; @@ -85,6 +105,7 @@ mod tests { const NEXUS: &str = "nexus"; const ROUTER: &str = "router"; + const AXELAR_GATEWAY: &str = "axelar_gateway"; #[test] fn migrate_sets_contract_version() { @@ -97,6 +118,80 @@ mod tests { assert_eq!(contract_version.version, CONTRACT_VERSION); } + #[test] + fn call_contract_with_token_no_token() { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(NEXUS, &[]), + ExecuteMsg::CallContractWithToken { + destination_chain: "destinationChain".parse().unwrap(), + destination_address: "0xD419".parse().unwrap(), + payload: decode("bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1") + .unwrap() + .into(), + }, + ); + assert!(res.is_err_and(|err| err_contains!( + err.report, + ContractError, + ContractError::InvalidToken { .. } + ))); + } + + #[test] + fn call_contract_with_token() { + let mut deps = mock_dependencies(); + deps.querier.update_wasm(move |msg| match msg { + WasmQuery::Smart { contract_addr, msg } if contract_addr == AXELAR_GATEWAY => { + let msg = from_json::(msg).unwrap(); + + match msg { + axelarnet_gateway::msg::QueryMsg::ChainName => { + QuerierResult::Ok(to_json_binary("axelarnet").into()) + } + _ => panic!("unexpected query: {:?}", msg), + } + } + _ => panic!("unexpected query: {:?}", msg), + }); + instantiate_contract(deps.as_mut()); + + let token = Coin { + denom: "denom".to_string(), + amount: 100u128.into(), + }; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(NEXUS, &[token.clone()]), + ExecuteMsg::CallContractWithToken { + destination_chain: "destinationChain".parse().unwrap(), + destination_address: "0xD419".parse().unwrap(), + payload: decode("bb9b5566c2f4876863333e481f4698350154259ffe6226e283b16ce18a64bcf1") + .unwrap() + .into(), + }, + ); + assert!(res.is_ok_and(move |res| match res.messages.as_slice() { + [SubMsg { + msg: CosmosMsg::Bank(BankMsg::Send { to_address, amount }), + .. + }, SubMsg { + msg: + CosmosMsg::Custom(nexus::Message { + token: Some(actual_token), + .. + }), + .. + }] => *actual_token == token && to_address == NEXUS && *amount == vec![token], + _ => false, + })); + } + #[test] fn route_to_router_unauthorized() { let mut deps = mock_dependencies(); @@ -252,6 +347,7 @@ mod tests { source_tx_id: msg_ids[0].tx_hash.to_vec().try_into().unwrap(), source_tx_index: msg_ids[0].event_index as u64, id: msg_ids[0].to_string(), + token: None, }, nexus::Message { source_chain: "sourceChain".parse().unwrap(), @@ -267,6 +363,7 @@ mod tests { source_tx_id: msg_ids[1].tx_hash.to_vec().try_into().unwrap(), source_tx_index: msg_ids[1].event_index as u64, id: msg_ids[1].to_string(), + token: None, }, ]; msgs @@ -316,6 +413,7 @@ mod tests { InstantiateMsg { nexus: NEXUS.to_string(), router: ROUTER.to_string(), + axelar_gateway: AXELAR_GATEWAY.to_string(), }, ) .unwrap(); diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index 523b830f1..71374ca8a 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -1,10 +1,69 @@ -use cosmwasm_std::{to_json_binary, Response, Storage, WasmMsg}; +use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; +use axelar_wasm_std::nonempty; +use cosmwasm_std::{BankMsg, HexBinary, MessageInfo, QuerierWrapper, Response, Storage}; +use error_stack::{bail, ResultExt}; +use router_api::{Address, ChainName}; +use sha3::{Digest, Keccak256}; use crate::error::ContractError; +use crate::state::load_config; use crate::{nexus, state}; type Result = error_stack::Result; +pub fn call_contract_with_token( + storage: &mut dyn Storage, + querier: QuerierWrapper, + info: MessageInfo, + destination_chain: ChainName, + destination_address: Address, + payload: HexBinary, +) -> Result> { + let config = load_config(storage)?; + let axelarnet_gateway: axelarnet_gateway::Client = + client::Client::new(querier, config.axelar_gateway).into(); + let source_address: Address = info + .sender + .into_string() + .parse() + .expect("invalid sender address"); + let token = match info.funds.as_slice() { + [token] => token.clone(), + _ => bail!(ContractError::InvalidToken(info.funds)), + }; + // TODO: Retrieve the actual tx hash and event index from core, since cosmwasm doesn't provide it. Use the all zeros as the placeholder in the meantime. + let tx_hash = [0; 32]; + let event_index = 0u32; + let id = HexTxHashAndEventIndex::new(tx_hash, event_index); + + // send the token to the nexus module account + let bank_transfer_msg = BankMsg::Send { + to_address: config.nexus.to_string(), + amount: vec![token.clone()], + }; + let msg = nexus::Message { + source_chain: axelarnet_gateway + .chain_name() + .change_context(ContractError::AxelarnetGateway)? + .into(), + source_address, + destination_chain, + destination_address, + payload_hash: Keccak256::digest(payload.as_slice()).into(), + source_tx_id: tx_hash + .to_vec() + .try_into() + .expect("tx hash must not be empty"), + source_tx_index: event_index.into(), + id: nonempty::String::from(id).into(), + token: Some(token), + }; + + Ok(Response::new() + .add_message(bank_transfer_msg) + .add_message(msg)) +} + pub fn route_to_router( storage: &dyn Storage, msgs: Vec, @@ -13,16 +72,11 @@ pub fn route_to_router( .into_iter() .map(router_api::Message::try_from) .collect::>>()?; - if msgs.is_empty() { - return Ok(Response::default()); - } - - Ok(Response::new().add_message(WasmMsg::Execute { - contract_addr: state::load_config(storage)?.router.to_string(), - msg: to_json_binary(&router_api::msg::ExecuteMsg::RouteMessages(msgs)) - .expect("must serialize route-messages message"), - funds: vec![], - })) + let router = router_api::client::Router { + address: state::load_config(storage)?.router, + }; + + Ok(Response::new().add_messages(router.route(msgs))) } pub fn route_to_nexus( diff --git a/contracts/nexus-gateway/src/error.rs b/contracts/nexus-gateway/src/error.rs index 44d26d157..18a9fed2f 100644 --- a/contracts/nexus-gateway/src/error.rs +++ b/contracts/nexus-gateway/src/error.rs @@ -1,5 +1,5 @@ use axelar_wasm_std::IntoContractError; -use cosmwasm_std::HexBinary; +use cosmwasm_std::{Coin, HexBinary}; use thiserror::Error; #[derive(Error, Debug, PartialEq, IntoContractError)] @@ -19,9 +19,9 @@ pub enum ContractError { #[error("invalid payload hash {0}")] InvalidMessagePayloadHash(HexBinary), - #[error("failed routing messages to the nexus module")] - RouteToNexus, + #[error("invalid token: one and only one token is required for this operation, got {0:?}")] + InvalidToken(Vec), - #[error("failed routing messages to the router")] - RouteToRouter, + #[error("failed querying the axelarnet gateway")] + AxelarnetGateway, } diff --git a/contracts/nexus-gateway/src/msg.rs b/contracts/nexus-gateway/src/msg.rs index a95cc7f46..0cfbf3e16 100644 --- a/contracts/nexus-gateway/src/msg.rs +++ b/contracts/nexus-gateway/src/msg.rs @@ -1,5 +1,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::HexBinary; use msgs_derive::EnsurePermissions; +use router_api::{Address, ChainName}; use crate::nexus; @@ -7,11 +9,22 @@ use crate::nexus; pub struct InstantiateMsg { pub nexus: String, pub router: String, + pub axelar_gateway: String, } #[cw_serde] #[derive(EnsurePermissions)] pub enum ExecuteMsg { + /// Initiate a cross-chain contract call with token from Axelarnet to another chain. + /// Note: This only works when the destination chain is a legacy chain. + #[permission(Any)] + CallContractWithToken { + destination_chain: ChainName, + destination_address: Address, + payload: HexBinary, + }, + /// Route a cross-chain message from Axelarnet to another chain. + /// Note: This only works when the destination chain is a legacy chain. #[permission(Specific(router))] RouteMessages(Vec), #[permission(Specific(nexus))] diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 32f509f8e..9e6e227a0 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use axelar_wasm_std::msg_id::HexTxHashAndEventIndex; use axelar_wasm_std::nonempty; -use cosmwasm_std::{CosmosMsg, CustomMsg}; +use cosmwasm_std::{Coin, CosmosMsg, CustomMsg}; use error_stack::{Report, Result, ResultExt}; use router_api::{Address, ChainName, ChainNameRaw, CrossChainId}; use schemars::JsonSchema; @@ -22,6 +22,7 @@ pub struct Message { pub source_tx_id: nonempty::Vec, pub source_tx_index: u64, pub id: String, + pub token: Option, } impl CustomMsg for Message {} @@ -52,6 +53,7 @@ impl From for Message { source_tx_id, source_tx_index, id: msg.cc_id.message_id.into(), + token: None, } } } @@ -104,6 +106,7 @@ mod test { source_tx_id: msg_id.tx_hash.to_vec().try_into().unwrap(), source_tx_index: msg_id.event_index as u64, id: msg_id.to_string(), + token: None, }; let router_msg = router_api::Message::try_from(msg.clone()); diff --git a/contracts/nexus-gateway/src/state.rs b/contracts/nexus-gateway/src/state.rs index 4be51dfe9..8efd48a2c 100644 --- a/contracts/nexus-gateway/src/state.rs +++ b/contracts/nexus-gateway/src/state.rs @@ -40,4 +40,5 @@ pub fn is_message_routed(storage: &dyn Storage, id: &CrossChainId) -> Result