Module sui_system::validator
- Struct ValidatorMetadata
- Struct Validator
- Struct StakingRequestEvent
- Struct UnstakingRequestEvent
- Struct ConvertingToFungibleStakedSuiEvent
- Struct RedeemingFungibleStakedSuiEvent
- Constants
- Function new_metadata
- Function new
- Function deactivate
- Function activate
- Function adjust_stake_and_gas_price
- Function request_add_stake
- Function convert_to_fungible_staked_sui
- Function redeem_fungible_staked_sui
- Function request_add_stake_at_genesis
- Function request_withdraw_stake
- Function request_set_gas_price
- Function set_candidate_gas_price
- Function request_set_commission_rate
- Function set_candidate_commission_rate
- Function deposit_stake_rewards
- Function process_pending_stakes_and_withdraws
- Function is_preactive
- Function metadata
- Function sui_address
- Function name
- Function description
- Function image_url
- Function project_url
- Function network_address
- Function p2p_address
- Function primary_address
- Function worker_address
- Function protocol_pubkey_bytes
- Function proof_of_possession
- Function network_pubkey_bytes
- Function worker_pubkey_bytes
- Function next_epoch_network_address
- Function next_epoch_p2p_address
- Function next_epoch_primary_address
- Function next_epoch_worker_address
- Function next_epoch_protocol_pubkey_bytes
- Function next_epoch_proof_of_possession
- Function next_epoch_network_pubkey_bytes
- Function next_epoch_worker_pubkey_bytes
- Function operation_cap_id
- Function next_epoch_gas_price
- Function total_stake_amount
- Function stake_amount
- Function total_stake
- Function voting_power
- Function set_voting_power
- Function pending_stake_amount
- Function pending_stake_withdraw_amount
- Function gas_price
- Function commission_rate
- Function pool_token_exchange_rate_at_epoch
- Function staking_pool_id
- Function is_duplicate
- Macro function both_some_and_equal
- Function new_unverified_validator_operation_cap_and_transfer
- Function update_name
- Function update_description
- Function update_image_url
- Function update_project_url
- Function update_next_epoch_network_address
- Function update_candidate_network_address
- Function update_next_epoch_p2p_address
- Function update_candidate_p2p_address
- Function update_next_epoch_primary_address
- Function update_candidate_primary_address
- Function update_next_epoch_worker_address
- Function update_candidate_worker_address
- Function update_next_epoch_protocol_pubkey
- Function update_candidate_protocol_pubkey
- Function update_next_epoch_network_pubkey
- Function update_candidate_network_pubkey
- Function update_next_epoch_worker_pubkey
- Function update_candidate_worker_pubkey
- Function effectuate_staged_metadata
- Macro function do_extract
- Function validate_metadata
- Function validate_metadata_bcs
- Function get_staking_pool_ref
- Function new_from_metadata
use std::address;
use std::ascii;
use std::bcs;
use std::option;
use std::string;
use std::type_name;
use std::u64;
use std::vector;
use sui::accumulator;
use sui::address;
use sui::bag;
use sui::balance;
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::hex;
use sui::object;
use sui::party;
use sui::sui;
use sui::table;
use sui::transfer;
use sui::tx_context;
use sui::types;
use sui::url;
use sui::vec_map;
use sui::vec_set;
use sui_system::staking_pool;
use sui_system::validator_cap;
Struct ValidatorMetadata
public struct ValidatorMetadata has store
Fields
- 
sui_address: address
- The Sui Address of the validator. This is the sender that created the Validator object, and also the address to send validator/coins to during withdraws.
- 
protocol_pubkey_bytes: vector<u8>
- The public key bytes corresponding to the private key that the validator holds to sign transactions. For now, this is the same as AuthorityName.
- 
network_pubkey_bytes: vector<u8>
- The public key bytes corresponding to the private key that the validator uses to establish TLS connections
- 
worker_pubkey_bytes: vector<u8>
- The public key bytes correstponding to the Narwhal Worker
- 
proof_of_possession: vector<u8>
- This is a proof that the validator has ownership of the private key
- 
name: std::string::String
- A unique human-readable name of this validator.
- 
description: std::string::String
- 
image_url: sui::url::Url
- 
project_url: sui::url::Url
- 
net_address: std::string::String
- The network address of the validator (could also contain extra info such as port, DNS and etc.).
- 
p2p_address: std::string::String
- The address of the validator used for p2p activities such as state sync (could also contain extra info such as port, DNS and etc.).
- 
primary_address: std::string::String
- The address of the narwhal primary
- 
worker_address: std::string::String
- The address of the narwhal worker
- 
next_epoch_protocol_pubkey_bytes: std::option::Option<vector<u8>>
- "next_epoch" metadata only takes effects in the next epoch. If none, current value will stay unchanged.
- 
next_epoch_proof_of_possession: std::option::Option<vector<u8>>
- 
next_epoch_network_pubkey_bytes: std::option::Option<vector<u8>>
- 
next_epoch_worker_pubkey_bytes: std::option::Option<vector<u8>>
- 
next_epoch_net_address: std::option::Option<std::string::String>
- 
next_epoch_p2p_address: std::option::Option<std::string::String>
- 
next_epoch_primary_address: std::option::Option<std::string::String>
- 
next_epoch_worker_address: std::option::Option<std::string::String>
- 
extra_fields: sui::bag::Bag
- Any extra fields that's not defined statically.
Struct Validator
public struct Validator has store
Fields
- 
metadata: sui_system::validator::ValidatorMetadata
- Summary of the validator.
- 
voting_power: u64
- The voting power of this validator, which might be different from its stake amount.
- 
operation_cap_id: sui::object::ID
- 
 The ID of this validator's current valid UnverifiedValidatorOperationCap
- 
gas_price: u64
- Gas price quote, updated only at end of epoch.
- 
staking_pool: sui_system::staking_pool::StakingPool
- Staking pool for this validator.
- 
commission_rate: u64
- Commission rate of the validator, in basis point.
- 
next_epoch_stake: u64
- Total amount of stake that would be active in the next epoch.
- 
next_epoch_gas_price: u64
- This validator's gas price quote for the next epoch.
- 
next_epoch_commission_rate: u64
- The commission rate of the validator starting the next epoch, in basis point.
- 
extra_fields: sui::bag::Bag
- Any extra fields that's not defined statically.
Struct StakingRequestEvent
Event emitted when a new stake request is received.
public struct StakingRequestEvent has copy, drop
Fields
- 
pool_id: sui::object::ID
- 
validator_address: address
- 
staker_address: address
- 
epoch: u64
- 
amount: u64
Struct UnstakingRequestEvent
Event emitted when a new unstake request is received.
public struct UnstakingRequestEvent has copy, drop
Fields
- 
pool_id: sui::object::ID
- 
validator_address: address
- 
staker_address: address
- 
stake_activation_epoch: u64
- 
unstaking_epoch: u64
- 
principal_amount: u64
- 
reward_amount: u64
Struct ConvertingToFungibleStakedSuiEvent
Event emitted when a staked SUI is converted to a fungible staked SUI.
public struct ConvertingToFungibleStakedSuiEvent has copy, drop
Fields
- 
pool_id: sui::object::ID
- 
stake_activation_epoch: u64
- 
staked_sui_principal_amount: u64
- 
fungible_staked_sui_amount: u64
Struct RedeemingFungibleStakedSuiEvent
Event emitted when a fungible staked SUI is redeemed.
public struct RedeemingFungibleStakedSuiEvent has copy, drop
Fields
- 
pool_id: sui::object::ID
- 
fungible_staked_sui_amount: u64
- 
sui_amount: u64
Constants
Invalid proof_of_possession field in ValidatorMetadata
const EInvalidProofOfPossession: u64 = 0;
Invalid pubkey_bytes field in ValidatorMetadata
const EMetadataInvalidPubkey: u64 = 1;
Invalid network_pubkey_bytes field in ValidatorMetadata
const EMetadataInvalidNetPubkey: u64 = 2;
Invalid worker_pubkey_bytes field in ValidatorMetadata
const EMetadataInvalidWorkerPubkey: u64 = 3;
Invalid net_address field in ValidatorMetadata
const EMetadataInvalidNetAddr: u64 = 4;
Invalid p2p_address field in ValidatorMetadata
const EMetadataInvalidP2pAddr: u64 = 5;
Invalid primary_address field in ValidatorMetadata
const EMetadataInvalidPrimaryAddr: u64 = 6;
Invalid worker_address field in ValidatorMetadata
const EMetadataInvalidWorkerAddr: u64 = 7;
Commission rate set by the validator is higher than the threshold
const ECommissionRateTooHigh: u64 = 8;
Validator Metadata is too long
const EValidatorMetadataExceedingLengthLimit: u64 = 9;
Intended validator is not a candidate one.
const ENotValidatorCandidate: u64 = 10;
Stake amount is invalid or wrong.
const EInvalidStakeAmount: u64 = 11;
Function called during non-genesis times.
const ECalledDuringNonGenesis: u64 = 12;
New Capability is not created by the validator itself
const ENewCapNotCreatedByValidatorItself: u64 = 100;
Capability code is not valid
const EInvalidCap: u64 = 101;
Validator trying to set gas price higher than threshold.
const EGasPriceHigherThanThreshold: u64 = 102;
const MAX_COMMISSION_RATE: u64 = 2000;
const MAX_VALIDATOR_METADATA_LENGTH: u64 = 256;
Max gas price a validator can set is 100K MIST.
const MAX_VALIDATOR_GAS_PRICE: u64 = 100000;
Function new_metadata
public(package) fun new_metadata(sui_address: address, protocol_pubkey_bytes: vector<u8>, network_pubkey_bytes: vector<u8>, worker_pubkey_bytes: vector<u8>, proof_of_possession: vector<u8>, name: std::string::String, description: std::string::String, image_url: sui::url::Url, project_url: sui::url::Url, net_address: std::string::String, p2p_address: std::string::String, primary_address: std::string::String, worker_address: std::string::String, extra_fields: sui::bag::Bag): sui_system::validator::ValidatorMetadata
Implementation
public(package) fun new_metadata(
    sui_address: address,
    protocol_pubkey_bytes: vector<u8>,
    network_pubkey_bytes: vector<u8>,
    worker_pubkey_bytes: vector<u8>,
    proof_of_possession: vector<u8>,
    name: String,
    description: String,
    image_url: Url,
    project_url: Url,
    net_address: String,
    p2p_address: String,
    primary_address: String,
    worker_address: String,
    extra_fields: Bag,
): ValidatorMetadata {
    ValidatorMetadata {
        sui_address,
        protocol_pubkey_bytes,
        network_pubkey_bytes,
        worker_pubkey_bytes,
        proof_of_possession,
        name,
        description,
        image_url,
        project_url,
        net_address,
        p2p_address,
        primary_address,
        worker_address,
        next_epoch_protocol_pubkey_bytes: option::none(),
        next_epoch_network_pubkey_bytes: option::none(),
        next_epoch_worker_pubkey_bytes: option::none(),
        next_epoch_proof_of_possession: option::none(),
        next_epoch_net_address: option::none(),
        next_epoch_p2p_address: option::none(),
        next_epoch_primary_address: option::none(),
        next_epoch_worker_address: option::none(),
        extra_fields,
    }
}
Function new
public(package) fun new(sui_address: address, protocol_pubkey_bytes: vector<u8>, network_pubkey_bytes: vector<u8>, worker_pubkey_bytes: vector<u8>, proof_of_possession: vector<u8>, name: vector<u8>, description: vector<u8>, image_url: vector<u8>, project_url: vector<u8>, net_address: vector<u8>, p2p_address: vector<u8>, primary_address: vector<u8>, worker_address: vector<u8>, gas_price: u64, commission_rate: u64, ctx: &mut sui::tx_context::TxContext): sui_system::validator::Validator
Implementation
public(package) fun new(
    sui_address: address,
    protocol_pubkey_bytes: vector<u8>,
    network_pubkey_bytes: vector<u8>,
    worker_pubkey_bytes: vector<u8>,
    proof_of_possession: vector<u8>,
    name: vector<u8>,
    description: vector<u8>,
    image_url: vector<u8>,
    project_url: vector<u8>,
    net_address: vector<u8>,
    p2p_address: vector<u8>,
    primary_address: vector<u8>,
    worker_address: vector<u8>,
    gas_price: u64,
    commission_rate: u64,
    ctx: &mut TxContext,
): Validator {
    assert!(
        net_address.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && p2p_address.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && primary_address.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && worker_address.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && name.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && description.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && image_url.length() <= MAX_VALIDATOR_METADATA_LENGTH
            && project_url.length() <= MAX_VALIDATOR_METADATA_LENGTH,
        EValidatorMetadataExceedingLengthLimit,
    );
    assert!(commission_rate <= MAX_COMMISSION_RATE, ECommissionRateTooHigh);
    assert!(gas_price < MAX_VALIDATOR_GAS_PRICE, EGasPriceHigherThanThreshold);
    let metadata = new_metadata(
        sui_address,
        protocol_pubkey_bytes,
        network_pubkey_bytes,
        worker_pubkey_bytes,
        proof_of_possession,
        name.to_ascii_string().to_string(),
        description.to_ascii_string().to_string(),
        url::new_unsafe_from_bytes(image_url),
        url::new_unsafe_from_bytes(project_url),
        net_address.to_ascii_string().to_string(),
        p2p_address.to_ascii_string().to_string(),
        primary_address.to_ascii_string().to_string(),
        worker_address.to_ascii_string().to_string(),
        bag::new(ctx),
    );
    // Checks that the keys & addresses & PoP are valid.
    metadata.validate();
    metadata.new_from_metadata(gas_price, commission_rate, ctx)
}
Function deactivate
Mark Validator's StakingPool as inactive by setting the deactivation_epoch.
public(package) fun deactivate(self: &mut sui_system::validator::Validator, deactivation_epoch: u64)
Implementation
public(package) fun deactivate(self: &mut Validator, deactivation_epoch: u64) {
    self.staking_pool.deactivate_staking_pool(deactivation_epoch)
}
Function activate
Activate Validator's StakingPool by setting the activation_epoch.
public(package) fun activate(self: &mut sui_system::validator::Validator, activation_epoch: u64)
Implementation
public(package) fun activate(self: &mut Validator, activation_epoch: u64) {
    self.staking_pool.activate_staking_pool(activation_epoch);
}
Function adjust_stake_and_gas_price
Process pending stake and pending withdraws, and update the gas price.
public(package) fun adjust_stake_and_gas_price(self: &mut sui_system::validator::Validator)
Implementation
public(package) fun adjust_stake_and_gas_price(self: &mut Validator) {
    self.gas_price = self.next_epoch_gas_price;
    self.commission_rate = self.next_epoch_commission_rate;
}
Function request_add_stake
Request to add stake to the validator's staking pool, processed at the end of the epoch.
public(package) fun request_add_stake(self: &mut sui_system::validator::Validator, stake: sui::balance::Balance<sui::sui::SUI>, staker_address: address, ctx: &mut sui::tx_context::TxContext): sui_system::staking_pool::StakedSui
Implementation
public(package) fun request_add_stake(
    self: &mut Validator,
    stake: Balance<SUI>,
    staker_address: address,
    ctx: &mut TxContext,
): StakedSui {
    let stake_amount = stake.value();
    assert!(stake_amount > 0, EInvalidStakeAmount);
    let stake_epoch = ctx.epoch() + 1;
    let staked_sui = self.staking_pool.request_add_stake(stake, stake_epoch, ctx);
    // Process stake right away if staking pool is preactive.
    if (self.staking_pool.is_preactive()) {
        self.staking_pool.process_pending_stake();
    };
    self.next_epoch_stake = self.next_epoch_stake + stake_amount;
    event::emit(StakingRequestEvent {
        pool_id: self.staking_pool_id(),
        validator_address: self.metadata.sui_address,
        staker_address,
        epoch: ctx.epoch(),
        amount: stake_amount,
    });
    staked_sui
}
Function convert_to_fungible_staked_sui
public(package) fun convert_to_fungible_staked_sui(self: &mut sui_system::validator::Validator, staked_sui: sui_system::staking_pool::StakedSui, ctx: &mut sui::tx_context::TxContext): sui_system::staking_pool::FungibleStakedSui
Implementation
public(package) fun convert_to_fungible_staked_sui(
    self: &mut Validator,
    staked_sui: StakedSui,
    ctx: &mut TxContext,
): FungibleStakedSui {
    let stake_activation_epoch = staked_sui.activation_epoch();
    let staked_sui_principal_amount = staked_sui.amount();
    let fungible_staked_sui = self.staking_pool.convert_to_fungible_staked_sui(staked_sui, ctx);
    event::emit(ConvertingToFungibleStakedSuiEvent {
        pool_id: self.staking_pool_id(),
        stake_activation_epoch,
        staked_sui_principal_amount,
        fungible_staked_sui_amount: fungible_staked_sui.value(),
    });
    fungible_staked_sui
}
Function redeem_fungible_staked_sui
public(package) fun redeem_fungible_staked_sui(self: &mut sui_system::validator::Validator, fungible_staked_sui: sui_system::staking_pool::FungibleStakedSui, ctx: &sui::tx_context::TxContext): sui::balance::Balance<sui::sui::SUI>
Implementation
public(package) fun redeem_fungible_staked_sui(
    self: &mut Validator,
    fungible_staked_sui: FungibleStakedSui,
    ctx: &TxContext,
): Balance<SUI> {
    let fungible_staked_sui_amount = fungible_staked_sui.value();
    let sui = self.staking_pool.redeem_fungible_staked_sui(fungible_staked_sui, ctx);
    self.next_epoch_stake = self.next_epoch_stake - sui.value();
    event::emit(RedeemingFungibleStakedSuiEvent {
        pool_id: self.staking_pool_id(),
        fungible_staked_sui_amount,
        sui_amount: sui.value(),
    });
    sui
}