Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 27 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/rs-drive-proof-verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ serde_json = { version = "1.0.103", features = [
], optional = true }
hex = { version = "0.4.3" }
derive_more = { version = "0.99.11" }
indexmap = { version = "2.6.0" }
69 changes: 39 additions & 30 deletions packages/rs-drive-proof-verifier/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use drive::query::vote_poll_contestant_votes_query::ContestedDocumentVotePollVot
use drive::query::vote_poll_vote_state_query::ContestedDocumentVotePollDriveQuery;
use drive::query::vote_polls_by_document_type_query::VotePollsByDocumentTypeQuery;
use drive::query::{DriveDocumentQuery, VotePollsByEndDateDriveQuery};
use indexmap::IndexMap;
use std::array::TryFromSliceError;
use std::collections::BTreeMap;
use std::num::TryFromIntError;
Expand Down Expand Up @@ -832,24 +833,23 @@ impl FromProof<platform::GetDataContractsRequest> for DataContracts {

verify_tenderdash_proof(proof, mtd, &root_hash, provider)?;

let maybe_contracts: Option<BTreeMap<Identifier, Option<DataContract>>> =
if !contracts.is_empty() {
let contracts: DataContracts = contracts
.into_iter()
.try_fold(DataContracts::new(), |mut acc, (k, v)| {
Identifier::from_bytes(&k).map(|id| {
acc.insert(id, v);
acc
})
let maybe_contracts: Option<DataContracts> = if !contracts.is_empty() {
let contracts: DataContracts = contracts
.into_iter()
.try_fold(DataContracts::new(), |mut acc, (k, v)| {
Identifier::from_bytes(&k).map(|id| {
acc.insert(id, v);
acc
})
.map_err(|e| Error::ResultEncodingError {
error: e.to_string(),
})?;
})
.map_err(|e| Error::ResultEncodingError {
error: e.to_string(),
})?;

Some(contracts)
} else {
None
};
Some(contracts)
} else {
None
};

Ok((maybe_contracts, mtd.clone(), proof.clone()))
}
Expand Down Expand Up @@ -987,13 +987,13 @@ impl FromProof<platform::GetEpochsInfoRequest> for ExtendedEpochInfo {
provider,
)?;

if let Some(mut e) = epochs.0 {
if let Some(e) = epochs.0 {
if e.len() != 1 {
return Err(Error::RequestError {
error: format!("expected 1 epoch, got {}", e.len()),
});
}
let epoch = e.pop_first().and_then(|v| v.1);
let epoch = e.into_iter().next().and_then(|v| v.1);
Ok((epoch, epochs.1, epochs.2))
} else {
Ok((None, epochs.1, epochs.2))
Expand Down Expand Up @@ -1056,7 +1056,7 @@ impl FromProof<platform::GetEpochsInfoRequest> for ExtendedEpochInfos {

(info.index, Some(v))
})
.collect::<BTreeMap<EpochIndex, Option<ExtendedEpochInfo>>>();
.collect::<ExtendedEpochInfos>();

verify_tenderdash_proof(proof, mtd, &root_hash, provider)?;

Expand Down Expand Up @@ -1203,10 +1203,11 @@ impl FromProof<GetPathElementsRequest> for Elements {

let (root_hash, objects) =
Drive::verify_elements(&proof.grovedb_proof, path, keys, platform_version)?;
let elements: Elements = Elements::from_iter(objects);

verify_tenderdash_proof(proof, mtd, &root_hash, provider)?;

Ok((objects.into_option(), mtd.clone(), proof.clone()))
Ok((elements.into_option(), mtd.clone(), proof.clone()))
}
}

Expand Down Expand Up @@ -1638,23 +1639,25 @@ impl FromProof<platform::GetContestedResourceIdentityVotesRequest> for Vote {
}
};

let (mut maybe_votes, mtd, proof) =
ResourceVotesByIdentity::maybe_from_proof_with_metadata(
request,
response,
network,
platform_version,
provider,
)?;
let (maybe_votes, mtd, proof) = ResourceVotesByIdentity::maybe_from_proof_with_metadata(
request,
response,
network,
platform_version,
provider,
)?;

let (id, vote) = match maybe_votes.as_mut() {
let (id, vote) = match maybe_votes {
Some(v) if v.len() > 1 => {
return Err(Error::ResponseDecodeError {
error: format!("expected 1 vote, got {}", v.len()),
})
}
Some(v) if v.is_empty() => return Ok((None, mtd, proof)),
Some(v) => v.pop_first().expect("is_empty() must detect empty map"),
Some(v) => v
.into_iter()
.next()
.expect("is_empty() must detect empty map"),
None => return Ok((None, mtd, proof)),
};

Expand Down Expand Up @@ -1878,6 +1881,12 @@ impl<K, T> Length for BTreeMap<K, Option<T>> {
}
}

impl<K, T> Length for IndexMap<K, Option<T>> {
fn count_some(&self) -> usize {
self.values().filter(|v| v.is_some()).count()
}
}

/// Implement Length trait for a type
///
/// # Arguments
Expand Down
2 changes: 1 addition & 1 deletion packages/rs-drive-proof-verifier/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub trait ContextProvider: Send + Sync {
/// # Returns
///
/// * `Ok(Option<Arc<DataContract>>)`: On success, returns the data contract if it exists, or `None` if it does not.
/// We use Arc to avoid copying the data contract.
/// We use Arc to avoid copying the data contract.
/// * `Err(Error)`: On failure, returns an error indicating why the operation failed.
fn get_data_contract(
&self,
Expand Down
4 changes: 3 additions & 1 deletion packages/rs-drive-proof-verifier/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use dpp::{
};
use drive::grovedb::query_result_type::Path;
use drive::grovedb::Element;
// IndexMap is exposed to the public API
pub use indexmap::IndexMap;
use std::collections::{BTreeMap, BTreeSet};

#[cfg(feature = "mocks")]
Expand All @@ -57,7 +59,7 @@ pub use evonode_status::*;
///
/// * `K`: The type of the keys in the map.
/// * `O`: The type of the objects in the map.
pub type RetrievedObjects<K, O> = BTreeMap<K, Option<O>>;
pub type RetrievedObjects<K, O> = IndexMap<K, Option<O>>;

/// A data structure that holds a set of objects of a generic type `O`, indexed by a key of type `K`.
///
Expand Down
Loading