From 08b90e9b77443bd85162ab9978bbe2dce660f7ee Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 31 Mar 2023 20:23:26 +0200 Subject: [PATCH 1/2] feat(rs-drive-abci): generate validator set update --- packages/rs-drive-abci/src/abci/error.rs | 5 + packages/rs-drive-abci/src/abci/mod.rs | 2 + .../rs-drive-abci/src/abci/validator_set.rs | 283 ++++++++++++++++++ packages/rs-drive-abci/src/config.rs | 2 +- packages/rs-drive-abci/src/rpc/core.rs | 48 ++- .../tests/strategy_tests/main.rs | 2 +- 6 files changed, 336 insertions(+), 6 deletions(-) create mode 100644 packages/rs-drive-abci/src/abci/validator_set.rs diff --git a/packages/rs-drive-abci/src/abci/error.rs b/packages/rs-drive-abci/src/abci/error.rs index 6c291869b26..a7983a5d602 100644 --- a/packages/rs-drive-abci/src/abci/error.rs +++ b/packages/rs-drive-abci/src/abci/error.rs @@ -8,8 +8,13 @@ pub enum AbciError { /// Bad request received from Tenderdash #[error("bad request received from Tenderdash: {0}")] BadRequest(String), + /// Error returned by tenderdash-abci library #[cfg(feature = "server")] #[error("tenderdash: {0}")] Tenderdash(#[from] tenderdash_abci::Error), + + /// Error occured during validator set creation + #[error("validator set: {0}")] + ValidatorSet(#[from] super::validator_set::ValSetError), } diff --git a/packages/rs-drive-abci/src/abci/mod.rs b/packages/rs-drive-abci/src/abci/mod.rs index d70cdd43104..d8179aa4573 100644 --- a/packages/rs-drive-abci/src/abci/mod.rs +++ b/packages/rs-drive-abci/src/abci/mod.rs @@ -6,6 +6,8 @@ pub mod handlers; // #[deprecated = "use tenderdash-proto crate whenever possible"] pub mod messages; +mod validator_set; + // new code - config, #[cfg(feature = "server")] pub mod config; diff --git a/packages/rs-drive-abci/src/abci/validator_set.rs b/packages/rs-drive-abci/src/abci/validator_set.rs new file mode 100644 index 00000000000..0d6ee174edd --- /dev/null +++ b/packages/rs-drive-abci/src/abci/validator_set.rs @@ -0,0 +1,283 @@ +//! Implementation of validator set updates, required by Tenderdash. +//! +//! + +use dashcore_rpc::dashcore_rpc_json::{QuorumHash, QuorumInfoResult, QuorumType}; +use tenderdash_abci::proto::{abci, crypto as abci_crypto}; + +use crate::{ + config::PlatformConfig, + rpc::core::{CoreHeight, CoreRPCLike}, +}; + +/// ValidatorSet contains validators that should be in use at a given height. +/// +/// You can easily convert ValidatorSet into [tenderdash_abci::proto::abci::ValdiatorSetUpdate] using [From]. +pub struct ValidatorSet { + quorum_info: QuorumInfoResult, +} + +/// Helper function to convert bytes into bls12381 public key, as required by Tenderdash +fn u8_to_bls12381_pubkey(public_key: Vec) -> abci_crypto::PublicKey { + abci_crypto::PublicKey { + sum: Some(tenderdash_abci::proto::crypto::public_key::Sum::Bls12381( + public_key, + )), + } +} + +impl From for tenderdash_abci::proto::abci::ValidatorSetUpdate { + fn from(value: ValidatorSet) -> Self { + let mut validator_updates: Vec = Vec::new(); + for validator in value.quorum_info.members { + if !validator.valid { + continue; + } + let pubkey = validator.pub_key_share.map(|k| u8_to_bls12381_pubkey(k)); + let vu = abci::ValidatorUpdate { + node_address: Default::default(), + power: 100, // TODO: double-check + pub_key: pubkey, // TODO: double-check if it should be pub_key_share + pro_tx_hash: validator.pro_tx_hash.0, + }; + + validator_updates.push(vu); + } + + Self { + validator_updates, + threshold_public_key: Some(u8_to_bls12381_pubkey(value.quorum_info.quorum_public_key)), + quorum_hash: value.quorum_info.quorum_hash.0, + } + } +} + +impl ValidatorSet { + /// Retrieve quorums from Dash Core at provided height and extract validator set information from it. + /// + /// ## Arguments + /// + /// - `client` - Core RPC client + /// - `config` - platform configuration + /// - `core_height` - height of dash core for which we create validator set + /// - `quorum_type` - type of LLMQ quorum + /// - `seed` - additional information that can be included in the selection algorithm to make it non-deterministic. + /// Use `None` to make it deterministic. + pub(crate) fn new_at_height_with_seed( + client: C, + config: &PlatformConfig, + core_height: CoreHeight, + quorum_type: &QuorumType, + seed: Option>, + ) -> Result { + // TODO: parse QuorumInfoResult to return + let quorums = client.get_quorum_listextended(Some(core_height))?; + let quorums = match quorum_type { + QuorumType::Llmq50_60 => quorums.llmq_50_60, + QuorumType::Llmq400_60 => quorums.llmq_400_60, + QuorumType::Llmq400_85 => quorums.llmq_400_85, + QuorumType::Llmq100_67 => quorums.llmq_100_67, + QuorumType::Llmq60_75 => panic!("unsupported quorum type {:?}", quorum_type), + QuorumType::LlmqTest => quorums.llmq_test, + QuorumType::LlmqDevnet => panic!("unsupported quorum type {:?}", quorum_type), + QuorumType::LlmqTestV17 => quorums.llmq_test_v17, + QuorumType::LlmqTestDip0024 => quorums.llmq_test_dip0024, + QuorumType::LlmqTestInstantsend => quorums.llmq_test_instantsend, + QuorumType::LlmqDevnetDip0024 => panic!("unsupported quorum type {:?}", quorum_type), + QuorumType::LlmqTestPlatform => quorums.llmq_test_platform, + QuorumType::LlmqDevnetPlatform => panic!("unsupported quorum type {:?}", quorum_type), + QuorumType::UNKNOWN => panic!("unsupported quorum type {:?}", quorum_type), + // no default here, so if the list of quorums changes, we will detect it during build + } + .ok_or(ValSetError::NoQuorumAtHeight( + Some(core_height), + quorum_type.to_owned(), + ))?; + + let entropy = if seed.is_none() { + Vec::new() + } else { + seed.unwrap() + }; + + let quorum_hash = + Self::choose_random_quorum(config, core_height, &quorum_type, &quorums, &entropy)?; + let quorum_info = client + .get_quorum_info(quorum_type.clone().into(), &quorum_hash, Some(false)) + .map_err(|e| ValSetError::RpcError(e))?; + + Ok(Self { quorum_info }) + } + + /// Returns best quorum to use + /// TODO: replace Vec with Vec + fn choose_random_quorum( + config: &PlatformConfig, + core_height: CoreHeight, + quorum_type: &QuorumType, + quorums_extended_info: &Vec, + entropy: &Vec, + ) -> Result { + // TODO: migrate to config file + const DKG_INTERVAL: CoreHeight = 24; + const MIN_QUORUM_VALID_MEMBERS: CoreHeight = 3; + let rotation_block_interval: CoreHeight = config.validator_set_quorum_rotation_block_count; + let min_ttl: CoreHeight = rotation_block_interval * 3; + + let number_of_quorums = quorums_extended_info.len() as u32; + if number_of_quorums == 0 { + return Err(ValSetError::NoQuorumAtHeight(None, quorum_type.to_owned())); + } + + // let quorum_hash = quorums_extended_info + // .first() + // .ok_or(ValSetError::NoQuorumAtHeight(None, quorum_type.to_owned()))?; + + let quorums_weighted = quorums_extended_info + .iter() + .map(|item| QuorumWeighted::new(item, entropy)) + .collect::>(); + + let mut final_quorums = quorums_weighted + .iter() + .filter(|_item| { + // TODO: read the items below from quorums_extended_info + let num_valid_members = 3; + + num_valid_members >= MIN_QUORUM_VALID_MEMBERS + }) + .filter(|item| item.quorum_ttl(core_height, DKG_INTERVAL, number_of_quorums) > min_ttl) + .collect::>(); + // let mut filtered_quorums = &filtered_quorums; + // if there is no "vital" quorums, we choose among others with default min quorum size + if final_quorums.len() == 0 { + final_quorums = quorums_weighted.iter().collect::>(); + } + + // Now we select best quorum, based on some scoring algorithm. + final_quorums.sort(); + let winner = final_quorums.first().ok_or(ValSetError::NoQuorumAtHeight( + Some(core_height), + quorum_type.to_owned(), + ))?; + + // TODO: when dashcore_rpc is updated, use winner.unwrap().quorum_details.quorum_hash below + Ok(QuorumHash(winner.quorum_details.to_owned())) + } +} + +/// Quorum info with additional weight details. Easy to sort by weight. +#[derive(PartialEq, Eq, PartialOrd, Ord)] +struct QuorumWeighted { + // ensure weight is first, as it metters when sorting + weight: Vec, + quorum_details: Vec, +} + +impl QuorumWeighted { + fn new(quorum_details: &QuorumHash, entropy: &Vec) -> Self { + QuorumWeighted { + quorum_details: quorum_details.0.to_owned(), + weight: Self::calculate_weight(quorum_details, entropy), + } + } + + /// Calculate weight to use when sorting. + fn calculate_weight(quorum_hash: &QuorumHash, entropy: &Vec) -> Vec { + let mut hash = quorum_hash.0.clone(); + hash.extend(entropy); + + hash + } + + /// Calculate estimated quorum time-to-live + fn quorum_ttl( + &self, + core_height: CoreHeight, + dkg_interval: u32, + number_of_quorums: u32, + ) -> u32 { + // TODO: read the item below from quorums_extended_info + let creation_height: CoreHeight = 2000; + + let quorum_remove_height: CoreHeight = creation_height + (dkg_interval * number_of_quorums); + let how_much_in_rest: CoreHeight = quorum_remove_height - core_height; + let quorum_ttl: u32 = how_much_in_rest * 5 / 2; // multiply by 2.5, round down + + quorum_ttl + } +} + +/// Error returned by Core RPC endpoint +#[derive(Debug, thiserror::Error)] +pub enum ValSetError { + #[error{"Core RPC returned error: {0}"}] + /// Error returned by RPC interface + RpcError(#[from] dashcore_rpc::Error), + + /// Requested height is not found + #[error{"No quorum of type {1:?} at core height {0:?} found"}] + NoQuorumAtHeight(Option, QuorumType), + + /// Quorum with given hash not found + #[error{"No quorum with hash {0:?} of type {1:?} found"}] + QuorumNotFound(QuorumHash, QuorumType), +} + +#[cfg(test)] +mod tests { + use dashcore_rpc::dashcore_rpc_json::{QuorumHash, QuorumInfoResult}; + use tenderdash_abci::proto::abci::ValidatorSetUpdate; + + use crate::config::PlatformConfig; + + #[test] + fn test_new_random_at_height() { + const CORE_HEIGHT: u32 = 2000; + let quorum_type = dashcore_rpc::dashcore_rpc_json::QuorumType::Llmq50_60; + let quorum1 = QuorumHash(vec![1u8; 32]); + let winning_quorum = quorum1.clone(); + + let config = PlatformConfig::default(); + let mut client = crate::rpc::core::MockCoreRPCLike::new(); + client + .expect_get_quorum_listextended() + .returning(move |_| { + Ok(dashcore_rpc::dashcore_rpc_json::QuorumListResult { + llmq_50_60: Some(vec![quorum1.clone()]), + llmq_400_60: None, + llmq_400_85: None, + llmq_100_67: None, + llmq_test: None, + llmq_test_instantsend: None, + llmq_test_v17: None, + llmq_test_dip0024: None, + llmq_test_platform: None, + }) + }) + .once(); + + client + .expect_get_quorum_info() + .returning(|quorum_type, quorum_hash, _| { + Ok(QuorumInfoResult { + height: CORE_HEIGHT as u64, + quorum_type, + mined_block: vec![], + quorum_hash: quorum_hash.clone(), + quorum_index: 1, + quorum_public_key: vec![], + members: vec![], + secret_key_share: None, + }) + }) + .once(); + + let vset = + super::ValidatorSet::new_at_height_with_seed(client, &config, 2000, &quorum_type, None) + .expect("failed to fetch validator set"); + + let vsu = ValidatorSetUpdate::from(vset); + assert_eq!(vsu.quorum_hash, winning_quorum.0); + } +} diff --git a/packages/rs-drive-abci/src/config.rs b/packages/rs-drive-abci/src/config.rs index e5cbbb3c9ae..6dce3f4a74a 100644 --- a/packages/rs-drive-abci/src/config.rs +++ b/packages/rs-drive-abci/src/config.rs @@ -108,7 +108,7 @@ pub struct PlatformConfig { pub quorum_size: u16, /// How often should quorums change? - pub validator_set_quorum_rotation_block_count: u64, + pub validator_set_quorum_rotation_block_count: u32, /// Path to data storage pub db_path: PathBuf, diff --git a/packages/rs-drive-abci/src/rpc/core.rs b/packages/rs-drive-abci/src/rpc/core.rs index 5a33c415dd9..6450f0b9462 100644 --- a/packages/rs-drive-abci/src/rpc/core.rs +++ b/packages/rs-drive-abci/src/rpc/core.rs @@ -1,20 +1,44 @@ use dashcore::{Block, BlockHash}; -use dashcore_rpc::{Auth, Client, Error, RpcApi}; +use dashcore_rpc::{ + dashcore_rpc_json::{QuorumHash, QuorumInfoResult, QuorumListResult, QuorumType}, + Auth, Client, Error, RpcApi, +}; + #[cfg(feature = "fixtures-and-mocks")] use mockall::{automock, predicate::*}; use serde_json::Value; +/// Core height must be of type u32 (Platform heights are u64) +pub type CoreHeight = u32; /// Core RPC interface #[cfg_attr(feature = "fixtures-and-mocks", automock)] pub trait CoreRPCLike { /// Get block hash by height - fn get_block_hash(&self, height: u32) -> Result; + fn get_block_hash(&self, height: CoreHeight) -> Result; /// Get block by hash fn get_block(&self, block_hash: &BlockHash) -> Result; /// Get block by hash in JSON format fn get_block_json(&self, block_hash: &BlockHash) -> Result; + + /// Get list of quorums at a given height. + /// + /// See https://dashcore.readme.io/v19.0.0/docs/core-api-ref-remote-procedure-calls-evo#quorum-listextended + fn get_quorum_listextended( + &self, + height: Option, + ) -> Result; + + /// Get quorum information. + /// + /// See https://dashcore.readme.io/v19.0.0/docs/core-api-ref-remote-procedure-calls-evo#quorum-info + fn get_quorum_info( + &self, + quorum_type: QuorumType, + hash: &QuorumHash, + o: Option, + ) -> Result; } /// Default implementation of Dash Core RPC using DashCoreRPC client @@ -32,8 +56,8 @@ impl DefaultCoreRPC { } impl CoreRPCLike for DefaultCoreRPC { - fn get_block_hash(&self, height: u32) -> Result { - self.inner.get_block_hash(height as u64) + fn get_block_hash(&self, height: CoreHeight) -> Result { + self.inner.get_block_hash(height) } fn get_block(&self, block_hash: &BlockHash) -> Result { @@ -43,4 +67,20 @@ impl CoreRPCLike for DefaultCoreRPC { fn get_block_json(&self, block_hash: &BlockHash) -> Result { self.inner.get_block_json(block_hash) } + fn get_quorum_listextended( + &self, + height: Option, + ) -> Result { + self.inner.get_quorum_listextended(height.map(|i| i as i64)) + } + + fn get_quorum_info( + &self, + quorum_type: QuorumType, + quorum_hash: &QuorumHash, + include_sk_share: Option, + ) -> Result { + self.inner + .get_quorum_info(quorum_type, quorum_hash, include_sk_share) + } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 1307aab75f1..6edfbaad60c 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -467,7 +467,7 @@ pub(crate) fn continue_chain_for_strategy( StrategyRandomness::RNGEntropy(rng) => rng, }; let quorum_size = config.quorum_size; - let quorum_rotation_block_count = config.validator_set_quorum_rotation_block_count; + let quorum_rotation_block_count = config.validator_set_quorum_rotation_block_count as u64; let first_block_time = 0; let mut current_identities = vec![]; let mut i = 0; From db765e68af65c885eda9bfd012b45241a5257921 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 3 Apr 2023 17:18:39 +0200 Subject: [PATCH 2/2] chore(rs-drive-abci): integrate with dashcore_rpc get_quorum_listextended --- Cargo.lock | 748 ++++++++++++++---- packages/rs-drive-abci/.env.example | 4 + packages/rs-drive-abci/Cargo.toml | 2 +- packages/rs-drive-abci/src/abci/handlers.rs | 4 +- packages/rs-drive-abci/src/abci/server.rs | 7 +- .../rs-drive-abci/src/abci/validator_set.rs | 183 +++-- packages/rs-drive-abci/src/config.rs | 36 +- .../src/identity_credit_withdrawal/mod.rs | 4 +- packages/rs-drive-abci/src/platform.rs | 2 +- packages/rs-drive-abci/src/rpc/core.rs | 15 +- packages/rs-drive-nodejs/src/lib.rs | 1 + 11 files changed, 751 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a592316d770..85c0b8b79b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,6 +58,46 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys 0.45.0", +] + [[package]] name = "anyhow" version = "1.0.70" @@ -78,13 +118,13 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-trait" -version = "0.1.67" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ea188f25f0255d8f92797797c97ebf5631fa88178beb1a46fdf5622c9a00e4" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.13", ] [[package]] @@ -504,9 +544,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -526,39 +566,45 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.13" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c911b090850d79fc64fe9ea01e28e465f65e821e08813ced95bced72f7a8a9b" +checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", - "clap_lex", - "is-terminal", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.12" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a932373bab67b984c790ddf2c9ca295d8e3af3b7ef92de5a5bacdccdee4b09b" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.13", ] [[package]] name = "clap_lex" -version = "0.3.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "codespan-reporting" @@ -581,6 +627,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + +[[package]] +name = "concolor-query" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" +dependencies = [ + "windows-sys 0.45.0", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -603,11 +664,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[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" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "costs" @@ -621,13 +692,22 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "criterion" version = "0.3.6" @@ -786,9 +866,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c00419335c41018365ddf7e4d5f1c12ee3659ddcf3e01974650ba1de73d038" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" dependencies = [ "cc", "cxxbridge-flags", @@ -798,9 +878,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8307ad413a98fff033c8545ecf133e3257747b3bae935e7602aab8aa92d4ca" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" dependencies = [ "cc", "codespan-reporting", @@ -808,24 +888,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.8", + "syn 2.0.13", ] [[package]] name = "cxxbridge-flags" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc52e2eb08915cb12596d29d55f0b5384f00d697a646dbd269b6ecb0fbd9d31" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" [[package]] name = "cxxbridge-macro" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.13", ] [[package]] @@ -877,12 +957,27 @@ dependencies = [ "serde", ] +[[package]] +name = "dashcore" +version = "0.29.1" +source = "git+https://github.com/dashpay/rust-dashcore?rev=51548a4a1b9eca7430f5f3caf94d9784886ff2e9#51548a4a1b9eca7430f5f3caf94d9784886ff2e9" +dependencies = [ + "anyhow", + "bech32", + "bitcoin_hashes 0.10.0", + "hex", + "rustversion", + "secp256k1", + "serde", +] + [[package]] name = "dashcore-rpc" version = "0.15.0" -source = "git+https://github.com/jawid-h/rust-dashcore-rpc?branch=fix/attempt-to-fix#5dbc28583ef77d0b6eca3b3519448569bc41ce8d" +source = "git+https://github.com/dashevo/rust-dashcore-rpc#fde07c63e90a70b1aa4d6c41d89fb8d2eda289b4" dependencies = [ "dashcore-rpc-json", + "env_logger 0.10.0", "jsonrpc", "log", "serde", @@ -892,11 +987,13 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.15.0" -source = "git+https://github.com/jawid-h/rust-dashcore-rpc?branch=fix/attempt-to-fix#5dbc28583ef77d0b6eca3b3519448569bc41ce8d" +source = "git+https://github.com/dashevo/rust-dashcore-rpc#fde07c63e90a70b1aa4d6c41d89fb8d2eda289b4" dependencies = [ - "dashcore", + "dashcore 0.29.1 (git+https://github.com/dashpay/rust-dashcore?rev=51548a4a1b9eca7430f5f3caf94d9784886ff2e9)", + "hex", "serde", "serde_json", + "serde_repr", "serde_with", ] @@ -997,9 +1094,9 @@ dependencies = [ "byteorder", "chrono", "ciborium", - "dashcore", + "dashcore 0.29.1 (git+https://github.com/dashevo/rust-dashcore?rev=51548a4a1b9eca7430f5f3caf94d9784886ff2e9)", "data-contracts", - "env_logger", + "env_logger 0.9.3", "futures", "getrandom", "hex", @@ -1072,8 +1169,8 @@ dependencies = [ "bytes", "chrono", "ciborium", - "clap 4.1.13", - "dashcore", + "clap 4.2.1", + "dashcore 0.29.1 (git+https://github.com/dashevo/rust-dashcore?rev=51548a4a1b9eca7430f5f3caf94d9784886ff2e9)", "dashcore-rpc", "dotenvy", "dpp", @@ -1135,6 +1232,15 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "enum-map" version = "2.5.0" @@ -1168,6 +1274,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "envy" version = "0.4.2" @@ -1179,13 +1298,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.45.0", ] [[package]] @@ -1272,6 +1391,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flex-error" version = "0.4.4" @@ -1296,6 +1425,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.1.0" @@ -1335,9 +1479,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -1350,9 +1494,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -1360,15 +1504,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -1377,38 +1521,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.13", ] [[package]] name = "futures-sink" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -1424,9 +1568,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1451,21 +1595,6 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" -[[package]] -name = "git2" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" -dependencies = [ - "bitflags", - "libc", - "libgit2-sys", - "log", - "openssl-probe", - "openssl-sys", - "url", -] - [[package]] name = "glob" version = "0.3.1" @@ -1504,6 +1633,25 @@ dependencies = [ "visualize", ] +[[package]] +name = "h2" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "1.8.2" @@ -1572,6 +1720,9 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hkdf" @@ -1593,12 +1744,83 @@ dependencies = [ "digest 0.9.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 = "hyper" +version = "0.14.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +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-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.54" @@ -1641,9 +1863,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", @@ -1685,11 +1907,17 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + [[package]] name = "is-terminal" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", @@ -1838,20 +2066,6 @@ version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" -[[package]] -name = "libgit2-sys" -version = "0.14.2+1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4" -dependencies = [ - "cc", - "libc", - "libssh2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", -] - [[package]] name = "libloading" version = "0.6.7" @@ -1887,20 +2101,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "libssh2-sys" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - [[package]] name = "libz-sys" version = "1.1.8" @@ -1908,7 +2108,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" dependencies = [ "cc", - "libc", "pkg-config", "vcpkg", ] @@ -1924,9 +2123,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "lock_api" @@ -2025,6 +2224,12 @@ dependencies = [ "visualize", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2054,9 +2259,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" dependencies = [ "cfg-if 1.0.0", "downcast", @@ -2069,9 +2274,9 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if 1.0.0", "proc-macro2", @@ -2107,6 +2312,24 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[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 = "neon" version = "0.10.1" @@ -2378,6 +2601,32 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "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", + "quote", + "syn 2.0.13", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -2386,23 +2635,16 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.83" +version = "0.9.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" +checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", "vcpkg", ] -[[package]] -name = "os_str_bytes" -version = "6.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" - [[package]] name = "output_vt100" version = "0.1.3" @@ -2445,7 +2687,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "windows-sys 0.45.0", ] @@ -2639,9 +2881,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.53" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -2832,11 +3074,20 @@ 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 = "regex" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce168fea28d3e05f158bda4576cf0c844d5045bc2cc3620fa0292ed5bb5814c" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", @@ -2867,11 +3118,48 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "reqwest" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rkyv" -version = "0.7.40" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c30f1d45d9aa61cbc8cd1eb87705470892289bb2d01943e7803b873a57404dc3" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" dependencies = [ "bytecheck", "hashbrown 0.12.3", @@ -2883,9 +3171,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.40" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff26ed6c7c4dfc2aa9480b86a60e3c7233543a270a680e10758a507c5a4ce476" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" dependencies = [ "proc-macro2", "quote", @@ -2904,9 +3192,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.29.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b1b21b8760b0ef8ae5b43d40913ff711a2053cb7ff892a34facff7a6365375a" +checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc" dependencies = [ "arrayvec", "borsh", @@ -2922,9 +3210,9 @@ dependencies = [ [[package]] name = "rust_decimal_macros" -version = "1.29.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4709403426683ccd5e1ef02b24a2468fe87f8df8a2a792743bb369d7656efa" +checksum = "0e773fd3da1ed42472fdf3cfdb4972948a555bc3d73f5e0bdb99d17e7b54c687" dependencies = [ "quote", "rust_decimal", @@ -2953,9 +3241,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.11" +version = "0.37.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" +checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" dependencies = [ "bitflags", "errno", @@ -2986,6 +3274,15 @@ dependencies = [ "winapi-util", ] +[[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 = "scheduled-thread-pool" version = "0.2.7" @@ -3034,6 +3331,29 @@ dependencies = [ "cc", ] +[[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 = "0.9.0" @@ -3060,9 +3380,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.158" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] @@ -3108,20 +3428,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.158" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.13", ] [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" dependencies = [ "indexmap", "itoa", @@ -3137,7 +3457,19 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.13", +] + +[[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]] @@ -3369,9 +3701,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.8" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" dependencies = [ "proc-macro2", "quote", @@ -3415,21 +3747,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if 1.0.0", "fastrand", - "redox_syscall", + "redox_syscall 0.3.5", "rustix", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "tenderdash-abci" version = "0.12.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci?branch=master#20ff131666e9cdc080e9ab2c70e1da2e8cef91e1" +source = "git+https://github.com/dashpay/rs-tenderdash-abci?branch=master#313c68396b9798a794a7c7154189989c8da5c22b" dependencies = [ "bytes", "prost", @@ -3444,7 +3776,7 @@ dependencies = [ [[package]] name = "tenderdash-proto" version = "0.12.0-dev.1" -source = "git+https://github.com/dashpay/rs-tenderdash-abci?branch=master#20ff131666e9cdc080e9ab2c70e1da2e8cef91e1" +source = "git+https://github.com/dashpay/rs-tenderdash-abci?branch=master#313c68396b9798a794a7c7154189989c8da5c22b" dependencies = [ "bytes", "chrono", @@ -3464,14 +3796,16 @@ dependencies = [ [[package]] name = "tenderdash-proto-compiler" version = "0.1.0" -source = "git+https://github.com/dashpay/rs-tenderdash-abci?branch=master#20ff131666e9cdc080e9ab2c70e1da2e8cef91e1" +source = "git+https://github.com/dashpay/rs-tenderdash-abci?branch=master#313c68396b9798a794a7c7154189989c8da5c22b" dependencies = [ - "git2", + "fs_extra", "prost-build", "regex", + "reqwest", "subtle-encoding", "tempfile", "walkdir", + "zip", ] [[package]] @@ -3537,7 +3871,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.8", + "syn 2.0.13", ] [[package]] @@ -3615,14 +3949,13 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.26.0" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", "parking_lot", @@ -3635,13 +3968,37 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.13", +] + +[[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-util" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", ] [[package]] @@ -3670,6 +4027,12 @@ dependencies = [ "winnow", ] +[[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" @@ -3721,6 +4084,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "typenum" version = "1.16.0" @@ -3798,6 +4167,12 @@ dependencies = [ "percent-encoding", ] +[[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" @@ -3844,6 +4219,16 @@ dependencies = [ "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.10.0+wasi-snapshot-preview1" @@ -4085,13 +4470,22 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "winnow" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deac0939bd6e4f24ab5919fbf751c97a8cfc8543bb083a305ed5c0c10bb241d1" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" 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 = "withdrawals-contract" version = "0.24.0-dev.1" @@ -4116,9 +4510,21 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + +[[package]] +name = "zip" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils 0.8.15", + "flate2", +] [[package]] name = "zstd-sys" diff --git a/packages/rs-drive-abci/.env.example b/packages/rs-drive-abci/.env.example index a044839b74b..a4a9e408e44 100644 --- a/packages/rs-drive-abci/.env.example +++ b/packages/rs-drive-abci/.env.example @@ -29,6 +29,10 @@ INITIAL_CORE_CHAINLOCKED_HEIGHT=1243 # https://github.com/dashevo/dashcore-lib/blob/286c33a9d29d33f05d874c47a9b33764a0be0cf1/lib/constants/index.js#L42-L57 VALIDATOR_SET_LLMQ_TYPE=100 VALIDATOR_SET_QUORUM_ROTATION_BLOCK_COUNT=1024 + +DKG_INTERVAL= +MIN_QUORUM_VALID_MEMBERS= + # DPNS Contract DPNS_MASTER_PUBLIC_KEY=02649a81b760e8635dd3a4fad8911388ed09d7c1680558a890180d4edc8bcece7e diff --git a/packages/rs-drive-abci/Cargo.toml b/packages/rs-drive-abci/Cargo.toml index d49514ab18a..e24d985b031 100644 --- a/packages/rs-drive-abci/Cargo.toml +++ b/packages/rs-drive-abci/Cargo.toml @@ -33,7 +33,7 @@ dashcore = { git = "https://github.com/dashevo/rust-dashcore", features = [ "signer", "use-serde", ], default-features = false, rev = "51548a4a1b9eca7430f5f3caf94d9784886ff2e9" } -dashcore-rpc = { git = "https://github.com/jawid-h/rust-dashcore-rpc", branch = "fix/attempt-to-fix" } +dashcore-rpc = { git = "https://github.com/dashevo/rust-dashcore-rpc" } # path = "../../../rust-dashcore-rpc/client" dpp = { path = "../rs-dpp", features = ["fixtures-and-mocks"] } rust_decimal = "1.2.5" rust_decimal_macros = "1.25.0" diff --git a/packages/rs-drive-abci/src/abci/handlers.rs b/packages/rs-drive-abci/src/abci/handlers.rs index e08371cc5fd..3fc72f2cc94 100644 --- a/packages/rs-drive-abci/src/abci/handlers.rs +++ b/packages/rs-drive-abci/src/abci/handlers.rs @@ -251,8 +251,8 @@ mod tests { use crate::config::PlatformConfig; use crate::rpc::core::MockCoreRPCLike; use chrono::{Duration, Utc}; - use dashcore::hashes::hex::FromHex; - use dashcore::BlockHash; + use dashcore_rpc::dashcore::hashes::hex::FromHex; + use dashcore_rpc::dashcore::BlockHash; use dpp::contracts::withdrawals_contract; use dpp::data_contract::DriveContractExt; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; diff --git a/packages/rs-drive-abci/src/abci/server.rs b/packages/rs-drive-abci/src/abci/server.rs index a842ed4a06c..cf4d47ad263 100644 --- a/packages/rs-drive-abci/src/abci/server.rs +++ b/packages/rs-drive-abci/src/abci/server.rs @@ -35,12 +35,9 @@ pub fn start(config: &PlatformConfig) -> Result<(), Error> { loop { tracing::info!("waiting for new connection"); - let result = std::panic::catch_unwind(|| match server.handle_connection() { - Ok(_) => (), + match server.handle_connection() { Err(e) => tracing::error!("tenderdash connection terminated: {:?}", e), - }); - if let Err(_e) = result { - tracing::error!("panic: connection terminated"); + Ok(_) => tracing::info!("tenderdash connection closed"), } } } diff --git a/packages/rs-drive-abci/src/abci/validator_set.rs b/packages/rs-drive-abci/src/abci/validator_set.rs index 0d6ee174edd..dafac837496 100644 --- a/packages/rs-drive-abci/src/abci/validator_set.rs +++ b/packages/rs-drive-abci/src/abci/validator_set.rs @@ -2,12 +2,15 @@ //! //! -use dashcore_rpc::dashcore_rpc_json::{QuorumHash, QuorumInfoResult, QuorumType}; +use dashcore_rpc::dashcore::hashes::{sha256, Hash, HashEngine}; +use dashcore_rpc::dashcore_rpc_json::{ + ExtendedQuorumDetails, QuorumHash, QuorumInfoResult, QuorumType, +}; use tenderdash_abci::proto::{abci, crypto as abci_crypto}; use crate::{ config::PlatformConfig, - rpc::core::{CoreHeight, CoreRPCLike}, + rpc::core::{CoreHeight, CoreRPCLike, QuorumListExtendedInfo}, }; /// ValidatorSet contains validators that should be in use at a given height. @@ -33,11 +36,12 @@ impl From for tenderdash_abci::proto::abci::ValidatorSetUpdate { if !validator.valid { continue; } + let pubkey = validator.pub_key_share.map(|k| u8_to_bls12381_pubkey(k)); let vu = abci::ValidatorUpdate { node_address: Default::default(), - power: 100, // TODO: double-check - pub_key: pubkey, // TODO: double-check if it should be pub_key_share + power: 100, // FIXME: double-check + pub_key: pubkey, // FIXME: double-check if it should be pub_key_share pro_tx_hash: validator.pro_tx_hash.0, }; @@ -70,7 +74,6 @@ impl ValidatorSet { quorum_type: &QuorumType, seed: Option>, ) -> Result { - // TODO: parse QuorumInfoResult to return let quorums = client.get_quorum_listextended(Some(core_height))?; let quorums = match quorum_type { QuorumType::Llmq50_60 => quorums.llmq_50_60, @@ -100,28 +103,28 @@ impl ValidatorSet { seed.unwrap() }; - let quorum_hash = + let quorum = Self::choose_random_quorum(config, core_height, &quorum_type, &quorums, &entropy)?; let quorum_info = client - .get_quorum_info(quorum_type.clone().into(), &quorum_hash, Some(false)) + .get_quorum_info(quorum_type.clone().into(), &quorum.into(), Some(false)) .map_err(|e| ValSetError::RpcError(e))?; Ok(Self { quorum_info }) } - /// Returns best quorum to use - /// TODO: replace Vec with Vec + /// Returns quorum to use at provided height fn choose_random_quorum( config: &PlatformConfig, core_height: CoreHeight, quorum_type: &QuorumType, - quorums_extended_info: &Vec, + quorums_extended_info: &Vec, entropy: &Vec, - ) -> Result { - // TODO: migrate to config file - const DKG_INTERVAL: CoreHeight = 24; - const MIN_QUORUM_VALID_MEMBERS: CoreHeight = 3; + ) -> Result { + // read some config let rotation_block_interval: CoreHeight = config.validator_set_quorum_rotation_block_count; + let min_valid_members = config.core.min_quorum_valid_members; + let dkg_interval = config.core.dkg_interval; + let min_ttl: CoreHeight = rotation_block_interval * 3; let number_of_quorums = quorums_extended_info.len() as u32; @@ -129,56 +132,76 @@ impl ValidatorSet { return Err(ValSetError::NoQuorumAtHeight(None, quorum_type.to_owned())); } - // let quorum_hash = quorums_extended_info - // .first() - // .ok_or(ValSetError::NoQuorumAtHeight(None, quorum_type.to_owned()))?; + // First, convert dashcore rpc quorum info into our Quorum struct + let quorums = quorums_extended_info + .into_iter() + .flatten() + .map(|(hash, details)| Quorum::new(hash, details, entropy)) + .collect::>(); - let quorums_weighted = quorums_extended_info + // Now, let's filter quorums. We use iter() to not consume `quorums`, needed later + let mut filtered_quorums = quorums .iter() - .map(|item| QuorumWeighted::new(item, entropy)) - .collect::>(); - - let mut final_quorums = quorums_weighted - .iter() - .filter(|_item| { - // TODO: read the items below from quorums_extended_info - let num_valid_members = 3; - - num_valid_members >= MIN_QUORUM_VALID_MEMBERS + .filter(|item| { + item.num_valid_members >= min_valid_members + && item.quorum_ttl(core_height, dkg_interval, number_of_quorums) > min_ttl }) - .filter(|item| item.quorum_ttl(core_height, DKG_INTERVAL, number_of_quorums) > min_ttl) - .collect::>(); - // let mut filtered_quorums = &filtered_quorums; + .collect::>(); + // if there is no "vital" quorums, we choose among others with default min quorum size - if final_quorums.len() == 0 { - final_quorums = quorums_weighted.iter().collect::>(); + if filtered_quorums.len() == 0 { + filtered_quorums = quorums.iter().collect::>(); } - // Now we select best quorum, based on some scoring algorithm. - final_quorums.sort(); - let winner = final_quorums.first().ok_or(ValSetError::NoQuorumAtHeight( - Some(core_height), - quorum_type.to_owned(), - ))?; - - // TODO: when dashcore_rpc is updated, use winner.unwrap().quorum_details.quorum_hash below - Ok(QuorumHash(winner.quorum_details.to_owned())) + // Now we select the final quorum, based on some scoring algorithm. + filtered_quorums.sort(); + let winner = filtered_quorums + .into_iter() + .next() + .ok_or(ValSetError::NoQuorumAtHeight( + Some(core_height), + quorum_type.to_owned(), + ))?; + + Ok(winner.to_owned()) } } +impl From for QuorumHash { + fn from(value: Quorum) -> Self { + QuorumHash(value.quorum_hash) + } +} /// Quorum info with additional weight details. Easy to sort by weight. -#[derive(PartialEq, Eq, PartialOrd, Ord)] -struct QuorumWeighted { +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone)] +struct Quorum { // ensure weight is first, as it metters when sorting weight: Vec, - quorum_details: Vec, + + quorum_hash: Vec, + + creation_height: u32, + quorum_index: Option, + // mined_block_hash: BlockHash, + num_valid_members: u32, + health_ratio: i32, } -impl QuorumWeighted { - fn new(quorum_details: &QuorumHash, entropy: &Vec) -> Self { - QuorumWeighted { - quorum_details: quorum_details.0.to_owned(), - weight: Self::calculate_weight(quorum_details, entropy), +impl Quorum { + fn new( + quorum_hash: &QuorumHash, + quorum_details: &ExtendedQuorumDetails, + entropy: &Vec, + ) -> Self { + Quorum { + weight: Self::calculate_weight(quorum_hash, entropy), + + quorum_hash: quorum_hash.0.clone(), + creation_height: quorum_details.creation_height, + // To avoid playing with floats, which don't implement Ord, we just multiply health ratio by 10^6 + health_ratio: (quorum_details.health_ratio * 1000000.0).round() as i32, + num_valid_members: quorum_details.num_valid_members, + quorum_index: quorum_details.quorum_index, } } @@ -187,7 +210,9 @@ impl QuorumWeighted { let mut hash = quorum_hash.0.clone(); hash.extend(entropy); - hash + let mut hasher = sha256::HashEngine::default(); + hasher.input(&hash); + sha256::Hash::from_engine(hasher).to_vec() } /// Calculate estimated quorum time-to-live @@ -197,10 +222,11 @@ impl QuorumWeighted { dkg_interval: u32, number_of_quorums: u32, ) -> u32 { - // TODO: read the item below from quorums_extended_info - let creation_height: CoreHeight = 2000; - - let quorum_remove_height: CoreHeight = creation_height + (dkg_interval * number_of_quorums); + let quorum_remove_height: CoreHeight = + self.creation_height + (dkg_interval * number_of_quorums); + if quorum_remove_height <= core_height { + return 0; + } let how_much_in_rest: CoreHeight = quorum_remove_height - core_height; let quorum_ttl: u32 = how_much_in_rest * 5 / 2; // multiply by 2.5, round down @@ -222,21 +248,47 @@ pub enum ValSetError { /// Quorum with given hash not found #[error{"No quorum with hash {0:?} of type {1:?} found"}] QuorumNotFound(QuorumHash, QuorumType), + + /// Quorum with given hash not found + #[error{"Invalid format of field {field}: {details}"}] + InvalidDataFormat { field: String, details: String }, } #[cfg(test)] mod tests { - use dashcore_rpc::dashcore_rpc_json::{QuorumHash, QuorumInfoResult}; + use dashcore_rpc::dashcore::{hashes::Hash, BlockHash}; + use dashcore_rpc::dashcore_rpc_json::{ExtendedQuorumDetails, QuorumHash, QuorumInfoResult}; use tenderdash_abci::proto::abci::ValidatorSetUpdate; - use crate::config::PlatformConfig; + use crate::{config::PlatformConfig, rpc::core::QuorumListExtendedInfo}; + + fn generate_quorums_extended_info(n: u32) -> QuorumListExtendedInfo { + let mut quorums = QuorumListExtendedInfo::new(); + + for i in 0..n { + let i_bytes = [i as u8; 32]; + + let hash = QuorumHash(i_bytes.to_vec()); + + let details = ExtendedQuorumDetails { + creation_height: i, + health_ratio: (i as f32) / (n as f32), + mined_block_hash: BlockHash::from_slice(&i_bytes).unwrap(), + num_valid_members: i, + quorum_index: Some(i), + }; + + quorums + .insert(hash.clone(), details) + .map(|v| panic!("duplicate record {:?}={:?}", hash, v)); + } + quorums + } #[test] fn test_new_random_at_height() { const CORE_HEIGHT: u32 = 2000; let quorum_type = dashcore_rpc::dashcore_rpc_json::QuorumType::Llmq50_60; - let quorum1 = QuorumHash(vec![1u8; 32]); - let winning_quorum = quorum1.clone(); let config = PlatformConfig::default(); let mut client = crate::rpc::core::MockCoreRPCLike::new(); @@ -244,15 +296,24 @@ mod tests { .expect_get_quorum_listextended() .returning(move |_| { Ok(dashcore_rpc::dashcore_rpc_json::QuorumListResult { - llmq_50_60: Some(vec![quorum1.clone()]), + llmq_50_60: Some(vec![generate_quorums_extended_info(100)]), llmq_400_60: None, llmq_400_85: None, llmq_100_67: None, + llmq_60_75: None, + llmq_25_67: None, + // for devnets only + llmq_devnet: None, + llmq_devnet_platform: None, + // for devnets only. rotated version (v2) for devnets + llmq_devnet_dip0024: None, + // for testing only llmq_test: None, llmq_test_instantsend: None, llmq_test_v17: None, llmq_test_dip0024: None, llmq_test_platform: None, + // TODO: simplify with ..Default::default() when it's implemented by dashcore_rpc }) }) .once(); @@ -278,6 +339,6 @@ mod tests { .expect("failed to fetch validator set"); let vsu = ValidatorSetUpdate::from(vset); - assert_eq!(vsu.quorum_hash, winning_quorum.0); + assert_eq!(vsu.quorum_hash, [17u8; 32]); } } diff --git a/packages/rs-drive-abci/src/config.rs b/packages/rs-drive-abci/src/config.rs index 6dce3f4a74a..4ca7ae8fa5f 100644 --- a/packages/rs-drive-abci/src/config.rs +++ b/packages/rs-drive-abci/src/config.rs @@ -61,12 +61,39 @@ impl CoreRpcConfig { } } +impl Default for CoreRpcConfig { + fn default() -> Self { + Self { + host: String::from("127.0.0.1"), + port: String::from("1234"), + username: String::from(""), + password: String::from(""), + } + } +} + /// Configuration for Dash Core related things #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(default)] pub struct CoreConfig { /// Core RPC config #[serde(flatten)] pub rpc: CoreRpcConfig, + + /// DKG interval + pub dkg_interval: u32, + /// Minimum number of valid members to use the quorum + pub min_quorum_valid_members: u32, +} + +impl Default for CoreConfig { + fn default() -> Self { + Self { + dkg_interval: 24, + min_quorum_valid_members: 3, + rpc: Default::default(), + } + } } /// Configurtion of Dash Platform. @@ -141,14 +168,7 @@ impl Default for PlatformConfig { validator_set_quorum_rotation_block_count: 15, drive: Default::default(), abci: Default::default(), - core: CoreConfig { - rpc: CoreRpcConfig { - host: "127.0.0.1".to_owned(), - port: "0".to_owned(), - username: "".to_owned(), - password: "".to_owned(), - }, - }, + core: Default::default(), db_path: PathBuf::from("/var/lib/dash-platform/data"), } } diff --git a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs index c4d788514bd..dc10c3798ea 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, ops::Deref}; -use dashcore::{ +use dashcore_rpc::dashcore::{ blockdata::transaction::special_transaction::asset_unlock::{ request_info::AssetUnlockRequestInfo, unqualified_asset_unlock::{AssetUnlockBasePayload, AssetUnlockBaseTransactionInfo}, @@ -533,7 +533,7 @@ impl Platform { #[cfg(test)] mod tests { - use dashcore::{ + use dashcore_rpc::dashcore::{ hashes::hex::{FromHex, ToHex}, BlockHash, }; diff --git a/packages/rs-drive-abci/src/platform.rs b/packages/rs-drive-abci/src/platform.rs index c9bfaa22754..5e478e95cf8 100644 --- a/packages/rs-drive-abci/src/platform.rs +++ b/packages/rs-drive-abci/src/platform.rs @@ -47,7 +47,7 @@ use crate::rpc::core::MockCoreRPCLike; #[cfg(feature = "fixtures-and-mocks")] use dashcore::hashes::hex::FromHex; #[cfg(feature = "fixtures-and-mocks")] -use dashcore::BlockHash; +use dashcore_rpc::dashcore::BlockHash; #[cfg(feature = "fixtures-and-mocks")] use serde_json::json; diff --git a/packages/rs-drive-abci/src/rpc/core.rs b/packages/rs-drive-abci/src/rpc/core.rs index 6450f0b9462..41835e1083a 100644 --- a/packages/rs-drive-abci/src/rpc/core.rs +++ b/packages/rs-drive-abci/src/rpc/core.rs @@ -1,6 +1,10 @@ -use dashcore::{Block, BlockHash}; +use std::collections::HashMap; + +use dashcore_rpc::dashcore::{Block, BlockHash}; use dashcore_rpc::{ - dashcore_rpc_json::{QuorumHash, QuorumInfoResult, QuorumListResult, QuorumType}, + dashcore_rpc_json::{ + ExtendedQuorumDetails, QuorumHash, QuorumInfoResult, QuorumListResult, QuorumType, + }, Auth, Client, Error, RpcApi, }; @@ -8,6 +12,9 @@ use dashcore_rpc::{ use mockall::{automock, predicate::*}; use serde_json::Value; +/// Information returned by QuorumListExtended +pub type QuorumListExtendedInfo = HashMap; + /// Core height must be of type u32 (Platform heights are u64) pub type CoreHeight = u32; /// Core RPC interface @@ -28,7 +35,7 @@ pub trait CoreRPCLike { fn get_quorum_listextended( &self, height: Option, - ) -> Result; + ) -> Result, Error>; /// Get quorum information. /// @@ -70,7 +77,7 @@ impl CoreRPCLike for DefaultCoreRPC { fn get_quorum_listextended( &self, height: Option, - ) -> Result { + ) -> Result, Error> { self.inner.get_quorum_listextended(height.map(|i| i as i64)) } diff --git a/packages/rs-drive-nodejs/src/lib.rs b/packages/rs-drive-nodejs/src/lib.rs index 31abef54eb0..d07ac534071 100644 --- a/packages/rs-drive-nodejs/src/lib.rs +++ b/packages/rs-drive-nodejs/src/lib.rs @@ -129,6 +129,7 @@ impl PlatformWrapper { username: core_rpc_username, password: core_rpc_password, }, + ..Default::default() }; let platform_config = PlatformConfig {