diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index ed5635ea45..d442960579 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -281,8 +281,7 @@ pub type BalanceResult = Result>; pub type BalanceFut = Box> + Send>; pub type NonZeroBalanceFut = Box> + Send>; pub type NumConversResult = Result>; -pub type StakingInfosResult = Result>; -pub type StakingInfosFut = Box> + Send>; +pub type StakingInfosFut = Box> + Send>; pub type DelegationResult = Result>; pub type DelegationFut = Box> + Send>; pub type WithdrawResult = Result>; @@ -2234,8 +2233,27 @@ pub struct ClaimStakingRewardsRequest { } #[derive(Deserialize)] -pub struct GetStakingInfosRequest { +pub struct DelegationsInfo { pub coin: String, + info_details: DelegationsInfoDetails, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "type")] +pub enum DelegationsInfoDetails { + Qtum, +} + +#[derive(Deserialize)] +pub struct ValidatorsInfo { + pub coin: String, + info_details: ValidatorsInfoDetails, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "type")] +pub enum ValidatorsInfoDetails { + Cosmos(rpc_command::tendermint::staking::ValidatorsRPC), } #[derive(Serialize, Deserialize)] @@ -2764,59 +2782,59 @@ impl From for BalanceError { #[derive(Debug, Deserialize, Display, EnumFromStringify, Serialize, SerializeErrorType)] #[serde(tag = "error_type", content = "error_data")] -pub enum StakingInfosError { - #[display(fmt = "Staking infos not available for: {}", coin)] - CoinDoesntSupportStakingInfos { coin: String }, +pub enum StakingInfoError { #[display(fmt = "No such coin {}", coin)] NoSuchCoin { coin: String }, #[from_stringify("UnexpectedDerivationMethod")] #[display(fmt = "Derivation method is not supported: {}", _0)] UnexpectedDerivationMethod(String), + #[display(fmt = "Invalid payload: {}", reason)] + InvalidPayload { reason: String }, #[display(fmt = "Transport error: {}", _0)] Transport(String), #[display(fmt = "Internal error: {}", _0)] Internal(String), } -impl From for StakingInfosError { +impl From for StakingInfoError { fn from(e: UtxoRpcError) -> Self { match e { UtxoRpcError::Transport(rpc) | UtxoRpcError::ResponseParseError(rpc) => { - StakingInfosError::Transport(rpc.to_string()) + StakingInfoError::Transport(rpc.to_string()) }, - UtxoRpcError::InvalidResponse(error) => StakingInfosError::Transport(error), - UtxoRpcError::Internal(error) => StakingInfosError::Internal(error), + UtxoRpcError::InvalidResponse(error) => StakingInfoError::Transport(error), + UtxoRpcError::Internal(error) => StakingInfoError::Internal(error), } } } -impl From for StakingInfosError { +impl From for StakingInfoError { fn from(e: Qrc20AddressError) -> Self { match e { - Qrc20AddressError::UnexpectedDerivationMethod(e) => StakingInfosError::UnexpectedDerivationMethod(e), + Qrc20AddressError::UnexpectedDerivationMethod(e) => StakingInfoError::UnexpectedDerivationMethod(e), Qrc20AddressError::ScriptHashTypeNotSupported { script_hash_type } => { - StakingInfosError::Internal(format!("Script hash type '{}' is not supported", script_hash_type)) + StakingInfoError::Internal(format!("Script hash type '{}' is not supported", script_hash_type)) }, } } } -impl HttpStatusCode for StakingInfosError { +impl HttpStatusCode for StakingInfoError { fn status_code(&self) -> StatusCode { match self { - StakingInfosError::NoSuchCoin { .. } - | StakingInfosError::CoinDoesntSupportStakingInfos { .. } - | StakingInfosError::UnexpectedDerivationMethod(_) => StatusCode::BAD_REQUEST, - StakingInfosError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, - StakingInfosError::Transport(_) => StatusCode::BAD_GATEWAY, + StakingInfoError::NoSuchCoin { .. } + | StakingInfoError::InvalidPayload { .. } + | StakingInfoError::UnexpectedDerivationMethod(_) => StatusCode::BAD_REQUEST, + StakingInfoError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, + StakingInfoError::Transport(_) => StatusCode::BAD_GATEWAY, } } } -impl From for StakingInfosError { +impl From for StakingInfoError { fn from(e: CoinFindError) -> Self { match e { - CoinFindError::NoSuchCoin { coin } => StakingInfosError::NoSuchCoin { coin }, + CoinFindError::NoSuchCoin { coin } => StakingInfoError::NoSuchCoin { coin }, } } } @@ -2897,18 +2915,16 @@ impl From for DelegationError { } } -impl From for DelegationError { - fn from(e: StakingInfosError) -> Self { +impl From for DelegationError { + fn from(e: StakingInfoError) -> Self { match e { - StakingInfosError::CoinDoesntSupportStakingInfos { coin } => { - DelegationError::CoinDoesntSupportDelegation { coin } - }, - StakingInfosError::NoSuchCoin { coin } => DelegationError::NoSuchCoin { coin }, - StakingInfosError::Transport(e) => DelegationError::Transport(e), - StakingInfosError::UnexpectedDerivationMethod(reason) => { + StakingInfoError::NoSuchCoin { coin } => DelegationError::NoSuchCoin { coin }, + StakingInfoError::Transport(e) => DelegationError::Transport(e), + StakingInfoError::UnexpectedDerivationMethod(reason) => { DelegationError::DelegationOpsNotSupported { reason } }, - StakingInfosError::Internal(e) => DelegationError::InternalError(e), + StakingInfoError::Internal(e) => DelegationError::InternalError(e), + StakingInfoError::InvalidPayload { reason } => DelegationError::InvalidPayload { reason }, } } } @@ -4969,18 +4985,32 @@ pub async fn remove_delegation(ctx: MmArc, req: RemoveDelegateRequest) -> Delega } } -pub async fn get_staking_infos(ctx: MmArc, req: GetStakingInfosRequest) -> StakingInfosResult { +pub async fn delegations_info(ctx: MmArc, req: DelegationsInfo) -> Result> { let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; - match coin { - MmCoinEnum::QtumCoin(qtum) => qtum.get_delegation_infos().compat().await, - _ => { - return MmError::err(StakingInfosError::CoinDoesntSupportStakingInfos { - coin: coin.ticker().to_string(), - }) + + match req.info_details { + DelegationsInfoDetails::Qtum => { + let MmCoinEnum::QtumCoin(qtum) = coin else { + return MmError::err(StakingInfoError::InvalidPayload { + reason: format!("{} is not a Qtum coin", req.coin) + }); + }; + + qtum.get_delegation_infos().compat().await.map(|v| json!(v)) }, } } +pub async fn validators_info(ctx: MmArc, req: ValidatorsInfo) -> Result> { + let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; + + match req.info_details { + ValidatorsInfoDetails::Cosmos(payload) => rpc_command::tendermint::staking::validators_rpc(coin, payload) + .await + .map(|v| json!(v)), + } +} + pub async fn add_delegation(ctx: MmArc, req: AddDelegateRequest) -> DelegationResult { let coin = lp_coinfind_or_err(&ctx, &req.coin).await?; diff --git a/mm2src/coins/rpc_command/tendermint/staking.rs b/mm2src/coins/rpc_command/tendermint/staking.rs index 5bf6b2a427..a9c81f9696 100644 --- a/mm2src/coins/rpc_command/tendermint/staking.rs +++ b/mm2src/coins/rpc_command/tendermint/staking.rs @@ -1,13 +1,12 @@ -use common::{HttpStatusCode, PagingOptions, StatusCode}; +use common::PagingOptions; use cosmrs::staking::{Commission, Description, Validator}; -use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::MmError; use mm2_number::BigDecimal; -use crate::{hd_wallet::WithdrawFrom, lp_coinfind_or_err, tendermint::TendermintCoinRpcError, MmCoinEnum, WithdrawFee}; +use crate::{hd_wallet::WithdrawFrom, tendermint::TendermintCoinRpcError, MmCoinEnum, StakingInfoError, WithdrawFee}; /// Represents current status of the validator. -#[derive(Default, Deserialize)] +#[derive(Debug, Default, Deserialize)] pub(crate) enum ValidatorStatus { All, /// Validator is in the active set and participates in consensus. @@ -30,10 +29,8 @@ impl ToString for ValidatorStatus { } } -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] pub struct ValidatorsRPC { - #[serde(rename = "ticker")] - coin: String, #[serde(flatten)] paging: PagingOptions, #[serde(default)] @@ -45,38 +42,14 @@ pub struct ValidatorsRPCResponse { validators: Vec, } -#[derive(Clone, Debug, Display, Serialize, SerializeErrorType, PartialEq)] -#[serde(tag = "error_type", content = "error_data")] -pub enum ValidatorsRPCError { - #[display(fmt = "Coin '{ticker}' could not be found in coins configuration.")] - CoinNotFound { ticker: String }, - #[display(fmt = "'{ticker}' is not a Cosmos coin.")] - UnexpectedCoinType { ticker: String }, - #[display(fmt = "Transport error: {}", _0)] - Transport(String), - #[display(fmt = "Internal error: {}", _0)] - InternalError(String), -} - -impl HttpStatusCode for ValidatorsRPCError { - fn status_code(&self) -> common::StatusCode { - match self { - ValidatorsRPCError::Transport(_) => StatusCode::SERVICE_UNAVAILABLE, - ValidatorsRPCError::InternalError(_) => StatusCode::INTERNAL_SERVER_ERROR, - ValidatorsRPCError::CoinNotFound { .. } => StatusCode::NOT_FOUND, - ValidatorsRPCError::UnexpectedCoinType { .. } => StatusCode::BAD_REQUEST, - } - } -} - -impl From for ValidatorsRPCError { +impl From for StakingInfoError { fn from(e: TendermintCoinRpcError) -> Self { match e { TendermintCoinRpcError::InvalidResponse(e) | TendermintCoinRpcError::PerformError(e) - | TendermintCoinRpcError::RpcClientError(e) => ValidatorsRPCError::Transport(e), - TendermintCoinRpcError::Prost(e) | TendermintCoinRpcError::InternalError(e) => ValidatorsRPCError::InternalError(e), - TendermintCoinRpcError::UnexpectedAccountType { .. } => ValidatorsRPCError::InternalError( + | TendermintCoinRpcError::RpcClientError(e) => StakingInfoError::Transport(e), + TendermintCoinRpcError::Prost(e) | TendermintCoinRpcError::InternalError(e) => StakingInfoError::Internal(e), + TendermintCoinRpcError::UnexpectedAccountType { .. } => StakingInfoError::Internal( "RPC client got an unexpected error 'TendermintCoinRpcError::UnexpectedAccountType', this isn't normal." .into(), ), @@ -85,9 +58,9 @@ impl From for ValidatorsRPCError { } pub async fn validators_rpc( - ctx: MmArc, + coin: MmCoinEnum, req: ValidatorsRPC, -) -> Result> { +) -> Result> { fn maybe_jsonize_description(description: Option) -> Option { description.map(|d| { json!({ @@ -133,16 +106,19 @@ pub async fn validators_rpc( }) } - let validators = match lp_coinfind_or_err(&ctx, &req.coin).await { - Ok(MmCoinEnum::Tendermint(coin)) => coin.validators_list(req.filter_by_status, req.paging).await?, - Ok(MmCoinEnum::TendermintToken(token)) => { + let validators = match coin { + MmCoinEnum::Tendermint(coin) => coin.validators_list(req.filter_by_status, req.paging).await?, + MmCoinEnum::TendermintToken(token) => { token .platform_coin .validators_list(req.filter_by_status, req.paging) .await? }, - Ok(_) => return MmError::err(ValidatorsRPCError::UnexpectedCoinType { ticker: req.coin }), - Err(_) => return MmError::err(ValidatorsRPCError::CoinNotFound { ticker: req.coin }), + other => { + return MmError::err(StakingInfoError::InvalidPayload { + reason: format!("{} is not a Cosmos coin", other.ticker()), + }) + }, }; Ok(ValidatorsRPCResponse { diff --git a/mm2src/coins/utxo/qtum_delegation.rs b/mm2src/coins/utxo/qtum_delegation.rs index f7573fafbf..2af8a83cdd 100644 --- a/mm2src/coins/utxo/qtum_delegation.rs +++ b/mm2src/coins/utxo/qtum_delegation.rs @@ -7,8 +7,8 @@ use crate::utxo::rpc_clients::UtxoRpcClientEnum; use crate::utxo::utxo_common::{big_decimal_from_sat_unsigned, UtxoTxBuilder}; use crate::utxo::{qtum, utxo_common, Address, GetUtxoListOps, UtxoCommonOps}; use crate::utxo::{PrivKeyPolicyNotAllowed, UTXO_LOCK}; -use crate::{DelegationError, DelegationFut, DelegationResult, MarketCoinOps, StakingInfos, StakingInfosError, - StakingInfosFut, StakingInfosResult, TransactionData, TransactionDetails, TransactionType}; +use crate::{DelegationError, DelegationFut, DelegationResult, MarketCoinOps, StakingInfoError, StakingInfos, + StakingInfosFut, TransactionData, TransactionDetails, TransactionType}; use bitcrypto::dhash256; use common::now_sec; use derive_more::Display; @@ -39,6 +39,7 @@ lazy_static! { } pub type QtumStakingAbiResult = Result>; +type StakingInfosResult = Result>; #[derive(Debug, Display)] pub enum QtumStakingAbiError { @@ -132,12 +133,12 @@ impl QtumCoin { .await } - async fn am_i_currently_staking(&self) -> Result, MmError> { + async fn am_i_currently_staking(&self) -> Result, MmError> { let utxo = self.as_ref(); let contract_address = contract_addr_into_rpc_format(&QTUM_DELEGATE_CONTRACT_ADDRESS); let client = match &utxo.rpc_client { UtxoRpcClientEnum::Native(_) => { - return MmError::err(StakingInfosError::Internal("Native not supported".to_string())) + return MmError::err(StakingInfoError::Internal("Native not supported".to_string())) }, UtxoRpcClientEnum::Electrum(electrum) => electrum, }; @@ -147,12 +148,12 @@ impl QtumCoin { .blockchain_contract_event_get_history(&address_rpc, &contract_address, QTUM_ADD_DELEGATION_TOPIC) .compat() .await - .map_to_mm(|e| StakingInfosError::Transport(e.to_string()))?; + .map_to_mm(|e| StakingInfoError::Transport(e.to_string()))?; let remove_delegation_history = client .blockchain_contract_event_get_history(&address_rpc, &contract_address, QTUM_REMOVE_DELEGATION_TOPIC) .compat() .await - .map_to_mm(|e| StakingInfosError::Transport(e.to_string()))?; + .map_to_mm(|e| StakingInfoError::Transport(e.to_string()))?; let am_i_staking = add_delegation_history.len() > remove_delegation_history.len(); if am_i_staking { let last_tx_add = some_or_return_ok_none!(add_delegation_history.last()); @@ -160,7 +161,7 @@ impl QtumCoin { .blockchain_transaction_get_receipt(&last_tx_add.tx_hash) .compat() .await - .map_to_mm(|e| StakingInfosError::Transport(e.to_string()))?; + .map_to_mm(|e| StakingInfoError::Transport(e.to_string()))?; // there is only 3 topics for an add_delegation // the first entry is the operation (add_delegation / remove_delegation), // the second entry is always the staker as hexadecimal 32 byte padded @@ -185,7 +186,7 @@ impl QtumCoin { .and_then(|log_entry| log_entry.topics.get(1)) .map(|padded_staker_address_hex| padded_staker_address_hex.trim_start_matches('0')) }) { - let hash = H160::from_str(raw).map_to_mm(|e| StakingInfosError::Internal(e.to_string()))?; + let hash = H160::from_str(raw).map_to_mm(|e| StakingInfoError::Internal(e.to_string()))?; let address = self.utxo_addr_from_contract_addr(hash); Ok(Some(address.to_string())) } else { diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index ea0e3258f0..a399d04c35 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -25,7 +25,6 @@ use crate::rpc::rate_limiter::{process_rate_limit, RateLimitContext}; use coins::eth::fee_estimation::rpc::get_eth_estimated_fee_per_gas; use coins::eth::EthCoin; use coins::my_tx_history_v2::my_tx_history_v2_rpc; -use coins::rpc_command::tendermint::staking::validators_rpc; use coins::rpc_command::tendermint::{ibc_chains, ibc_transfer_channels}; use coins::rpc_command::{account_balance::account_balance, get_current_mtp::get_current_mtp_rpc, @@ -46,9 +45,9 @@ use coins::utxo::qtum::QtumCoin; use coins::utxo::slp::SlpToken; use coins::utxo::utxo_standard::UtxoStandardCoin; use coins::z_coin::ZCoin; -use coins::{add_delegation, claim_staking_rewards, get_my_address, get_raw_transaction, get_staking_infos, +use coins::{add_delegation, claim_staking_rewards, delegations_info, get_my_address, get_raw_transaction, get_swap_transaction_fee_policy, nft, remove_delegation, set_swap_transaction_fee_policy, sign_message, - sign_raw_transaction, verify_message, withdraw}; + sign_raw_transaction, validators_info, verify_message, withdraw}; use coins_activation::{cancel_init_l2, cancel_init_platform_coin_with_tokens, cancel_init_standalone_coin, cancel_init_token, enable_platform_coin_with_tokens, enable_token, init_l2, init_l2_status, init_l2_user_action, init_platform_coin_with_tokens, init_platform_coin_with_tokens_status, @@ -148,20 +147,43 @@ async fn auth(request: &MmRpcRequest, ctx: &MmArc, client: &SocketAddr) -> Dispa } } +/// Handles experimental RPCs. +/// +/// When an RPC is recently implemented and may go for breaking changes based on client feedback, +/// it should be handled in this dispatcher to apply the `experimental::` prefix to the RPC name. +async fn experimental_rpcs_dispatcher( + request: MmRpcRequest, + ctx: MmArc, + experimental_method: &str, +) -> DispatcherResult>> { + if let Some(staking_method) = experimental_method.strip_prefix("staking::") { + return staking_dispatcher(request, ctx, staking_method).await; + } + + MmError::err(DispatcherError::NoSuchMethod) +} + async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult>> { if let Some(streaming_request) = request.method.strip_prefix("stream::") { let streaming_request = streaming_request.to_string(); return rpc_streaming_dispatcher(request, ctx, streaming_request).await; } + if let Some(task_method) = request.method.strip_prefix("task::") { let task_method = task_method.to_string(); return rpc_task_dispatcher(request, ctx, task_method).await; } + if let Some(gui_storage_method) = request.method.strip_prefix("gui_storage::") { let gui_storage_method = gui_storage_method.to_owned(); return gui_storage_dispatcher(request, ctx, &gui_storage_method).await; } + if let Some(experimental_method) = request.method.strip_prefix("experimental::") { + let experimental_method = experimental_method.to_string(); + return experimental_rpcs_dispatcher(request, ctx, &experimental_method).await; + } + #[cfg(not(target_arch = "wasm32"))] if let Some(lightning_method) = request.method.strip_prefix("lightning::") { let lightning_method = lightning_method.to_owned(); @@ -171,12 +193,10 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, account_balance).await, "active_swaps" => handle_mmrpc(ctx, request, active_swaps_rpc).await, - "add_delegation" => handle_mmrpc(ctx, request, add_delegation).await, "add_node_to_version_stat" => handle_mmrpc(ctx, request, add_node_to_version_stat).await, "approve_token" => handle_mmrpc(ctx, request, approve_token_rpc).await, "get_token_allowance" => handle_mmrpc(ctx, request, get_token_allowance_rpc).await, "best_orders" => handle_mmrpc(ctx, request, best_orders_rpc_v2).await, - "claim_staking_rewards" => handle_mmrpc(ctx, request, claim_staking_rewards).await, "clear_nft_db" => handle_mmrpc(ctx, request, clear_nft_db).await, "enable_bch_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, "enable_slp" => handle_mmrpc(ctx, request, enable_token::).await, @@ -200,7 +220,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, get_public_key_hash).await, "get_raw_transaction" => handle_mmrpc(ctx, request, get_raw_transaction).await, "get_shared_db_id" => handle_mmrpc(ctx, request, get_shared_db_id).await, - "get_staking_infos" => handle_mmrpc(ctx, request, get_staking_infos).await, "get_token_info" => handle_mmrpc(ctx, request, get_token_info).await, "get_wallet_names" => handle_mmrpc(ctx, request, get_wallet_names_rpc).await, "max_maker_vol" => handle_mmrpc(ctx, request, max_maker_vol).await, @@ -210,7 +229,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, orderbook_rpc_v2).await, "recreate_swap_data" => handle_mmrpc(ctx, request, recreate_swap_data).await, "refresh_nft_metadata" => handle_mmrpc(ctx, request, refresh_nft_metadata).await, - "remove_delegation" => handle_mmrpc(ctx, request, remove_delegation).await, "remove_node_from_version_stat" => handle_mmrpc(ctx, request, remove_node_from_version_stat).await, "sign_message" => handle_mmrpc(ctx, request, sign_message).await, "sign_raw_transaction" => handle_mmrpc(ctx, request, sign_raw_transaction).await, @@ -218,7 +236,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, start_version_stat_collection).await, "stop_simple_market_maker_bot" => handle_mmrpc(ctx, request, stop_simple_market_maker_bot).await, "stop_version_stat_collection" => handle_mmrpc(ctx, request, stop_version_stat_collection).await, - "tendermint_validators" => handle_mmrpc(ctx, request, validators_rpc).await, "trade_preimage" => handle_mmrpc(ctx, request, trade_preimage_rpc).await, "trezor_connection_status" => handle_mmrpc(ctx, request, trezor_connection_status).await, "update_nft" => handle_mmrpc(ctx, request, update_nft).await, @@ -438,3 +455,33 @@ async fn lightning_dispatcher( _ => MmError::err(DispatcherError::NoSuchMethod), } } + +/// Dispatcher for `staking` namespace that handles all the staking related RPCs. +async fn staking_dispatcher( + request: MmRpcRequest, + ctx: MmArc, + staking_method: &str, +) -> DispatcherResult>> { + async fn query_dispatcher( + request: MmRpcRequest, + ctx: MmArc, + staking_query_method: &str, + ) -> DispatcherResult>> { + match staking_query_method { + "validators" => handle_mmrpc(ctx, request, validators_info).await, + "delegations" => handle_mmrpc(ctx, request, delegations_info).await, + _ => MmError::err(DispatcherError::NoSuchMethod), + } + } + + if let Some(query_method) = staking_method.strip_prefix("query::") { + return query_dispatcher(request, ctx, query_method).await; + } + + match staking_method { + "claim_rewards" => handle_mmrpc(ctx, request, claim_staking_rewards).await, + "delegate" => handle_mmrpc(ctx, request, add_delegation).await, + "undelegate" => handle_mmrpc(ctx, request, remove_delegation).await, + _ => MmError::err(DispatcherError::NoSuchMethod), + } +} diff --git a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs index 5e1b445497..5e702371b1 100644 --- a/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs +++ b/mm2src/mm2_main/tests/mm2_tests/mm2_tests_inner.rs @@ -2792,10 +2792,11 @@ fn test_add_delegation_qtum() { ])); log!("{}", json.balance); + let rpc_endpoint = "experimental::staking::delegate"; let rc = block_on(mm.rpc(&json!({ "userpass": "pass", "mmrpc": "2.0", - "method": "add_delegation", + "method": rpc_endpoint, "params": { "coin": "tQTUM", "staking_details": { @@ -2809,13 +2810,13 @@ fn test_add_delegation_qtum() { assert_eq!( rc.0, StatusCode::OK, - "RPC «add_delegation» failed with status «{}»", + "RPC «{rpc_endpoint}» failed with status «{}»", rc.0 ); let rc = block_on(mm.rpc(&json!({ "userpass": "pass", "mmrpc": "2.0", - "method": "add_delegation", + "method": rpc_endpoint, "params": { "coin": "tQTUM", "staking_details": { @@ -2828,7 +2829,7 @@ fn test_add_delegation_qtum() { .unwrap(); assert!( rc.0.is_client_error(), - "!add_delegation success but should be error: {}", + "!{rpc_endpoint} success but should be error: {}", rc.1 ); } @@ -2873,10 +2874,11 @@ fn test_remove_delegation_qtum() { let json = block_on(enable_electrum_json(&mm, "tQTUM", false, tqtum_electrums())); log!("{}", json.balance); + let rpc_endpoint = "experimental::staking::undelegate"; let rc = block_on(mm.rpc(&json!({ "userpass": "pass", "mmrpc": "2.0", - "method": "remove_delegation", + "method": rpc_endpoint, "params": {"coin": "tQTUM"}, "id": 0 }))) @@ -2884,14 +2886,14 @@ fn test_remove_delegation_qtum() { assert_eq!( rc.0, StatusCode::OK, - "RPC «remove_delegation» failed with status «{}»", + "RPC «{rpc_endpoint}» failed with status «{}»", rc.0 ); } #[test] #[cfg(not(target_arch = "wasm32"))] -fn test_get_staking_infos_qtum() { +fn test_query_delegations_info_qtum() { let coins = json!([{ "coin": "tQTUM", "name": "qtumtest", @@ -2933,18 +2935,24 @@ fn test_get_staking_infos_qtum() { ])); log!("{}", json.balance); + let rpc_endpoint = "experimental::staking::query::delegations"; let rc = block_on(mm.rpc(&json!({ "userpass": "pass", "mmrpc": "2.0", - "method": "get_staking_infos", - "params": {"coin": "tQTUM"}, + "method": rpc_endpoint, + "params": { + "coin": "tQTUM", + "info_details": { + "type": "Qtum" + } + }, "id": 0 }))) .unwrap(); assert_eq!( rc.0, StatusCode::OK, - "RPC «get_staking_infos» failed with status «{}»", + "RPC «{rpc_endpoint}» failed with status «{}»", rc.0 ); } diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index b098c59f4c..9d51dbdfeb 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -3163,16 +3163,19 @@ pub async fn tendermint_validators( limit: usize, page_number: usize, ) -> Json { - let rpc_endpoint = "tendermint_validators"; + let rpc_endpoint = "experimental::staking::query::validators"; let request = json!({ "userpass": mm.userpass, "method": rpc_endpoint, "mmrpc": "2.0", "params": { - "ticker": coin, - "filter_by_status": filter_by_status, - "limit": limit, - "page_number": page_number + "coin": coin, + "info_details": { + "type": "Cosmos", + "filter_by_status": filter_by_status, + "limit": limit, + "page_number": page_number + } } }); log!("{rpc_endpoint} request {}", json::to_string(&request).unwrap()); @@ -3189,7 +3192,7 @@ pub async fn tendermint_add_delegation( validator_address: &str, amount: &str, ) -> TransactionDetails { - let rpc_endpoint = "add_delegation"; + let rpc_endpoint = "experimental::staking::delegate"; let request = json!({ "userpass": mm.userpass, "method": rpc_endpoint, @@ -3219,7 +3222,7 @@ pub async fn tendermint_remove_delegation_raw( validator_address: &str, amount: &str, ) -> (StatusCode, String, HeaderMap) { - let rpc_endpoint = "remove_delegation"; + let rpc_endpoint = "experimental::staking::undelegate"; let request = json!({ "userpass": mm.userpass, "method": rpc_endpoint, @@ -3244,7 +3247,7 @@ pub async fn tendermint_remove_delegation( validator_address: &str, amount: &str, ) -> TransactionDetails { - let rpc_endpoint = "remove_delegation"; + let rpc_endpoint = "experimental::staking::undelegate"; let response = tendermint_remove_delegation_raw(mm, coin, validator_address, amount).await; assert_eq!(response.0, StatusCode::OK, "{rpc_endpoint} failed: {}", response.1); log!("{rpc_endpoint} response {}", response.1);