Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iota-genesis-builder): Add configurable delegator to genesis CLI #4346

Open
wants to merge 29 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b6fc756
feat(iota-genesis-builder): add delegator as cli arg for genesis
nonast Dec 4, 2024
c44b0b3
add bail when delegator missing
nonast Dec 4, 2024
232f688
fix genesis tests
nonast Dec 4, 2024
7e90668
feat(genesis): add delegator map type to genesis builder
nonast Dec 6, 2024
19e1efa
refactor(iota-genesis-builder): add comments and restructure resolve_…
miker83z Dec 6, 2024
0d90ad1
refactor(iota-genesis-builder): genesis cli arg to IotaAddress and ad…
nonast Dec 9, 2024
ab907ad
feat(genesis-ceremony): add InitDelegatorMap command
nonast Dec 9, 2024
6d6199e
refactor(iota-genesis-builder): renaming structs and replace fold() u…
nonast Dec 10, 2024
b77f93a
feat(iota-genesis-builder): add GenesisDelegation enum
nonast Dec 10, 2024
4b20406
chore(iota): correct bail messages to start with lower case
nonast Dec 10, 2024
25ec11f
refactor(iota-genesis-builder): rename schedule_without_migration to …
nonast Dec 10, 2024
4066d42
feat(iota-genesis-builder): create a token allocation to pay validato…
miker83z Dec 10, 2024
22fdd90
feat(iota-genesis-builder): optimize timelock and gas objects picks
miker83z Dec 10, 2024
8042a2e
fix format
miker83z Dec 10, 2024
4a35f0c
fix: add hardcoded delegator arg to docker config
nonast Dec 11, 2024
3ac99ea
fix(iota-genesis-builder): fix csv read and write functions
nonast Dec 11, 2024
a255e9f
chore: fix clippy warnings
nonast Dec 11, 2024
a6783fa
fix pick_objects_for_allocation logic
miker83z Dec 11, 2024
9b88238
Merge branch 'develop' into sc-platform/custom-genesis-delegator
miker83z Dec 13, 2024
dd0ebee
minor improvements
DaughterOfMars Dec 13, 2024
1211f0a
fix: add delegator to start cmd and partially revert minor improvement
nonast Dec 16, 2024
d850a38
refactor: add comments and adjust example argument
nonast Dec 17, 2024
1304b0e
fix fmt
miker83z Dec 17, 2024
3331460
fix clippy issue
nonast Dec 17, 2024
ab802af
Merge branch 'develop' into sc-platform/custom-genesis-delegator
nonast Dec 18, 2024
c42f614
chore: fix typos in comments
nonast Dec 19, 2024
59145c7
fix(iota-genesis-builder): comments and names to make it clearer
miker83z Dec 20, 2024
1ef83d2
refactor(iota-genesis-builder): use the destroy verb instead of burn
miker83z Dec 20, 2024
dea22ae
Merge branch 'develop' into sc-platform/custom-genesis-delegator
miker83z Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 41 additions & 51 deletions crates/iota-config/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ impl PartialEq for Genesis {
fn eq(&self, other: &Self) -> bool {
self.checkpoint.data() == other.checkpoint.data()
&& {
let this = self.checkpoint.auth_sig();
let other = other.checkpoint.auth_sig();
let this = self.checkpoint.auth_sig();
nonast marked this conversation as resolved.
Show resolved Hide resolved
let other = other.checkpoint.auth_sig();

this.epoch == other.epoch
&& this.signature.as_ref() == other.signature.as_ref()
&& this.signers_map == other.signers_map
}
this.epoch == other.epoch
&& this.signature.as_ref() == other.signature.as_ref()
&& this.signers_map == other.signers_map
}
&& self.checkpoint_contents == other.checkpoint_contents
&& self.transaction == other.transaction
&& self.effects == other.effects
Expand Down Expand Up @@ -418,11 +418,11 @@ impl GenesisCeremonyParameters {
max_validator_count: iota_types::governance::MAX_VALIDATOR_COUNT,
min_validator_joining_stake: iota_types::governance::MIN_VALIDATOR_JOINING_STAKE_NANOS,
validator_low_stake_threshold:
iota_types::governance::VALIDATOR_LOW_STAKE_THRESHOLD_NANOS,
iota_types::governance::VALIDATOR_LOW_STAKE_THRESHOLD_NANOS,
validator_very_low_stake_threshold:
iota_types::governance::VALIDATOR_VERY_LOW_STAKE_THRESHOLD_NANOS,
iota_types::governance::VALIDATOR_VERY_LOW_STAKE_THRESHOLD_NANOS,
validator_low_stake_grace_period:
iota_types::governance::VALIDATOR_LOW_STAKE_GRACE_PERIOD,
iota_types::governance::VALIDATOR_LOW_STAKE_GRACE_PERIOD,
}
}
}
Expand Down Expand Up @@ -454,11 +454,11 @@ impl TokenDistributionSchedule {
for allocation in &self.allocations {
total_nanos = total_nanos
.checked_add(allocation.amount_nanos)
.expect("TokenDistributionSchedule allocates more than the maximum supply which equals u64::MAX", );
.expect("TokenDistributionSchedule allocates more than the maximum supply which equals u64::MAX");
}
}

pub fn check_minimum_stake_for_validators<I: IntoIterator<Item = IotaAddress>>(
pub fn check_minimum_stake_for_validators<I: IntoIterator<Item=IotaAddress>>(
&self,
validators: I,
) -> Result<()> {
Expand Down Expand Up @@ -489,7 +489,7 @@ impl TokenDistributionSchedule {
Ok(())
}

pub fn new_for_validators_with_default_allocation<I: IntoIterator<Item = IotaAddress>>(
pub fn new_for_validators_with_default_allocation<I: IntoIterator<Item=IotaAddress>>(
validators: I,
) -> Self {
let default_allocation = iota_types::governance::VALIDATOR_LOW_STAKE_THRESHOLD_NANOS;
Expand Down Expand Up @@ -603,7 +603,7 @@ impl TokenDistributionScheduleBuilder {
self.pre_minted_supply = pre_minted_supply;
}

pub fn default_allocation_for_validators<I: IntoIterator<Item = IotaAddress>>(
pub fn default_allocation_for_validators<I: IntoIterator<Item=IotaAddress>>(
&mut self,
validators: I,
) {
Expand Down Expand Up @@ -647,48 +647,44 @@ pub struct ValidatorAllocation {

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct DelegatorDistribution {
pub struct Delegation {
/// The address from which take the nanos for staking/gas
pub delegator: IotaAddress,
/// The allocation to a validator receiving a stake and/or a gas payment
pub validator_allocation: ValidatorAllocation,
}

/// Represents genesis delegations to validators.
///
/// This struct maps a delegator address to a list of validators and their
/// stake and gas allocations. Each ValidatorAllocation contains the address of a
/// validator that will receive an amount of nanos to stake and an amount as gas payment.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct DelegatorMap {
// Maps a delegator address to a tuple containing the address of a validator (1nd element of
// the tuple) that will receive an amount of nanos to stake (2nd element) and an amount as gas
// payment (3rd element).
pub struct Delegations {
pub allocations: HashMap<IotaAddress, Vec<ValidatorAllocation>>,
}

impl DelegatorMap {
pub fn new_for_validators_with_default_allocation<I: IntoIterator<Item = IotaAddress>>(
impl Delegations {
pub fn new_for_validators_with_default_allocation<I: IntoIterator<Item=IotaAddress>>(
validators: I,
delegator: IotaAddress,
) -> Self {
let default_allocation = iota_types::governance::MIN_VALIDATOR_JOINING_STAKE_NANOS;

let allocations = validators.into_iter().fold(
HashMap::new(),
|mut allocations: HashMap<IotaAddress, Vec<_>>, address| {
allocations
.entry(delegator)
.or_default()
.push(ValidatorAllocation {
address,
amount_nanos_to_stake: default_allocation,
amount_nanos_to_pay_gas: 0,
});
allocations
},
);
let validator_allocations = validators.into_iter().map(|address| ValidatorAllocation {
address,
amount_nanos_to_stake: default_allocation,
amount_nanos_to_pay_gas: 0,
}).collect();

let mut allocations = HashMap::new();
allocations.insert(delegator, validator_allocations);

Self { allocations }
}

/// Helper to read a DelegatorMap from a csv file.
/// Helper to read a Delegations struct from a csv file.
///
/// The file is encoded such that the final entry in the CSV file is used to
/// denote the allocation coming from a delegator. It must be in the
Expand All @@ -700,25 +696,19 @@ impl DelegatorMap {
pub fn from_csv<R: std::io::Read>(reader: R) -> Result<Self> {
let mut reader = csv::Reader::from_reader(reader);

let allocations = reader
.deserialize::<DelegatorDistribution>()
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.fold(
HashMap::new(),
|mut allocations: HashMap<IotaAddress, Vec<_>>, allocation| {
allocations
.entry(allocation.delegator)
.or_default()
.push(allocation.validator_allocation);
allocations
},
);
let mut allocations: HashMap<IotaAddress, Vec<ValidatorAllocation>> = HashMap::new();
for delegation in reader.deserialize::<Delegation>() {
let delegation = delegation?;
allocations
.entry(delegation.delegator)
.or_default()
.push(delegation.validator_allocation);
}

Ok(Self { allocations })
}

/// Helper to write a DelegatorMap into a csv file.
/// Helper to write a Delegations struct into a csv file.
///
/// It writes in the following format:
/// `delegator,validator,amount-nanos-to-stake,amount-nanos-to-pay-gas
Expand All @@ -730,7 +720,7 @@ impl DelegatorMap {

for (&delegator, validators_allocations) in &self.allocations {
for &validator_allocation in validators_allocations {
writer.serialize(DelegatorDistribution {
writer.serialize(Delegation {
delegator,
validator_allocation,
})?;
Expand Down
13 changes: 6 additions & 7 deletions crates/iota-genesis-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use genesis_build_effects::GenesisBuildEffects;
use iota_config::{
IOTA_GENESIS_MIGRATION_TX_DATA_FILENAME,
genesis::{
DelegatorMap, Genesis, GenesisCeremonyParameters, GenesisChainParameters,
Delegations, Genesis, GenesisCeremonyParameters, GenesisChainParameters,
TokenDistributionSchedule, UnsignedGenesis,
},
migration_tx_data::{MigrationTxData, TransactionsData},
Expand All @@ -28,7 +28,7 @@ use iota_execution::{self, Executor};
use iota_framework::{BuiltInFramework, SystemPackage};
use iota_genesis_common::{execute_genesis_transaction, get_genesis_protocol_config};
use iota_protocol_config::{Chain, ProtocolConfig, ProtocolVersion};
use iota_sdk::{Url, types::block::address::Address};
use iota_sdk::{Url};
use iota_types::{
BRIDGE_ADDRESS, IOTA_BRIDGE_OBJECT_ID, IOTA_FRAMEWORK_PACKAGE_ID, IOTA_SYSTEM_ADDRESS,
balance::{BALANCE_MODULE_NAME, Balance},
Expand Down Expand Up @@ -63,7 +63,6 @@ use iota_types::{
object::{Object, Owner},
programmable_transaction_builder::ProgrammableTransactionBuilder,
randomness_state::{RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_CREATE_FUNCTION_NAME},
stardust::stardust_to_iota_address,
system_admin_cap::IOTA_SYSTEM_ADMIN_CAP_MODULE_NAME,
timelock::{
stardust_upgrade_label::STARDUST_UPGRADE_LABEL_VALUE,
Expand Down Expand Up @@ -117,7 +116,7 @@ pub struct Builder {
migration_sources: Vec<SnapshotSource>,
migration_tx_data: Option<MigrationTxData>,
delegator: Option<IotaAddress>,
delegator_map: Option<DelegatorMap>,
delegator_map: Option<Delegations>,
}

impl Default for Builder {
Expand Down Expand Up @@ -149,7 +148,7 @@ impl Builder {
self
}

pub fn with_delegator_map(mut self, delegator_map: DelegatorMap) -> Self {
pub fn with_delegator_map(mut self, delegator_map: Delegations) -> Self {
self.delegator_map = Some(delegator_map);
self
}
Expand Down Expand Up @@ -282,7 +281,7 @@ impl Builder {
} else if let Some(delegator) = &self.delegator {
// Case 2 -> use one default delegator passed as input and delegate the
// minimum required stake to all validators to create the genesis stake
DelegatorMap::new_for_validators_with_default_allocation(
Delegations::new_for_validators_with_default_allocation(
self.validators.values().map(|v| v.info.iota_address()),
*delegator,
)
Expand Down Expand Up @@ -874,7 +873,7 @@ impl Builder {
let delegator_map_file =
path.join(GENESIS_BUILDER_DELEGATOR_MAP_FILE);
let delegator_map = if delegator_map_file.exists() {
Some(DelegatorMap::from_csv(fs::File::open(
Some(Delegations::from_csv(fs::File::open(
delegator_map_file,
)?)?)
} else {
Expand Down
4 changes: 2 additions & 2 deletions crates/iota/src/genesis_ceremony.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use clap::Parser;
use fastcrypto::encoding::{Encoding, Hex};
use iota_config::{
IOTA_GENESIS_FILENAME,
genesis::{DelegatorMap, TokenDistributionScheduleBuilder, UnsignedGenesis},
genesis::{Delegations, TokenDistributionScheduleBuilder, UnsignedGenesis},
};
use iota_genesis_builder::{
Builder, GENESIS_BUILDER_PARAMETERS_FILE, SnapshotSource, SnapshotUrl,
Expand Down Expand Up @@ -268,7 +268,7 @@ pub async fn run(cmd: Ceremony) -> Result<()> {
CeremonyCommand::InitDelegatorMap { delegator_map_path } => {
let mut builder = Builder::load(&dir).await?;
let file = File::open(delegator_map_path)?;
let delegator_map = DelegatorMap::from_csv(file)?;
let delegator_map = Delegations::from_csv(file)?;
builder = builder.with_delegator_map(delegator_map);
builder.save(dir)?;
}
Expand Down
Loading