Skip to main content

Module sui_system::validator_set

use std::address;
use std::ascii;
use std::bcs;
use std::internal;
use std::option;
use std::string;
use std::type_name;
use std::u128;
use std::u64;
use std::vector;
use sui::accumulator;
use sui::accumulator_settlement;
use sui::address;
use sui::bag;
use sui::balance;
use sui::bcs;
use sui::coin;
use sui::config;
use sui::deny_list;
use sui::dynamic_field;
use sui::dynamic_object_field;
use sui::event;
use sui::funds_accumulator;
use sui::hash;
use sui::hex;
use sui::object;
use sui::party;
use sui::priority_queue;
use sui::protocol_config;
use sui::sui;
use sui::table;
use sui::table_vec;
use sui::transfer;
use sui::tx_context;
use sui::types;
use sui::url;
use sui::vec_map;
use sui::vec_set;
use sui::versioned;
use sui_system::staking_pool;
use sui_system::validator;
use sui_system::validator_cap;
use sui_system::validator_wrapper;
use sui_system::voting_power;

Struct ValidatorSet

public struct ValidatorSet has store
Click to open
Fields
total_stake: u64
Total amount of stake from all active validators at the beginning of the epoch.
Written only once per epoch, in advance_epoch function.
active_validators: vector<sui_system::validator::Validator>
The current list of active validators.
pending_active_validators: sui::table_vec::TableVec<sui_system::validator::Validator>
List of new validator candidates added during the current epoch.
They will be processed at the end of the epoch.
pending_removals: vector<u64>
Removal requests from the validators. Each element is an index pointing to active_validators.
staking_pool_mappings: sui::table::Table<sui::object::ID, address>
Mappings from staking pool's ID to the sui address of a validator.
inactive_validators: sui::table::Table<sui::object::ID, sui_system::validator_wrapper::ValidatorWrapper>
Mapping from a staking pool ID to the inactive validator that has that pool as its staking pool.
When a validator is deactivated the validator is removed from active_validators it is added to this table so that stakers can continue to withdraw their stake from it.
validator_candidates: sui::table::Table<address, sui_system::validator_wrapper::ValidatorWrapper>
Table storing preactive/candidate validators, mapping their addresses to their Validator structs.
When an address calls request_add_validator_candidate, they get added to this table and become a preactive validator.
When the candidate has met the min stake requirement, they can call request_add_validator to officially add them to the active validator set active_validators next epoch.
at_risk_validators: sui::vec_map::VecMap<address, u64>
Table storing the number of epochs during which a validator's stake has been below the low stake threshold.
extra_fields: sui::bag::Bag
Any extra fields that's not defined statically.

Struct ValidatorEpochInfoEvent

Event containing staking and rewards related information of each validator, emitted during epoch advancement.

public struct ValidatorEpochInfoEvent has copy, drop
Click to open
Fields
epoch: u64
validator_address: address
reference_gas_survey_quote: u64
stake: u64
commission_rate: u64
pool_staking_reward: u64
storage_fund_staking_reward: u64
pool_token_exchange_rate: sui_system::staking_pool::PoolTokenExchangeRate
tallying_rule_reporters: vector<address>
tallying_rule_global_score: u64

Struct ValidatorEpochInfoEventV2

V2 of ValidatorEpochInfoEvent containing more information about the validator.

public struct ValidatorEpochInfoEventV2 has copy, drop
Click to open
Fields
epoch: u64
validator_address: address
reference_gas_survey_quote: u64
stake: u64
voting_power: u64
commission_rate: u64
pool_staking_reward: u64
storage_fund_staking_reward: u64
pool_token_exchange_rate: sui_system::staking_pool::PoolTokenExchangeRate
tallying_rule_reporters: vector<address>
tallying_rule_global_score: u64

Struct ValidatorJoinEvent

Event emitted every time a new validator joins the committee.
The epoch value corresponds to the first epoch this change takes place.

public struct ValidatorJoinEvent has copy, drop
Click to open
Fields
epoch: u64
validator_address: address
staking_pool_id: sui::object::ID

Struct ValidatorLeaveEvent

Event emitted every time a validator leaves the committee.
The epoch value corresponds to the first epoch this change takes place.

public struct ValidatorLeaveEvent has copy, drop
Click to open
Fields
epoch: u64
validator_address: address
staking_pool_id: sui::object::ID
is_voluntary: bool

Struct VotingPowerAdmissionStartEpochKey

Key for the extra_fields bag to store the start epoch of allowing admission of new validators based on a minimum voting power rather than a minimum stake.

public struct VotingPowerAdmissionStartEpochKey has copy, drop, store

Constants

const ENonValidatorInReportRecords: u64 = 0;
const EInvalidStakeAdjustmentAmount: u64 = 1;
const EDuplicateValidator: u64 = 2;
const ENoPoolFound: u64 = 3;
const ENotAValidator: u64 = 4;
const EMinJoiningStakeNotReached: u64 = 5;
const EAlreadyValidatorCandidate: u64 = 6;
const EValidatorNotCandidate: u64 = 7;
const ENotValidatorCandidate: u64 = 8;
const ENotActiveOrPendingValidator: u64 = 9;
const EStakingBelowThreshold: u64 = 10;
const EValidatorAlreadyRemoved: u64 = 11;
const ENotAPendingValidator: u64 = 12;
const EValidatorSetEmpty: u64 = 13;
const EInvalidCap: u64 = 101;
const ACTIVE_VALIDATOR_ONLY: u8 = 1;
const ACTIVE_OR_PENDING_VALIDATOR: u8 = 2;
const ANY_VALIDATOR: u8 = 3;
const BASIS_POINT_DENOMINATOR: u64 = 10000;
const MIN_STAKING_THRESHOLD: u64 = 1000000000;
const PHASE_LENGTH: u64 = 14;

Function new

public(package) fun new(init_active_validators: vector<sui_system::validator::Validator>, ctx: &mut sui::tx_context::TxContext): sui_system::validator_set::ValidatorSet

Function request_add_validator_candidate

Called by sui_system to add a new validator candidate.

public(package) fun request_add_validator_candidate(self: &mut sui_system::validator_set::ValidatorSet, validator: sui_system::validator::Validator, ctx: &mut sui::tx_context::TxContext)

Function request_remove_validator_candidate

Called by sui_system to remove a validator candidate, and move them to inactive_validators.

public(package) fun request_remove_validator_candidate(self: &mut sui_system::validator_set::ValidatorSet, ctx: &mut sui::tx_context::TxContext)

Function request_add_validator

Called by sui_system to add a new validator to pending_active_validators, which will be processed at the end of epoch.

public(package) fun request_add_validator(self: &mut sui_system::validator_set::ValidatorSet, ctx: &sui::tx_context::TxContext)

Function can_join

Return true if a candidate validator with stake will have sufficeint voting power to join the validator set

fun can_join(self: &sui_system::validator_set::ValidatorSet, stake: u64, ctx: &sui::tx_context::TxContext): bool

Function get_voting_power_thresholds

return (min, low, very low voting power) thresholds

fun get_voting_power_thresholds(self: &sui_system::validator_set::ValidatorSet, ctx: &sui::tx_context::TxContext): (u64, u64, u64)

Function assert_no_pending_or_active_duplicates

public(package) fun assert_no_pending_or_active_duplicates(self: &sui_system::validator_set::ValidatorSet, validator: &sui_system::validator::Validator)

Function request_remove_validator

Called by sui_system, to remove a validator.
The index of the validator is added to pending_removals and will be processed at the end of epoch.
Only an active validator can request to be removed.

public(package) fun request_remove_validator(self: &mut sui_system::validator_set::ValidatorSet, ctx: &sui::tx_context::TxContext)

Function request_add_stake

Called by sui_system, to add a new stake to the validator.
This request is added to the validator's staking pool's pending stake entries, processed at the end of the epoch.
Aborts in case the staking amount is smaller than MIN_STAKING_THRESHOLD

public(package) fun request_add_stake(self: &mut sui_system::validator_set::ValidatorSet, validator_address: address, stake: sui::balance::Balance<sui::sui::SUI>, ctx: &mut sui::tx_context::TxContext): sui_system::staking_pool::StakedSui

Function request_withdraw_stake

Called by sui_system, to withdraw some share of a stake from the validator. The share to withdraw is denoted by principal_withdraw_amount. One of two things occurs in this function:

  1. If the staked_sui is staked with an active validator, the request is added to the validator's staking pool's pending stake withdraw entries, processed at the end of the epoch.
  2. If the staked_sui was staked with a validator that is no longer active, the stake and any rewards corresponding to it will be immediately processed.
public(package) fun request_withdraw_stake(self: &mut sui_system::validator_set::ValidatorSet, staked_sui: sui_system::staking_pool::StakedSui, ctx: &sui::tx_context::TxContext): sui::balance::Balance<sui::sui::SUI>

Function convert_to_fungible_staked_sui

public(package) fun convert_to_fungible_staked_sui(self: &mut sui_system::validator_set::ValidatorSet, staked_sui: sui_system::staking_pool::StakedSui, ctx: &mut sui::tx_context::TxContext): sui_system::staking_pool::FungibleStakedSui

Function redeem_fungible_staked_sui

public(package) fun redeem_fungible_staked_sui(self: &mut sui_system::validator_set::ValidatorSet, fungible_staked_sui: sui_system::staking_pool::FungibleStakedSui, ctx: &sui::tx_context::TxContext): sui::balance::Balance<sui::sui::SUI>

Function request_set_commission_rate

public(package) fun request_set_commission_rate(self: &mut sui_system::validator_set::ValidatorSet, new_commission_rate: u64, ctx: &sui::tx_context::TxContext)

Function advance_epoch

Update the validator set at the end of epoch.
It does the following things:

  1. Distribute stake award.
  2. Process pending stake deposits and withdraws for each validator (adjust_stake).
  3. Process pending stake deposits, and withdraws.
  4. Process pending validator application and withdraws.
  5. At the end, we calculate the total stake for the new epoch.
public(package) fun advance_epoch(self: &mut sui_system::validator_set::ValidatorSet, computation_reward: &mut sui::balance::Balance<sui::sui::SUI>, storage_fund_reward: &mut sui::balance::Balance<sui::sui::SUI>, validator_report_records: &mut sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>, reward_slashing_rate: u64, low_stake_grace_period: u64, ctx: &mut sui::tx_context::TxContext)

Function update_validator_positions_and_calculate_total_stake

This function does the following:

  • removes validators from at_risk group if their voting power is above the LOW threshold
  • increments the number of epochs a validator has been below the LOW threshold but above the.
    VERY LOW threshold
  • removes validators from the active set if they have been below the LOW threshold for more than low_stake_grace_period epochs
  • removes validators from the active set immediately if they are below the VERY LOW threshold
  • activates pending validators if they have sufficient voting power
fun update_validator_positions_and_calculate_total_stake(self: &mut sui_system::validator_set::ValidatorSet, low_stake_grace_period: u64, validator_report_records: &mut sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>, ctx: &mut sui::tx_context::TxContext): u64

Function effectuate_staged_metadata

Effectuate pending next epoch metadata if they are staged.

fun effectuate_staged_metadata(self: &mut sui_system::validator_set::ValidatorSet)

Function derive_reference_gas_price

Called by sui_system to derive reference gas price for the new epoch.
Derive the reference gas price based on the gas price quote submitted by each validator.
The returned gas price should be greater than or equal to 2/3 of the validators submitted gas price, weighted by stake.

public fun derive_reference_gas_price(self: &sui_system::validator_set::ValidatorSet): u64

Function total_stake

public fun total_stake(self: &sui_system::validator_set::ValidatorSet): u64

Function validator_total_stake_amount

public fun validator_total_stake_amount(self: &sui_system::validator_set::ValidatorSet, validator_address: address): u64

Function validator_stake_amount

public fun validator_stake_amount(self: &sui_system::validator_set::ValidatorSet, validator_address: address): u64

Function validator_voting_power

public fun validator_voting_power(self: &sui_system::validator_set::ValidatorSet, validator_address: address): u64

Function validator_staking_pool_id

public fun validator_staking_pool_id(self: &sui_system::validator_set::ValidatorSet, validator_address: address): sui::object::ID

Function staking_pool_mappings

public fun staking_pool_mappings(self: &sui_system::validator_set::ValidatorSet): &sui::table::Table<sui::object::ID, address>

Function validator_address_by_pool_id

public fun validator_address_by_pool_id(self: &mut sui_system::validator_set::ValidatorSet, pool_id: &sui::object::ID): address

Function pool_exchange_rates

public(package) fun pool_exchange_rates(self: &mut sui_system::validator_set::ValidatorSet, pool_id: &sui::object::ID): &sui::table::Table<u64, sui_system::staking_pool::PoolTokenExchangeRate>

Function validator_by_pool_id

public(package) fun validator_by_pool_id(self: &mut sui_system::validator_set::ValidatorSet, pool_id: &sui::object::ID): &sui_system::validator::Validator

Function next_epoch_validator_count

Get the total number of validators in the next epoch.

public(package) fun next_epoch_validator_count(self: &sui_system::validator_set::ValidatorSet): u64

Function is_active_validator_by_sui_address

Returns true iff the address exists in active validators.

public(package) fun is_active_validator_by_sui_address(self: &sui_system::validator_set::ValidatorSet, validator_address: address): bool

Function is_duplicate_with_active_validator

Checks whether new_validator is duplicate with any currently active validators.
It differs from is_active_validator_by_sui_address in that the former checks only the sui address but this function looks at more metadata.

fun is_duplicate_with_active_validator(self: &sui_system::validator_set::ValidatorSet, new_validator: &sui_system::validator::Validator): bool

Function is_duplicate_validator

public(package) fun is_duplicate_validator(validators: &vector<sui_system::validator::Validator>, new_validator: &sui_system::validator::Validator): bool

Function count_duplicates_vec

fun count_duplicates_vec(validators: &vector<sui_system::validator::Validator>, validator: &sui_system::validator::Validator): u64

Function is_duplicate_with_pending_validator

Checks whether new_validator is duplicate with any currently pending validators.

fun is_duplicate_with_pending_validator(self: &sui_system::validator_set::ValidatorSet, new_validator: &sui_system::validator::Validator): bool

Function count_duplicates_tablevec

fun count_duplicates_tablevec(validators: &sui::table_vec::TableVec<sui_system::validator::Validator>, validator: &sui_system::validator::Validator): u64

Function get_candidate_or_active_validator_mut

Get mutable reference to either a candidate or an active validator by address.

fun get_candidate_or_active_validator_mut(self: &mut sui_system::validator_set::ValidatorSet, validator_address: address): &mut sui_system::validator::Validator

Function find_validator

Find validator by validator_address, in validators.
Returns (true, index) if the validator is found, and the index is its index in the list.
If not found, returns (false, 0).

fun find_validator(validators: &vector<sui_system::validator::Validator>, validator_address: address): std::option::Option<u64>

Function find_validator_from_table_vec

Find validator by validator_address, in validators.
Returns (true, index) if the validator is found, and the index is its index in the list.
If not found, returns (false, 0).

fun find_validator_from_table_vec(validators: &sui::table_vec::TableVec<sui_system::validator::Validator>, validator_address: address): std::option::Option<u64>

Function get_validator_indices

Given a vector of validator addresses, return their indices in the validator set.
Aborts if any address isn't in the given validator set.

fun get_validator_indices(validators: &vector<sui_system::validator::Validator>, validator_addresses: &vector<address>): vector<u64>

Function get_validator_mut

public(package) fun get_validator_mut(validators: &mut vector<sui_system::validator::Validator>, validator_address: address): &mut sui_system::validator::Validator

Function get_active_or_pending_or_candidate_validator_mut

Get mutable reference to an active or (if active does not exist) pending or (if pending and active do not exist) or candidate validator by address.
Note: this function should be called carefully, only after verifying the transaction sender has the ability to modify the Validator.

fun get_active_or_pending_or_candidate_validator_mut(self: &mut sui_system::validator_set::ValidatorSet, validator_address: address, include_candidate: bool): &mut sui_system::validator::Validator

Function get_validator_mut_with_verified_cap

public(package) fun get_validator_mut_with_verified_cap(self: &mut sui_system::validator_set::ValidatorSet, verified_cap: &sui_system::validator_cap::ValidatorOperationCap, include_candidate: bool): &mut sui_system::validator::Validator

Function get_validator_mut_with_ctx

public(package) fun get_validator_mut_with_ctx(self: &mut sui_system::validator_set::ValidatorSet, ctx: &sui::tx_context::TxContext): &mut sui_system::validator::Validator

Function get_validator_mut_with_ctx_including_candidates

public(package) fun get_validator_mut_with_ctx_including_candidates(self: &mut sui_system::validator_set::ValidatorSet, ctx: &sui::tx_context::TxContext): &mut sui_system::validator::Validator

Function get_validator_ref

fun get_validator_ref(validators: &vector<sui_system::validator::Validator>, validator_address: address): &sui_system::validator::Validator

Function get_active_or_pending_or_candidate_validator_ref

public(package) fun get_active_or_pending_or_candidate_validator_ref(self: &mut sui_system::validator_set::ValidatorSet, validator_address: address, which_validator: u8): &sui_system::validator::Validator

Function get_active_validator_ref

public fun get_active_validator_ref(self: &sui_system::validator_set::ValidatorSet, addr: address): &sui_system::validator::Validator

Function get_pending_validator_ref

public fun get_pending_validator_ref(self: &sui_system::validator_set::ValidatorSet, addr: address): &sui_system::validator::Validator

Function verify_cap

Verify the capability is valid for a Validator.
If active_validator_only is true, only verify the Cap for an active validator.
Otherwise, verify the Cap for au either active or pending validator.

public(package) fun verify_cap(self: &mut sui_system::validator_set::ValidatorSet, cap: &sui_system::validator_cap::UnverifiedValidatorOperationCap, which_validator: u8): sui_system::validator_cap::ValidatorOperationCap

Function process_pending_removals

Process the pending withdraw requests. For each pending request, the validator is removed from validators and its staking pool is put into the inactive_validators table.

fun process_pending_removals(self: &mut sui_system::validator_set::ValidatorSet, validator_report_records: &mut sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>, ctx: &mut sui::tx_context::TxContext)

Function process_validator_departure

Remove validator from self and return the amount of stake that was removed

fun process_validator_departure(self: &mut sui_system::validator_set::ValidatorSet, validator: sui_system::validator::Validator, validator_report_records: &mut sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>, is_voluntary: bool, ctx: &mut sui::tx_context::TxContext): u64

Function clean_report_records_leaving_validator

fun clean_report_records_leaving_validator(validator_report_records: &mut sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>, leaving_validator_addr: address)

Function sort_removal_list

Sort all the pending removal indexes.

fun sort_removal_list(withdraw_list: &mut vector<u64>)

Function process_pending_stakes_and_withdraws

Process all active validators' pending stake deposits and withdraws.

fun process_pending_stakes_and_withdraws(validators: &mut vector<sui_system::validator::Validator>, ctx: &sui::tx_context::TxContext)

Function calculate_total_stakes

Calculate the total active validator stake.

public(package) fun calculate_total_stakes(validators: &vector<sui_system::validator::Validator>): u64

Function adjust_stake_and_gas_price

Process the pending stake changes for each validator.

fun adjust_stake_and_gas_price(validators: &mut vector<sui_system::validator::Validator>)

Function compute_reward_adjustments

Compute both the individual reward adjustments and total reward adjustment for staking rewards as well as storage fund rewards.

fun compute_reward_adjustments(slashed_validator_indices: vector<u64>, reward_slashing_rate: u64, unadjusted_staking_reward_amounts: &vector<u64>, unadjusted_storage_fund_reward_amounts: &vector<u64>): (u64, sui::vec_map::VecMap<u64, u64>, u64, sui::vec_map::VecMap<u64, u64>)

Function compute_slashed_validators

Process the validator report records of the epoch and return the addresses of the non-performant validators according to the input threshold.

fun compute_slashed_validators(self: &sui_system::validator_set::ValidatorSet, validator_report_records: sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>): vector<address>

Function compute_unadjusted_reward_distribution

Given the current list of active validators, the total stake and total reward, calculate the amount of reward each validator should get, without taking into account the tallying rule results.
Returns the unadjusted amounts of staking reward and storage fund reward for each validator.

fun compute_unadjusted_reward_distribution(validators: &vector<sui_system::validator::Validator>, total_voting_power: u64, total_staking_reward: u64, total_storage_fund_reward: u64): (vector<u64>, vector<u64>)

Function compute_adjusted_reward_distribution

Use the reward adjustment info to compute the adjusted rewards each validator should get.
Returns the staking rewards each validator gets and the storage fund rewards each validator gets.
The staking rewards are shared with the stakers while the storage fund ones are not.

fun compute_adjusted_reward_distribution(validators: &vector<sui_system::validator::Validator>, total_voting_power: u64, total_slashed_validator_voting_power: u64, unadjusted_staking_reward_amounts: vector<u64>, unadjusted_storage_fund_reward_amounts: vector<u64>, total_staking_reward_adjustment: u64, individual_staking_reward_adjustments: sui::vec_map::VecMap<u64, u64>, total_storage_fund_reward_adjustment: u64, individual_storage_fund_reward_adjustments: sui::vec_map::VecMap<u64, u64>): (vector<u64>, vector<u64>)

Function distribute_reward

fun distribute_reward(validators: &mut vector<sui_system::validator::Validator>, adjusted_staking_reward_amounts: &vector<u64>, adjusted_storage_fund_reward_amounts: &vector<u64>, staking_rewards: &mut sui::balance::Balance<sui::sui::SUI>, storage_fund_reward: &mut sui::balance::Balance<sui::sui::SUI>, ctx: &mut sui::tx_context::TxContext)

Function emit_validator_epoch_events

Emit events containing information of each validator for the epoch, including stakes, rewards, performance, etc.

fun emit_validator_epoch_events(new_epoch: u64, vs: &vector<sui_system::validator::Validator>, pool_staking_reward_amounts: &vector<u64>, storage_fund_staking_reward_amounts: &vector<u64>, report_records: &sui::vec_map::VecMap<address, sui::vec_set::VecSet<address>>, slashed_validators: &vector<address>)

Function sum_voting_power_by_addresses

Sum up the total stake of a given list of validator addresses.

public fun sum_voting_power_by_addresses(vs: &vector<sui_system::validator::Validator>, addresses: &vector<address>): u64

Function active_validators

Return the active validators in self

public fun active_validators(self: &sui_system::validator_set::ValidatorSet): &vector<sui_system::validator::Validator>

Function is_validator_candidate

Returns true if the addr is a validator candidate.

public fun is_validator_candidate(self: &sui_system::validator_set::ValidatorSet, addr: address): bool

Function is_active_validator

Returns true if addr is an active validator

public(package) fun is_active_validator(self: &sui_system::validator_set::ValidatorSet, addr: address): bool

Function is_inactive_validator

Returns true if the staking pool identified by staking_pool_id is of an inactive validator.

public fun is_inactive_validator(self: &sui_system::validator_set::ValidatorSet, staking_pool_id: sui::object::ID): bool

Function is_at_risk_validator

Return true if addr is currently an at-risk validator below the minimum stake for removal

public(package) fun is_at_risk_validator(self: &sui_system::validator_set::ValidatorSet, addr: address): bool

Function active_validator_addresses

public(package) fun active_validator_addresses(self: &sui_system::validator_set::ValidatorSet): vector<address>

Macro function mul_div

macro fun mul_div($a: u64, $b: u64, $c: u64): u64