Skip to content

Commit a9315fd

Browse files
test(drive-abci): improve batch validation test coverage (#3280)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dc17af2 commit a9315fd

4 files changed

Lines changed: 698 additions & 0 deletions

File tree

  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
use super::*;
2+
3+
mod additional_validation_tests {
4+
use super::*;
5+
use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors;
6+
7+
#[test]
8+
fn test_token_freeze_already_frozen_should_fail() {
9+
let platform_version = PlatformVersion::latest();
10+
let mut platform = TestPlatformBuilder::new()
11+
.with_latest_protocol_version()
12+
.build_with_mock_rpc()
13+
.set_genesis_state();
14+
15+
let mut rng = StdRng::seed_from_u64(49853);
16+
let platform_state = platform.state.load();
17+
18+
let (identity, signer, key) =
19+
setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5));
20+
21+
let (identity_2, _, _) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5));
22+
23+
let (contract, token_id) = create_token_contract_with_owner_identity(
24+
&mut platform,
25+
identity.id(),
26+
Some(|token_configuration: &mut TokenConfiguration| {
27+
token_configuration.set_freeze_rules(ChangeControlRules::V0(
28+
ChangeControlRulesV0 {
29+
authorized_to_make_change: AuthorizedActionTakers::ContractOwner,
30+
admin_action_takers: AuthorizedActionTakers::NoOne,
31+
changing_authorized_action_takers_to_no_one_allowed: false,
32+
changing_admin_action_takers_to_no_one_allowed: false,
33+
self_changing_admin_action_takers_allowed: false,
34+
},
35+
));
36+
}),
37+
None,
38+
None,
39+
None,
40+
platform_version,
41+
);
42+
43+
// Freeze identity_2
44+
let freeze_transition = BatchTransition::new_token_freeze_transition(
45+
token_id,
46+
identity.id(),
47+
contract.id(),
48+
0,
49+
identity_2.id(),
50+
None,
51+
None,
52+
&key,
53+
2,
54+
0,
55+
&signer,
56+
platform_version,
57+
None,
58+
)
59+
.expect("expected to create freeze transition");
60+
61+
let serialized = freeze_transition
62+
.serialize_to_bytes()
63+
.expect("expected to serialize");
64+
65+
let transaction = platform.drive.grove.start_transaction();
66+
67+
let processing_result = platform
68+
.platform
69+
.process_raw_state_transitions(
70+
&[serialized],
71+
&platform_state,
72+
&BlockInfo::default(),
73+
&transaction,
74+
platform_version,
75+
false,
76+
None,
77+
)
78+
.expect("expected to process state transition");
79+
80+
assert_matches!(
81+
processing_result.execution_results().as_slice(),
82+
[StateTransitionExecutionResult::SuccessfulExecution { .. }]
83+
);
84+
85+
platform
86+
.drive
87+
.grove
88+
.commit_transaction(transaction)
89+
.unwrap()
90+
.expect("expected to commit transaction");
91+
92+
// Verify frozen
93+
let info = platform
94+
.drive
95+
.fetch_identity_token_info(
96+
token_id.to_buffer(),
97+
identity_2.id().to_buffer(),
98+
None,
99+
platform_version,
100+
)
101+
.expect("expected to fetch token info");
102+
assert_eq!(info.map(|i| i.frozen()), Some(true));
103+
104+
// Try to freeze again - should fail
105+
let freeze_again_transition = BatchTransition::new_token_freeze_transition(
106+
token_id,
107+
identity.id(),
108+
contract.id(),
109+
0,
110+
identity_2.id(),
111+
None,
112+
None,
113+
&key,
114+
3,
115+
0,
116+
&signer,
117+
platform_version,
118+
None,
119+
)
120+
.expect("expected to create freeze transition");
121+
122+
let serialized = freeze_again_transition
123+
.serialize_to_bytes()
124+
.expect("expected to serialize");
125+
126+
let transaction = platform.drive.grove.start_transaction();
127+
128+
let processing_result = platform
129+
.platform
130+
.process_raw_state_transitions(
131+
&[serialized],
132+
&platform_state,
133+
&BlockInfo::default(),
134+
&transaction,
135+
platform_version,
136+
false,
137+
None,
138+
)
139+
.expect("expected to process state transition");
140+
141+
assert_matches!(
142+
processing_result.execution_results().as_slice(),
143+
[PaidConsensusError {
144+
error: ConsensusError::StateError(
145+
StateError::IdentityTokenAccountAlreadyFrozenError(_)
146+
),
147+
..
148+
}]
149+
);
150+
}
151+
152+
#[test]
153+
fn test_token_unfreeze_not_frozen_should_fail() {
154+
let platform_version = PlatformVersion::latest();
155+
let mut platform = TestPlatformBuilder::new()
156+
.with_latest_protocol_version()
157+
.build_with_mock_rpc()
158+
.set_genesis_state();
159+
160+
let mut rng = StdRng::seed_from_u64(49853);
161+
let platform_state = platform.state.load();
162+
163+
let (identity, signer, key) =
164+
setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5));
165+
166+
let (identity_2, _, _) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5));
167+
168+
let (contract, token_id) = create_token_contract_with_owner_identity(
169+
&mut platform,
170+
identity.id(),
171+
Some(|token_configuration: &mut TokenConfiguration| {
172+
token_configuration.set_unfreeze_rules(ChangeControlRules::V0(
173+
ChangeControlRulesV0 {
174+
authorized_to_make_change: AuthorizedActionTakers::ContractOwner,
175+
admin_action_takers: AuthorizedActionTakers::NoOne,
176+
changing_authorized_action_takers_to_no_one_allowed: false,
177+
changing_admin_action_takers_to_no_one_allowed: false,
178+
self_changing_admin_action_takers_allowed: false,
179+
},
180+
));
181+
}),
182+
None,
183+
None,
184+
None,
185+
platform_version,
186+
);
187+
188+
// Try to unfreeze without being frozen
189+
let unfreeze_transition = BatchTransition::new_token_unfreeze_transition(
190+
token_id,
191+
identity.id(),
192+
contract.id(),
193+
0,
194+
identity_2.id(),
195+
None,
196+
None,
197+
&key,
198+
2,
199+
0,
200+
&signer,
201+
platform_version,
202+
None,
203+
)
204+
.expect("expected to create unfreeze transition");
205+
206+
let serialized = unfreeze_transition
207+
.serialize_to_bytes()
208+
.expect("expected to serialize");
209+
210+
let transaction = platform.drive.grove.start_transaction();
211+
212+
let processing_result = platform
213+
.platform
214+
.process_raw_state_transitions(
215+
&[serialized],
216+
&platform_state,
217+
&BlockInfo::default(),
218+
&transaction,
219+
platform_version,
220+
false,
221+
None,
222+
)
223+
.expect("expected to process state transition");
224+
225+
assert_matches!(
226+
processing_result.execution_results().as_slice(),
227+
[PaidConsensusError {
228+
error: ConsensusError::StateError(StateError::IdentityTokenAccountNotFrozenError(
229+
_
230+
)),
231+
..
232+
}]
233+
);
234+
}
235+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
use super::*;
2+
3+
mod token_destroy_frozen_funds_tests {
4+
use super::*;
5+
6+
#[test]
7+
fn test_token_destroy_frozen_funds_on_unfrozen_account_should_fail() {
8+
let platform_version = PlatformVersion::latest();
9+
let mut platform = TestPlatformBuilder::new()
10+
.with_latest_protocol_version()
11+
.build_with_mock_rpc()
12+
.set_genesis_state();
13+
14+
let mut rng = StdRng::seed_from_u64(49853);
15+
let platform_state = platform.state.load();
16+
17+
let (identity, signer, key) =
18+
setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5));
19+
20+
let (identity_2, _, _) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5));
21+
22+
let (contract, token_id) = create_token_contract_with_owner_identity(
23+
&mut platform,
24+
identity.id(),
25+
Some(|token_configuration: &mut TokenConfiguration| {
26+
token_configuration.set_destroy_frozen_funds_rules(ChangeControlRules::V0(
27+
ChangeControlRulesV0 {
28+
authorized_to_make_change: AuthorizedActionTakers::ContractOwner,
29+
admin_action_takers: AuthorizedActionTakers::NoOne,
30+
changing_authorized_action_takers_to_no_one_allowed: false,
31+
changing_admin_action_takers_to_no_one_allowed: false,
32+
self_changing_admin_action_takers_allowed: false,
33+
},
34+
));
35+
// We also need mint + distribution rules to give identity_2 tokens
36+
token_configuration.set_manual_minting_rules(ChangeControlRules::V0(
37+
ChangeControlRulesV0 {
38+
authorized_to_make_change: AuthorizedActionTakers::ContractOwner,
39+
admin_action_takers: AuthorizedActionTakers::NoOne,
40+
changing_authorized_action_takers_to_no_one_allowed: false,
41+
changing_admin_action_takers_to_no_one_allowed: false,
42+
self_changing_admin_action_takers_allowed: false,
43+
},
44+
));
45+
token_configuration
46+
.distribution_rules_mut()
47+
.set_minting_allow_choosing_destination(true);
48+
}),
49+
None,
50+
None,
51+
None,
52+
platform_version,
53+
);
54+
55+
// Mint tokens to identity_2 so they have a token info record (but not frozen)
56+
let mint_transition = BatchTransition::new_token_mint_transition(
57+
token_id,
58+
identity.id(),
59+
contract.id(),
60+
0,
61+
5000,
62+
Some(identity_2.id()),
63+
None,
64+
None,
65+
&key,
66+
2,
67+
0,
68+
&signer,
69+
platform_version,
70+
None,
71+
)
72+
.expect("expected to create mint transition");
73+
74+
let serialized = mint_transition
75+
.serialize_to_bytes()
76+
.expect("expected to serialize");
77+
78+
let transaction = platform.drive.grove.start_transaction();
79+
80+
platform
81+
.platform
82+
.process_raw_state_transitions(
83+
&[serialized],
84+
&platform_state,
85+
&BlockInfo::default(),
86+
&transaction,
87+
platform_version,
88+
false,
89+
None,
90+
)
91+
.expect("expected to process state transition");
92+
93+
platform
94+
.drive
95+
.grove
96+
.commit_transaction(transaction)
97+
.unwrap()
98+
.expect("expected to commit transaction");
99+
100+
// Try to destroy funds of identity that is not frozen
101+
let destroy_transition = BatchTransition::new_token_destroy_frozen_funds_transition(
102+
token_id,
103+
identity.id(),
104+
contract.id(),
105+
0,
106+
identity_2.id(),
107+
None,
108+
None,
109+
&key,
110+
3,
111+
0,
112+
&signer,
113+
platform_version,
114+
None,
115+
)
116+
.expect("expected to create destroy frozen funds transition");
117+
118+
let serialized = destroy_transition
119+
.serialize_to_bytes()
120+
.expect("expected to serialize");
121+
122+
let transaction = platform.drive.grove.start_transaction();
123+
124+
let processing_result = platform
125+
.platform
126+
.process_raw_state_transitions(
127+
&[serialized],
128+
&platform_state,
129+
&BlockInfo::default(),
130+
&transaction,
131+
platform_version,
132+
false,
133+
None,
134+
)
135+
.expect("expected to process state transition");
136+
137+
assert_matches!(
138+
processing_result.execution_results().as_slice(),
139+
[PaidConsensusError {
140+
error: ConsensusError::StateError(StateError::IdentityTokenAccountNotFrozenError(
141+
_
142+
)),
143+
..
144+
}]
145+
);
146+
}
147+
}

0 commit comments

Comments
 (0)