From b919bd3d35f8704f6f661ea44c76fbd74616b7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 17 May 2022 12:42:45 +0100 Subject: [PATCH] Recovering assigned node index --- .../nymd/cosmwasm_client/signing_client.rs | 2 ++ .../src/nymd/traits/dkg_client.rs | 20 +++++++++++++ .../coconut-dkg-contract/src/dealer.rs | 30 +++++++++++++++++++ .../coconut-dkg-contract/src/msg.rs | 3 ++ contracts/Cargo.lock | 7 +++++ contracts/coconut-dkg/src/dealers/queries.rs | 20 ++++++++++++- contracts/coconut-dkg/src/lib.rs | 5 +++- validator-api/src/dkg/error.rs | 5 +++- validator-api/src/dkg/main_loop/mod.rs | 13 +++++--- .../src/dkg/smart_contract/publisher/mod.rs | 16 ++++++++-- validator-api/src/dkg/state/mod.rs | 6 ++++ validator-api/src/nymd_client.rs | 13 ++++++++ 12 files changed, 130 insertions(+), 10 deletions(-) diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs index 50b0f9dfe6..a61f122d30 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs @@ -320,6 +320,8 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .await? .check_response()?; + println!("height: {}", tx_res.height); + let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); Ok(ExecuteResult { diff --git a/common/client-libs/validator-client/src/nymd/traits/dkg_client.rs b/common/client-libs/validator-client/src/nymd/traits/dkg_client.rs index 440c666fbf..1585f2ac15 100644 --- a/common/client-libs/validator-client/src/nymd/traits/dkg_client.rs +++ b/common/client-libs/validator-client/src/nymd/traits/dkg_client.rs @@ -5,16 +5,22 @@ use crate::nymd::cosmwasm_client::types::ExecuteResult; use crate::nymd::error::NymdError; use crate::nymd::{cosmwasm_coin_to_cosmos_coin, Fee, NymdClient, SigningCosmWasmClient}; use async_trait::async_trait; +use coconut_dkg_common::dealer::DealerDetailsResponse; use coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg; use coconut_dkg_common::msg::QueryMsg as DkgQueryMsg; use coconut_dkg_common::types::{ BlacklistingResponse, EncodedBTEPublicKeyWithProof, EncodedEd25519PublicKey, Epoch, MinimumDepositResponse, PagedBlacklistingResponse, PagedDealerResponse, }; +use cosmrs::AccountId; #[async_trait] pub trait DkgClient { async fn get_current_dkg_epoch(&self) -> Result; + async fn get_dealer_details( + &self, + address: &AccountId, + ) -> Result; async fn get_current_dealers_paged( &self, start_after: Option, @@ -63,6 +69,19 @@ where .query_contract_smart(self.coconut_dkg_contract_address()?, &request) .await } + + async fn get_dealer_details( + &self, + address: &AccountId, + ) -> Result { + let request = DkgQueryMsg::GetDealerDetails { + dealer_address: address.to_string(), + }; + self.client + .query_contract_smart(self.coconut_dkg_contract_address()?, &request) + .await + } + async fn get_current_dealers_paged( &self, start_after: Option, @@ -76,6 +95,7 @@ where .query_contract_smart(self.coconut_dkg_contract_address()?, &request) .await } + async fn get_past_dealers_paged( &self, start_after: Option, diff --git a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/dealer.rs b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/dealer.rs index 05863335cf..2f2ce2b072 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/dealer.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/dealer.rs @@ -88,6 +88,36 @@ impl Display for BlacklistingReason { } } +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum DealerType { + Current, + Past, + Unknown, +} + +impl DealerType { + pub fn is_current(&self) -> bool { + matches!(&self, DealerType::Current) + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(rename_all = "snake_case")] +pub struct DealerDetailsResponse { + pub details: Option, + pub dealer_type: DealerType, +} + +impl DealerDetailsResponse { + pub fn new(details: Option, dealer_type: DealerType) -> Self { + DealerDetailsResponse { + details, + dealer_type, + } + } +} + #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "snake_case")] pub struct PagedDealerResponse { diff --git a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/msg.rs index 758451bf6d..24f8f75015 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/msg.rs @@ -38,6 +38,9 @@ pub enum ExecuteMsg { #[serde(rename_all = "snake_case")] pub enum QueryMsg { GetCurrentEpoch {}, + GetDealerDetails { + dealer_address: String, + }, GetCurrentDealers { limit: Option, start_after: Option, diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 81d920c06d..cd4c1414fd 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -66,6 +66,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bech32" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5738be7561b0eeb501ef1d5c5db3f24e01ceb55fededd9b00039aada34966ad" + [[package]] name = "bitflags" version = "1.3.2" @@ -227,6 +233,7 @@ dependencies = [ name = "coconut-dkg" version = "0.1.0" dependencies = [ + "bech32", "bs58", "coconut-dkg-common", "config", diff --git a/contracts/coconut-dkg/src/dealers/queries.rs b/contracts/coconut-dkg/src/dealers/queries.rs index 1a09bcaec8..219665e0a5 100644 --- a/contracts/coconut-dkg/src/dealers/queries.rs +++ b/contracts/coconut-dkg/src/dealers/queries.rs @@ -4,7 +4,8 @@ use crate::dealers::storage; use crate::dealers::storage::{IndexedDealersMap, BLACKLISTED_DEALERS}; use coconut_dkg_common::dealer::{ - BlacklistedDealer, BlacklistingResponse, PagedBlacklistingResponse, PagedDealerResponse, + BlacklistedDealer, BlacklistingResponse, DealerDetailsResponse, DealerType, + PagedBlacklistingResponse, PagedDealerResponse, }; use cosmwasm_std::{Deps, Order, StdResult}; use cw_storage_plus::Bound; @@ -36,6 +37,23 @@ fn query_dealers( Ok(PagedDealerResponse::new(dealers, limit, start_next_after)) } +pub fn query_dealer_details( + deps: Deps<'_>, + dealer_address: String, +) -> StdResult { + let addr = deps.api.addr_validate(&dealer_address)?; + if let Some(current) = storage::current_dealers().may_load(deps.storage, &addr)? { + return Ok(DealerDetailsResponse::new( + Some(current), + DealerType::Current, + )); + } + if let Some(past) = storage::past_dealers().may_load(deps.storage, &addr)? { + return Ok(DealerDetailsResponse::new(Some(past), DealerType::Past)); + } + Ok(DealerDetailsResponse::new(None, DealerType::Unknown)) +} + pub fn query_current_dealers_paged( deps: Deps<'_>, start_after: Option, diff --git a/contracts/coconut-dkg/src/lib.rs b/contracts/coconut-dkg/src/lib.rs index bfb7f733b2..893a8dff21 100644 --- a/contracts/coconut-dkg/src/lib.rs +++ b/contracts/coconut-dkg/src/lib.rs @@ -4,7 +4,7 @@ use crate::constants::MINIMUM_DEPOSIT; use crate::dealers::queries::{ query_blacklisted_dealers_paged, query_blacklisting, query_current_dealers_paged, - query_past_dealers_paged, + query_dealer_details, query_past_dealers_paged, }; use crate::epoch::queries::query_current_epoch; use crate::error::ContractError; @@ -131,6 +131,9 @@ fn reset_contract_state( pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { let response = match msg { QueryMsg::GetCurrentEpoch {} => to_binary(&query_current_epoch(deps.storage)?)?, + QueryMsg::GetDealerDetails { dealer_address } => { + to_binary(&query_dealer_details(deps, dealer_address)?)? + } QueryMsg::GetCurrentDealers { limit, start_after } => { to_binary(&query_current_dealers_paged(deps, start_after, limit)?)? } diff --git a/validator-api/src/dkg/error.rs b/validator-api/src/dkg/error.rs index 90d0fa1fe8..4dce611a1a 100644 --- a/validator-api/src/dkg/error.rs +++ b/validator-api/src/dkg/error.rs @@ -23,9 +23,12 @@ pub enum DkgError { #[error("Failed to serialize message - {0}")] SerializationError(#[from] bincode::Error), + #[error("Failed to recover assigned node index")] + NodeIndexRecoveryError, + #[error("todo")] MalformedDealerDetails, - + #[error("todo")] DeserializationError, } diff --git a/validator-api/src/dkg/main_loop/mod.rs b/validator-api/src/dkg/main_loop/mod.rs index ea0d20e621..7979a9875e 100644 --- a/validator-api/src/dkg/main_loop/mod.rs +++ b/validator-api/src/dkg/main_loop/mod.rs @@ -122,7 +122,7 @@ where .dkg_state .prepare_dealer_registration(chain_address, self.network_host.to_string()); - if let Err(err) = self + match self .contract_publisher .register_dealer( registration.identity, @@ -132,9 +132,14 @@ where ) .await { - error!("failed to register our dealer - {}", err) - } else { - info!("registered our dealer for this DKG round") + Err(err) => error!("failed to register our dealer - {}", err), + Ok(node_index) => { + info!( + "registered our dealer for this DKG round and got assigned index: {}", + node_index + ); + self.dkg_state.post_key_submission(node_index).await + } } } diff --git a/validator-api/src/dkg/smart_contract/publisher/mod.rs b/validator-api/src/dkg/smart_contract/publisher/mod.rs index b0a147f1cd..07f9389409 100644 --- a/validator-api/src/dkg/smart_contract/publisher/mod.rs +++ b/validator-api/src/dkg/smart_contract/publisher/mod.rs @@ -3,7 +3,7 @@ use crate::dkg::error::DkgError; use crate::Client; -use coconut_dkg_common::types::{EncodedBTEPublicKeyWithProof, EncodedEd25519PublicKey}; +use coconut_dkg_common::types::{EncodedBTEPublicKeyWithProof, EncodedEd25519PublicKey, NodeIndex}; use validator_client::nymd::{AccountId, SigningCosmWasmClient}; pub(crate) struct Publisher { @@ -28,11 +28,21 @@ where bte_key: EncodedBTEPublicKeyWithProof, owner_signature: String, listening_address: String, - ) -> Result<(), DkgError> { + ) -> Result { self.client .register_dealer(identity, bte_key, owner_signature, listening_address) .await?; - Ok(()) + + // once we figure out how to properly deserialize `data` field from the response use that + // instead of this query + let self_details = self.client.get_self_registered_dealer_details().await?; + if let Some(details) = self_details.details { + if self_details.dealer_type.is_current() { + return Ok(details.assigned_index); + } + } + + Err(DkgError::NodeIndexRecoveryError) } pub(crate) async fn submit_dealing_commitment(&self) { diff --git a/validator-api/src/dkg/state/mod.rs b/validator-api/src/dkg/state/mod.rs index b189607d8c..e34b97d717 100644 --- a/validator-api/src/dkg/state/mod.rs +++ b/validator-api/src/dkg/state/mod.rs @@ -193,6 +193,12 @@ impl DkgState { todo!() } + pub(crate) async fn post_key_submission(&self, assigned_index: NodeIndex) { + let mut guard = self.inner_state.lock().await; + guard.submitted_keys = true; + guard.assigned_index = assigned_index; + } + pub(crate) async fn is_dealers_remote_address(&self, remote: SocketAddr) -> (bool, Epoch) { let guard = self.inner_state.lock().await; let epoch = guard.current_epoch; diff --git a/validator-api/src/nymd_client.rs b/validator-api/src/nymd_client.rs index 6f78edda73..3e07ba7da4 100644 --- a/validator-api/src/nymd_client.rs +++ b/validator-api/src/nymd_client.rs @@ -5,6 +5,7 @@ use crate::config::Config; use crate::rewarded_set_updater::error::RewardingError; #[cfg(feature = "coconut")] use async_trait::async_trait; +use coconut_dkg_common::dealer::DealerDetailsResponse; use coconut_dkg_common::types::{ BlacklistedDealer, BlacklistingResponse, Coin, DealerDetails, EncodedBTEPublicKeyWithProof, EncodedEd25519PublicKey, Epoch as DkgEpoch, @@ -455,6 +456,18 @@ where self.0.read().await.nymd.get_current_dkg_epoch().await } + pub(crate) async fn get_self_registered_dealer_details( + &self, + ) -> Result { + let self_address = &self.address().await; + self.0 + .read() + .await + .nymd + .get_dealer_details(self_address) + .await + } + pub(crate) async fn get_current_dealers( &self, ) -> Result, ValidatorClientError> {