Module 0x1::randomness_config_seqnum
Randomness stall recovery utils.
The right recovery procedure depends on what is broken:
-
Common case: randomness DKG output is stuck but consensus is still alive (the chain keeps producing blocks; only the epoch transition is wedged). Submit a governance proposal calling
aptos_governance::force_end_epoch. This invokesreconfiguration_with_dkg::finishdirectly, atomically clearing the lingering DKG session and advancing the epoch in a single Move transaction. No restarts, no local override, no operator-managed halt. -
Rare case: a randomness/DKG-related bug breaks consensus itself, so the chain cannot make any progress (no governance txn can be committed). Recover by per-validator local override:
- Ensure more than 2/3 stakes are stuck at the same version.
- On every validator, set
consensus.sync_only = trueand restart so the chain is uniformly halted (avoids execution divergence during the staggered application of the override in the next step). - On every validator, set
randomness_override_seq_numtoX+1in the node config file (whereXis the currentRandomnessConfigSeqNumon chain), setconsensus.sync_only = false, and restart. The chain should then be unblocked. - Once the bug is fixed and the binary + framework have been patched,
a governance proposal is needed to set
RandomnessConfigSeqNumtoX+2.
- Resource
RandomnessConfigSeqNum - Constants
- Function
set_for_next_epoch - Function
initialize - Function
on_new_epoch - Specification
use 0x1::config_buffer;
use 0x1::system_addresses;
Resource RandomnessConfigSeqNum
If this seqnum is smaller than a validator local override, the on-chain RandomnessConfig will be ignored.
Useful in a chain recovery from randomness stall.
struct RandomnessConfigSeqNum has drop, store, key
Fields
-
seq_num: u64
Constants
The new sequence number must be strictly greater than the current one.
const E_SEQ_NUM_MUST_INCREASE: u64 = 1;
Function set_for_next_epoch
Update RandomnessConfigSeqNum.
Used when re-enable randomness after an emergency randomness disable via local override.
The new seq_num must be strictly greater than the current on-chain value.
public fun set_for_next_epoch(framework: &signer, seq_num: u64)
Implementation
public fun set_for_next_epoch(framework: &signer, seq_num: u64) acquires RandomnessConfigSeqNum {
system_addresses::assert_aptos_framework(framework);
if (exists<RandomnessConfigSeqNum>(@aptos_framework)) {
let current = borrow_global<RandomnessConfigSeqNum>(@aptos_framework).seq_num;
assert!(seq_num > current, E_SEQ_NUM_MUST_INCREASE);
};
config_buffer::upsert(RandomnessConfigSeqNum { seq_num });
}
Function initialize
Initialize the configuration. Used in genesis or governance.
public fun initialize(framework: &signer)
Implementation
public fun initialize(framework: &signer) {
system_addresses::assert_aptos_framework(framework);
if (!exists<RandomnessConfigSeqNum>(@aptos_framework)) {
move_to(framework, RandomnessConfigSeqNum { seq_num: 0 })
}
}
Function on_new_epoch
Only used in reconfigurations to apply the pending RandomnessConfig, if there is any.
public(friend) fun on_new_epoch(framework: &signer)
Implementation
public(friend) fun on_new_epoch(framework: &signer) acquires RandomnessConfigSeqNum {
system_addresses::assert_aptos_framework(framework);
if (config_buffer::does_exist<RandomnessConfigSeqNum>()) {
let new_config = config_buffer::extract_v2<RandomnessConfigSeqNum>();
if (exists<RandomnessConfigSeqNum>(@aptos_framework)) {
*borrow_global_mut<RandomnessConfigSeqNum>(@aptos_framework) = new_config;
} else {
move_to(framework, new_config);
}
}
}
Specification
Function on_new_epoch
public(friend) fun on_new_epoch(framework: &signer)
requires @aptos_framework == std::signer::address_of(framework);
include config_buffer::OnNewEpochRequirement<RandomnessConfigSeqNum>;
aborts_if false;