updated dealings queries
This commit is contained in:
@@ -70,7 +70,7 @@ pub trait DkgQueryClient {
|
||||
start_after: Option<String>,
|
||||
limit: Option<u32>,
|
||||
) -> Result<PagedDealingsResponse, NyxdError> {
|
||||
let request = DkgQueryMsg::GetDealing {
|
||||
let request = DkgQueryMsg::GetDealings {
|
||||
idx,
|
||||
limit,
|
||||
start_after,
|
||||
@@ -165,7 +165,7 @@ mod tests {
|
||||
DkgQueryMsg::GetPastDealers { limit, start_after } => {
|
||||
client.get_past_dealers_paged(start_after, limit).ignore()
|
||||
}
|
||||
DkgQueryMsg::GetDealing {
|
||||
DkgQueryMsg::GetDealings {
|
||||
idx,
|
||||
limit,
|
||||
start_after,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::types::{ContractSafeBytes, EncodedBTEPublicKeyWithProof, NodeIndex};
|
||||
use crate::types::{
|
||||
ContractDealing, DealingIndex, EncodedBTEPublicKeyWithProof, EpochId, NodeIndex,
|
||||
PartialContractDealing,
|
||||
};
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::Addr;
|
||||
|
||||
@@ -65,37 +68,40 @@ impl PagedDealerResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[cw_serde]
|
||||
pub struct ContractDealing {
|
||||
pub dealing: ContractSafeBytes,
|
||||
pub dealer: Addr,
|
||||
}
|
||||
pub struct DealingResponse {
|
||||
pub epoch_id: EpochId,
|
||||
|
||||
impl ContractDealing {
|
||||
pub fn new(dealing: ContractSafeBytes, dealer: Addr) -> Self {
|
||||
ContractDealing { dealing, dealer }
|
||||
}
|
||||
pub dealer: Addr,
|
||||
|
||||
pub dealing_index: DealingIndex,
|
||||
|
||||
pub dealing: Option<ContractDealing>,
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
pub struct PagedDealingsResponse {
|
||||
pub dealings: Vec<ContractDealing>,
|
||||
pub per_page: usize,
|
||||
pub epoch_id: EpochId,
|
||||
|
||||
pub dealer: Addr,
|
||||
|
||||
pub dealings: Vec<PartialContractDealing>,
|
||||
|
||||
/// Field indicating paging information for the following queries if the caller wishes to get further entries.
|
||||
pub start_next_after: Option<Addr>,
|
||||
pub start_next_after: Option<DealingIndex>,
|
||||
}
|
||||
|
||||
impl PagedDealingsResponse {
|
||||
pub fn new(
|
||||
dealings: Vec<ContractDealing>,
|
||||
per_page: usize,
|
||||
start_next_after: Option<Addr>,
|
||||
epoch_id: EpochId,
|
||||
dealer: Addr,
|
||||
dealings: Vec<PartialContractDealing>,
|
||||
start_next_after: Option<DealingIndex>,
|
||||
) -> Self {
|
||||
PagedDealingsResponse {
|
||||
epoch_id,
|
||||
dealer,
|
||||
dealings,
|
||||
per_page,
|
||||
start_next_after,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::types::{PartialContractDealing, EncodedBTEPublicKeyWithProof, EpochId, TimeConfiguration};
|
||||
use crate::types::{
|
||||
DealingIndex, EncodedBTEPublicKeyWithProof, EpochId, PartialContractDealing, TimeConfiguration,
|
||||
};
|
||||
use crate::verification_key::VerificationKeyShare;
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::Addr;
|
||||
|
||||
#[cfg(feature = "schema")]
|
||||
use crate::{
|
||||
dealer::{DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse},
|
||||
dealer::{DealerDetailsResponse, DealingResponse, PagedDealerResponse, PagedDealingsResponse},
|
||||
types::{Epoch, InitialReplacementData},
|
||||
verification_key::PagedVKSharesResponse,
|
||||
};
|
||||
@@ -82,11 +84,19 @@ pub enum QueryMsg {
|
||||
start_after: Option<String>,
|
||||
},
|
||||
|
||||
#[cfg_attr(feature = "schema", returns(PagedDealingsResponse))]
|
||||
#[cfg_attr(feature = "schema", returns(DealingResponse))]
|
||||
GetDealing {
|
||||
idx: u64,
|
||||
epoch_id: EpochId,
|
||||
dealer: String,
|
||||
dealing_index: DealingIndex,
|
||||
},
|
||||
|
||||
#[cfg_attr(feature = "schema", returns(PagedDealingsResponse))]
|
||||
GetDealings {
|
||||
epoch_id: EpochId,
|
||||
dealer: String,
|
||||
limit: Option<u32>,
|
||||
start_after: Option<String>,
|
||||
start_after: Option<DealingIndex>,
|
||||
},
|
||||
|
||||
#[cfg_attr(feature = "schema", returns(PagedVKSharesResponse))]
|
||||
|
||||
@@ -14,6 +14,7 @@ pub type EncodedBTEPublicKeyWithProofRef<'a> = &'a str;
|
||||
pub type NodeIndex = u64;
|
||||
pub type EpochId = u64;
|
||||
pub type DealingIndex = u32;
|
||||
pub type ContractDealing = ContractSafeBytes;
|
||||
|
||||
// 2 public attributes, 2 private attributes, 1 fixed for coconut credential
|
||||
pub const TOTAL_DEALINGS: usize = 2 + 2 + 1;
|
||||
@@ -21,7 +22,7 @@ pub const TOTAL_DEALINGS: usize = 2 + 2 + 1;
|
||||
#[cw_serde]
|
||||
pub struct PartialContractDealing {
|
||||
pub index: u32,
|
||||
pub data: ContractSafeBytes,
|
||||
pub data: ContractDealing,
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::dealers::queries::{
|
||||
query_current_dealers_paged, query_dealer_details, query_past_dealers_paged,
|
||||
};
|
||||
use crate::dealers::transactions::try_add_dealer;
|
||||
use crate::dealings::queries::query_dealings_paged;
|
||||
use crate::dealings::queries::{query_dealing, query_dealings_paged};
|
||||
use crate::dealings::transactions::try_commit_dealings;
|
||||
use crate::epoch_state::queries::{
|
||||
query_current_epoch, query_current_epoch_threshold, query_initial_dealers,
|
||||
@@ -112,10 +112,22 @@ pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result<QueryResponse,
|
||||
to_binary(&query_past_dealers_paged(deps, start_after, limit)?)?
|
||||
}
|
||||
QueryMsg::GetDealing {
|
||||
idx,
|
||||
epoch_id,
|
||||
dealer,
|
||||
dealing_index,
|
||||
} => to_binary(&query_dealing(deps, epoch_id, dealer, dealing_index)?)?,
|
||||
QueryMsg::GetDealings {
|
||||
epoch_id,
|
||||
dealer,
|
||||
limit,
|
||||
start_after,
|
||||
} => to_binary(&query_dealings_paged(deps, idx, start_after, limit)?)?,
|
||||
} => to_binary(&query_dealings_paged(
|
||||
deps,
|
||||
epoch_id,
|
||||
dealer,
|
||||
limit,
|
||||
start_after,
|
||||
)?)?,
|
||||
QueryMsg::GetVerificationKeys {
|
||||
epoch_id,
|
||||
limit,
|
||||
|
||||
@@ -2,44 +2,52 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::dealings::storage;
|
||||
use crate::dealings::storage::DEALINGS_BYTES;
|
||||
use cosmwasm_std::{Deps, Order, StdResult};
|
||||
use crate::dealings::storage::StoredDealing;
|
||||
use cosmwasm_std::{Deps, StdResult};
|
||||
use cw_storage_plus::Bound;
|
||||
use nym_coconut_dkg_common::dealer::{ContractDealing, PagedDealingsResponse};
|
||||
use nym_coconut_dkg_common::types::TOTAL_DEALINGS;
|
||||
use nym_coconut_dkg_common::dealer::{DealingResponse, PagedDealingsResponse};
|
||||
use nym_coconut_dkg_common::types::{DealingIndex, EpochId};
|
||||
pub fn query_dealing(
|
||||
deps: Deps<'_>,
|
||||
epoch_id: EpochId,
|
||||
dealer: String,
|
||||
dealing_index: DealingIndex,
|
||||
) -> StdResult<DealingResponse> {
|
||||
let dealer = deps.api.addr_validate(&dealer)?;
|
||||
let dealing = StoredDealing::read(deps.storage, epoch_id, &dealer, dealing_index);
|
||||
|
||||
Ok(DealingResponse {
|
||||
epoch_id,
|
||||
dealer,
|
||||
dealing_index,
|
||||
dealing,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn query_dealings_paged(
|
||||
deps: Deps<'_>,
|
||||
idx: u64,
|
||||
start_after: Option<String>,
|
||||
epoch_id: EpochId,
|
||||
dealer: String,
|
||||
start_after: Option<DealingIndex>,
|
||||
limit: Option<u32>,
|
||||
) -> StdResult<PagedDealingsResponse> {
|
||||
let limit = limit
|
||||
.unwrap_or(storage::DEALINGS_PAGE_DEFAULT_LIMIT)
|
||||
.min(storage::DEALINGS_PAGE_MAX_LIMIT) as usize;
|
||||
.min(storage::DEALINGS_PAGE_MAX_LIMIT);
|
||||
|
||||
let idx = idx as usize;
|
||||
if idx >= TOTAL_DEALINGS {
|
||||
return Ok(PagedDealingsResponse::new(vec![], limit, None));
|
||||
}
|
||||
let dealer = deps.api.addr_validate(&dealer)?;
|
||||
let start = start_after.map(Bound::exclusive);
|
||||
|
||||
let addr = start_after
|
||||
.map(|addr| deps.api.addr_validate(&addr))
|
||||
.transpose()?;
|
||||
|
||||
let start = addr.as_ref().map(Bound::exclusive);
|
||||
|
||||
let dealings = DEALINGS_BYTES[idx]
|
||||
.range(deps.storage, start, None, Order::Ascending)
|
||||
.take(limit)
|
||||
.map(|res| res.map(|(dealer, dealing)| ContractDealing::new(dealing, dealer)))
|
||||
let dealings = StoredDealing::prefix_range(deps.storage, (epoch_id, &dealer), start)
|
||||
.take(limit as usize)
|
||||
.collect::<StdResult<Vec<_>>>()?;
|
||||
|
||||
let start_next_after = dealings.last().map(|dealing| dealing.dealer.clone());
|
||||
let start_next_after = dealings.last().map(|dealing| dealing.index);
|
||||
|
||||
Ok(PagedDealingsResponse::new(
|
||||
epoch_id,
|
||||
dealer,
|
||||
dealings,
|
||||
limit,
|
||||
start_next_after,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::ContractError;
|
||||
use cosmwasm_std::{Addr, Storage};
|
||||
use cw_storage_plus::Map;
|
||||
use cosmwasm_std::{Addr, Order, Record, StdResult, Storage};
|
||||
use cw_storage_plus::{
|
||||
range_with_prefix, Bound, Key, KeyDeserialize, Path, Prefix, Prefixer, PrimaryKey,
|
||||
};
|
||||
use nym_coconut_dkg_common::types::{
|
||||
ContractSafeBytes, DealingIndex, EpochId, PartialContractDealing, TOTAL_DEALINGS,
|
||||
ContractDealing, ContractSafeBytes, DealingIndex, EpochId, PartialContractDealing,
|
||||
};
|
||||
|
||||
pub(crate) const DEALINGS_PAGE_MAX_LIMIT: u32 = 2;
|
||||
@@ -13,56 +14,102 @@ pub(crate) const DEALINGS_PAGE_DEFAULT_LIMIT: u32 = 1;
|
||||
|
||||
type Dealer<'a> = &'a Addr;
|
||||
|
||||
#[deprecated]
|
||||
type DealingKey<'a> = &'a Addr;
|
||||
|
||||
// dealings are stored in a multilevel map with the following hierarchy:
|
||||
// - epoch-id:
|
||||
// - issuer-address:
|
||||
// - dealing id:
|
||||
// - dealing content
|
||||
// NOTE: we're storing raw bytes bypassing serialization, so make sure you always use the below methods for using the storage!
|
||||
pub(crate) const DEALINGS: Map<(EpochId, Dealer, DealingIndex), ContractSafeBytes> =
|
||||
Map::new("dealing");
|
||||
// NOTE: we're storing raw bytes bypassing serialization, so we can't use the `Map` type,
|
||||
// thus make sure you always use the below methods for using the storage!
|
||||
|
||||
pub fn has_committed_dealing(
|
||||
storage: &dyn Storage,
|
||||
epoch_id: EpochId,
|
||||
dealer: &Addr,
|
||||
dealing_index: DealingIndex,
|
||||
) -> bool {
|
||||
DEALINGS.has(storage, (epoch_id, dealer, dealing_index))
|
||||
pub(crate) struct StoredDealing;
|
||||
|
||||
impl StoredDealing {
|
||||
const NAMESPACE: &'static [u8] = b"dealing";
|
||||
|
||||
fn deserialize_raw_dealing(kv: Record) -> StdResult<PartialContractDealing> {
|
||||
let (k, v) = kv;
|
||||
let index = <DealingIndex as KeyDeserialize>::from_vec(k)?;
|
||||
let data = ContractSafeBytes(v);
|
||||
|
||||
Ok(PartialContractDealing { index, data })
|
||||
}
|
||||
|
||||
fn storage_key(
|
||||
epoch_id: EpochId,
|
||||
dealer: Dealer,
|
||||
dealing_index: DealingIndex,
|
||||
) -> Path<Vec<u8>> {
|
||||
// just replicate the behaviour from `Map::key`
|
||||
let key = (epoch_id, dealer, dealing_index);
|
||||
Path::new(
|
||||
Self::NAMESPACE,
|
||||
&key.key().iter().map(Key::as_ref).collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
|
||||
fn prefix(prefix: (EpochId, Dealer)) -> Prefix<DealingIndex, ContractSafeBytes> {
|
||||
Prefix::with_deserialization_functions(
|
||||
Self::NAMESPACE,
|
||||
&prefix.prefix(),
|
||||
&[],
|
||||
// explicitly panic to make sure we're never attempting to call an unexpected deserializer on our data
|
||||
|_, _, _| panic!("attempted to call custom de_fn_kv"),
|
||||
|_, _, _| panic!("attempted to call custom de_fn_v"),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn exists(
|
||||
storage: &dyn Storage,
|
||||
epoch_id: EpochId,
|
||||
dealer: &Addr,
|
||||
dealing_index: DealingIndex,
|
||||
) -> bool {
|
||||
StoredDealing::storage_key(epoch_id, dealer, dealing_index).has(storage)
|
||||
}
|
||||
|
||||
pub(crate) fn save(
|
||||
storage: &mut dyn Storage,
|
||||
epoch_id: EpochId,
|
||||
dealer: Dealer,
|
||||
dealing: PartialContractDealing,
|
||||
) {
|
||||
// NOTE: we're storing bytes directly here!
|
||||
let storage_key = StoredDealing::storage_key(epoch_id, dealer, dealing.index);
|
||||
storage.set(&storage_key, dealing.data.as_slice());
|
||||
}
|
||||
|
||||
pub(crate) fn read(
|
||||
storage: &dyn Storage,
|
||||
epoch_id: EpochId,
|
||||
dealer: Dealer,
|
||||
dealing_index: DealingIndex,
|
||||
) -> Option<ContractDealing> {
|
||||
let storage_key = StoredDealing::storage_key(epoch_id, dealer, dealing_index);
|
||||
let raw_dealing = storage.get(&storage_key);
|
||||
raw_dealing.map(ContractSafeBytes)
|
||||
}
|
||||
|
||||
pub(crate) fn prefix_range<'a>(
|
||||
storage: &'a dyn Storage,
|
||||
prefix: (EpochId, Dealer),
|
||||
start: Option<Bound<DealingIndex>>,
|
||||
) -> Box<dyn Iterator<Item = StdResult<PartialContractDealing>> + 'a> {
|
||||
// replicate the behaviour of `Prefix::range_raw` but without the fallible deserialization on the data
|
||||
// (since we're reading from the storage directly)
|
||||
// and whilst combining the data on the spot
|
||||
let prefix = Self::prefix(prefix);
|
||||
|
||||
let mapped = range_with_prefix(
|
||||
storage,
|
||||
// note: Prefix's Deref implementation gives back its storage_prefix
|
||||
&prefix,
|
||||
start.map(|b| b.to_raw_bound()),
|
||||
None,
|
||||
Order::Ascending,
|
||||
)
|
||||
.map(Self::deserialize_raw_dealing);
|
||||
|
||||
Box::new(mapped)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_dealing(
|
||||
storage: &mut dyn Storage,
|
||||
epoch_id: EpochId,
|
||||
dealer: &Addr,
|
||||
dealing: PartialContractDealing,
|
||||
) {
|
||||
// NOTE: we're storing bytes directly here!
|
||||
let storage_key = DEALINGS.key((epoch_id, dealer, dealing.index));
|
||||
storage.set(&storage_key, dealing.data.as_slice());
|
||||
}
|
||||
|
||||
// Note to whoever is looking at this implementation and is thinking of using something similar
|
||||
// for storing small commitments/hashes of data on chain:
|
||||
// If there's a lot of entries you want to store thinking, "oh, this digest is only 32 bytes, it's not that much",
|
||||
// the default cosmwasm' serializer will bloat it to around ~100B. So you really don't want to be using
|
||||
// Buckets/Maps, etc. for that purpose. Instead you want to use `storage` directly (look into the actual implementation of
|
||||
// `Map` or `Bucket` to see what I mean. Instead of using the `to_vec` method on serde_json_wasm, you'd
|
||||
// provide your data directly yourself.
|
||||
// but you must be extremely careful when doing so, as you might end up overwriting some existing data
|
||||
// if you don't choose your prefixes wisely.
|
||||
// I didn't have to do it here as I'm storing relatively little data and after just base58-encoding
|
||||
// my bytes, I was fine with the json overhead.
|
||||
|
||||
// if TOTAL_DEALINGS is modified to anything other then current value (5), this part will also need
|
||||
// to be modified
|
||||
pub(crate) const DEALINGS_BYTES: [Map<'_, DealingKey<'_>, ContractSafeBytes>; TOTAL_DEALINGS] = [
|
||||
Map::new("dbyt1"),
|
||||
Map::new("dbyt2"),
|
||||
Map::new("dbyt3"),
|
||||
Map::new("dbyt4"),
|
||||
Map::new("dbyt5"),
|
||||
];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::dealers::storage as dealers_storage;
|
||||
use crate::dealings::storage::{has_committed_dealing, save_dealing};
|
||||
use crate::dealings::storage::StoredDealing;
|
||||
use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA};
|
||||
use crate::epoch_state::utils::check_epoch_state;
|
||||
use crate::error::ContractError;
|
||||
@@ -48,7 +48,7 @@ pub fn try_commit_dealings(
|
||||
}
|
||||
|
||||
// check if this dealer has already committed this particular dealing
|
||||
if has_committed_dealing(deps.storage, epoch.epoch_id, &info.sender, dealing.index) {
|
||||
if StoredDealing::exists(deps.storage, epoch.epoch_id, &info.sender, dealing.index) {
|
||||
return Err(ContractError::DealingAlreadyCommitted {
|
||||
epoch_id: epoch.epoch_id,
|
||||
dealer: info.sender,
|
||||
@@ -56,7 +56,7 @@ pub fn try_commit_dealings(
|
||||
});
|
||||
}
|
||||
|
||||
save_dealing(deps.storage, epoch.epoch_id, &info.sender, dealing);
|
||||
StoredDealing::save(deps.storage, epoch.epoch_id, &info.sender, dealing);
|
||||
|
||||
Ok(Response::new())
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::dealers::storage::{current_dealers, past_dealers};
|
||||
use crate::dealings::storage::DEALINGS_BYTES;
|
||||
use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA, THRESHOLD};
|
||||
use crate::epoch_state::utils::check_epoch_state;
|
||||
use crate::error::ContractError;
|
||||
@@ -17,21 +16,22 @@ fn reset_epoch_state(storage: &mut dyn Storage) -> Result<(), ContractError> {
|
||||
.keys(storage, None, None, Order::Ascending)
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
for dealer_addr in dealers {
|
||||
let details = current_dealers().load(storage, &dealer_addr)?;
|
||||
for dealings in DEALINGS_BYTES {
|
||||
let dealing_keys: Vec<_> = dealings
|
||||
.keys(storage, None, None, Order::Ascending)
|
||||
.flatten()
|
||||
.collect();
|
||||
for key in dealing_keys {
|
||||
dealings.remove(storage, &key);
|
||||
}
|
||||
}
|
||||
current_dealers().remove(storage, &dealer_addr)?;
|
||||
past_dealers().save(storage, &dealer_addr, &details)?;
|
||||
}
|
||||
Ok(())
|
||||
todo!()
|
||||
// for dealer_addr in dealers {
|
||||
// let details = current_dealers().load(storage, &dealer_addr)?;
|
||||
// for dealings in DEALINGS_BYTES {
|
||||
// let dealing_keys: Vec<_> = dealings
|
||||
// .keys(storage, None, None, Order::Ascending)
|
||||
// .flatten()
|
||||
// .collect();
|
||||
// for key in dealing_keys {
|
||||
// dealings.remove(storage, &key);
|
||||
// }
|
||||
// }
|
||||
// current_dealers().remove(storage, &dealer_addr)?;
|
||||
// past_dealers().save(storage, &dealer_addr, &details)?;
|
||||
// }
|
||||
// Ok(())
|
||||
}
|
||||
|
||||
fn dealers_still_active(
|
||||
|
||||
Reference in New Issue
Block a user