Module 0x3::genesis
- Struct
GenesisValidatorMetadata
- Struct
GenesisChainParameters
- Struct
TokenDistributionSchedule
- Struct
TokenAllocation
- Constants
- Function
create
- Function
allocate_tokens
- Function
activate_validators
use 0x1::option;
use 0x1::string;
use 0x1::vector;
use 0x2::balance;
use 0x2::coin;
use 0x2::iota;
use 0x2::object;
use 0x2::system_admin_cap;
use 0x2::tx_context;
use 0x3::iota_system;
use 0x3::iota_system_state_inner;
use 0x3::timelocked_staking;
use 0x3::validator;
use 0x3::validator_set;
Struct GenesisValidatorMetadata
struct GenesisValidatorMetadata has copy, drop
Fields
name: vector<u8>
description: vector<u8>
image_url: vector<u8>
project_url: vector<u8>
iota_address: address
gas_price: u64
commission_rate: u64
authority_public_key: vector<u8>
proof_of_possession: vector<u8>
network_public_key: vector<u8>
protocol_public_key: vector<u8>
network_address: vector<u8>
p2p_address: vector<u8>
primary_address: vector<u8>
Struct GenesisChainParameters
struct GenesisChainParameters has copy, drop
Fields
Struct TokenDistributionSchedule
structTokenDistributionSchedule
Fields
pre_minted_supply: u64
allocations: vector<genesis::TokenAllocation>
Struct TokenAllocation
structTokenAllocation
Fields
recipient_address: address
amount_nanos: u64
staked_with_validator: option::Option<address>
Indicates if this allocation should be staked at genesis and with which validator
staked_with_timelock_expiration: option::Option<u64>
Indicates if this allocation should be staked with timelock at genesis and contains its timelock_expiration
Constants
The create
function was called at a non-genesis epoch.
const ENotCalledAtGenesis: u64 = 0;
The create
function was called with duplicate validators.
const EDuplicateValidator: u64 = 1;
The create
function was called with wrong pre-minted supply.
const EWrongPreMintedSupply: u64 = 2;
Function create
This function will be explicitly called once at genesis. It will create a singleton IotaSystemState object, which contains all the information we need in the system.
fun create(iota_system_state_id: object::UID, iota_treasury_cap: iota::IotaTreasuryCap, genesis_chain_parameters: genesis::GenesisChainParameters, genesis_validators: vector<genesis::GenesisValidatorMetadata>, token_distribution_schedule: genesis::TokenDistributionSchedule, timelock_genesis_label: option::Option<string::String>, iota_system_admin_cap: system_admin_cap::IotaSystemAdminCap, ctx: &mut tx_context::TxContext)
Implementation
fun create(
iota_system_state_id: UID,
mut iota_treasury_cap: IotaTreasuryCap,
genesis_chain_parameters: GenesisChainParameters,
genesis_validators: vector<GenesisValidatorMetadata>,
token_distribution_schedule: TokenDistributionSchedule,
timelock_genesis_label: Option<String>,
iota_system_admin_cap: IotaSystemAdminCap,
ctx: &mut TxContext,
) {
// Ensure this is only called at genesis
assert!(ctx.epoch() == 0, ENotCalledAtGenesis);
let TokenDistributionSchedule {
pre_minted_supply,
allocations,
} = token_distribution_schedule;
assert!(iota_treasury_cap.total_supply() == pre_minted_supply, EWrongPreMintedSupply);
let storage_fund = balance::zero();
// Create all the ValidatorV1
structs
let mut validators = vector[];
let count = genesis_validators.length();
let mut i = 0;
while (i < count) {
let GenesisValidatorMetadata {
name,
description,
image_url,
project_url,
iota_address,
gas_price,
commission_rate,
authority_public_key,
proof_of_possession,
network_public_key,
protocol_public_key,
network_address,
p2p_address,
primary_address,
} = genesis_validators[i];
let validator = validator::new(
iota_address,
authority_public_key,
network_public_key,
protocol_public_key,
proof_of_possession,
name,
description,
image_url,
project_url,
network_address,
p2p_address,
primary_address,
gas_price,
commission_rate,
ctx
);
// Ensure that each validator is unique
assert!(
!validator_set::is_duplicate_validator(&validators, &validator),
EDuplicateValidator,
);
validators.push_back(validator);
i = i + 1;
};
// Allocate tokens and staking operations
allocate_tokens(
&mut iota_treasury_cap,
allocations,
&mut validators,
timelock_genesis_label,
ctx
);
// Activate all validators
activate_validators(&mut validators);
let system_parameters = iota_system_state_inner::create_system_parameters(
genesis_chain_parameters.epoch_duration_ms,
// ValidatorV1 committee parameters
genesis_chain_parameters.max_validator_count,
genesis_chain_parameters.min_validator_joining_stake,
genesis_chain_parameters.validator_low_stake_threshold,
genesis_chain_parameters.validator_very_low_stake_threshold,
genesis_chain_parameters.validator_low_stake_grace_period,
ctx,
);
iota_system::create(
iota_system_state_id,
iota_treasury_cap,
validators,
storage_fund,
genesis_chain_parameters.protocol_version,
genesis_chain_parameters.chain_start_timestamp_ms,
system_parameters,
iota_system_admin_cap,
ctx,
);
}
Function allocate_tokens
fun allocate_tokens(iota_treasury_cap: &mut iota::IotaTreasuryCap, allocations: vector<genesis::TokenAllocation>, validators: &mut vector<validator::ValidatorV1>, timelock_genesis_label: option::Option<string::String>, ctx: &mut tx_context::TxContext)
Implementation
fun allocate_tokens(
iota_treasury_cap: &mut IotaTreasuryCap,
mut allocations: vector<TokenAllocation>,
validators: &mut vector<ValidatorV1>,
timelock_genesis_label: Option<String>,
ctx: &mut TxContext,
) {
while (!allocations.is_empty()) {
let TokenAllocation {
recipient_address,
amount_nanos,
staked_with_validator,
staked_with_timelock_expiration,
} = allocations.pop_back();
let allocation_balance = iota_treasury_cap.mint_balance(amount_nanos, ctx);
if (staked_with_validator.is_some()) {
let validator_address = staked_with_validator.destroy_some();
let validator = validator_set::get_validator_mut(
validators, validator_address
);
if (staked_with_timelock_expiration.is_some()) {
let timelock_expiration = staked_with_timelock_expiration.destroy_some();
timelocked_staking::request_add_stake_at_genesis(
validator,
allocation_balance,
recipient_address,
timelock_expiration,
timelock_genesis_label,
ctx
);
} else {
validator.request_add_stake_at_genesis(
allocation_balance,
recipient_address,
ctx
);
}
} else {
iota::transfer(
allocation_balance.into_coin(ctx),
recipient_address,
);
};
};
allocations.destroy_empty();
}
Function activate_validators
fun activate_validators(validators: &mut vector<validator::ValidatorV1>)
Implementation
fun activate_validators(validators: &mut vector<ValidatorV1>) {
// Activate all genesis validators
let count = validators.length();
let mut i = 0;
while (i < count) {
let validator = &mut validators[i];
validator.activate(0);
i = i + 1;
};
}