-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
279d16f
commit cf32dd5
Showing
11 changed files
with
1,185 additions
and
4 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#[cfg(feature = "server")] | ||
mod prove; | ||
mod queries; | ||
#[cfg(feature = "server")] | ||
mod update; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
use crate::drive::Drive; | ||
use crate::error::Error; | ||
|
||
use dpp::version::drive_versions::DriveVersion; | ||
|
||
use grovedb::TransactionArg; | ||
|
||
impl Drive { | ||
/// Proves an Identity's token balance from the backing store | ||
pub fn prove_identity_token_balance( | ||
&self, | ||
identity_id: [u8; 32], | ||
token_id: [u8; 32], | ||
transaction: TransactionArg, | ||
drive_version: &DriveVersion, | ||
) -> Result<Vec<u8>, Error> { | ||
let balance_query = Self::token_balance_for_identity_id_query(token_id, identity_id); | ||
self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) | ||
} | ||
|
||
/// Proves multiple Identity token balances from the backing store | ||
pub fn prove_many_identity_token_balances( | ||
&self, | ||
identity_ids: &[[u8; 32]], | ||
token_id: [u8; 32], | ||
transaction: TransactionArg, | ||
drive_version: &DriveVersion, | ||
) -> Result<Vec<u8>, Error> { | ||
let balance_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); | ||
self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) | ||
} | ||
|
||
/// Proves multiple Identity balances from the backing store by range | ||
pub fn prove_many_identity_token_balances_by_range( | ||
&self, | ||
start_at: Option<([u8; 32], bool)>, | ||
ascending: bool, | ||
limit: u16, | ||
transaction: TransactionArg, | ||
drive_version: &DriveVersion, | ||
) -> Result<Vec<u8>, Error> { | ||
let balance_query = Self::balances_for_range_query(start_at, ascending, limit); | ||
self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; | ||
use dpp::block::block_info::BlockInfo; | ||
use dpp::identity::Identity; | ||
|
||
mod prove_identity_balance { | ||
use super::*; | ||
use dpp::identity::accessors::IdentityGettersV0; | ||
use dpp::version::PlatformVersion; | ||
|
||
#[test] | ||
fn should_prove_a_single_identity_balance() { | ||
let drive = setup_drive_with_initial_state_structure(None); | ||
|
||
let platform_version = PlatformVersion::first(); | ||
|
||
let identity = Identity::random_identity(3, Some(14), platform_version) | ||
.expect("expected a platform identity"); | ||
|
||
let identity_id = identity.id().to_buffer(); | ||
drive | ||
.add_new_identity( | ||
identity.clone(), | ||
false, | ||
&BlockInfo::default(), | ||
true, | ||
None, | ||
platform_version, | ||
) | ||
.expect("expected to add an identity"); | ||
let proof = drive | ||
.prove_identity_balance(identity.id().to_buffer(), None, &platform_version.drive) | ||
.expect("should not error when proving an identity"); | ||
|
||
let (_, proved_identity_balance) = Drive::verify_identity_balance_for_identity_id( | ||
proof.as_slice(), | ||
identity_id, | ||
false, | ||
platform_version, | ||
) | ||
.expect("expect that this be verified"); | ||
|
||
assert_eq!(proved_identity_balance, Some(identity.balance())); | ||
} | ||
} | ||
|
||
mod prove_many_identity_balances { | ||
use super::*; | ||
use dpp::fee::Credits; | ||
use dpp::identity::accessors::IdentityGettersV0; | ||
use platform_version::version::PlatformVersion; | ||
use std::collections::BTreeMap; | ||
|
||
#[test] | ||
fn should_prove_multiple_identity_balances() { | ||
let drive = setup_drive_with_initial_state_structure(None); | ||
let platform_version = PlatformVersion::latest(); | ||
let identities: BTreeMap<[u8; 32], Identity> = | ||
Identity::random_identities(10, 3, Some(14), platform_version) | ||
.expect("expected to get random identities") | ||
.into_iter() | ||
.map(|identity| (identity.id().to_buffer(), identity)) | ||
.collect(); | ||
|
||
for identity in identities.values() { | ||
drive | ||
.add_new_identity( | ||
identity.clone(), | ||
false, | ||
&BlockInfo::default(), | ||
true, | ||
None, | ||
platform_version, | ||
) | ||
.expect("expected to add an identity"); | ||
} | ||
let identity_ids = identities.keys().copied().collect::<Vec<[u8; 32]>>(); | ||
let identity_balances = identities | ||
.into_iter() | ||
.map(|(id, identity)| (id, Some(identity.balance()))) | ||
.collect::<BTreeMap<[u8; 32], Option<Credits>>>(); | ||
let proof = drive | ||
.prove_many_identity_balances( | ||
identity_ids.as_slice(), | ||
None, | ||
&platform_version.drive, | ||
) | ||
.expect("should not error when proving an identity"); | ||
|
||
let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option<Credits>>) = | ||
Drive::verify_identity_balances_for_identity_ids( | ||
proof.as_slice(), | ||
false, | ||
identity_ids.as_slice(), | ||
platform_version, | ||
) | ||
.expect("expect that this be verified"); | ||
|
||
assert_eq!(proved_identity_balances, identity_balances); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use crate::drive::balances::balance_path_vec; | ||
use crate::drive::tokens::token_balances_path_vec; | ||
use crate::drive::Drive; | ||
use crate::query::{Query, QueryItem}; | ||
use grovedb::{PathQuery, SizedQuery}; | ||
use std::ops::RangeFull; | ||
|
||
impl Drive { | ||
/// The query for proving the identities balance of a token from an identity id. | ||
pub fn token_balance_for_identity_id_query( | ||
token_id: [u8; 32], | ||
identity_id: [u8; 32], | ||
) -> PathQuery { | ||
let balance_path = token_balances_path_vec(token_id); | ||
PathQuery::new_single_key(balance_path, identity_id.to_vec()) | ||
} | ||
|
||
/// The query getting a token balance for many identities | ||
pub fn token_balances_for_identity_ids_query( | ||
token_id: [u8; 32], | ||
identity_ids: &[[u8; 32]], | ||
) -> PathQuery { | ||
let balance_path = token_balances_path_vec(token_id); | ||
let mut query = Query::new(); | ||
query.insert_keys(identity_ids.iter().map(|key| key.to_vec()).collect()); | ||
PathQuery { | ||
path: balance_path, | ||
query: SizedQuery { | ||
query, | ||
limit: None, | ||
offset: None, | ||
}, | ||
} | ||
} | ||
|
||
/// The query getting token balances for identities in a range | ||
pub fn token_balances_for_range_query( | ||
token_id: [u8; 32], | ||
start_at: Option<([u8; 32], bool)>, | ||
ascending: bool, | ||
limit: u16, | ||
) -> PathQuery { | ||
let balance_path = token_balances_path_vec(token_id); | ||
let mut query = Query::new_with_direction(ascending); | ||
if ascending { | ||
if let Some((start_at, start_at_included)) = start_at { | ||
if start_at_included { | ||
query.insert_item(QueryItem::RangeFrom(start_at.to_vec()..)) | ||
} else { | ||
query.insert_item(QueryItem::RangeAfter(start_at.to_vec()..)) | ||
} | ||
} else { | ||
query.insert_item(QueryItem::RangeFull(RangeFull)) | ||
} | ||
} else if let Some((start_at, start_at_included)) = start_at { | ||
if start_at_included { | ||
query.insert_item(QueryItem::RangeToInclusive(..=start_at.to_vec())) | ||
} else { | ||
query.insert_item(QueryItem::RangeTo(..start_at.to_vec())) | ||
} | ||
} else { | ||
query.insert_item(QueryItem::RangeFull(RangeFull)) | ||
} | ||
PathQuery { | ||
path: balance_path, | ||
query: SizedQuery { | ||
query, | ||
limit: Some(limit), | ||
offset: None, | ||
}, | ||
} | ||
} | ||
} |
Oops, something went wrong.