From 00421c8b06b3a5efc5f897fd36f8a69eb1e01256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 16 May 2022 16:52:28 +0100 Subject: [PATCH] decoding validator address when validating dealer eligibility --- contracts/coconut-dkg/Cargo.toml | 1 + .../coconut-dkg/src/dealers/transactions.rs | 21 +++++++++++++++---- contracts/coconut-dkg/src/error.rs | 7 ++++++- validator-api/src/dkg/mod.rs | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/contracts/coconut-dkg/Cargo.toml b/contracts/coconut-dkg/Cargo.toml index a83aca344b..1b0187196f 100644 --- a/contracts/coconut-dkg/Cargo.toml +++ b/contracts/coconut-dkg/Cargo.toml @@ -17,4 +17,5 @@ cosmwasm-std = { version = "1.0.0-beta8", features = ["staking"] } cosmwasm-storage = "1.0.0-beta8" cw-storage-plus = "0.13.2" serde = { version = "1.0.103", default-features = false, features = ["derive"] } +bech32 = "0.9.0" thiserror = "1.0.23" diff --git a/contracts/coconut-dkg/src/dealers/transactions.rs b/contracts/coconut-dkg/src/dealers/transactions.rs index 504a059815..e26cc82ec4 100644 --- a/contracts/coconut-dkg/src/dealers/transactions.rs +++ b/contracts/coconut-dkg/src/dealers/transactions.rs @@ -37,11 +37,24 @@ fn verify_dealer( return Err(ContractError::AlreadyADealer); } + // validator addresses are using a different prefix, so we need to check if their underlying + // data is the same as the senders address + // for example, for sender `nymt1qs3k39g2sw7qcqn0u2eedkpszl02hu605uymu2`, where bech32 prefix is "nymt", + // the associated validator address is `nymtvaloper1qs3k39g2sw7qcqn0u2eedkpszl02hu60jph657` + + // this is impossible to fail as the address has been validated by the validator's api, + // but catch it with an error just in case anyway... + let (_, data, _) = + bech32::decode(dealer.as_ref()).map_err(|_| ContractError::InvalidValidatedAddress { + address: dealer.clone(), + })?; + let all_validators = deps.querier.query_all_validators()?; - if !all_validators - .iter() - .any(|validator| validator.address == dealer.as_ref()) - { + if !all_validators.iter().any(|validator| { + bech32::decode(&validator.address) + .map(|(_, validator_data, _)| validator_data == data) + .unwrap_or_default() + }) { return Err(ContractError::NotAValidator); } diff --git a/contracts/coconut-dkg/src/error.rs b/contracts/coconut-dkg/src/error.rs index bc1be7d192..421f42d3d6 100644 --- a/contracts/coconut-dkg/src/error.rs +++ b/contracts/coconut-dkg/src/error.rs @@ -3,7 +3,7 @@ use coconut_dkg_common::types::Blacklisting; use config::defaults::STAKE_DENOM; -use cosmwasm_std::{StdError, VerificationError}; +use cosmwasm_std::{Addr, StdError, VerificationError}; use thiserror::Error; /// Custom errors for contract failure conditions. @@ -50,4 +50,9 @@ pub enum ContractError { #[error("Attempted to set the current epoch state to finish in the past")] EpochStateFinishInPast, + + // we should never ever see this error (famous last words in programming), therefore, I'd want to + // explicitly declare it so that when we ultimate do see it, it's gonna be more informative over "normal" panic + #[error("Somehow our validated address {address} is not using correct bech32 encoding")] + InvalidValidatedAddress { address: Addr }, } diff --git a/validator-api/src/dkg/mod.rs b/validator-api/src/dkg/mod.rs index 2f66e948a7..987561026e 100644 --- a/validator-api/src/dkg/mod.rs +++ b/validator-api/src/dkg/mod.rs @@ -112,7 +112,7 @@ fn make_client() -> Client { // this one is irrelevant as we don't need to call it let api_url = "http://localhost:8080".parse().unwrap(); - let contract_address = "nymt14hj2tavq8fpesdwxxcu44rty3hh90vhuysqrsr" + let contract_address = "nymt1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrqf95z3q" .parse() .unwrap();