gas_schedule - [devnet]
Esta página aún no está disponible en tu idioma.
This module defines structs and methods to initialize the gas schedule, which dictates how much it costs to execute Move on the network.
use 0x1::aptos_hash;use 0x1::bcs;use 0x1::chain_status;use 0x1::config_buffer;use 0x1::error;use 0x1::reconfiguration;use 0x1::storage_gas;use 0x1::string;use 0x1::system_addresses;use 0x1::util;use 0x1::vector;
Constants
const EINVALID_GAS_FEATURE_VERSION: u64 = 2;
The provided gas schedule bytes are empty or invalid
const EINVALID_GAS_SCHEDULE: u64 = 1;
const EINVALID_GAS_SCHEDULE_HASH: u64 = 3;
Structs
GasEntry
struct GasEntry has copy, drop, store
Fields
-
key: string::String
-
val: u64
Resources
GasSchedule
struct GasSchedule has copy, drop, key
Fields
-
entries: vector<gas_schedule::GasEntry>
GasScheduleV2
struct GasScheduleV2 has copy, drop, store, key
Fields
-
feature_version: u64
-
entries: vector<gas_schedule::GasEntry>
Functions
initialize
Only called during genesis.
public(friend) fun initialize(aptos_framework: &signer, gas_schedule_blob: vector<u8>)
Implementation
public(friend) fun initialize(aptos_framework: &signer, gas_schedule_blob: vector<u8>) { system_addresses::assert_aptos_framework(aptos_framework); assert!(!vector::is_empty(&gas_schedule_blob), error::invalid_argument(EINVALID_GAS_SCHEDULE));
// TODO(Gas): check if gas schedule is consistent let gas_schedule: GasScheduleV2 = from_bytes(gas_schedule_blob); move_to<GasScheduleV2>(aptos_framework, gas_schedule);}
set_gas_schedule
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_gas_schedule(aptos_framework: &signer, gas_schedule_blob: vector<u8>)
Implementation
public fun set_gas_schedule(aptos_framework: &signer, gas_schedule_blob: vector<u8>) acquires GasSchedule, GasScheduleV2 { system_addresses::assert_aptos_framework(aptos_framework); assert!(!vector::is_empty(&gas_schedule_blob), error::invalid_argument(EINVALID_GAS_SCHEDULE)); chain_status::assert_genesis();
if (exists<GasScheduleV2>(@aptos_framework)) { let gas_schedule = borrow_global_mut<GasScheduleV2>(@aptos_framework); let new_gas_schedule: GasScheduleV2 = from_bytes(gas_schedule_blob); assert!(new_gas_schedule.feature_version >= gas_schedule.feature_version, error::invalid_argument(EINVALID_GAS_FEATURE_VERSION)); // TODO(Gas): check if gas schedule is consistent *gas_schedule = new_gas_schedule; } else { if (exists<GasSchedule>(@aptos_framework)) { _ = move_from<GasSchedule>(@aptos_framework); }; let new_gas_schedule: GasScheduleV2 = from_bytes(gas_schedule_blob); // TODO(Gas): check if gas schedule is consistent move_to<GasScheduleV2>(aptos_framework, new_gas_schedule); };
// Need to trigger reconfiguration so validator nodes can sync on the updated gas schedule. reconfiguration::reconfigure();}
set_for_next_epoch
Set the gas schedule for the next epoch, typically called by on-chain governance. Abort if the version of the given schedule is lower than the current version.
Example usage:
aptos_framework::gas_schedule::set_for_next_epoch(&framework_signer, some_gas_schedule_blob);aptos_framework::aptos_governance::reconfigure(&framework_signer);
public fun set_for_next_epoch(aptos_framework: &signer, gas_schedule_blob: vector<u8>)
Implementation
public fun set_for_next_epoch(aptos_framework: &signer, gas_schedule_blob: vector<u8>) acquires GasScheduleV2 { system_addresses::assert_aptos_framework(aptos_framework); assert!(!vector::is_empty(&gas_schedule_blob), error::invalid_argument(EINVALID_GAS_SCHEDULE)); let new_gas_schedule: GasScheduleV2 = from_bytes(gas_schedule_blob); if (exists<GasScheduleV2>(@aptos_framework)) { let cur_gas_schedule = borrow_global<GasScheduleV2>(@aptos_framework); assert!( new_gas_schedule.feature_version >= cur_gas_schedule.feature_version, error::invalid_argument(EINVALID_GAS_FEATURE_VERSION) ); }; config_buffer::upsert(new_gas_schedule);}
set_for_next_epoch_check_hash
Set the gas schedule for the next epoch, typically called by on-chain governance. Abort if the version of the given schedule is lower than the current version. Require a hash of the old gas schedule to be provided and will abort if the hashes mismatch.
public fun set_for_next_epoch_check_hash(aptos_framework: &signer, old_gas_schedule_hash: vector<u8>, new_gas_schedule_blob: vector<u8>)
Implementation
public fun set_for_next_epoch_check_hash( aptos_framework: &signer, old_gas_schedule_hash: vector<u8>, new_gas_schedule_blob: vector<u8>) acquires GasScheduleV2 { system_addresses::assert_aptos_framework(aptos_framework); assert!(!vector::is_empty(&new_gas_schedule_blob), error::invalid_argument(EINVALID_GAS_SCHEDULE));
let new_gas_schedule: GasScheduleV2 = from_bytes(new_gas_schedule_blob); if (exists<GasScheduleV2>(@aptos_framework)) { let cur_gas_schedule = borrow_global<GasScheduleV2>(@aptos_framework); assert!( new_gas_schedule.feature_version >= cur_gas_schedule.feature_version, error::invalid_argument(EINVALID_GAS_FEATURE_VERSION) ); let cur_gas_schedule_bytes = bcs::to_bytes(cur_gas_schedule); let cur_gas_schedule_hash = aptos_hash::sha3_512(cur_gas_schedule_bytes); assert!( cur_gas_schedule_hash == old_gas_schedule_hash, error::invalid_argument(EINVALID_GAS_SCHEDULE_HASH) ); };
config_buffer::upsert(new_gas_schedule);}
on_new_epoch
Only used in reconfigurations to apply the pending GasScheduleV2
, if there is any.
public(friend) fun on_new_epoch(framework: &signer)
Implementation
public(friend) fun on_new_epoch(framework: &signer) acquires GasScheduleV2 { system_addresses::assert_aptos_framework(framework); if (config_buffer::does_exist<GasScheduleV2>()) { let new_gas_schedule = config_buffer::extract_v2<GasScheduleV2>(); if (exists<GasScheduleV2>(@aptos_framework)) { *borrow_global_mut<GasScheduleV2>(@aptos_framework) = new_gas_schedule; } else { move_to(framework, new_gas_schedule); } }}
set_storage_gas_config
public fun set_storage_gas_config(aptos_framework: &signer, config: storage_gas::StorageGasConfig)
Implementation
public fun set_storage_gas_config(aptos_framework: &signer, config: StorageGasConfig) { storage_gas::set_config(aptos_framework, config); // Need to trigger reconfiguration so the VM is guaranteed to load the new gas fee starting from the next // transaction. reconfiguration::reconfigure();}
set_storage_gas_config_for_next_epoch
public fun set_storage_gas_config_for_next_epoch(aptos_framework: &signer, config: storage_gas::StorageGasConfig)
Implementation
public fun set_storage_gas_config_for_next_epoch(aptos_framework: &signer, config: StorageGasConfig) { storage_gas::set_config(aptos_framework, config);}
Specification
High-level Requirements
No. | Requirement | Criticality | Implementation | Enforcement |
---|---|---|---|---|
1 | During genesis, the Aptos framework account should be assigned the gas schedule resource. | Medium | The gas_schedule::initialize function calls the assert_aptos_framework function to ensure that the signer is the aptos_framework and then assigns the GasScheduleV2 resource to it. | Formally verified via initialize. |
2 | Only the Aptos framework account should be allowed to update the gas schedule resource. | Critical | The gas_schedule::set_gas_schedule function calls the assert_aptos_framework function to ensure that the signer is the aptos framework account. | Formally verified via set_gas_schedule. |
3 | Only valid gas schedule should be allowed for initialization and update. | Medium | The initialize and set_gas_schedule functions ensures that the gas_schedule_blob is not empty. | Formally verified via initialize and set_gas_schedule. |
4 | Only a gas schedule with the feature version greater or equal than the current feature version is allowed to be provided when performing an update operation. | Medium | The set_gas_schedule function validates the feature_version of the new_gas_schedule by ensuring that it is greater or equal than the current gas_schedule.feature_version. | Formally verified via set_gas_schedule. |
Module-level Specification
pragma verify = true;pragma aborts_if_is_strict;
initialize
public(friend) fun initialize(aptos_framework: &signer, gas_schedule_blob: vector<u8>)
let addr = signer::address_of(aptos_framework);// This enforces high-level requirement 1:include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };// This enforces high-level requirement 3:aborts_if len(gas_schedule_blob) == 0;aborts_if exists<GasScheduleV2>(addr);ensures exists<GasScheduleV2>(addr);
set_gas_schedule
public fun set_gas_schedule(aptos_framework: &signer, gas_schedule_blob: vector<u8>)
pragma verify_duration_estimate = 600;requires exists<CoinInfo<AptosCoin>>(@aptos_framework);requires chain_status::is_genesis();include staking_config::StakingRewardsConfigRequirement;// This enforces high-level requirement 2:include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };// This enforces high-level requirement 3:aborts_if len(gas_schedule_blob) == 0;let new_gas_schedule = util::spec_from_bytes<GasScheduleV2>(gas_schedule_blob);let gas_schedule = global<GasScheduleV2>(@aptos_framework);// This enforces high-level requirement 4:aborts_if exists<GasScheduleV2>(@aptos_framework) && new_gas_schedule.feature_version < gas_schedule.feature_version;ensures exists<GasScheduleV2>(signer::address_of(aptos_framework));ensures global<GasScheduleV2>(@aptos_framework) == new_gas_schedule;
set_for_next_epoch
public fun set_for_next_epoch(aptos_framework: &signer, gas_schedule_blob: vector<u8>)
include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };include config_buffer::SetForNextEpochAbortsIf { account: aptos_framework, config: gas_schedule_blob};let new_gas_schedule = util::spec_from_bytes<GasScheduleV2>(gas_schedule_blob);let cur_gas_schedule = global<GasScheduleV2>(@aptos_framework);aborts_if exists<GasScheduleV2>(@aptos_framework) && new_gas_schedule.feature_version < cur_gas_schedule.feature_version;
set_for_next_epoch_check_hash
public fun set_for_next_epoch_check_hash(aptos_framework: &signer, old_gas_schedule_hash: vector<u8>, new_gas_schedule_blob: vector<u8>)
include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };include config_buffer::SetForNextEpochAbortsIf { account: aptos_framework, config: new_gas_schedule_blob};let new_gas_schedule = util::spec_from_bytes<GasScheduleV2>(new_gas_schedule_blob);let cur_gas_schedule = global<GasScheduleV2>(@aptos_framework);aborts_if exists<GasScheduleV2>(@aptos_framework) && new_gas_schedule.feature_version < cur_gas_schedule.feature_version;aborts_if exists<GasScheduleV2>(@aptos_framework) && (!features::spec_sha_512_and_ripemd_160_enabled() || aptos_hash::spec_sha3_512_internal(bcs::serialize(cur_gas_schedule)) != old_gas_schedule_hash);
on_new_epoch
public(friend) fun on_new_epoch(framework: &signer)
requires @aptos_framework == std::signer::address_of(framework);include config_buffer::OnNewEpochRequirement<GasScheduleV2>;aborts_if false;
set_storage_gas_config
public fun set_storage_gas_config(aptos_framework: &signer, config: storage_gas::StorageGasConfig)
pragma verify_duration_estimate = 600;requires exists<CoinInfo<AptosCoin>>(@aptos_framework);include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };include staking_config::StakingRewardsConfigRequirement;aborts_if !exists<StorageGasConfig>(@aptos_framework);ensures global<StorageGasConfig>(@aptos_framework) == config;
include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };aborts_if !exists<storage_gas::StorageGasConfig>(@aptos_framework);
set_storage_gas_config_for_next_epoch
public fun set_storage_gas_config_for_next_epoch(aptos_framework: &signer, config: storage_gas::StorageGasConfig)
include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };aborts_if !exists<storage_gas::StorageGasConfig>(@aptos_framework);