From b77229cf6008481f86c46e92d6ff6c9c9ef046ca Mon Sep 17 00:00:00 2001 From: Igor Date: Thu, 24 Oct 2024 21:55:27 -0700 Subject: [PATCH] tests and removing limit from friend --- .../e2e-move-tests/src/tests/aggregator.rs | 2 +- .../aptos-framework/doc/aggregator_factory.md | 32 +++++---- .../framework/aptos-framework/doc/coin.md | 14 +--- .../doc/optional_aggregator.md | 27 +++++--- .../aggregator/aggregator_factory.move | 25 ++++--- .../aggregator/aggregator_factory.spec.move | 5 +- .../aggregator/optional_aggregator.move | 66 ++++++++++++------- .../aggregator/optional_aggregator.spec.move | 2 +- .../aptos-framework/sources/coin.move | 9 +-- .../tests/aggregator_tests.move | 9 ++- .../executor/tests/internal_indexer_test.rs | 1 - 11 files changed, 114 insertions(+), 78 deletions(-) diff --git a/aptos-move/e2e-move-tests/src/tests/aggregator.rs b/aptos-move/e2e-move-tests/src/tests/aggregator.rs index e547e5d0079a9..be473248b396b 100644 --- a/aptos-move/e2e-move-tests/src/tests/aggregator.rs +++ b/aptos-move/e2e-move-tests/src/tests/aggregator.rs @@ -146,7 +146,7 @@ proptest! { } #[test] - fn test_aggregator_lifetime_lower_limit(block_split in BlockSplit::arbitrary(15)) { + fn test_aggregator_lifetime_lower_limit(block_split in BlockSplit::arbitrary(14)) { let (mut h, acc) = setup(); let txns = vec![ diff --git a/aptos-move/framework/aptos-framework/doc/aggregator_factory.md b/aptos-move/framework/aptos-framework/doc/aggregator_factory.md index a19b106dd84f8..4e53e07bd5b20 100644 --- a/aptos-move/framework/aptos-framework/doc/aggregator_factory.md +++ b/aptos-move/framework/aptos-framework/doc/aggregator_factory.md @@ -89,7 +89,7 @@ Aggregator factory is not published yet. -Aggregator V1 only supports limit == MAX_U128 +Aggregator V1 only supports limit == MAX_U128.
const EAGG_V1_LIMIT_DEPRECATED: u64 = 2;
@@ -133,7 +133,7 @@ Creates a new factory for aggregators. Can only be called during genesis.
 Creates a new aggregator instance which overflows on exceeding a limit.
 
 
-
public(friend) fun create_aggregator_internal(limit: u128): aggregator::Aggregator
+
public(friend) fun create_aggregator_internal(): aggregator::Aggregator
 
@@ -142,19 +142,14 @@ Creates a new aggregator instance which overflows on exceeding a limitImplementation -
public(friend) fun create_aggregator_internal(limit: u128): Aggregator acquires AggregatorFactory {
-    assert!(
-        limit == MAX_U128,
-        error::invalid_argument(EAGG_V1_LIMIT_DEPRECATED)
-    );
-
+
public(friend) fun create_aggregator_internal(): Aggregator acquires AggregatorFactory {
     assert!(
         exists<AggregatorFactory>(@aptos_framework),
         error::not_found(EAGGREGATOR_FACTORY_NOT_FOUND)
     );
 
     let aggregator_factory = borrow_global_mut<AggregatorFactory>(@aptos_framework);
-    new_aggregator(aggregator_factory, limit)
+    new_aggregator(aggregator_factory, MAX_U128)
 }
 
@@ -170,7 +165,8 @@ This is currently a function closed for public. This can be updated in the futur to allow any signer to call. -
public fun create_aggregator(account: &signer, limit: u128): aggregator::Aggregator
+
#[deprecated]
+public fun create_aggregator(account: &signer, limit: u128): aggregator::Aggregator
 
@@ -180,9 +176,15 @@ to allow any signer to call.
public fun create_aggregator(account: &signer, limit: u128): Aggregator acquires AggregatorFactory {
+    // deprecated. Currently used only in aptos-move/e2e-move-tests/src/tests/aggregator.data/pack/sources/aggregator_test.move
+
     // Only Aptos Framework (0x1) account can call this for now.
     system_addresses::assert_aptos_framework(account);
-    create_aggregator_internal(limit)
+    assert!(
+        limit == MAX_U128,
+        error::invalid_argument(EAGG_V1_LIMIT_DEPRECATED)
+    );
+    create_aggregator_internal()
 }
 
@@ -303,7 +305,7 @@ AggregatorFactory is not under the caller before creating the resource. ### Function `create_aggregator_internal` -
public(friend) fun create_aggregator_internal(limit: u128): aggregator::Aggregator
+
public(friend) fun create_aggregator_internal(): aggregator::Aggregator
 
@@ -311,7 +313,7 @@ AggregatorFactory is not under the caller before creating the resource.
// This enforces high-level requirement 2:
 include CreateAggregatorInternalAbortsIf;
-ensures aggregator::spec_get_limit(result) == limit;
+ensures aggregator::spec_get_limit(result) == MAX_U128;
 ensures aggregator::spec_aggregator_get_val(result) == 0;
 
@@ -333,7 +335,8 @@ AggregatorFactory is not under the caller before creating the resource. ### Function `create_aggregator` -
public fun create_aggregator(account: &signer, limit: u128): aggregator::Aggregator
+
#[deprecated]
+public fun create_aggregator(account: &signer, limit: u128): aggregator::Aggregator
 
@@ -344,6 +347,7 @@ AggregatorFactory existed under the @aptos_framework when Creating a new aggrega
let addr = signer::address_of(account);
 // This enforces high-level requirement 3:
 aborts_if addr != @aptos_framework;
+aborts_if limit != MAX_U128;
 aborts_if !exists<AggregatorFactory>(@aptos_framework);
 
diff --git a/aptos-move/framework/aptos-framework/doc/coin.md b/aptos-move/framework/aptos-framework/doc/coin.md index ee6bc77fd7125..273f2a2f3e1f0 100644 --- a/aptos-move/framework/aptos-framework/doc/coin.md +++ b/aptos-move/framework/aptos-framework/doc/coin.md @@ -987,16 +987,6 @@ Maximum possible aggregatable coin value. - - -Maximum possible coin supply. - - -
const MAX_U128: u128 = 340282366920938463463374607431768211455;
-
- - - Not enough coins to complete transaction @@ -2984,7 +2974,7 @@ Same as initialize but supply can be initialized to parallelizable decimals, supply: if (monitor_supply) { option::some( - optional_aggregator::new(MAX_U128, parallelizable) + optional_aggregator::new(parallelizable) ) } else { option::none() }, }; @@ -4256,7 +4246,7 @@ Only the creator of CoinType can initialize. && coin_info.symbol == symbol && coin_info.decimals == decimals; ensures if (monitor_supply) { - value == 0 && limit == MAX_U128 + value == 0 && limit == MAX_U128 && (parallelizable == optional_aggregator::is_parallelizable(supply)) } else { option::spec_is_none(coin_info.supply) diff --git a/aptos-move/framework/aptos-framework/doc/optional_aggregator.md b/aptos-move/framework/aptos-framework/doc/optional_aggregator.md index cdae8a1fd9bc6..10ece6b6de997 100644 --- a/aptos-move/framework/aptos-framework/doc/optional_aggregator.md +++ b/aptos-move/framework/aptos-framework/doc/optional_aggregator.md @@ -126,6 +126,15 @@ Contains either an aggregator or a normal integer, both overflowing on limit. ## Constants + + + + +
const MAX_U128: u128 = 340282366920938463463374607431768211455;
+
+ + + The value of aggregator underflows (goes below zero). Raised by native code. @@ -148,7 +157,7 @@ Aggregator feature is not supported. Raised by native code. -OptionalAggregator (Agg V1) switch not supported any more +OptionalAggregator (Agg V1) switch not supported any more.
const ESWITCH_DEPRECATED: u64 = 3;
@@ -321,7 +330,7 @@ Destroys an integer.
 Creates a new optional aggregator.
 
 
-
public(friend) fun new(limit: u128, parallelizable: bool): optional_aggregator::OptionalAggregator
+
public(friend) fun new(parallelizable: bool): optional_aggregator::OptionalAggregator
 
@@ -330,16 +339,16 @@ Creates a new optional aggregator. Implementation -
public(friend) fun new(limit: u128, parallelizable: bool): OptionalAggregator {
+
public(friend) fun new(parallelizable: bool): OptionalAggregator {
     if (parallelizable) {
         OptionalAggregator {
-            aggregator: option::some(aggregator_factory::create_aggregator_internal(limit)),
+            aggregator: option::some(aggregator_factory::create_aggregator_internal()),
             integer: option::none(),
         }
     } else {
         OptionalAggregator {
             aggregator: option::none(),
-            integer: option::some(new_integer(limit)),
+            integer: option::some(new_integer(MAX_U128)),
         }
     }
 }
@@ -702,7 +711,7 @@ Check for overflow.
 
 
 
aborts_if value > (integer.limit - integer.value);
-aborts_if integer.value + value > MAX_U128;
+aborts_if integer.value + value > MAX_U128;
 ensures integer.value <= integer.limit;
 ensures integer.value == old(integer.value) + value;
 
@@ -782,7 +791,7 @@ Check for overflow. ### Function `new` -
public(friend) fun new(limit: u128, parallelizable: bool): optional_aggregator::OptionalAggregator
+
public(friend) fun new(parallelizable: bool): optional_aggregator::OptionalAggregator
 
@@ -925,9 +934,9 @@ The integer exists and the aggregator does not exist when destroy the integer. aborts_if is_parallelizable(optional_aggregator) && (aggregator::spec_aggregator_get_val(option::borrow(optional_aggregator.aggregator)) + value > aggregator::spec_get_limit(option::borrow(optional_aggregator.aggregator))); aborts_if is_parallelizable(optional_aggregator) && (aggregator::spec_aggregator_get_val(option::borrow(optional_aggregator.aggregator)) - + value > MAX_U128); + + value > MAX_U128); aborts_if !is_parallelizable(optional_aggregator) && - (option::borrow(optional_aggregator.integer).value + value > MAX_U128); + (option::borrow(optional_aggregator.integer).value + value > MAX_U128); aborts_if !is_parallelizable(optional_aggregator) && (value > (option::borrow(optional_aggregator.integer).limit - option::borrow(optional_aggregator.integer).value)); } diff --git a/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.move b/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.move index e70397551b61e..c7192e646d900 100644 --- a/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.move +++ b/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.move @@ -16,7 +16,7 @@ module aptos_framework::aggregator_factory { /// Aggregator factory is not published yet. const EAGGREGATOR_FACTORY_NOT_FOUND: u64 = 1; - /// Aggregator V1 only supports limit == MAX_U128 + /// Aggregator V1 only supports limit == MAX_U128. const EAGG_V1_LIMIT_DEPRECATED: u64 = 2; const MAX_U128: u128 = 340282366920938463463374607431768211455; @@ -38,32 +38,39 @@ module aptos_framework::aggregator_factory { } /// Creates a new aggregator instance which overflows on exceeding a `limit`. - public(friend) fun create_aggregator_internal(limit: u128): Aggregator acquires AggregatorFactory { - assert!( - limit == MAX_U128, - error::invalid_argument(EAGG_V1_LIMIT_DEPRECATED) - ); - + public(friend) fun create_aggregator_internal(): Aggregator acquires AggregatorFactory { assert!( exists(@aptos_framework), error::not_found(EAGGREGATOR_FACTORY_NOT_FOUND) ); let aggregator_factory = borrow_global_mut(@aptos_framework); - new_aggregator(aggregator_factory, limit) + new_aggregator(aggregator_factory, MAX_U128) } + #[deprecated] /// This is currently a function closed for public. This can be updated in the future by on-chain governance /// to allow any signer to call. public fun create_aggregator(account: &signer, limit: u128): Aggregator acquires AggregatorFactory { + // deprecated. Currently used only in aptos-move/e2e-move-tests/src/tests/aggregator.data/pack/sources/aggregator_test.move + // Only Aptos Framework (0x1) account can call this for now. system_addresses::assert_aptos_framework(account); - create_aggregator_internal(limit) + assert!( + limit == MAX_U128, + error::invalid_argument(EAGG_V1_LIMIT_DEPRECATED) + ); + create_aggregator_internal() } /// Returns a new aggregator. native fun new_aggregator(aggregator_factory: &mut AggregatorFactory, limit: u128): Aggregator; + #[test_only] + public fun create_aggregator_for_test(): Aggregator acquires AggregatorFactory { + create_aggregator_internal() + } + #[test_only] public fun initialize_aggregator_factory_for_test(aptos_framework: &signer) { initialize_aggregator_factory(aptos_framework); diff --git a/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.spec.move b/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.spec.move index 9ffe7a78d2dde..7606e54d49dc0 100644 --- a/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.spec.move +++ b/aptos-move/framework/aptos-framework/sources/aggregator/aggregator_factory.spec.move @@ -54,10 +54,10 @@ spec aptos_framework::aggregator_factory { ensures exists(addr); } - spec create_aggregator_internal(limit: u128): Aggregator { + spec create_aggregator_internal(): Aggregator { /// [high-level-req-2] include CreateAggregatorInternalAbortsIf; - ensures aggregator::spec_get_limit(result) == limit; + ensures aggregator::spec_get_limit(result) == MAX_U128; ensures aggregator::spec_aggregator_get_val(result) == 0; } spec schema CreateAggregatorInternalAbortsIf { @@ -71,6 +71,7 @@ spec aptos_framework::aggregator_factory { let addr = signer::address_of(account); /// [high-level-req-3] aborts_if addr != @aptos_framework; + aborts_if limit != MAX_U128; aborts_if !exists(@aptos_framework); } diff --git a/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.move b/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.move index 8fea44651a14b..a5d9794862c52 100644 --- a/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.move +++ b/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.move @@ -16,9 +16,11 @@ module aptos_framework::optional_aggregator { /// Aggregator feature is not supported. Raised by native code. const EAGGREGATOR_UNDERFLOW: u64 = 2; - /// OptionalAggregator (Agg V1) switch not supported any more + /// OptionalAggregator (Agg V1) switch not supported any more. const ESWITCH_DEPRECATED: u64 = 3; + const MAX_U128: u128 = 340282366920938463463374607431768211455; + /// Wrapper around integer with a custom overflow limit. Supports add, subtract and read just like `Aggregator`. struct Integer has store { value: u128, @@ -72,16 +74,16 @@ module aptos_framework::optional_aggregator { } /// Creates a new optional aggregator. - public(friend) fun new(limit: u128, parallelizable: bool): OptionalAggregator { + public(friend) fun new(parallelizable: bool): OptionalAggregator { if (parallelizable) { OptionalAggregator { - aggregator: option::some(aggregator_factory::create_aggregator_internal(limit)), + aggregator: option::some(aggregator_factory::create_aggregator_internal()), integer: option::none(), } } else { OptionalAggregator { aggregator: option::none(), - integer: option::some(new_integer(limit)), + integer: option::some(new_integer(MAX_U128)), } } } @@ -156,11 +158,20 @@ module aptos_framework::optional_aggregator { option::is_some(&optional_aggregator.aggregator) } + #[test(account = @aptos_framework)] + #[expected_failure(abort_code = 0x030003, location = Self)] + fun optional_aggregator_swith_fail_test(account: signer) { + aggregator_factory::initialize_aggregator_factory(&account); + let aggregator = new(true); + switch(&mut aggregator); + destroy(aggregator); + } + #[test(account = @aptos_framework)] fun optional_aggregator_test_integer(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(30, false); + let aggregator = new(false); assert!(!is_parallelizable(&aggregator), 0); add(&mut aggregator, 12); @@ -169,14 +180,28 @@ module aptos_framework::optional_aggregator { sub(&mut aggregator, 10); assert!(read(&aggregator) == 5, 0); + + add(&mut aggregator, 12); + add(&mut aggregator, 3); + assert!(read(&aggregator) == 20, 0); + + sub(&mut aggregator, 10); + assert!(read(&aggregator) == 10, 0); + + destroy(aggregator); } #[test(account = @aptos_framework)] fun optional_aggregator_test_aggregator(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(5, true); - + let aggregator = new(true); assert!(is_parallelizable(&aggregator), 0); + + add(&mut aggregator, 12); + add(&mut aggregator, 3); + assert!(read(&aggregator) == 15, 0); + + sub(&mut aggregator, 10); assert!(read(&aggregator) == 5, 0); add(&mut aggregator, 12); @@ -186,11 +211,6 @@ module aptos_framework::optional_aggregator { sub(&mut aggregator, 10); assert!(read(&aggregator) == 10, 0); - // Switch back! - switch(&mut aggregator); - assert!(!is_parallelizable(&aggregator), 0); - assert!(read(&aggregator) == 10, 0); - destroy(aggregator); } @@ -198,24 +218,25 @@ module aptos_framework::optional_aggregator { fun optional_aggregator_destroy_test(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(30, false); + let aggregator = new(false); destroy(aggregator); - let aggregator = new(30, true); + let aggregator = new(true); destroy(aggregator); - let aggregator = new(12, false); - assert!(destroy_optional_integer(aggregator) == 12, 0); + let aggregator = new(false); + assert!(destroy_optional_integer(aggregator) == MAX_U128, 0); - let aggregator = new(21, true); - assert!(destroy_optional_aggregator(aggregator) == 21, 0); + let aggregator = new(true); + assert!(destroy_optional_aggregator(aggregator) == MAX_U128, 0); } #[test(account = @aptos_framework)] #[expected_failure(abort_code = 0x020001, location = Self)] fun non_parallelizable_aggregator_overflow_test(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(15, false); + let aggregator = new(false); + add(&mut aggregator, MAX_U128 - 15); // Overflow! add(&mut aggregator, 16); @@ -227,7 +248,7 @@ module aptos_framework::optional_aggregator { #[expected_failure(abort_code = 0x020002, location = Self)] fun non_parallelizable_aggregator_underflow_test(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(100, false); + let aggregator = new(false); // Underflow! sub(&mut aggregator, 100); @@ -240,7 +261,8 @@ module aptos_framework::optional_aggregator { #[expected_failure(abort_code = 0x020001, location = aptos_framework::aggregator)] fun parallelizable_aggregator_overflow_test(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(15, true); + let aggregator = new(true); + add(&mut aggregator, MAX_U128 - 15); // Overflow! add(&mut aggregator, 16); @@ -252,7 +274,7 @@ module aptos_framework::optional_aggregator { #[expected_failure(abort_code = 0x020002, location = aptos_framework::aggregator)] fun parallelizable_aggregator_underflow_test(account: signer) { aggregator_factory::initialize_aggregator_factory(&account); - let aggregator = new(100, true); + let aggregator = new(true); // Underflow! add(&mut aggregator, 99); diff --git a/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.spec.move b/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.spec.move index c71df72b5cabf..4a86db69d0ce7 100644 --- a/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.spec.move +++ b/aptos-move/framework/aptos-framework/sources/aggregator/optional_aggregator.spec.move @@ -114,7 +114,7 @@ spec aptos_framework::optional_aggregator { ensures integer.value == old(integer.value) - value; } - spec new(limit: u128, parallelizable: bool): OptionalAggregator { + spec new(parallelizable: bool): OptionalAggregator { aborts_if parallelizable && !exists(@aptos_framework); ensures parallelizable ==> is_parallelizable(result); ensures !parallelizable ==> !is_parallelizable(result); diff --git a/aptos-move/framework/aptos-framework/sources/coin.move b/aptos-move/framework/aptos-framework/sources/coin.move index 8823ffd27aa88..f1d9a81962785 100644 --- a/aptos-move/framework/aptos-framework/sources/coin.move +++ b/aptos-move/framework/aptos-framework/sources/coin.move @@ -141,9 +141,6 @@ module aptos_framework::coin { withdraw_events: EventHandle, } - /// Maximum possible coin supply. - const MAX_U128: u128 = 340282366920938463463374607431768211455; - #[deprecated] /// Configuration that controls the behavior of total coin supply. If the field /// is set, coin creators are allowed to upgrade to parallelizable implementations. @@ -978,7 +975,7 @@ module aptos_framework::coin { decimals, supply: if (monitor_supply) { option::some( - optional_aggregator::new(MAX_U128, parallelizable) + optional_aggregator::new(parallelizable) ) } else { option::none() }, }; @@ -1665,6 +1662,10 @@ module aptos_framework::coin { assert!(optional_aggregator::read(supply) == 1000, 0); } + #[test_only] + /// Maximum possible coin supply. + const MAX_U128: u128 = 340282366920938463463374607431768211455; + #[test(framework = @aptos_framework)] #[expected_failure(abort_code = 0x20001, location = aptos_framework::aggregator)] fun test_supply_overflow(framework: signer) acquires CoinInfo { diff --git a/aptos-move/framework/aptos-framework/tests/aggregator_tests.move b/aptos-move/framework/aptos-framework/tests/aggregator_tests.move index 9350c245268d7..5a4ae5fa0c469 100644 --- a/aptos-move/framework/aptos-framework/tests/aggregator_tests.move +++ b/aptos-move/framework/aptos-framework/tests/aggregator_tests.move @@ -4,10 +4,12 @@ module aptos_framework::aggregator_tests { use aptos_framework::aggregator; use aptos_framework::aggregator_factory; + const MAX_U128: u128 = 340282366920938463463374607431768211455; + #[test(account = @aptos_framework)] fun test_can_add_and_sub_and_read(account: signer) { aggregator_factory::initialize_aggregator_factory_for_test(&account); - let aggregator = aggregator_factory::create_aggregator(&account, 1000); + let aggregator = aggregator_factory::create_aggregator_for_test(); aggregator::add(&mut aggregator, 12); assert!(aggregator::read(&aggregator) == 12, 0); @@ -30,7 +32,8 @@ module aptos_framework::aggregator_tests { #[expected_failure(abort_code = 0x020001, location = aptos_framework::aggregator)] fun test_overflow(account: signer) { aggregator_factory::initialize_aggregator_factory_for_test(&account); - let aggregator = aggregator_factory::create_aggregator(&account, 10); + let aggregator = aggregator_factory::create_aggregator_for_test(); + aggregator::add(&mut aggregator, MAX_U128 - 10); // Overflow! aggregator::add(&mut aggregator, 12); @@ -42,7 +45,7 @@ module aptos_framework::aggregator_tests { #[expected_failure(abort_code = 0x020002, location = aptos_framework::aggregator)] fun test_underflow(account: signer) { aggregator_factory::initialize_aggregator_factory_for_test(&account); - let aggregator = aggregator_factory::create_aggregator(&account, 10); + let aggregator = aggregator_factory::create_aggregator_for_test(); // Underflow! aggregator::sub(&mut aggregator, 100); diff --git a/execution/executor/tests/internal_indexer_test.rs b/execution/executor/tests/internal_indexer_test.rs index 53c88ca9673b1..dbc58d60d64d6 100644 --- a/execution/executor/tests/internal_indexer_test.rs +++ b/execution/executor/tests/internal_indexer_test.rs @@ -318,7 +318,6 @@ fn test_db_indexer_data() { (false, "0x1::version::Version"), (false, "0x1::jwks::PatchedJWKs"), (false, "0x1::chain_id::ChainId"), - (false, "0x1::coin::SupplyConfig"), (false, "0x1::jwks::ObservedJWKs"), (false, "0x1::features::Features"), (false, "0x1::stake::ValidatorSet"),