Module 0x3::validator
- Struct
ValidatorMetadata
- Struct
Validator
- Struct
StakingRequestEvent
- Struct
UnstakingRequestEvent
- Constants
- Function
new_metadata
- Function
new
- Function
deactivate
- Function
activate
- Function
adjust_stake_and_gas_price
- Function
request_add_stake
- 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
- Function
is_equal_some_and_value
- Function
is_equal_some
- 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
- Function
validate_metadata
- Function
validate_metadata_bcs
- Function
get_staking_pool_ref
- Function
new_from_metadata
use 0x1::ascii;
use 0x1::bcs;
use 0x1::option;
use 0x1::string;
use 0x2::bag;
use 0x2::balance;
use 0x2::event;
use 0x2::object;
use 0x2::sui;
use 0x2::transfer;
use 0x2::tx_context;
use 0x2::url;
use 0x3::staking_pool;
use 0x3::validator_cap;
Struct ValidatorMetadata
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: string::String
- A unique human-readable name of this validator.
- description: string::String
- image_url: url::Url
- project_url: url::Url
- net_address: string::String
- The network address of the validator (could also contain extra info such as port, DNS and etc.).
- p2p_address: 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: string::String
- The address of the narwhal primary
- worker_address: string::String
- The address of the narwhal worker
- next_epoch_protocol_pubkey_bytes: 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: option::Option<vector<u8>>
- next_epoch_network_pubkey_bytes: option::Option<vector<u8>>
- next_epoch_worker_pubkey_bytes: option::Option<vector<u8>>
- next_epoch_net_address: option::Option<string::String>
- next_epoch_p2p_address: option::Option<string::String>
- next_epoch_primary_address: option::Option<string::String>
- next_epoch_worker_address: option::Option<string::String>
- extra_fields: bag::Bag
- Any extra fields that's not defined statically.
Struct Validator
struct Validator has store
Fields
- metadata: 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: 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: 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: bag::Bag
- Any extra fields that's not defined statically.
Struct StakingRequestEvent
Event emitted when a new stake request is received.
struct StakingRequestEvent has copy, drop
Fields
- pool_id: object::ID
- validator_address: address
- staker_address: address
- epoch: u64
- amount: u64
Struct UnstakingRequestEvent
Event emitted when a new unstake request is received.
struct UnstakingRequestEvent has copy, drop
Fields
- pool_id: object::ID
- validator_address: address
- staker_address: address
- stake_activation_epoch: u64
- unstaking_epoch: u64
- principal_amount: u64
- reward_amount: u64
Constants
Function called during non-genesis times.
const ECalledDuringNonGenesis: u64 = 12;
Commission rate set by the validator is higher than the threshold
const ECommissionRateTooHigh: u64 = 8;
Validator trying to set gas price higher than threshold.
const EGasPriceHigherThanThreshold: u64 = 102;
Capability code is not valid
const EInvalidCap: u64 = 101;
Invalid proof_of_possession field in ValidatorMetadata
const EInvalidProofOfPossession: u64 = 0;
Stake amount is invalid or wrong.
const EInvalidStakeAmount: u64 = 11;
Invalid net_address field in ValidatorMetadata
const EMetadataInvalidNetAddr: u64 = 4;
Invalid network_pubkey_bytes field in ValidatorMetadata
const EMetadataInvalidNetPubkey: u64 = 2;
Invalid p2p_address field in ValidatorMetadata
const EMetadataInvalidP2pAddr: u64 = 5;
Invalid primary_address field in ValidatorMetadata
const EMetadataInvalidPrimaryAddr: u64 = 6;
Invalid pubkey_bytes field in ValidatorMetadata
const EMetadataInvalidPubkey: u64 = 1;
Invalidworker_address field in ValidatorMetadata
const EMetadataInvalidWorkerAddr: u64 = 7;
Invalid worker_pubkey_bytes field in ValidatorMetadata
const EMetadataInvalidWorkerPubkey: u64 = 3;
New Capability is not created by the validator itself
const ENewCapNotCreatedByValidatorItself: u64 = 100;
Intended validator is not a candidate one.
const ENotValidatorCandidate: u64 = 10;
Validator Metadata is too long
const EValidatorMetadataExceedingLengthLimit: u64 = 9;
const MAX_COMMISSION_RATE: u64 = 2000;
Max gas price a validator can set is 100K MIST.
const MAX_VALIDATOR_GAS_PRICE: u64 = 100000;
const MAX_VALIDATOR_METADATA_LENGTH: u64 = 256;
Function new_metadata
public(friend) 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::String, description: string::String, image_url: url::Url, project_url: url::Url, net_address: string::String, p2p_address: string::String, primary_address: string::String, worker_address: string::String, extra_fields: bag::Bag): 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 {
let metadata = 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,
};
metadata
}
Function new
public(friend) 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 tx_context::TxContext): 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.
validate_metadata(&metadata);
new_from_metadata(
metadata,
gas_price,
commission_rate,
ctx
)
}
Function deactivate
Deactivate this validator's staking pool
public(friend) fun deactivate(self: &mut 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
public(friend) fun activate(self: &mut 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(friend) fun adjust_stake_and_gas_price(self: &mut 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(friend) fun request_add_stake(self: &mut validator::Validator, stake: balance::Balance<sui::SUI>, staker_address: address, ctx: &mut tx_context::TxContext): 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: staking_pool_id(self),
validator_address: self.metadata.sui_address,
staker_address,
epoch: ctx.epoch(),
amount: stake_amount,
}
);
staked_sui
}
Function request_add_stake_at_genesis
Request to add stake to the validator's staking pool at genesis
public(friend) fun request_add_stake_at_genesis(self: &mut validator::Validator, stake: balance::Balance<sui::SUI>, staker_address: address, ctx: &mut tx_context::TxContext)
Implementation
public(package) fun request_add_stake_at_genesis(
self: &mut Validator,
stake: Balance<SUI>,
staker_address: address,
ctx: &mut TxContext,
) {
assert!(ctx.epoch() == 0, ECalledDuringNonGenesis);
let stake_amount = stake.value();
assert!(stake_amount > 0, EInvalidStakeAmount);
let staked_sui = self.staking_pool.request_add_stake(
stake,
0, // epoch 0 -- genesis
ctx
);
transfer::public_transfer(staked_sui, staker_address);
// Process stake right away
self.staking_pool.process_pending_stake();
self.next_epoch_stake = self.next_epoch_stake + stake_amount;
}
Function request_withdraw_stake
Request to withdraw stake from the validator's staking pool, processed at the end of the epoch.
public(friend) fun request_withdraw_stake(self: &mut validator::Validator, staked_sui: staking_pool::StakedSui, ctx: &tx_context::TxContext): balance::Balance<sui::SUI>
Implementation
public(package) fun request_withdraw_stake(
self: &mut Validator,
staked_sui: StakedSui,
ctx: &TxContext,
) : Balance<SUI> {
let principal_amount = staked_sui.staked_sui_amount();
let stake_activation_epoch = staked_sui.stake_activation_epoch();
let withdrawn_stake = self.staking_pool.request_withdraw_stake(staked_sui, ctx);
let withdraw_amount = withdrawn_stake.value();
let reward_amount = withdraw_amount - principal_amount;
self.next_epoch_stake = self.next_epoch_stake - withdraw_amount;
event::emit(
UnstakingRequestEvent {
pool_id: staking_pool_id(self),
validator_address: self.metadata.sui_address,
staker_address: ctx.sender(),
stake_activation_epoch,
unstaking_epoch: ctx.epoch(),
principal_amount,
reward_amount,
}
);
withdrawn_stake
}
Function request_set_gas_price
Request to set new gas price for the next epoch. Need to present a ValidatorOperationCap.
public(friend) fun request_set_gas_price(self: &mut validator::Validator, verified_cap: validator_cap::ValidatorOperationCap, new_price: u64)
Implementation
public(package) fun request_set_gas_price(
self: &mut Validator,
verified_cap: ValidatorOperationCap,
new_price: u64,
) {
assert!(new_price < MAX_VALIDATOR_GAS_PRICE, EGasPriceHigherThanThreshold);
let validator_address = *verified_cap.verified_operation_cap_address();
assert!(validator_address == self.metadata.sui_address, EInvalidCap);
self.next_epoch_gas_price = new_price;
}
Function set_candidate_gas_price
Set new gas price for the candidate validator.
public(friend) fun set_candidate_gas_price(self: &mut validator::Validator, verified_cap: validator_cap::ValidatorOperationCap, new_price: u64)
Implementation
public(package) fun set_candidate_gas_price(
self: &mut Validator,
verified_cap: ValidatorOperationCap,
new_price: u64
) {
assert!(is_preactive(self), ENotValidatorCandidate);
assert!(new_price < MAX_VALIDATOR_GAS_PRICE, EGasPriceHigherThanThreshold);
let validator_address = *verified_cap.verified_operation_cap_address();
assert!(validator_address == self.metadata.sui_address, EInvalidCap);
self.next_epoch_gas_price = new_price;
self.gas_price = new_price;
}
Function request_set_commission_rate
Request to set new commission rate for the next epoch.
public(friend) fun request_set_commission_rate(self: &mut validator::Validator, new_commission_rate: u64)
Implementation
public(package) fun request_set_commission_rate(self: &mut Validator, new_commission_rate: u64) {
assert!(new_commission_rate <= MAX_COMMISSION_RATE, ECommissionRateTooHigh);
self.next_epoch_commission_rate = new_commission_rate;
}
Function set_candidate_commission_rate
Set new commission rate for the candidate validator.
public(friend) fun set_candidate_commission_rate(self: &mut validator::Validator, new_commission_rate: u64)
Implementation
public(package) fun set_candidate_commission_rate(self: &mut Validator, new_commission_rate: u64) {
assert!(is_preactive(self), ENotValidatorCandidate);
assert!(new_commission_rate <= MAX_COMMISSION_RATE, ECommissionRateTooHigh);
self.commission_rate = new_commission_rate;
}
Function deposit_stake_rewards
Deposit stakes rewards into the validator's staking pool, called at the end of the epoch.
public(friend) fun deposit_stake_rewards(self: &mut validator::Validator, reward: balance::Balance<sui::SUI>)
Implementation
public(package) fun deposit_stake_rewards(self: &mut Validator, reward: Balance<SUI>) {
self.next_epoch_stake = self.next_epoch_stake + reward.value();
self.staking_pool.deposit_rewards(reward);
}
Function process_pending_stakes_and_withdraws
Process pending stakes and withdraws, called at the end of the epoch.
public(friend) fun process_pending_stakes_and_withdraws(self: &mut validator::Validator, ctx: &tx_context::TxContext)
Implementation
public(package) fun process_pending_stakes_and_withdraws(self: &mut Validator, ctx: &TxContext) {
self.staking_pool.process_pending_stakes_and_withdraws(ctx);
assert!(stake_amount(self) == self.next_epoch_stake, EInvalidStakeAmount);
}
Function is_preactive
Returns true if the validator is preactive.
public fun is_preactive(self: &validator::Validator): bool
Implementation
public fun is_preactive(self: &Validator): bool {
self.staking_pool.is_preactive()
}
Function metadata
public fun metadata(self: &validator::Validator): &validator::ValidatorMetadata
Implementation
public fun metadata(self: &Validator): &ValidatorMetadata {
&self.metadata
}
Function sui_address
public fun sui_address(self: &validator::Validator): address
Implementation
public fun sui_address(self: &Validator): address {
self.metadata.sui_address
}
Function name
public fun name(self: &validator::Validator): &string::String
Function description
public fun description(self: &validator::Validator): &string::String
Implementation
public fun description(self: &Validator): &String {
&self.metadata.description
}