-
Notifications
You must be signed in to change notification settings - Fork 54
feat(sdk): get identities by non-unique public key hashes (part 1) #2502
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| use crate::error::query::QueryError; | ||
| use crate::error::Error; | ||
| use crate::platform_types::platform::Platform; | ||
| use crate::platform_types::platform_state::PlatformState; | ||
| use crate::query::QueryValidationResult; | ||
| use dapi_grpc::platform::v0::get_identity_by_non_unique_public_key_hash_request::Version as RequestVersion; | ||
| use dapi_grpc::platform::v0::get_identity_by_non_unique_public_key_hash_response::Version as ResponseVersion; | ||
| use dapi_grpc::platform::v0::{ | ||
| GetIdentityByNonUniquePublicKeyHashRequest, GetIdentityByNonUniquePublicKeyHashResponse, | ||
| GetIdentityByPublicKeyHashResponse, | ||
| }; | ||
| use dpp::version::PlatformVersion; | ||
|
|
||
| mod v0; | ||
|
|
||
| impl<C> Platform<C> { | ||
| /// Querying of an identity by a public key hash | ||
| pub fn query_identity_by_non_unique_public_key_hash( | ||
| &self, | ||
| GetIdentityByNonUniquePublicKeyHashRequest { version }: GetIdentityByNonUniquePublicKeyHashRequest, | ||
| platform_state: &PlatformState, | ||
| platform_version: &PlatformVersion, | ||
| ) -> Result<QueryValidationResult<GetIdentityByNonUniquePublicKeyHashResponse>, Error> { | ||
| let Some(version) = version else { | ||
| return Ok(QueryValidationResult::new_with_error( | ||
| QueryError::DecodingError( | ||
| "could not decode identity by public key non unique hash query".to_string(), | ||
| ), | ||
| )); | ||
| }; | ||
|
|
||
| let feature_version_bounds = &platform_version | ||
| .drive_abci | ||
| .query | ||
| .identity_based_queries | ||
| .identity_by_unique_public_key_hash; | ||
|
|
||
| let feature_version = match &version { | ||
| RequestVersion::V0(_) => 0, | ||
| }; | ||
|
|
||
| if !feature_version_bounds.check_version(feature_version) { | ||
| return Ok(QueryValidationResult::new_with_error( | ||
| QueryError::UnsupportedQueryVersion( | ||
| "identity_by_non_unique_public_key_hash".to_string(), | ||
| feature_version_bounds.min_version, | ||
| feature_version_bounds.max_version, | ||
| platform_version.protocol_version, | ||
| feature_version, | ||
| ), | ||
| )); | ||
| } | ||
|
|
||
| match version { | ||
| RequestVersion::V0(request_v0) => { | ||
| let request = self.query_identity_by_non_unique_public_key_hash_v0( | ||
| request_v0, | ||
| platform_state, | ||
| platform_version, | ||
| )?; | ||
|
|
||
| Ok( | ||
| request.map(|response_v0| GetIdentityByNonUniquePublicKeyHashResponse { | ||
| version: Some(ResponseVersion::V0(response_v0)), | ||
| }), | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,192 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| use crate::error::query::QueryError; | ||||||||||||||||||||||||||||||||||||||||||||||
| use crate::error::Error; | ||||||||||||||||||||||||||||||||||||||||||||||
| use crate::platform_types::platform::Platform; | ||||||||||||||||||||||||||||||||||||||||||||||
| use crate::platform_types::platform_state::PlatformState; | ||||||||||||||||||||||||||||||||||||||||||||||
| use crate::query::QueryValidationResult; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dapi_grpc::platform::v0::get_identity_by_non_unique_public_key_hash_request::GetIdentityByNonUniquePublicKeyHashRequestV0; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dapi_grpc::platform::v0::get_identity_by_non_unique_public_key_hash_response::{ | ||||||||||||||||||||||||||||||||||||||||||||||
| get_identity_by_non_unique_public_key_hash_response_v0, GetIdentityByNonUniquePublicKeyHashResponseV0, | ||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dapi_grpc::platform::v0::get_identity_by_non_unique_public_key_hash_response::get_identity_by_non_unique_public_key_hash_response_v0::{IdentityProvedResponse, IdentityResponse}; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dpp::check_validation_result_with_data; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dpp::platform_value::{Bytes20, Bytes32}; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dpp::serialization::PlatformSerializable; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dpp::validation::ValidationResult; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dpp::version::PlatformVersion; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| impl<C> Platform<C> { | ||||||||||||||||||||||||||||||||||||||||||||||
| pub(super) fn query_identity_by_non_unique_public_key_hash_v0( | ||||||||||||||||||||||||||||||||||||||||||||||
| &self, | ||||||||||||||||||||||||||||||||||||||||||||||
| GetIdentityByNonUniquePublicKeyHashRequestV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| public_key_hash, | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after, | ||||||||||||||||||||||||||||||||||||||||||||||
| prove, | ||||||||||||||||||||||||||||||||||||||||||||||
| }: GetIdentityByNonUniquePublicKeyHashRequestV0, | ||||||||||||||||||||||||||||||||||||||||||||||
| platform_state: &PlatformState, | ||||||||||||||||||||||||||||||||||||||||||||||
| platform_version: &PlatformVersion, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<QueryValidationResult<GetIdentityByNonUniquePublicKeyHashResponseV0>, Error> { | ||||||||||||||||||||||||||||||||||||||||||||||
| let public_key_hash = | ||||||||||||||||||||||||||||||||||||||||||||||
| check_validation_result_with_data!(Bytes20::from_vec(public_key_hash) | ||||||||||||||||||||||||||||||||||||||||||||||
| .map(|bytes| bytes.0) | ||||||||||||||||||||||||||||||||||||||||||||||
| .map_err(|_| QueryError::InvalidArgument( | ||||||||||||||||||||||||||||||||||||||||||||||
| "public key hash must be 20 bytes long".to_string() | ||||||||||||||||||||||||||||||||||||||||||||||
| ))); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let start_after = if let Some(start_after) = start_after { | ||||||||||||||||||||||||||||||||||||||||||||||
| Some(check_validation_result_with_data!(Bytes32::from_vec( | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| .map(|bytes| bytes.0) | ||||||||||||||||||||||||||||||||||||||||||||||
| .map_err(|_| QueryError::InvalidArgument( | ||||||||||||||||||||||||||||||||||||||||||||||
| "public key hash must be 20 bytes long".to_string() | ||||||||||||||||||||||||||||||||||||||||||||||
| )))) | ||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+35
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix misleading error message for Consider applying the following fix: - .map_err(|_| QueryError::InvalidArgument(
- "public key hash must be 20 bytes long".to_string()
- ))
+ .map_err(|_| QueryError::InvalidArgument(
+ "start_after must be 32 bytes long".to_string()
+ ))📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let response = if prove { | ||||||||||||||||||||||||||||||||||||||||||||||
| let proof = self | ||||||||||||||||||||||||||||||||||||||||||||||
| .drive | ||||||||||||||||||||||||||||||||||||||||||||||
| .prove_full_identity_by_non_unique_public_key_hash( | ||||||||||||||||||||||||||||||||||||||||||||||
| public_key_hash, | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after, | ||||||||||||||||||||||||||||||||||||||||||||||
| None, | ||||||||||||||||||||||||||||||||||||||||||||||
| platform_version, | ||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| GetIdentityByNonUniquePublicKeyHashResponseV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| result: Some( | ||||||||||||||||||||||||||||||||||||||||||||||
| get_identity_by_non_unique_public_key_hash_response_v0::Result::Proof( | ||||||||||||||||||||||||||||||||||||||||||||||
| IdentityProvedResponse { | ||||||||||||||||||||||||||||||||||||||||||||||
| grovedb_identity_public_key_hash_proof: Some(self.response_proof_v0( | ||||||||||||||||||||||||||||||||||||||||||||||
| platform_state, | ||||||||||||||||||||||||||||||||||||||||||||||
| proof.identity_id_public_key_hash_proof, | ||||||||||||||||||||||||||||||||||||||||||||||
| )), | ||||||||||||||||||||||||||||||||||||||||||||||
| identity_proof_bytes: proof.identity_proof, | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||
| metadata: Some(self.response_metadata_v0(platform_state)), | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||
| let maybe_identity = self | ||||||||||||||||||||||||||||||||||||||||||||||
| .drive | ||||||||||||||||||||||||||||||||||||||||||||||
| .fetch_full_identity_by_non_unique_public_key_hash( | ||||||||||||||||||||||||||||||||||||||||||||||
| public_key_hash, | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after, | ||||||||||||||||||||||||||||||||||||||||||||||
| None, | ||||||||||||||||||||||||||||||||||||||||||||||
| platform_version, | ||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let serialized_identity = maybe_identity | ||||||||||||||||||||||||||||||||||||||||||||||
| .map(|identity| { | ||||||||||||||||||||||||||||||||||||||||||||||
| identity | ||||||||||||||||||||||||||||||||||||||||||||||
| .serialize_consume_to_bytes() | ||||||||||||||||||||||||||||||||||||||||||||||
| .map_err(Error::Protocol) | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| .transpose()?; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| GetIdentityByNonUniquePublicKeyHashResponseV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| metadata: Some(self.response_metadata_v0(platform_state)), | ||||||||||||||||||||||||||||||||||||||||||||||
| result: Some( | ||||||||||||||||||||||||||||||||||||||||||||||
| get_identity_by_non_unique_public_key_hash_response_v0::Result::Identity( | ||||||||||||||||||||||||||||||||||||||||||||||
| IdentityResponse { | ||||||||||||||||||||||||||||||||||||||||||||||
| identity: serialized_identity, | ||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| Ok(QueryValidationResult::new_with_data(response)) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #[cfg(test)] | ||||||||||||||||||||||||||||||||||||||||||||||
| mod tests { | ||||||||||||||||||||||||||||||||||||||||||||||
| use super::*; | ||||||||||||||||||||||||||||||||||||||||||||||
| use crate::query::tests::setup_platform; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dapi_grpc::platform::v0::ResponseMetadata; | ||||||||||||||||||||||||||||||||||||||||||||||
| use dpp::dashcore::Network; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||
| fn test_invalid_public_key_hash() { | ||||||||||||||||||||||||||||||||||||||||||||||
| let (platform, state, version) = setup_platform(None, Network::Testnet, None); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let request = GetIdentityByNonUniquePublicKeyHashRequestV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| public_key_hash: vec![0; 8], | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after: None, | ||||||||||||||||||||||||||||||||||||||||||||||
| prove: false, | ||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let result = platform | ||||||||||||||||||||||||||||||||||||||||||||||
| .query_identity_by_non_unique_public_key_hash_v0(request, &state, version) | ||||||||||||||||||||||||||||||||||||||||||||||
| .expect("expected query to succeed"); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| assert!(matches!( | ||||||||||||||||||||||||||||||||||||||||||||||
| result.errors.as_slice(), | ||||||||||||||||||||||||||||||||||||||||||||||
| [QueryError::InvalidArgument(msg)] if msg == &"public key hash must be 20 bytes long".to_string() | ||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||
| fn test_identity_not_found() { | ||||||||||||||||||||||||||||||||||||||||||||||
| let (platform, state, version) = setup_platform(None, Network::Testnet, None); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let public_key_hash = vec![0; 20]; | ||||||||||||||||||||||||||||||||||||||||||||||
| let request = GetIdentityByNonUniquePublicKeyHashRequestV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| public_key_hash: public_key_hash.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after: None, | ||||||||||||||||||||||||||||||||||||||||||||||
| prove: false, | ||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let result = platform | ||||||||||||||||||||||||||||||||||||||||||||||
| .query_identity_by_non_unique_public_key_hash_v0(request, &state, version) | ||||||||||||||||||||||||||||||||||||||||||||||
| .expect("expected query to succeed"); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||||||||||||||||||
| result.data, | ||||||||||||||||||||||||||||||||||||||||||||||
| Some(GetIdentityByNonUniquePublicKeyHashResponseV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| metadata: Some(ResponseMetadata { | ||||||||||||||||||||||||||||||||||||||||||||||
| height: 0, | ||||||||||||||||||||||||||||||||||||||||||||||
| core_chain_locked_height: 0, | ||||||||||||||||||||||||||||||||||||||||||||||
| epoch: 0, | ||||||||||||||||||||||||||||||||||||||||||||||
| time_ms: 0, | ||||||||||||||||||||||||||||||||||||||||||||||
| protocol_version: 9, | ||||||||||||||||||||||||||||||||||||||||||||||
| chain_id: "chain_id".to_string() | ||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||
| result: Some( | ||||||||||||||||||||||||||||||||||||||||||||||
| get_identity_by_non_unique_public_key_hash_response_v0::Result::Identity( | ||||||||||||||||||||||||||||||||||||||||||||||
| IdentityResponse { identity: None } | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||||||||||||||||||||||
| fn test_identity_absence_proof() { | ||||||||||||||||||||||||||||||||||||||||||||||
| let (platform, state, version) = setup_platform(None, Network::Testnet, None); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let public_key_hash = vec![0; 20]; | ||||||||||||||||||||||||||||||||||||||||||||||
| let request = GetIdentityByNonUniquePublicKeyHashRequestV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| public_key_hash: public_key_hash.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||
| start_after: None, | ||||||||||||||||||||||||||||||||||||||||||||||
| prove: true, | ||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| let result = platform | ||||||||||||||||||||||||||||||||||||||||||||||
| .query_identity_by_non_unique_public_key_hash_v0(request, &state, version) | ||||||||||||||||||||||||||||||||||||||||||||||
| .expect("expected query to succeed"); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| assert!(matches!( | ||||||||||||||||||||||||||||||||||||||||||||||
| result.data, | ||||||||||||||||||||||||||||||||||||||||||||||
| Some(GetIdentityByNonUniquePublicKeyHashResponseV0 { | ||||||||||||||||||||||||||||||||||||||||||||||
| result: Some( | ||||||||||||||||||||||||||||||||||||||||||||||
| get_identity_by_non_unique_public_key_hash_response_v0::Result::Proof(_) | ||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||
| metadata: Some(_), | ||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix mismatch in naming for feature version field.
Here, you reference
identity_by_unique_public_key_hash(line 36) while we are in a file specifically for non-unique public key hashes. This can be confusing and could lead to errors if the underlying version bounds differ. Confirm you’re referencing the correct feature.📝 Committable suggestion