Skip to content

consensus_config - [mainnet]

Maintains the consensus config for the blockchain. The config is stored in a Reconfiguration, and may be updated by root.

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

Constants

The provided on chain config bytes are empty or invalid

const EINVALID_CONFIG: u64 = 1;

Resources

ConsensusConfig

struct ConsensusConfig has drop, store, key
Fields
config: vector<u8>

Functions

initialize

Publishes the ConsensusConfig config.

public(friend) fun initialize(aptos_framework: &signer, config: vector<u8>)
Implementation
public(friend) fun initialize(aptos_framework: &signer, config: vector<u8>) {
system_addresses::assert_aptos_framework(aptos_framework);
assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG));
move_to(aptos_framework, ConsensusConfig { config });
}

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 ConsensusConfig {
system_addresses::assert_aptos_framework(account);
chain_status::assert_genesis();
assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG));
let config_ref = &mut borrow_global_mut<ConsensusConfig>(@aptos_framework).config;
*config_ref = config;
// Need to trigger reconfiguration so validator nodes can sync on the updated configs.
reconfiguration::reconfigure();
}

set_for_next_epoch

This can be called by on-chain governance to update on-chain consensus configs for the next epoch. Example usage:

aptos_framework::consensus_config::set_for_next_epoch(&framework_signer, some_config_bytes);
aptos_framework::aptos_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_aptos_framework(account);
assert!(vector::length(&config) > 0, error::invalid_argument(EINVALID_CONFIG));
std::config_buffer::upsert<ConsensusConfig>(ConsensusConfig {config});
}

on_new_epoch

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

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

validator_txn_enabled

public fun validator_txn_enabled(): bool
Implementation
public fun validator_txn_enabled(): bool acquires ConsensusConfig {
let config_bytes = borrow_global<ConsensusConfig>(@aptos_framework).config;
validator_txn_enabled_internal(config_bytes)
}

validator_txn_enabled_internal

fun validator_txn_enabled_internal(config_bytes: vector<u8>): bool
Implementation
native fun validator_txn_enabled_internal(config_bytes: vector<u8>): bool;

Specification

High-level Requirements

No.RequirementCriticalityImplementationEnforcement
1 During genesis, the Aptos framework account should be assigned the consensus config resource. Medium The consensus_config::initialize function calls the assert_aptos_framework function to ensure that the signer is the aptos_framework and then assigns the ConsensusConfig resource to it. Formally verified via initialize.
2 Only aptos framework account is allowed to update the consensus configuration. Medium The consensus_config::set function ensures that the signer is aptos_framework. Formally verified via set.
3 Only a valid configuration can be used during initialization and update. Medium Both the initialize and set functions validate the config by ensuring its length to be greater than 0. Formally verified via initialize and set.

Module-level Specification

pragma verify = true;
pragma aborts_if_is_strict;
invariant [suspendable] chain_status::is_operating() ==> exists<ConsensusConfig>(@aptos_framework);

initialize

public(friend) fun initialize(aptos_framework: &signer, config: vector<u8>)

Ensure caller is admin. Aborts if StateStorageUsage already exists.

let addr = signer::address_of(aptos_framework);
// This enforces high-level requirement 1:
aborts_if !system_addresses::is_aptos_framework_address(addr);
aborts_if exists<ConsensusConfig>(@aptos_framework);
// This enforces high-level requirement 3:
aborts_if !(len(config) > 0);
ensures global<ConsensusConfig>(addr) == ConsensusConfig { config };

set

public fun set(account: &signer, config: vector<u8>)

Ensure the caller is admin and ConsensusConfig should be existed. When setting now time must be later than last_reconfiguration_time.

pragma verify_duration_estimate = 600;
include staking_config::StakingRewardsConfigRequirement;
let addr = signer::address_of(account);
// This enforces high-level requirement 2:
aborts_if !system_addresses::is_aptos_framework_address(addr);
aborts_if !exists<ConsensusConfig>(@aptos_framework);
// This enforces high-level requirement 3:
aborts_if !(len(config) > 0);
requires chain_status::is_genesis();
requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
ensures global<ConsensusConfig>(@aptos_framework).config == config;

set_for_next_epoch

public fun set_for_next_epoch(account: &signer, config: vector<u8>)
include config_buffer::SetForNextEpochAbortsIf;

on_new_epoch

public(friend) fun on_new_epoch(framework: &signer)
requires @aptos_framework == std::signer::address_of(framework);
include config_buffer::OnNewEpochRequirement<ConsensusConfig>;
aborts_if false;

validator_txn_enabled

public fun validator_txn_enabled(): bool
pragma opaque;
aborts_if !exists<ConsensusConfig>(@aptos_framework);
ensures [abstract] result == spec_validator_txn_enabled_internal(global<ConsensusConfig>(@aptos_framework).config);

validator_txn_enabled_internal

fun validator_txn_enabled_internal(config_bytes: vector<u8>): bool
pragma opaque;
ensures [abstract] result == spec_validator_txn_enabled_internal(config_bytes);
fun spec_validator_txn_enabled_internal(config_bytes: vector<u8>): bool;