diff --git a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/lib.rs b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/lib.rs index f1fcac4d04..cf978b6d14 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/lib.rs @@ -2,3 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 pub mod msg; +pub mod types; 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 c9c579db39..4512f48913 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/msg.rs @@ -5,6 +5,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[serde(rename_all = "snake_case")] pub struct InstantiateMsg {} #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] diff --git a/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/types.rs new file mode 100644 index 0000000000..ea59bf4942 --- /dev/null +++ b/common/cosmwasm-smart-contracts/coconut-dkg-contract/src/types.rs @@ -0,0 +1,38 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub struct Blacklisting { + reason: BlacklistingReason, + height: u64, +} + +impl Display for Blacklisting { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "blacklisted at block height {}. reason given: {}", + self.height, self.height + ) + } +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum BlacklistingReason { + InactiveForConsecutiveEpochs, +} + +impl Display for BlacklistingReason { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + BlacklistingReason::InactiveForConsecutiveEpochs => { + write!(f, "has been inactive for multiple consecutive epochs") + } + } + } +} diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 248797bf30..3c34783af9 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -221,6 +221,7 @@ dependencies = [ "config", "cosmwasm-std", "cosmwasm-storage", + "cw-storage-plus", "serde", "thiserror", ] @@ -403,9 +404,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e8b7f9a758c030d375520df947323c052704f784561fc28dcaab4f988c50a30" +checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" dependencies = [ "cosmwasm-std", "schemars", diff --git a/contracts/coconut-dkg/Cargo.toml b/contracts/coconut-dkg/Cargo.toml index 8e8207e99a..6c21c36b92 100644 --- a/contracts/coconut-dkg/Cargo.toml +++ b/contracts/coconut-dkg/Cargo.toml @@ -12,7 +12,8 @@ crate-type = ["cdylib", "rlib"] coconut-dkg-common = { path = "../../common/cosmwasm-smart-contracts/coconut-dkg-contract" } config = { path = "../../common/config"} -cosmwasm-std = "1.0.0-beta8" +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"] } thiserror = "1.0.23" diff --git a/contracts/coconut-dkg/src/error.rs b/contracts/coconut-dkg/src/error.rs index 8302728323..e182198ca9 100644 --- a/contracts/coconut-dkg/src/error.rs +++ b/contracts/coconut-dkg/src/error.rs @@ -1,6 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use coconut_dkg_common::types::Blacklisting; use cosmwasm_std::StdError; use thiserror::Error; @@ -17,4 +18,10 @@ pub enum ContractError { #[error("Wrong coin denomination, you must send {}", DENOM)] WrongDenom, + + #[error("This dealer has been blacklisted - {reason}")] + BlacklistedDealer { reason: Blacklisting }, + + #[error("This potential dealer is not a validator")] + NotAValidator, } diff --git a/contracts/coconut-dkg/src/lib.rs b/contracts/coconut-dkg/src/lib.rs index e835b4e873..c5765037f1 100644 --- a/contracts/coconut-dkg/src/lib.rs +++ b/contracts/coconut-dkg/src/lib.rs @@ -7,6 +7,7 @@ use cosmwasm_std::{entry_point, Deps, DepsMut, Env, MessageInfo, QueryResponse, mod error; mod queries; +mod storage; mod support; mod transactions; diff --git a/contracts/coconut-dkg/src/storage.rs b/contracts/coconut-dkg/src/storage.rs new file mode 100644 index 0000000000..f5b5eb530b --- /dev/null +++ b/contracts/coconut-dkg/src/storage.rs @@ -0,0 +1,8 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use coconut_dkg_common::types::Blacklisting; +use cosmwasm_std::Addr; +use cw_storage_plus::Map; + +pub(crate) const BLACKLISTED_DEALERS: Map<'_, &'_ Addr, Blacklisting> = Map::new("bld"); diff --git a/contracts/coconut-dkg/src/transactions.rs b/contracts/coconut-dkg/src/transactions.rs index 87d5c392c8..a5e8611476 100644 --- a/contracts/coconut-dkg/src/transactions.rs +++ b/contracts/coconut-dkg/src/transactions.rs @@ -1,2 +1,36 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 + +use crate::storage::BLACKLISTED_DEALERS; +use crate::ContractError; +use cosmwasm_std::{ensure, Addr, Deps, DepsMut, Env, MessageInfo, Response, Storage}; + +// currently we only require that +// a) it's a validator +// b) it wasn't blacklisted +fn verify_dealer(deps: Deps<'_>, dealer: &Addr) -> Result<(), ContractError> { + if let Some(blacklisting) = BLACKLISTED_DEALERS.may_load(deps.storage, dealer)? { + return Err(ContractError::BlacklistedDealer { + reason: blacklisting, + }); + } + let all_validators = deps.querier.query_all_validators()?; + if !all_validators + .iter() + .any(|validator| validator.address == dealer.as_ref()) + { + return Err(ContractError::NotAValidator); + } + + Ok(()) +} + +pub fn try_add_dealer( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, +) -> Result { + verify_dealer(deps.as_ref(), &info.sender)?; + + todo!() +}