Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sdk)!: wrong order of objects returned by Drive #2207

Merged
merged 9 commits into from
Oct 16, 2024
45 changes: 26 additions & 19 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions packages/rs-drive-proof-verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mocks = [
"dep:platform-serialization-derive",
"dep:platform-serialization",
"dpp/document-serde-conversion",
"indexmap/serde",
]

[dependencies]
Expand Down Expand Up @@ -42,4 +43,5 @@ serde_json = { version = "1.0.103", features = [
"preserve_order",
], optional = true }
hex = { version = "0.4.3" }
indexmap = { version = "2.6.0" }
lklimek marked this conversation as resolved.
Show resolved Hide resolved
derive_more = { version = "1.0", features = ["from"] }
72 changes: 39 additions & 33 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 @@ -831,25 +832,17 @@ 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
})
})
.map_err(|e| Error::ResultEncodingError {
let maybe_contracts = contracts
.into_iter()
.map(|(k, v)| {
Identifier::from_bytes(&k).map(|id| (id, v)).map_err(|e| {
Error::ResultEncodingError {
error: e.to_string(),
})?;

Some(contracts)
} else {
None
};
}
})
})
.collect::<Result<DataContracts, Error>>()?
.into_option();

Ok((maybe_contracts, mtd.clone(), proof.clone()))
}
Expand Down Expand Up @@ -904,7 +897,11 @@ impl FromProof<platform::GetDataContractHistoryRequest> for DataContractHistory

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

Ok((maybe_history, mtd.clone(), proof.clone()))
Ok((
maybe_history.map(IndexMap::from_iter),
mtd.clone(),
proof.clone(),
))
}
}

Expand Down Expand Up @@ -987,13 +984,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 +1053,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 +1200,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 +1636,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"),
lklimek marked this conversation as resolved.
Show resolved Hide resolved
None => return Ok((None, mtd, proof)),
};

Expand Down Expand Up @@ -1878,6 +1878,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
Loading
Loading