@@ -5,6 +5,9 @@ module aptos_framework::account {
5
5
use std::option::{Self , Option };
6
6
use std::signer;
7
7
use std::vector;
8
+ use std::features::get_decommission_core_resources_enabled;
9
+ #[test_only]
10
+ use std::features::change_feature_flags_for_testing;
8
11
use aptos_framework::chain_id;
9
12
use aptos_framework::create_signer::create_signer;
10
13
use aptos_framework::event::{Self , EventHandle };
@@ -130,6 +133,9 @@ module aptos_framework::account {
130
133
/// whose address matches an existing address of a MultiEd25519 wallet.
131
134
const DERIVE_RESOURCE_ACCOUNT_SCHEME : u8 = 255 ;
132
135
136
+ /// Feature flag for decommissioning core resources.
137
+ const DECOMMISSION_CORE_RESOURCES : u64 = 222 ;
138
+
133
139
/// Account already exists
134
140
const EACCOUNT_ALREADY_EXISTS : u64 = 1 ;
135
141
/// Account does not exist
@@ -170,6 +176,8 @@ module aptos_framework::account {
170
176
const ENO_SIGNER_CAPABILITY_OFFERED : u64 = 19 ;
171
177
// This account has exceeded the allocated GUIDs it can create. It should be impossible to reach this number for real applications.
172
178
const EEXCEEDED_MAX_GUID_CREATION_NUM : u64 = 20 ;
179
+ // A required feature flag is not enabled.
180
+ const EFLAG_NOT_ENABLED : u64 = 21 ;
173
181
174
182
/// Explicitly separate the GUID space between Object and Account to prevent accidental overlap.
175
183
const MAX_GUID_CREATION_NUM : u64 = 0x4000000000000 ;
@@ -199,9 +207,18 @@ module aptos_framework::account {
199
207
// there cannot be an Account resource under new_addr already.
200
208
assert !(!exists <Account >(new_address), error::already_exists (EACCOUNT_ALREADY_EXISTS ));
201
209
202
- // NOTE: @core_resources gets created via a `create_account` call, so we do not include it below.
210
+ // Check if the feature flag for decommissioning core resources is enabled.
211
+ if (get_decommission_core_resources_enabled ()) {
212
+ // Assert separately for the core resources address if the feature flag is enabled.
213
+ assert !(
214
+ new_address != @0xa550c18 ,
215
+ error::invalid_argument (ECANNOT_RESERVED_ADDRESS )
216
+ );
217
+ };
218
+
219
+ // Assert for other reserved addresses.
203
220
assert !(
204
- new_address != @vm_reserved && new_address != @aptos_framework && new_address != @aptos_token && new_address != @0xa550c18 ,
221
+ new_address != @vm_reserved && new_address != @aptos_framework && new_address != @aptos_token ,
205
222
error::invalid_argument (ECANNOT_RESERVED_ADDRESS )
206
223
);
207
224
@@ -245,6 +262,12 @@ module aptos_framework::account {
245
262
public fun destroy_account_from (account: &signer , from: address ) acquires Account {
246
263
system_addresses::assert_aptos_framework (account);
247
264
265
+ // Assert that the feature flag for decommissioning core resources is enabled
266
+ assert !(
267
+ std::features ::get_decommission_core_resources_enabled (),
268
+ EFLAG_NOT_ENABLED
269
+ );
270
+
248
271
let Account {
249
272
authentication_key: _,
250
273
sequence_number: _,
@@ -976,10 +999,13 @@ module aptos_framework::account {
976
999
}
977
1000
978
1001
#[test(aptos_framework = @aptos_framework , from = @0xdead )]
979
- public entry fun test_destroy_account_from (
1002
+ public entry fun test_destroy_account_from_with_flag_enabled (
980
1003
aptos_framework: &signer ,
981
1004
from: &signer ,
982
1005
) acquires Account {
1006
+ // Enable the feature flag for testing
1007
+ std::features ::change_feature_flags_for_testing (aptos_framework, vector [222 ], vector []);
1008
+
983
1009
// Ensure the Account resource exists under the from account
984
1010
if (!exists <Account >(signer ::address_of (from))) {
985
1011
create_account (signer ::address_of (from));
@@ -995,6 +1021,27 @@ module aptos_framework::account {
995
1021
assert !(!exists <Account >(signer ::address_of (from)), 2 );
996
1022
}
997
1023
1024
+ #[test(aptos_framework = @aptos_framework , from = @0xdead )]
1025
+ #[expected_failure(abort_code = 21 , location = Self)]
1026
+ public entry fun test_destroy_account_from_with_flag_disabled (
1027
+ aptos_framework: &signer ,
1028
+ from: &signer ,
1029
+ ) acquires Account {
1030
+ // Disable the feature flag for testing
1031
+ std::features ::change_feature_flags_for_testing (aptos_framework, vector [], vector [222 ]);
1032
+
1033
+ // Ensure the Account resource exists under the from account
1034
+ if (!exists <Account >(signer ::address_of (from))) {
1035
+ create_account (signer ::address_of (from));
1036
+ };
1037
+
1038
+ // Confirm it now exists
1039
+ assert !(exists <Account >(signer ::address_of (from)), 1 );
1040
+
1041
+ // Attempt to destroy the Account resource (should fail)
1042
+ destroy_account_from (aptos_framework, signer ::address_of (from));
1043
+ }
1044
+
998
1045
#[test_only]
999
1046
struct DummyResource has key {}
1000
1047
@@ -1574,9 +1621,22 @@ module aptos_framework::account {
1574
1621
assert !(!event::was_event_emitted_by_handle (eventhandle, &event), 3 );
1575
1622
}
1576
1623
1577
- #[test]
1624
+ #[test(framework = @0x1 ) ]
1578
1625
#[expected_failure(abort_code = 65541 , location = Self)]
1579
- public entry fun test_cannot_create_account_at_core_resources_address () {
1626
+ public entry fun test_cannot_create_account_at_core_resources_address_with_feature_flag (framework: signer ) {
1627
+ // Enable the feature flag for testing
1628
+ change_feature_flags_for_testing (&framework, vector [222 ], vector []);
1629
+
1630
+ // Attempt to create an account at the core resources address
1631
+ create_account (@0xa550c18 );
1632
+ }
1633
+
1634
+ #[test(framework = @0x1 )]
1635
+ public entry fun test_can_create_account_at_core_resources_address_without_feature_flag (framework: signer ) {
1636
+ // Disable the feature flag for testing
1637
+ change_feature_flags_for_testing (&framework, vector [], vector [222 ]);
1638
+
1639
+ // Attempt to create an account at the core resources address
1580
1640
create_account (@0xa550c18 );
1581
1641
}
1582
1642
}
0 commit comments