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

Conversation

nonast
Copy link
Contributor

@nonast nonast commented Dec 4, 2024

Description of change

To make the genesis delegator(s) configurable by the cli, we need to make changes to two iota commands:

  1. iota genesis
  2. iota genesis-ceremony

This draft-PR contains the progress of this task, in which the changes to both commands have been made to allow for a custom delegation configuration through the CLI. The iota-genesis command expects a single delegator when a migration snapshot has been provided. The iota genesis-ceremony now contains a new sub command called init-delegations and expects a path to a .csv file as argument, which contains the custom delegation configuration. The command is expected to be run before the build-unsigned-checkpoint command.

This csv file has the following format:

delegator,validator,amount-nanos-to-stake,amount-nanos-to-pay-gas
<delegator1-address>,<validator-1-address>,2000000000000000,5000000000
<delegator1-address>,<validator-2-address>,3000000000000000,5000000000
<delegator2-address>,<validator-3-address>,4500000000000000,5000000000

Links to any relevant issues

fixes #4218

Type of change

Choose a type of change, and delete any options that are not relevant.

  • Enhancement (a non-breaking change which adds functionality)

How the change has been tested

Tested the local genesis:

  1. cargo run --release --bin iota genesis --working-dir ./test_iota_config -f --with-faucet --num-validators 2 --remote-migration-snapshots https://stardust-objects.s3.eu-central-1.amazonaws.com/iota/alphanet/test/stardust_object_snapshot.bin.gz --delegator 0x4f72f788cdf4bb478cf9809e878e6163d5b351c82c11f1ea28750430752e7892
  2. cargo run --release --bin iota start --network.config test_iota_config --with-faucet

Tested the following affected example:

  • cargo run --example snapshot_only_test_outputs --features="test-outputs" iota --snapshot-path ../latest-full_snapshot.bin --delegator 0x4f72f788cdf4bb478cf9809e878e6163d5b351c82c11f1ea28750430752e7892

Tested running the genesis ceremony, which resulted in a genesis.blob and migration.blob, which were then used to run a local network with iota start. Using the explorer on this local network showed the correct delegations.

todo: the validate-state command of the genesis ceremony is broken when used with a migrated state. This step was therefore skipped in the tests mentioned above.

Change checklist

Tick the boxes that are relevant to your changes, and delete any items that are not.

  • I have followed the contribution guidelines for this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I have checked that new and existing unit tests pass locally with my changes

@iota-ci iota-ci added sc-platform Issues related to the Smart Contract Platform group. vm-language Issues related to the VM & Language Team labels Dec 4, 2024
@nonast nonast self-assigned this Dec 4, 2024
@nonast nonast added this to the Mainnet milestone Dec 4, 2024
@miker83z miker83z force-pushed the sc-platform/custom-genesis-delegator branch from 6043c59 to 7e90668 Compare December 6, 2024 21:57
crates/iota-genesis-builder/src/lib.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/lib.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/lib.rs Outdated Show resolved Hide resolved
crates/iota/src/genesis_ceremony.rs Outdated Show resolved Hide resolved
crates/iota/src/iota_commands.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@kodemartin kodemartin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nonast looks good in general. Made a few minor suggestions that you could consider.

crates/iota-config/src/genesis.rs Outdated Show resolved Hide resolved
crates/iota-config/src/genesis.rs Outdated Show resolved Hide resolved
crates/iota-config/src/genesis.rs Outdated Show resolved Hide resolved
crates/iota-config/src/genesis.rs Outdated Show resolved Hide resolved
crates/iota-config/src/genesis.rs Show resolved Hide resolved
crates/iota-genesis-builder/src/lib.rs Outdated Show resolved Hide resolved
crates/iota/src/iota_commands.rs Outdated Show resolved Hide resolved
crates/iota/src/iota_commands.rs Show resolved Hide resolved
crates/iota-genesis-builder/src/lib.rs Outdated Show resolved Hide resolved
@nonast nonast marked this pull request as ready for review December 11, 2024 13:27
@nonast nonast requested review from a team as code owners December 11, 2024 13:27
crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
let mut timelock_objects =
pick_objects_for_allocation(timelocks_pool, target_stake, &mut timelock_surplus);
if !timelock_objects.to_burn.is_empty() {
// Inside this block, the previous surplus is empty so we update it (possibly)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bit confusing to me, why is it empty here? Is it because pick_objects_for_allocation enforces that? If yes, maybe we should add that to the comment. At first look I would say that the if condition checks that it's not empty, but then that's the to_burn object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, shouldn't we check that it is really empty before replacing it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing that comes to my mind.... why do we even "burn" something? Is it because we consume those "UTXO's"? If yes, shouldn't we rather call it to_consume instead of to_burn?
Burning, at least in my head, is only used if we actually destroy tokens that are gone forever afterwards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are technically "draining" the surplus object from its surplus_nanos. Therefore, the surplus object can be burned.

In the pick_objects_for_allocation function, we try and take all the nanos that we need from the surplus object first. If we have "drained" the surplus object, we place it in the timelock_objects.to_burn Vec. This means that the previous surplus is empty, and it needs to be replaced with a new one (picked in pick_objects_for_allocation because the previous allocation might have needed some extra nanos).

Inside pick_objects_for_allocation this happens:
surplus = Coin(50)

  1. if target_stake == 49 then surplus = Coin(1); timelock_objects.amount_nanos = 49; timelock_objects.to_burn = empty
  2. if target_stake == 50 then surplus = empty; timelock_objects.amount_nanos = 50; timelock_objects.to_burn = [surplus]
  3. if target_stake == 51 then surplus = empty; timelock_objects.amount_nanos = 51; timelock_objects.to_burn = [surplus, timelock_1]

Btw, shouldn't we check that it is really empty before replacing it?

This is a given, since we're in the scope of timelock_objects.to_burn.is_empty(). If the to_burn field is empty, it means we still have nanos in the surplus object. Would you advice adding a check here out of safety/clarity? Or could some comments explaining this be sufficient?

Another thing that comes to my mind.... why do we even "burn" something? Is it because we consume those "UTXO's"? If yes, shouldn't we rather call it to_consume instead of to_burn?
Burning, at least in my head, is only used if we actually destroy tokens that are gone forever afterwards.

Indeed, at first glance I also think we could use another term for this, something more in line with what's being used throughout the code: to destroy empty objects.
However, these objects are not really "consumed" in the actual object database yet. This happens in a later stage in the build_unsigned_genesis_data phase of the ceremony. First, the required genesis objects are created. After this, the genesis objects are being "cleansed" from the to be burned objects that we have specified earlier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed burn into destroy here 1ef83d2

crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
/// The surplus amount for that coin object.
surplus_nanos: u64,
/// Possibly indicate a timelock stake expiration.
timestamp: u64,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to use an option here?
I mean someone could still create an UTXO with a timelock and set the timelock to zero.
Maybe that would lead to the same result, but I'm just wondering if using >0 logic is really the cleanest way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. I guess it makes sense to use an Option here if there should be a clear distinction between surplus being 0 and non-existent. In this case, I don't think it's necessary to convert this to an Option. It would add additional complexity to the code (checks).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During the migration from UTXO to Object, here we check if the timelock still holds at the "target milestone timestamp". If it is not timelocked at that time then we treat is as a simple basic output. This process is performed before this genesis building step, so we can't have unwanted behaviors like your scenario.

crates/iota-genesis-builder/src/stake.rs Show resolved Hide resolved
Copy link
Contributor

@muXxer muXxer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Just some small renaming and comment fixes

crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
crates/iota-genesis-builder/src/stake.rs Outdated Show resolved Hide resolved
@miker83z miker83z force-pushed the sc-platform/custom-genesis-delegator branch from dea22ae to e052623 Compare December 20, 2024 16:49
@github-actions github-actions bot added documentation Improvements or additions to documentation explorer Issues related to the Explorer labels Dec 20, 2024
@miker83z miker83z force-pushed the sc-platform/custom-genesis-delegator branch from e052623 to dea22ae Compare December 20, 2024 16:51
@miker83z miker83z removed documentation Improvements or additions to documentation explorer Issues related to the Explorer labels Dec 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sc-platform Issues related to the Smart Contract Platform group. vm-language Issues related to the VM & Language Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[genesis] Make the genesis delegator configurable by CLI
8 participants