Skip to content

Commit a66f15d

Browse files
test(drive): add verify proof coverage for tokens and voting v0 modules (#3263)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 78800af commit a66f15d

13 files changed

Lines changed: 1192 additions & 0 deletions

File tree

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,4 @@ book/book/
9090
grpc-coverage-report.txt
9191

9292
__pycache__/
93+
.claude/worktrees/

‎packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_id/v0/mod.rs‎

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,178 @@ impl Drive {
7272
}
7373
}
7474
}
75+
76+
#[cfg(test)]
77+
mod tests {
78+
use super::*;
79+
use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure;
80+
use dpp::block::block_info::BlockInfo;
81+
use dpp::data_contract::accessors::v1::DataContractV1Getters;
82+
use dpp::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0;
83+
use dpp::data_contract::associated_token::token_configuration::TokenConfiguration;
84+
use dpp::data_contract::config::v0::DataContractConfigV0;
85+
use dpp::data_contract::config::DataContractConfig;
86+
use dpp::data_contract::v1::DataContractV1;
87+
use dpp::identity::accessors::IdentityGettersV0;
88+
use dpp::identity::Identity;
89+
use dpp::prelude::DataContract;
90+
use dpp::tokens::info::v0::IdentityTokenInfoV0;
91+
use dpp::version::PlatformVersion;
92+
use std::collections::BTreeMap;
93+
94+
fn create_token_contract(_platform_version: &PlatformVersion) -> DataContract {
95+
DataContract::V1(DataContractV1 {
96+
id: Default::default(),
97+
version: 0,
98+
owner_id: Default::default(),
99+
document_types: Default::default(),
100+
config: DataContractConfig::V0(DataContractConfigV0 {
101+
can_be_deleted: false,
102+
readonly: false,
103+
keeps_history: false,
104+
documents_keep_history_contract_default: false,
105+
documents_mutable_contract_default: false,
106+
documents_can_be_deleted_contract_default: false,
107+
requires_identity_encryption_bounded_key: None,
108+
requires_identity_decryption_bounded_key: None,
109+
}),
110+
schema_defs: None,
111+
created_at: None,
112+
updated_at: None,
113+
created_at_block_height: None,
114+
updated_at_block_height: None,
115+
created_at_epoch: None,
116+
updated_at_epoch: None,
117+
groups: Default::default(),
118+
tokens: BTreeMap::from([(
119+
0,
120+
TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()),
121+
)]),
122+
keywords: Vec::new(),
123+
description: None,
124+
})
125+
}
126+
127+
#[test]
128+
fn should_prove_and_verify_token_infos_for_identity_id_with_frozen_token() {
129+
let drive = setup_drive_with_initial_state_structure(None);
130+
let platform_version = PlatformVersion::latest();
131+
132+
let identity = Identity::random_identity(3, Some(14), platform_version)
133+
.expect("expected a platform identity");
134+
let identity_id = identity.id().to_buffer();
135+
136+
let contract = create_token_contract(platform_version);
137+
let token_id = contract.token_id(0).expect("expected token at position 0");
138+
139+
drive
140+
.add_new_identity(
141+
identity.clone(),
142+
false,
143+
&BlockInfo::default(),
144+
true,
145+
None,
146+
platform_version,
147+
)
148+
.expect("expected to add an identity");
149+
150+
drive
151+
.insert_contract(
152+
&contract,
153+
BlockInfo::default(),
154+
true,
155+
None,
156+
platform_version,
157+
)
158+
.expect("expected to insert contract");
159+
160+
// Freeze the identity for this token
161+
drive
162+
.token_freeze(
163+
token_id,
164+
identity.id(),
165+
&BlockInfo::default(),
166+
true,
167+
None,
168+
platform_version,
169+
)
170+
.expect("expected to freeze token");
171+
172+
// Generate proof
173+
let token_ids = vec![token_id.to_buffer()];
174+
let proof = drive
175+
.prove_identity_token_infos(&token_ids, identity_id, None, platform_version)
176+
.expect("expected to get proof");
177+
178+
let (_, infos): (_, BTreeMap<[u8; 32], Option<IdentityTokenInfo>>) =
179+
Drive::verify_token_infos_for_identity_id(
180+
proof.as_slice(),
181+
&token_ids,
182+
identity_id,
183+
false,
184+
platform_version,
185+
)
186+
.expect("expected proof verification to succeed");
187+
188+
assert_eq!(infos.len(), 1);
189+
assert_eq!(
190+
infos.get(&token_id.to_buffer()),
191+
Some(&Some(IdentityTokenInfo::V0(IdentityTokenInfoV0 {
192+
frozen: true
193+
})))
194+
);
195+
}
196+
197+
#[test]
198+
fn should_prove_and_verify_absent_token_infos_for_identity_id() {
199+
let drive = setup_drive_with_initial_state_structure(None);
200+
let platform_version = PlatformVersion::latest();
201+
202+
let identity = Identity::random_identity(3, Some(14), platform_version)
203+
.expect("expected a platform identity");
204+
let identity_id = identity.id().to_buffer();
205+
206+
let contract = create_token_contract(platform_version);
207+
let token_id = contract.token_id(0).expect("expected token at position 0");
208+
209+
drive
210+
.add_new_identity(
211+
identity.clone(),
212+
false,
213+
&BlockInfo::default(),
214+
true,
215+
None,
216+
platform_version,
217+
)
218+
.expect("expected to add an identity");
219+
220+
drive
221+
.insert_contract(
222+
&contract,
223+
BlockInfo::default(),
224+
true,
225+
None,
226+
platform_version,
227+
)
228+
.expect("expected to insert contract");
229+
230+
// No freeze -- info should be absent
231+
let token_ids = vec![token_id.to_buffer()];
232+
let proof = drive
233+
.prove_identity_token_infos(&token_ids, identity_id, None, platform_version)
234+
.expect("expected to get proof");
235+
236+
let (_, infos): (_, BTreeMap<[u8; 32], Option<IdentityTokenInfo>>) =
237+
Drive::verify_token_infos_for_identity_id(
238+
proof.as_slice(),
239+
&token_ids,
240+
identity_id,
241+
false,
242+
platform_version,
243+
)
244+
.expect("expected proof verification to succeed");
245+
246+
assert_eq!(infos.len(), 1);
247+
assert_eq!(infos.get(&token_id.to_buffer()), Some(&None));
248+
}
249+
}

‎packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/v0/mod.rs‎

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,201 @@ impl Drive {
6363
}
6464
}
6565
}
66+
67+
#[cfg(test)]
68+
mod tests {
69+
use super::*;
70+
use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure;
71+
use dpp::block::block_info::BlockInfo;
72+
use dpp::data_contract::accessors::v1::DataContractV1Getters;
73+
use dpp::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0;
74+
use dpp::data_contract::associated_token::token_configuration::TokenConfiguration;
75+
use dpp::data_contract::config::v0::DataContractConfigV0;
76+
use dpp::data_contract::config::DataContractConfig;
77+
use dpp::data_contract::v1::DataContractV1;
78+
use dpp::identity::accessors::IdentityGettersV0;
79+
use dpp::identity::Identity;
80+
use dpp::prelude::DataContract;
81+
use dpp::tokens::info::v0::IdentityTokenInfoV0;
82+
use dpp::version::PlatformVersion;
83+
use std::collections::BTreeMap;
84+
85+
fn create_token_contract() -> DataContract {
86+
DataContract::V1(DataContractV1 {
87+
id: Default::default(),
88+
version: 0,
89+
owner_id: Default::default(),
90+
document_types: Default::default(),
91+
config: DataContractConfig::V0(DataContractConfigV0 {
92+
can_be_deleted: false,
93+
readonly: false,
94+
keeps_history: false,
95+
documents_keep_history_contract_default: false,
96+
documents_mutable_contract_default: false,
97+
documents_can_be_deleted_contract_default: false,
98+
requires_identity_encryption_bounded_key: None,
99+
requires_identity_decryption_bounded_key: None,
100+
}),
101+
schema_defs: None,
102+
created_at: None,
103+
updated_at: None,
104+
created_at_block_height: None,
105+
updated_at_block_height: None,
106+
created_at_epoch: None,
107+
updated_at_epoch: None,
108+
groups: Default::default(),
109+
tokens: BTreeMap::from([(
110+
0,
111+
TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()),
112+
)]),
113+
keywords: Vec::new(),
114+
description: None,
115+
})
116+
}
117+
118+
#[test]
119+
fn should_prove_and_verify_token_infos_for_multiple_identity_ids() {
120+
let drive = setup_drive_with_initial_state_structure(None);
121+
let platform_version = PlatformVersion::latest();
122+
123+
let identity1 = Identity::random_identity(3, Some(14), platform_version)
124+
.expect("expected a platform identity");
125+
let identity2 = Identity::random_identity(3, Some(15), platform_version)
126+
.expect("expected a platform identity");
127+
128+
let contract = create_token_contract();
129+
let token_id = contract.token_id(0).expect("expected token at position 0");
130+
131+
// Add both identities
132+
drive
133+
.add_new_identity(
134+
identity1.clone(),
135+
false,
136+
&BlockInfo::default(),
137+
true,
138+
None,
139+
platform_version,
140+
)
141+
.expect("expected to add identity 1");
142+
143+
drive
144+
.add_new_identity(
145+
identity2.clone(),
146+
false,
147+
&BlockInfo::default(),
148+
true,
149+
None,
150+
platform_version,
151+
)
152+
.expect("expected to add identity 2");
153+
154+
drive
155+
.insert_contract(
156+
&contract,
157+
BlockInfo::default(),
158+
true,
159+
None,
160+
platform_version,
161+
)
162+
.expect("expected to insert contract");
163+
164+
// Freeze only identity1 for this token
165+
drive
166+
.token_freeze(
167+
token_id,
168+
identity1.id(),
169+
&BlockInfo::default(),
170+
true,
171+
None,
172+
platform_version,
173+
)
174+
.expect("expected to freeze token for identity1");
175+
176+
let identity_ids = vec![identity1.id().to_buffer(), identity2.id().to_buffer()];
177+
178+
let proof = drive
179+
.prove_identities_token_infos(
180+
token_id.to_buffer(),
181+
&identity_ids,
182+
None,
183+
platform_version,
184+
)
185+
.expect("expected to get proof");
186+
187+
let (_, infos): (_, BTreeMap<[u8; 32], Option<IdentityTokenInfo>>) =
188+
Drive::verify_token_infos_for_identity_ids(
189+
proof.as_slice(),
190+
token_id.to_buffer(),
191+
&identity_ids,
192+
false,
193+
platform_version,
194+
)
195+
.expect("expected proof verification to succeed");
196+
197+
assert_eq!(infos.len(), 2);
198+
assert_eq!(
199+
infos.get(&identity1.id().to_buffer()),
200+
Some(&Some(IdentityTokenInfo::V0(IdentityTokenInfoV0 {
201+
frozen: true
202+
})))
203+
);
204+
assert_eq!(infos.get(&identity2.id().to_buffer()), Some(&None));
205+
}
206+
207+
#[test]
208+
fn should_prove_and_verify_absent_token_infos_for_identity_ids() {
209+
let drive = setup_drive_with_initial_state_structure(None);
210+
let platform_version = PlatformVersion::latest();
211+
212+
let identity = Identity::random_identity(3, Some(14), platform_version)
213+
.expect("expected a platform identity");
214+
215+
let contract = create_token_contract();
216+
let token_id = contract.token_id(0).expect("expected token at position 0");
217+
218+
drive
219+
.add_new_identity(
220+
identity.clone(),
221+
false,
222+
&BlockInfo::default(),
223+
true,
224+
None,
225+
platform_version,
226+
)
227+
.expect("expected to add an identity");
228+
229+
drive
230+
.insert_contract(
231+
&contract,
232+
BlockInfo::default(),
233+
true,
234+
None,
235+
platform_version,
236+
)
237+
.expect("expected to insert contract");
238+
239+
let identity_ids = vec![identity.id().to_buffer()];
240+
241+
let proof = drive
242+
.prove_identities_token_infos(
243+
token_id.to_buffer(),
244+
&identity_ids,
245+
None,
246+
platform_version,
247+
)
248+
.expect("expected to get proof");
249+
250+
let (_, infos): (_, BTreeMap<[u8; 32], Option<IdentityTokenInfo>>) =
251+
Drive::verify_token_infos_for_identity_ids(
252+
proof.as_slice(),
253+
token_id.to_buffer(),
254+
&identity_ids,
255+
false,
256+
platform_version,
257+
)
258+
.expect("expected proof verification to succeed");
259+
260+
assert_eq!(infos.len(), 1);
261+
assert_eq!(infos.get(&identity.id().to_buffer()), Some(&None));
262+
}
263+
}

0 commit comments

Comments
 (0)