Module 0x1::hot_state_config

Maintains the hot state config for the blockchain.

The config is opaque to Move and interpreted by node software, so fields can be added without a framework upgrade. Since it affects the hot state root, it only changes at epoch boundaries. A config that nodes can't apply is rejected here, as applying it would halt the chain.

use 0x1::config_buffer;
use 0x1::error;
use 0x1::system_addresses;

Resource HotStateConfig

struct HotStateConfig 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 initial config. Only used in genesis.

public(friend) fun initialize(framework: &signer, config: vector<u8>)
Implementation
public(friend) fun initialize(framework: &signer, config: vector<u8>) {
    system_addresses::assert_aptos_framework(framework);
    assert!(config.length() > 0, error::invalid_argument(EINVALID_CONFIG));
    assert!(validate_internal(config), error::invalid_argument(EINVALID_CONFIG));
    if (!exists<HotStateConfig>(@aptos_framework)) {
        move_to(framework, HotStateConfig { config });
    }
}

Function set_for_next_epoch

This can be called by on-chain governance to update the hot state config for the next epoch. Example usage:

aptos_framework::hot_state_config::set_for_next_epoch(&framework_signer, some_config_bytes);
aptos_framework::aptos_governance::reconfigure(&framework_signer);
public fun set_for_next_epoch(framework: &signer, config: vector<u8>)
Implementation
public fun set_for_next_epoch(framework: &signer, config: vector<u8>) {
    system_addresses::assert_aptos_framework(framework);
    assert!(config.length() > 0, error::invalid_argument(EINVALID_CONFIG));
    assert!(validate_internal(config), error::invalid_argument(EINVALID_CONFIG));
    config_buffer::upsert(HotStateConfig { config });
}

Function on_new_epoch

Only used in reconfigurations to apply the pending HotStateConfig, if there is any.

public(friend) fun on_new_epoch(framework: &signer)
Implementation
public(friend) fun on_new_epoch(framework: &signer) acquires HotStateConfig {
    system_addresses::assert_aptos_framework(framework);
    if (config_buffer::does_exist<HotStateConfig>()) {
        let config = config_buffer::extract_v2<HotStateConfig>();
        if (exists<HotStateConfig>(@aptos_framework)) {
            *borrow_global_mut<HotStateConfig>(@aptos_framework) = config;
        } else {
            move_to(framework, config);
        };
    }
}

Function validate_internal

Whether config is a BCS-serialized OnChainHotStateConfig that nodes accept.

fun validate_internal(config: vector<u8>): bool
Implementation
native fun validate_internal(config: vector<u8>): bool;

Specification

Function initialize

public(friend) fun initialize(framework: &signer, config: vector<u8>)
pragma opaque;
include config_buffer::InitializeResource<HotStateConfig> {
    config: HotStateConfig { config }
};
aborts_if len(config) == 0;
aborts_if !spec_validate_internal(config);

Function set_for_next_epoch

public fun set_for_next_epoch(framework: &signer, config: vector<u8>)
pragma opaque;
modifies global<config_buffer::PendingConfigs>(@aptos_framework);
include config_buffer::SetForNextEpochAbortsIf { account: framework };
aborts_if !spec_validate_internal(config);
let key = std::type_info::type_name<HotStateConfig>();
let post configs_post = global<config_buffer::PendingConfigs>(@aptos_framework).configs;
ensures std::simple_map::spec_contains_key(configs_post, key);
ensures std::simple_map::spec_get(configs_post, key) == std::any::pack(HotStateConfig { config });

Function on_new_epoch

public(friend) fun on_new_epoch(framework: &signer)
pragma opaque;
include config_buffer::OnNewEpochApply<HotStateConfig>;

Function validate_internal

fun validate_internal(config: vector<u8>): bool
pragma opaque;
aborts_if [abstract] false;
ensures [abstract] result == spec_validate_internal(config);

fun spec_validate_internal(config: vector<u8>): bool;