diff --git a/dash/src/hash_types.rs b/dash/src/hash_types.rs index 06f77743e..dc4866889 100644 --- a/dash/src/hash_types.rs +++ b/dash/src/hash_types.rs @@ -73,7 +73,7 @@ mod newtypes { #[cfg(feature = "core-block-hash-use-x11")] use hashes::hash_x11; use hashes::hex::Error; - use hashes::{Hash, hash_newtype, hash_newtype_no_ord, hash160, sha256, sha256d}; + use hashes::{hash160, hash_newtype, hash_newtype_no_ord, sha256, sha256d, Hash}; use crate::alloc::string::ToString; use crate::prelude::String; @@ -168,7 +168,9 @@ mod newtypes { } impl PartialOrd for ScoreHash { - fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } } /// A hash used to identify a quorum @@ -211,10 +213,14 @@ mod newtypes { impl Txid { /// Create a Txid from a string - pub fn from_hex(s: &str) -> Result { Ok(Self(sha256d::Hash::from_str(s)?)) } + pub fn from_hex(s: &str) -> Result { + Ok(Self(sha256d::Hash::from_str(s)?)) + } /// Convert a Txid to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } impl ProTxHash { @@ -224,7 +230,9 @@ mod newtypes { } /// Convert a ProTxHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } impl ScoreHash { @@ -234,7 +242,9 @@ mod newtypes { } /// Convert a ScoreHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } /// Creates a score based on the optional confirmed hash and the quorum modifier. /// @@ -266,7 +276,9 @@ mod newtypes { } /// Convert a ScoreHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } /// Creates an ordering hash based on the quorum and request id. /// @@ -285,7 +297,9 @@ mod newtypes { } impl Default for ConfirmedHash { - fn default() -> Self { ConfirmedHash::from_byte_array([0; 32]) } + fn default() -> Self { + ConfirmedHash::from_byte_array([0; 32]) + } } impl ConfirmedHash { @@ -295,7 +309,9 @@ mod newtypes { } /// Convert a ConfirmedHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } impl ConfirmedHashHashedWithProRegTx { @@ -305,7 +321,9 @@ mod newtypes { } /// Convert a ConfirmedHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } /// Hashes the members pub fn hash_members(pro_tx_hash: &ProTxHash, confirmed_hash: &ConfirmedHash) -> Self { @@ -329,7 +347,9 @@ mod newtypes { } /// Convert a ConfirmedHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } impl InputsHash { @@ -339,12 +359,16 @@ mod newtypes { } /// Convert an InputsHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } impl SpecialTransactionPayloadHash { /// Create a SpecialTransactionPayloadHash from a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } impl PubkeyHash { @@ -354,6 +378,8 @@ mod newtypes { } /// Convert a PubkeyHash to a string - pub fn to_hex(&self) -> String { self.0.to_string() } + pub fn to_hex(&self) -> String { + self.0.to_string() + } } } diff --git a/rpc-client/src/client.rs b/rpc-client/src/client.rs index 1e6a4195b..94ea73b5a 100644 --- a/rpc-client/src/client.rs +++ b/rpc-client/src/client.rs @@ -21,7 +21,12 @@ use serde; use serde_json::{self, Value}; use crate::dashcore::address::NetworkUnchecked; +use crate::dashcore::secp256k1::hashes::hex::DisplayHex; use crate::dashcore::{block, consensus, ScriptBuf}; +use crate::error::*; +use crate::json; +use crate::queryable; +use crate::Error::UnexpectedStructure; use dashcore::hashes::hex::FromHex; use dashcore::secp256k1::ecdsa::Signature; use dashcore::{ @@ -32,11 +37,6 @@ use dashcore_rpc_json::dashcore::{BlockHash, ChainLock}; use dashcore_rpc_json::{ProTxInfo, ProTxListType, QuorumType}; use hex::ToHex; use log::Level::{Debug, Trace, Warn}; -use crate::dashcore::secp256k1::hashes::hex::DisplayHex; -use crate::error::*; -use crate::json; -use crate::queryable; -use crate::Error::UnexpectedStructure; /// Crate-specific Result type, shorthand for `std::result::Result` with our /// crate-specific Error type; @@ -446,12 +446,10 @@ pub trait RpcApi: Sized { Ok(dashcore::consensus::encode::deserialize(&bytes)?) } - fn get_instant_locks( - &self, - txids: Vec<&dashcore::Txid>, - ) -> Result> { + fn get_instant_locks(&self, txids: Vec<&dashcore::Txid>) -> Result> { let mut args = [into_json(txids)?]; - let instant_locks: Vec = self.call("getislocks", handle_defaults(&mut args, &[null()]))?; + let instant_locks: Vec = + self.call("getislocks", handle_defaults(&mut args, &[null()]))?; Ok(instant_locks) } @@ -1236,6 +1234,30 @@ pub trait RpcApi: Sized { self.call::("quorum", handle_defaults(&mut args, &[])) } + /// Returns an extended list of on-chain quorums with quorum hashes reversed + /// This is incorrect response format, but it was used by platform and we need to support it + fn get_quorum_listextended_reversed( + &self, + height: Option, + ) -> Result { + let mut result = self.get_quorum_listextended(height)?; + + result.quorums_by_type = result + .quorums_by_type + .into_iter() + .map(|(quorum_type, quorums)| { + let reversed_quorums = quorums + .into_iter() + .map(|(quorum_hash, details)| (quorum_hash.reverse(), details)) + .collect(); + + (quorum_type, reversed_quorums) + }) + .collect(); + + Ok(result) + } + /// Returns information about a specific quorum fn get_quorum_info( &self, @@ -1252,6 +1274,22 @@ pub trait RpcApi: Sized { self.call::("quorum", handle_defaults(&mut args, &[null()])) } + /// Returns information about a specific quorum with quorum hash reversed + /// This is incorrect response format, but it was used by platform and we need to support it + fn get_quorum_info_reversed( + &self, + llmq_type: QuorumType, + quorum_hash: &QuorumHash, + include_sk_share: Option, + ) -> Result { + let mut result = + self.get_quorum_info(llmq_type, &quorum_hash.reverse(), include_sk_share)?; + + result.quorum_hash = result.quorum_hash.reverse(); + + Ok(result) + } + /// Returns the status of the current DKG process fn get_quorum_dkgstatus(&self, detail_level: Option) -> Result { let mut args = ["dkgstatus".into(), opt_into_json(detail_level)?]; @@ -1397,7 +1435,11 @@ pub trait RpcApi: Sized { } /// Returns a returns detailed information about a deterministic masternode - fn get_protx_info(&self, protx_hash: &ProTxHash, block_hash: Option<&BlockHash>) -> Result { + fn get_protx_info( + &self, + protx_hash: &ProTxHash, + block_hash: Option<&BlockHash>, + ) -> Result { let mut args = ["info".into(), into_json(protx_hash.to_hex())?, opt_into_json(block_hash)?]; self.call::("protx", handle_defaults(&mut args, &[null()])) diff --git a/rpc-json/src/lib.rs b/rpc-json/src/lib.rs index 5189315b4..ba994c5b5 100644 --- a/rpc-json/src/lib.rs +++ b/rpc-json/src/lib.rs @@ -3260,7 +3260,9 @@ mod tests { use dashcore::hashes::Hash; use serde_json::json; - use crate::{deserialize_u32_opt, MasternodeListDiff, MnSyncStatus}; + use crate::{ + deserialize_u32_opt, ExtendedQuorumListResult, MasternodeListDiff, MnSyncStatus, QuorumType, + }; #[test] fn test_deserialize_u32_opt() { @@ -3278,35 +3280,50 @@ mod tests { assert_eq!(result.field, None); } - // #[test] - // fn deserialize_quorum_listextended() { - // let json_list = r#"{ - // "llmq_50_60": [ - // { - // "000000da4509523408c751905d4e48df335e3ee565b4d2288800c7e51d592e2f": { - // "creationHeight": 871992, - // "minedBlockHash": "000000cd7f101437069956c0ca9f4180b41f0506827a828d57e85b35f215487e", - // "numValidMembers": 50, - // "healthRatio": "1.00" - // } - // } - // ] - // }"#; - // let result: ExtendedQuorumListResult = - // serde_json::from_str(json_list).expect("expected to deserialize json"); - // println!("{:#?}", result); - // let first_type = result.quorums_by_type.get(&QuorumType::Llmq50_60).unwrap(); - // let first_quorum = first_type.into_iter().nth(0).unwrap(); - // - // assert_eq!( - // "000000da4509523408c751905d4e48df335e3ee565b4d2288800c7e51d592e2f", - // first_quorum.0.to_hex() - // ); - // assert_eq!( - // "000000cd7f101437069956c0ca9f4180b41f0506827a828d57e85b35f215487e", - // first_quorum.1.mined_block_hash.to_hex() - // ); - // } + #[test] + fn deserialize_quorum_listextended() { + let json_list = r#"{ + "llmq_50_60": [ + { + "000000da4509523408c751905d4e48df335e3ee565b4d2288800c7e51d592e2f": { + "creationHeight": 871992, + "minedBlockHash": "000000cd7f101437069956c0ca9f4180b41f0506827a828d57e85b35f215487e", + "numValidMembers": 50, + "healthRatio": "1.00" + } + } + ] + }"#; + let result: ExtendedQuorumListResult = + serde_json::from_str(json_list).expect("expected to deserialize json"); + let first_type = result.quorums_by_type.get(&QuorumType::Llmq50_60).unwrap(); + let first_quorum = first_type.into_iter().nth(0).unwrap(); + + assert_eq!( + first_quorum.0.to_byte_array(), + [ + 47, 46, 89, 29, 229, 199, 0, 136, 40, 210, 180, 101, 229, 62, 94, 51, 223, 72, 78, + 93, 144, 81, 199, 8, 52, 82, 9, 69, 218, 0, 0, 0, + ] + ); + + assert_eq!( + first_quorum.1.mined_block_hash.to_byte_array(), + [ + 126, 72, 21, 242, 53, 91, 232, 87, 141, 130, 122, 130, 6, 5, 31, 180, 128, 65, 159, + 202, 192, 86, 153, 6, 55, 20, 16, 127, 205, 0, 0, 0, + ] + ); + + assert_eq!( + "000000da4509523408c751905d4e48df335e3ee565b4d2288800c7e51d592e2f", + first_quorum.0.to_string() + ); + assert_eq!( + "000000cd7f101437069956c0ca9f4180b41f0506827a828d57e85b35f215487e", + first_quorum.1.mined_block_hash.to_string() + ); + } #[test] fn deserialize_mn_listdiff() {