Skip to content

Commit cf32dd5

Browse files
more work on tokens
1 parent 279d16f commit cf32dd5

File tree

11 files changed

+1185
-4
lines changed

11 files changed

+1185
-4
lines changed

packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json

Whitespace-only changes.

packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use platform_value::{Value, ValueMapHelper};
66
pub const DATA_CONTRACT_SCHEMA_URI_V0: &str =
77
"https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json";
88

9+
pub const TOKEN_SCHEMA_URI_V0: &str =
10+
"https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/token-meta.json";
11+
912
pub const PROPERTY_SCHEMA: &str = "$schema";
1013

1114
const SYSTEM_GENERATED_FIELDS: [&str; 9] = [

packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ pub mod document_replace_transition;
1717
pub mod document_transfer_transition;
1818
pub mod document_update_price_transition;
1919
pub mod token_base_transition;
20+
pub mod token_burn_transition;
2021
pub mod token_issuance_transition;
2122
pub mod token_transfer_transition;
22-
pub mod token_burn_transition;
2323

2424
use crate::prelude::Revision;
2525
use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods;

packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ pub use self::document_transition::{
1616
document_create_transition::DocumentCreateTransition, document_delete_transition,
1717
document_delete_transition::DocumentDeleteTransition, document_replace_transition,
1818
document_replace_transition::DocumentReplaceTransition, token_base_transition,
19-
token_issuance_transition, token_issuance_transition::TokenIssuanceTransition,
20-
token_burn_transition, token_burn_transition::TokenBurnTransition,
21-
token_transfer_transition, token_transfer_transition::TokenTransferTransition,
19+
token_burn_transition, token_burn_transition::TokenBurnTransition, token_issuance_transition,
20+
token_issuance_transition::TokenIssuanceTransition, token_transfer_transition,
21+
token_transfer_transition::TokenTransferTransition,
2222
};
2323

2424
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable};

packages/rs-drive/src/drive/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub mod votes;
5050

5151
#[cfg(feature = "server")]
5252
mod shared;
53+
mod tokens;
5354

5455
#[cfg(feature = "server")]
5556
use crate::cache::DriveCache;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[cfg(feature = "server")]
2+
mod prove;
3+
mod queries;
4+
#[cfg(feature = "server")]
5+
mod update;
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
use crate::drive::Drive;
2+
use crate::error::Error;
3+
4+
use dpp::version::drive_versions::DriveVersion;
5+
6+
use grovedb::TransactionArg;
7+
8+
impl Drive {
9+
/// Proves an Identity's token balance from the backing store
10+
pub fn prove_identity_token_balance(
11+
&self,
12+
identity_id: [u8; 32],
13+
token_id: [u8; 32],
14+
transaction: TransactionArg,
15+
drive_version: &DriveVersion,
16+
) -> Result<Vec<u8>, Error> {
17+
let balance_query = Self::token_balance_for_identity_id_query(token_id, identity_id);
18+
self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version)
19+
}
20+
21+
/// Proves multiple Identity token balances from the backing store
22+
pub fn prove_many_identity_token_balances(
23+
&self,
24+
identity_ids: &[[u8; 32]],
25+
token_id: [u8; 32],
26+
transaction: TransactionArg,
27+
drive_version: &DriveVersion,
28+
) -> Result<Vec<u8>, Error> {
29+
let balance_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids);
30+
self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version)
31+
}
32+
33+
/// Proves multiple Identity balances from the backing store by range
34+
pub fn prove_many_identity_token_balances_by_range(
35+
&self,
36+
start_at: Option<([u8; 32], bool)>,
37+
ascending: bool,
38+
limit: u16,
39+
transaction: TransactionArg,
40+
drive_version: &DriveVersion,
41+
) -> Result<Vec<u8>, Error> {
42+
let balance_query = Self::balances_for_range_query(start_at, ascending, limit);
43+
self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version)
44+
}
45+
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use super::*;
50+
use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure;
51+
use dpp::block::block_info::BlockInfo;
52+
use dpp::identity::Identity;
53+
54+
mod prove_identity_balance {
55+
use super::*;
56+
use dpp::identity::accessors::IdentityGettersV0;
57+
use dpp::version::PlatformVersion;
58+
59+
#[test]
60+
fn should_prove_a_single_identity_balance() {
61+
let drive = setup_drive_with_initial_state_structure(None);
62+
63+
let platform_version = PlatformVersion::first();
64+
65+
let identity = Identity::random_identity(3, Some(14), platform_version)
66+
.expect("expected a platform identity");
67+
68+
let identity_id = identity.id().to_buffer();
69+
drive
70+
.add_new_identity(
71+
identity.clone(),
72+
false,
73+
&BlockInfo::default(),
74+
true,
75+
None,
76+
platform_version,
77+
)
78+
.expect("expected to add an identity");
79+
let proof = drive
80+
.prove_identity_balance(identity.id().to_buffer(), None, &platform_version.drive)
81+
.expect("should not error when proving an identity");
82+
83+
let (_, proved_identity_balance) = Drive::verify_identity_balance_for_identity_id(
84+
proof.as_slice(),
85+
identity_id,
86+
false,
87+
platform_version,
88+
)
89+
.expect("expect that this be verified");
90+
91+
assert_eq!(proved_identity_balance, Some(identity.balance()));
92+
}
93+
}
94+
95+
mod prove_many_identity_balances {
96+
use super::*;
97+
use dpp::fee::Credits;
98+
use dpp::identity::accessors::IdentityGettersV0;
99+
use platform_version::version::PlatformVersion;
100+
use std::collections::BTreeMap;
101+
102+
#[test]
103+
fn should_prove_multiple_identity_balances() {
104+
let drive = setup_drive_with_initial_state_structure(None);
105+
let platform_version = PlatformVersion::latest();
106+
let identities: BTreeMap<[u8; 32], Identity> =
107+
Identity::random_identities(10, 3, Some(14), platform_version)
108+
.expect("expected to get random identities")
109+
.into_iter()
110+
.map(|identity| (identity.id().to_buffer(), identity))
111+
.collect();
112+
113+
for identity in identities.values() {
114+
drive
115+
.add_new_identity(
116+
identity.clone(),
117+
false,
118+
&BlockInfo::default(),
119+
true,
120+
None,
121+
platform_version,
122+
)
123+
.expect("expected to add an identity");
124+
}
125+
let identity_ids = identities.keys().copied().collect::<Vec<[u8; 32]>>();
126+
let identity_balances = identities
127+
.into_iter()
128+
.map(|(id, identity)| (id, Some(identity.balance())))
129+
.collect::<BTreeMap<[u8; 32], Option<Credits>>>();
130+
let proof = drive
131+
.prove_many_identity_balances(
132+
identity_ids.as_slice(),
133+
None,
134+
&platform_version.drive,
135+
)
136+
.expect("should not error when proving an identity");
137+
138+
let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option<Credits>>) =
139+
Drive::verify_identity_balances_for_identity_ids(
140+
proof.as_slice(),
141+
false,
142+
identity_ids.as_slice(),
143+
platform_version,
144+
)
145+
.expect("expect that this be verified");
146+
147+
assert_eq!(proved_identity_balances, identity_balances);
148+
}
149+
}
150+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use crate::drive::balances::balance_path_vec;
2+
use crate::drive::tokens::token_balances_path_vec;
3+
use crate::drive::Drive;
4+
use crate::query::{Query, QueryItem};
5+
use grovedb::{PathQuery, SizedQuery};
6+
use std::ops::RangeFull;
7+
8+
impl Drive {
9+
/// The query for proving the identities balance of a token from an identity id.
10+
pub fn token_balance_for_identity_id_query(
11+
token_id: [u8; 32],
12+
identity_id: [u8; 32],
13+
) -> PathQuery {
14+
let balance_path = token_balances_path_vec(token_id);
15+
PathQuery::new_single_key(balance_path, identity_id.to_vec())
16+
}
17+
18+
/// The query getting a token balance for many identities
19+
pub fn token_balances_for_identity_ids_query(
20+
token_id: [u8; 32],
21+
identity_ids: &[[u8; 32]],
22+
) -> PathQuery {
23+
let balance_path = token_balances_path_vec(token_id);
24+
let mut query = Query::new();
25+
query.insert_keys(identity_ids.iter().map(|key| key.to_vec()).collect());
26+
PathQuery {
27+
path: balance_path,
28+
query: SizedQuery {
29+
query,
30+
limit: None,
31+
offset: None,
32+
},
33+
}
34+
}
35+
36+
/// The query getting token balances for identities in a range
37+
pub fn token_balances_for_range_query(
38+
token_id: [u8; 32],
39+
start_at: Option<([u8; 32], bool)>,
40+
ascending: bool,
41+
limit: u16,
42+
) -> PathQuery {
43+
let balance_path = token_balances_path_vec(token_id);
44+
let mut query = Query::new_with_direction(ascending);
45+
if ascending {
46+
if let Some((start_at, start_at_included)) = start_at {
47+
if start_at_included {
48+
query.insert_item(QueryItem::RangeFrom(start_at.to_vec()..))
49+
} else {
50+
query.insert_item(QueryItem::RangeAfter(start_at.to_vec()..))
51+
}
52+
} else {
53+
query.insert_item(QueryItem::RangeFull(RangeFull))
54+
}
55+
} else if let Some((start_at, start_at_included)) = start_at {
56+
if start_at_included {
57+
query.insert_item(QueryItem::RangeToInclusive(..=start_at.to_vec()))
58+
} else {
59+
query.insert_item(QueryItem::RangeTo(..start_at.to_vec()))
60+
}
61+
} else {
62+
query.insert_item(QueryItem::RangeFull(RangeFull))
63+
}
64+
PathQuery {
65+
path: balance_path,
66+
query: SizedQuery {
67+
query,
68+
limit: Some(limit),
69+
offset: None,
70+
},
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)