diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index bda88fbaf95ad..242cff6d1e499 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -73,6 +73,7 @@ use 0x1::string; use 0x1::supra_account; use 0x1::supra_coin; +use 0x1::supra_config; use 0x1::supra_governance; use 0x1::timestamp; use 0x1::transaction_fee; @@ -550,7 +551,7 @@ Genesis step 1: Initialize aptos framework account and core modules on chain. -
fun initialize(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, genesis_timestamp_in_microseconds: u64)
+
fun initialize(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, genesis_timestamp_in_microseconds: u64)
 
@@ -565,6 +566,7 @@ Genesis step 1: Initialize aptos framework account and core modules on chain. initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, + supra_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, @@ -603,6 +605,7 @@ Genesis step 1: Initialize aptos framework account and core modules on chain. consensus_config::initialize(&supra_framework_account, consensus_config); execution_config::set(&supra_framework_account, execution_config); + supra_config::set(&supra_framework_account, supra_config); version::initialize(&supra_framework_account, initial_version); stake::initialize(&supra_framework_account); staking_config::initialize( @@ -1385,7 +1388,7 @@ The last step of genesis.
#[verify_only]
-fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
+fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
 
@@ -1400,6 +1403,7 @@ The last step of genesis. initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, + supra_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, @@ -1426,6 +1430,7 @@ The last step of genesis. initial_version, consensus_config, execution_config, + supra_config, epoch_interval_microsecs, minimum_stake, maximum_stake, @@ -1532,7 +1537,7 @@ The last step of genesis. ### Function `initialize` -
fun initialize(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, genesis_timestamp_in_microseconds: u64)
+
fun initialize(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, genesis_timestamp_in_microseconds: u64)
 
@@ -1785,7 +1790,7 @@ The last step of genesis.
#[verify_only]
-fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
+fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
 
diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 7c2537a6ddaad..79baab0c61527 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -62,6 +62,7 @@ This is the reference documentation of the Aptos framework. - [`0x1::storage_gas`](storage_gas.md#0x1_storage_gas) - [`0x1::supra_account`](supra_account.md#0x1_supra_account) - [`0x1::supra_coin`](supra_coin.md#0x1_supra_coin) +- [`0x1::supra_config`](supra_config.md#0x1_supra_config) - [`0x1::supra_governance`](supra_governance.md#0x1_supra_governance) - [`0x1::system_addresses`](system_addresses.md#0x1_system_addresses) - [`0x1::timestamp`](timestamp.md#0x1_timestamp) diff --git a/aptos-move/framework/supra-framework/doc/supra_config.md b/aptos-move/framework/supra-framework/doc/supra_config.md new file mode 100644 index 0000000000000..956a286244093 --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/supra_config.md @@ -0,0 +1,199 @@ + + + +# Module `0x1::supra_config` + +Maintains the consensus config for the blockchain. The config is stored in a +Reconfiguration, and may be updated by root. + + +- [Resource `SupraConfig`](#0x1_supra_config_SupraConfig) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_supra_config_initialize) +- [Function `set`](#0x1_supra_config_set) +- [Function `set_for_next_epoch`](#0x1_supra_config_set_for_next_epoch) +- [Function `on_new_epoch`](#0x1_supra_config_on_new_epoch) + + +
use 0x1::chain_status;
+use 0x1::config_buffer;
+use 0x1::error;
+use 0x1::reconfiguration;
+use 0x1::system_addresses;
+
+ + + + + +## Resource `SupraConfig` + + + +
struct SupraConfig has drop, store, key
+
+ + + +
+Fields + + +
+
+config: vector<u8> +
+
+ +
+
+ + +
+ + + +## Constants + + + + +The provided on chain config bytes are empty or invalid + + +
const EINVALID_CONFIG: u64 = 1;
+
+ + + + + +## Function `initialize` + +Publishes the SupraConfig config. + + +
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>)
+
+ + + +
+Implementation + + +
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>) {
+    system_addresses::assert_supra_framework(supra_framework);
+    assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG));
+    move_to(supra_framework, SupraConfig { config });
+}
+
+ + + +
+ + + +## Function `set` + +Deprecated by set_for_next_epoch(). + +WARNING: calling this while randomness is enabled will trigger a new epoch without randomness! + +TODO: update all the tests that reference this function, then disable this function. + + +
public fun set(account: &signer, config: vector<u8>)
+
+ + + +
+Implementation + + +
public fun set(account: &signer, config: vector<u8>) acquires SupraConfig {
+    system_addresses::assert_supra_framework(account);
+    chain_status::assert_genesis();
+    assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG));
+
+    let config_ref = &mut borrow_global_mut<SupraConfig>(@supra_framework).config;
+    *config_ref = config;
+
+    // Need to trigger reconfiguration so validator nodes can sync on the updated configs.
+    reconfiguration::reconfigure();
+}
+
+ + + +
+ + + +## Function `set_for_next_epoch` + +This can be called by on-chain governance to update on-chain configs for the next epoch. +Example usage: +``` +supra_framework::supra_config::set_for_next_epoch(&framework_signer, some_config_bytes); +supra_framework::supra_governance::reconfigure(&framework_signer); +``` + + +
public fun set_for_next_epoch(account: &signer, config: vector<u8>)
+
+ + + +
+Implementation + + +
public fun set_for_next_epoch(account: &signer, config: vector<u8>) {
+    system_addresses::assert_supra_framework(account);
+    assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG));
+    std::config_buffer::upsert<SupraConfig>(SupraConfig {config});
+}
+
+ + + +
+ + + +## Function `on_new_epoch` + +Only used in reconfigurations to apply the pending SupraConfig, if there is any. + + +
public(friend) fun on_new_epoch(framework: &signer)
+
+ + + +
+Implementation + + +
public(friend) fun on_new_epoch(framework: &signer) acquires SupraConfig {
+    system_addresses::assert_supra_framework(framework);
+    if (config_buffer::does_exist<SupraConfig>()) {
+        let new_config = config_buffer::extract<SupraConfig>();
+        if (exists<SupraConfig>(@supra_framework)) {
+            *borrow_global_mut<SupraConfig>(@supra_framework) = new_config;
+        } else {
+            move_to(framework, new_config);
+        };
+    }
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move index a500e54da295f..dfd161e2a991b 100644 --- a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move +++ b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move @@ -20,6 +20,7 @@ module supra_framework::config_buffer { friend supra_framework::consensus_config; friend supra_framework::execution_config; + friend supra_framework::supra_config; friend supra_framework::gas_schedule; friend supra_framework::jwks; friend supra_framework::jwk_consensus_config; diff --git a/aptos-move/framework/supra-framework/sources/configs/supra_config.move b/aptos-move/framework/supra-framework/sources/configs/supra_config.move new file mode 100644 index 0000000000000..e5b9ac46b1427 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/configs/supra_config.move @@ -0,0 +1,70 @@ +/// Maintains the consensus config for the blockchain. The config is stored in a +/// Reconfiguration, and may be updated by root. +module supra_framework::supra_config { + use std::error; + use std::vector; + use supra_framework::chain_status; + use supra_framework::config_buffer; + + use supra_framework::reconfiguration; + use supra_framework::system_addresses; + + friend supra_framework::genesis; + friend supra_framework::reconfiguration_with_dkg; + + struct SupraConfig has drop, key, store { + config: vector, + } + + /// The provided on chain config bytes are empty or invalid + const EINVALID_CONFIG: u64 = 1; + + /// Publishes the SupraConfig config. + public(friend) fun initialize(supra_framework: &signer, config: vector) { + system_addresses::assert_supra_framework(supra_framework); + assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG)); + move_to(supra_framework, SupraConfig { config }); + } + + /// Deprecated by `set_for_next_epoch()`. + /// + /// WARNING: calling this while randomness is enabled will trigger a new epoch without randomness! + /// + /// TODO: update all the tests that reference this function, then disable this function. + public fun set(account: &signer, config: vector) acquires SupraConfig { + system_addresses::assert_supra_framework(account); + chain_status::assert_genesis(); + assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG)); + + let config_ref = &mut borrow_global_mut(@supra_framework).config; + *config_ref = config; + + // Need to trigger reconfiguration so validator nodes can sync on the updated configs. + reconfiguration::reconfigure(); + } + + /// This can be called by on-chain governance to update on-chain configs for the next epoch. + /// Example usage: + /// ``` + /// supra_framework::supra_config::set_for_next_epoch(&framework_signer, some_config_bytes); + /// supra_framework::supra_governance::reconfigure(&framework_signer); + /// ``` + public fun set_for_next_epoch(account: &signer, config: vector) { + system_addresses::assert_supra_framework(account); + assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG)); + std::config_buffer::upsert(SupraConfig {config}); + } + + /// Only used in reconfigurations to apply the pending `SupraConfig`, if there is any. + public(friend) fun on_new_epoch(framework: &signer) acquires SupraConfig { + system_addresses::assert_supra_framework(framework); + if (config_buffer::does_exist()) { + let new_config = config_buffer::extract(); + if (exists(@supra_framework)) { + *borrow_global_mut(@supra_framework) = new_config; + } else { + move_to(framework, new_config); + }; + } + } +} diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index d0894cb2be53c..2c3d973717d7f 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -20,6 +20,7 @@ module supra_framework::genesis { use supra_framework::coin; use supra_framework::consensus_config; use supra_framework::execution_config; + use supra_framework::supra_config; use supra_framework::create_signer::create_signer; use supra_framework::gas_schedule; use supra_framework::reconfiguration; @@ -124,6 +125,7 @@ module supra_framework::genesis { initial_version: u64, consensus_config: vector, execution_config: vector, + supra_config: vector, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, @@ -162,6 +164,7 @@ module supra_framework::genesis { consensus_config::initialize(&supra_framework_account, consensus_config); execution_config::set(&supra_framework_account, execution_config); + supra_config::set(&supra_framework_account, supra_config); version::initialize(&supra_framework_account, initial_version); stake::initialize(&supra_framework_account); staking_config::initialize( @@ -622,6 +625,7 @@ module supra_framework::genesis { initial_version: u64, consensus_config: vector, execution_config: vector, + supra_config: vector, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, @@ -648,6 +652,7 @@ module supra_framework::genesis { initial_version, consensus_config, execution_config, + supra_config, epoch_interval_microsecs, minimum_stake, maximum_stake, @@ -684,6 +689,7 @@ module supra_framework::genesis { 0, x"12", x"13", + x"14", 1, 0, 1000 * ONE_APT, diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration.move b/aptos-move/framework/supra-framework/sources/reconfiguration.move index 8e03ec1b262a2..9c4b11debea8c 100644 --- a/aptos-move/framework/supra-framework/sources/reconfiguration.move +++ b/aptos-move/framework/supra-framework/sources/reconfiguration.move @@ -19,6 +19,7 @@ module supra_framework::reconfiguration { friend supra_framework::block; friend supra_framework::consensus_config; friend supra_framework::execution_config; + friend supra_framework::supra_config; friend supra_framework::gas_schedule; friend supra_framework::genesis; friend supra_framework::version; diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index 1592db5198c6d..742885a814b9b 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -124,6 +124,7 @@ pub fn encode_aptos_mainnet_genesis_transaction( framework: &ReleaseBundle, chain_id: ChainId, genesis_config: &GenesisConfiguration, + supra_config_bytes: Vec, ) -> Transaction { assert!(!genesis_config.is_test, "This is mainnet!"); validate_genesis_config(genesis_config); @@ -149,6 +150,7 @@ pub fn encode_aptos_mainnet_genesis_transaction( &consensus_config, &execution_config, &gas_schedule, + supra_config_bytes, ); initialize_features( &mut session, @@ -223,6 +225,7 @@ pub fn encode_genesis_transaction( consensus_config: &OnChainConsensusConfig, execution_config: &OnChainExecutionConfig, gas_schedule: &GasScheduleV2, + supra_config_bytes: Vec, ) -> Transaction { Transaction::GenesisTransaction(WriteSetPayload::Direct(encode_genesis_change_set( &aptos_root_key, @@ -238,6 +241,7 @@ pub fn encode_genesis_transaction( consensus_config, execution_config, gas_schedule, + supra_config_bytes, ))) } @@ -255,6 +259,7 @@ pub fn encode_genesis_change_set( consensus_config: &OnChainConsensusConfig, execution_config: &OnChainExecutionConfig, gas_schedule: &GasScheduleV2, + supra_config_bytes: Vec, ) -> ChangeSet { validate_genesis_config(genesis_config); @@ -276,6 +281,7 @@ pub fn encode_genesis_change_set( consensus_config, execution_config, gas_schedule, + supra_config_bytes, ); initialize_features( &mut session, @@ -439,6 +445,7 @@ fn initialize( consensus_config: &OnChainConsensusConfig, execution_config: &OnChainExecutionConfig, gas_schedule: &GasScheduleV2, + supra_config_bytes: Vec, ) { let gas_schedule_blob = bcs::to_bytes(gas_schedule).expect("Failure serializing genesis gas schedule"); @@ -472,6 +479,7 @@ fn initialize( MoveValue::U64(APTOS_MAX_KNOWN_VERSION.major), MoveValue::vector_u8(consensus_config_bytes), MoveValue::vector_u8(execution_config_bytes), + MoveValue::vector_u8(supra_config_bytes), MoveValue::U64(epoch_interval_usecs), MoveValue::U64(genesis_config.min_stake), MoveValue::U64(genesis_config.max_stake), @@ -1124,6 +1132,7 @@ pub fn generate_test_genesis( &OnChainConsensusConfig::default_for_genesis(), &OnChainExecutionConfig::default_for_genesis(), &default_gas_schedule(), + Vec::new(), ); (genesis, test_validators) } @@ -1151,6 +1160,7 @@ pub fn generate_mainnet_genesis( &OnChainConsensusConfig::default_for_genesis(), &OnChainExecutionConfig::default_for_genesis(), &default_gas_schedule(), + Vec::new(), ); (genesis, test_validators) } @@ -1748,6 +1758,7 @@ pub fn test_mainnet_end_to_end() { aptos_cached_packages::head_release_bundle(), ChainId::mainnet(), &mainnet_genesis_config(), + Vec::new(), ); let direct_writeset = if let Transaction::GenesisTransaction(direct_writeset) = transaction { diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs index c4c6463a3dd05..e30d57cbe48bf 100644 --- a/crates/aptos-genesis/src/lib.rs +++ b/crates/aptos-genesis/src/lib.rs @@ -165,6 +165,7 @@ impl GenesisInfo { &self.consensus_config, &self.execution_config, &self.gas_schedule, + Vec::new(), ) } diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs index a11c76e872a99..f26feeae98b43 100644 --- a/crates/aptos-genesis/src/mainnet.rs +++ b/crates/aptos-genesis/src/mainnet.rs @@ -154,6 +154,7 @@ impl MainnetGenesisInfo { randomness_config_override: self.randomness_config_override.clone(), jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), }, + Vec::new(), ) } diff --git a/unit_test.sh b/unit_test.sh new file mode 100755 index 0000000000000..908e1293d40a3 --- /dev/null +++ b/unit_test.sh @@ -0,0 +1,7 @@ +#!/bin/bash +ROOT="$(pwd)" +cargo build --release +cd ./aptos-move/framework/supra-framework && "$ROOT"/target/release/aptos move test || exit 1 +cd .. +cargo test --release -p aptos-framework -- --skip prover || exit 2 +RUST_MIN_STACK=104857600 cargo nextest run -p e2e-move-tests || exit 3