Neuron attributes and commands

From Internet Computer Wiki
Jump to: navigation, search

This page provides more details about the neurons in the Network Nervous System (NNS), focusing on their attributes and the commands by which they can be changed.

Neuron Attributes

Each neuron in the NNS has the following attributes.

  • id: The identifier of the neuron.
  • account: The principal of the ICP ledger account where the locked ICP balance resides. That is, each neuron's ICP token balance is stored on an account on the ledger canister. In contrast to non-neuron accounts the controller can however not just transfer the funds out of this account.
  • controller: The principal that controls the neuron. The principal must be derived from a public key, which acts as a “master key” (the corresponding secret key should be kept secure). The principal may control many neurons.
  • hot_keys: Keys that can be used to authorize actions with limited privileges, for example voting with a neuron. The idea is that while the controller key should be kept very secure, the loss or compromise of keys that are used more often (and thus very secure storage might not be feasible) has less security impact.
  • cached_neuron_stake_e8s: The amount of staked ICP tokens, measured in fractions of 10E-8 of an ICP. This does not include the fees or some of the collected rewards (see below) and might not correspond exactly to the amount of ICP tokens of the neuron's account at all times. For example, to top up a neuron, one first transfers some ICP tokens to the neuron's account and then refreshes the neuron, which means that in between these actions the neuron's account actually holds more tokens than indicated by the corresponding cached stake.
  • neuron_fees_e8s: The amount that this neuron owes, measured in fractions of 10E-8 of an ICP. This amount is increased when a neuron makes a proposal of topic ManageNeuron or when a neuron makes a proposal of any other topic (in the latter case the fee is reimbursed if the proposal is accepted). When a neuron is disbursed, these tokens are burned.
  • created_timestamp_seconds: The time when the neuron was created.
  • aging_since_timestamp_seconds: The time, in seconds from the Unix epoch as measured by the IC, this neuron has last entered the non-dissolving state.
  • dissolve_state: The state specifying whether a neuron is dissolving, i.e., the timer when the staked tokens can be retrieved is decreasing, or non-dissolving, i.e., the time how much into the future the staked tokens can be retrieved is stopped.
    • When a neuron is dissolving, i.e., the dissolve timer is running, the state is when_dissolved_timestamp_seconds and stores the timestamp, in seconds from the Unix epoch, at which the neuron becomes dissolved.
    • When a neuron is non-dissolving, i.e., the dissolve timer is stopped, the state is dissolve_delay_seconds and stores how much time, in seconds, the dissolve timer will be started with.
  • followees: A neuron's followees stored as a map of topics (represented by an integer) to set of followee neurons.
  • recent_ballots: Information about how this neuron voted in the recent past. It only contains proposals that the neuron voted yes or no on.
  • kyc_verified: `true` if this neuron has passed KYC, `false` otherwise
  • transfer: The record of the transfer that was made to create this neuron. This is not used anymore and always set to "None".
  • maturity_e8s_equivalent: A neuron's maturity in "e8s equivalent". The maturity keeps track of the rewards that the neurons has collected. While this quantity is on the same scale as ICP tokens, it is not directly convertible to ICPs and conversion requires a minting event (i.e., spawn the maturity).
  • not_for_profit: Whether this neuron is "Not for profit", making it dissolvable by voting (see below)
  • joined_community_fund_timestamp_seconds: The time point when this neuron joined the community fund.

Manage Neuron Commands

In general, any changes to or in the name of a neuron (e.g., changes to the neuron's attributes or casting a vote in the name of the neuron) can be made in two ways:

  1. by using the manage_neuron interface of the governance canister or
  2. by making a special proposal of topic ManageNeuron, where the basic idea is that a set of neurons can control a managed neuron by submitting and voting on special proposals. This only works if the managed neuron follows these controlling neurons for the proposal topic ManageNeuron. If this is given, the set of controlling neurons can send commands to the governance canister as if they were issued by the managed neuron's controller (that is with the same privileges that the managed neuron's controller has to manipulate the neuron). Thus, if it is stated that some neuron commands can only be done by a neuron's controller, this also includes the possibility that these commands are done per manageNeuron proposal.

The next section lists all commands that can be performed by manage_neuron.

Claiming a Neuron

This can be used to stake ICP utility tokens into a neuron. To do so, first a transfer must be made to the neuron's associated ledger account. Each transfer on the ledger account can be provided with a memo. After this transfer, the neuron can be claimed on the governance canister by providing the memo and the controller of the neuron. This allows the governance canister to find the corresponding account on the ledger canister and learn how many tokens should be staked in the corresponding neuron. A neuron is then created.

Access control (who can issue this command): Anyone can call this method.

Preconditions (other conditions that must hold):

The effect on the neuron's attributes:

Refreshing a Neuron

Similarly to how a neuron is first created, a neuron can be topped up by making a transfer to the neuron's Ledger canister account and then calling the Governance canister, which will adjust the neuron's stake to the new balance on the neuron's account. For this to work, the caller must either provide the governance canister with the memo and controller (as with claiming a neuron) or with the neuron's ID or account.

Access control (who can issue this command): Anyone can call this method.

Preconditions (other conditions that must hold):

The effect on the neuron's attributes:

Configuring a Neuron

Once a neuron is claimed, a neuron's controller might want to configure it. The following are commands that only configure a given neuron, but do not interact with the outside world.

Access control (who can issue this command): All neuron configurations can only be invoked by a neuron's controller.

  • IncreaseDissolveDelay: Increases a neuron's dissolve delay by the given additional dissolve delay but at most to a given maximum dissolve delay (which is currently set to 8 years). If this method is called on a non-dissolving neuron, it remains non-dissolving. If it is called on dissolving neuron, it remains dissolving. If this configuration is called on a dissolved neuron, it becomes non-dissolving. Moreover, the neuron's aging_since_timestamp_seconds is reset to start counting from when it last entered the dissolved state in the case where the dissolved state was reached through explicit dissolution or to `now` when this is not applicable, e.g., when the neuron is newly created with zero dissolve delay.
  • SetDissolveTimestamp: This is just another way of increasing the dissolve delay, by stating the target dissolve timestamp rather than the relative increase in the dissolve delay. It is internally translated to do the same as increasing the dissolve delay.
  • StartDissolving: If this neuron is not dissolving, start dissolving it. If the neuron is dissolving or dissolved, an error is returned. Starting to dissolve a neuron intuitively means that the neuron's countdown to when the staked tokens can be liquidated is started. In terms of neuron attributes, the neuron's dissolve state is set to when_dissolved_timestamp_seconds which specifies the time now plus the neuron's dissolve delay (i.e., the defined countdown's duration). Moreover, the neuron's aging_since_timestamp_seconds is set to the maximum possible value, which represents that the neuron has no age as this will be in the future.
  • StopDissolving: If this neuron is dissolving, set it to not dissolving. If the neuron is not dissolving, an error is returned. Intuitively, this means that the neuron's countdown towards when the staked tokens can be liquidated is stopped. In terms of neuron attributes, the neuron's state is set to dissolve_delay_seconds, which now tracks the remaining time on the countdown. Also, the neuron's aging_since_timestamp_seconds is set to now.
  • AddHotKey: A new hot key is added to the neuron if the following preconditions hold: - key to add is not already present in 'hot_keys' - the key to add is well-formed - there are not already too many hot keys for this neuron (currently 10 hot keys are allowed).
  • RemoveHotKey: The specified hot key is removed if it is in the list of hot keys.
  • JoinCommunityFund: If the neuron has not yet joined the community fund, this configuration sets the neuron's joined_community_fund_timestamp_seconds to the current time. If the neuron is already a member of the community fund, an error is returned.

Make Proposal

This command can be used to have a neuron controlled by the issuer of the command to submit a proposal. If successful, the command creates an initial electoral roll that includes a ballot for all neurons that are eligible to vote on the proposal at the time when the proposal is created and where the ballots state the neurons' voting power at the time of the proposal creation. The neuron that makes the proposal is charged the rejection fee upfront which will be reimbursed if the proposal is accepted (except for proposals of topic ManageNeuron) and the voting power of the proposer neuron is already counted towards the yes votes of the proposal.

Access control (who can issue this command): The neuron's controller or a registered hot key.

Preconditions (other conditions that must hold):

  • The proposal is valid.
  • The neuron is eligible to vote on the proposal (i.e., still has a minimum dissolve delay currently set to 6 months).
  • The neuron has more stake than the cost of a rejected proposal, which is currently 1 ICP.
  • There are not too many open proposals.

The effect on the neuron's attributes:

  • The neuron_fees_e8s are increased by the rejection fee (or, in case of a ManageNeuron proposal the corresponding fee).
  • The recent_ballots are updated with the yes ballot that is cast for the proposer.

Register Vote

This is used to directly register a neuron's vote for a given proposal. Also, it triggers the registration of a vote for all neurons that follow this neuron.

Access control (who can issue this command): The neuron's controller or a registered hot key.

Preconditions (other conditions that must hold):

  • A proposal is specified that exists.
  • The neuron is eligible to vote on this proposal, i.e., an empty ballot has been entered to the electoral roll (if this is not the case, then the neuron was not eligible at the time when the proposal was created and thus the neuron is not allowed to vote on it).
  • The neuron has not already voted on this proposal.

The effect on the neuron's attributes:

  • The recent_ballots are updated.

Follow

Add or remove followees for this neuron for a specified topic. If the list of followees is empty, remove the followees for this topic. If the list has at least one element, replace the current list of followees for the given topic with the provided list. Note that the list is replaced, not added to.

Access control (who can issue this command): The neuron's controller.

Preconditions (other conditions that must hold):

  • The list of followees is not too long (the current maximum is 15 followees per topic).

The effect on the neuron's attributes:

  • The followees for the given topic are updated.

Spawn

This command allows to convert the neuron's collected rewards that are stored as the neuron's maturity to (staked) ICP utility tokens by minting the corresponding tokens (on the Ledger canister) and "spawning" them into a new neuron. The new child neuron, containing the spawned staked tokens has a small dissolve delay, which means that the tokens can be liquidated after only a short period of time while the original parent neuron's tokens may still be locked for much longer.

Access control (who can issue this command): The neuron's controller.

Preconditions (other conditions that must hold):

  • The parent neuron exists.
  • The parent neuron is not involved in any neuron commands that have ledger interactions (to avoid inconsistencies).
  • The parent neuron has accumulated maturity that would generate more than the minimum stake needed to create a new neuron.
  • A controller for the new child neuron is provided that is valid.

The effect on the neuron's attributes:

  • The maturity is decreased by the maturity at the time when the command started (a new reward event might have set it to non-zero already again).

The new "child" neuron's attributes:

  • id: random identifier
  • account: random account (that does not yet exist)
  • controller: set to the provided controller
  • hot_keys: same as parent neuron
  • cached_neuron_stake_e8s: set to the parent's maturity at the time when the command started.
  • neuron_fees_e8s: 0
  • created_timestamp_seconds: current time
  • aging_since_timestamp_seconds: current time
  • dissolve_state: (non-dissolving) dissolve_delay_seconds set to neuron_spawn_dissolve_delay_seconds as defined in the governance economics (currently set to 7 days)
  • followees: same as parent neuron
  • recent_ballots: empty
  • kyc_verified: same as parent neuron
  • transfer: not set
  • maturity_e8s_equivalent:0
  • not_for_profit: false
  • joined_community_fund_timestamp_seconds: None

Disburse

Once a dissolving neuron's countdown has reached zero, the neuron is dissolved and can thus be disbursed, which means that (some or only a specified number of) the staked tokens can be transferred to a given account. If no target account is provided, the transfer is made to the caller's account (i.e., the neuron's controller's account).

In more detail, when a neuron is disbursed multiple steps happen:

  1. The neuron's accumulated fees are burned.
  2. The neuron's accumulated maturity is converted to ICP utility tokens by minting the corresponding tokens and also transferring them to the target account.
  3. The given staked amount (or the full stake if none is provided) is transferred to the target account.

Access control (who can issue this command): The neuron's controller.

Preconditions (other conditions that must hold):

  • The neuron exists.
  • The neuron's state is `Dissolved` at the current timestamp, i.e., the dissolve countdown has reached zero.
  • The neuron's kyc_verified is not false. That is, a neuron that was created with kyc_verified false cannot be disbursed until it went through kyc.

The effect on the neuron's attributes:

  • The specified amount is subtracted from the neuron's cached_neuron_stake_e8s, as are the original neuron fees.
  • The neuron_fees_e8s is set to zero.
  • The maturity_e8s_equivalent is set to zero.

Split

This command splits a parent neuron into two neurons, the original parent neuron and a new child neuron. This command may be useful, if a neuron holder would like for example to set the neuron configurations differently for a portion of the locked tokens.

The parent neuron's stake is decreased by the amount specified, while the child neuron is created with a stake equal to that amount, minus the Ledger canister transfer fee. The child neuron inherits all the properties of its parent.

Access control (who can issue this command): The neuron's controller.

Preconditions (other conditions that must hold):

  • The parent neuron exists.
  • The parent neuron is not involved in any neuron commands that have ledger interactions (to avoid inconsistencies).
  • The staked amount minus amount to split is more than the minimum stake (ensuring that the parent neuron has at least the minimum stake).
  • The amount to split minus the transfer fee is more than the minimum stake (ensuring that the child neuron has at least the minimum stake).

The effect on the (parent) neuron's attributes:

  • cached_neuron_stake_e8s: deduced by specified amount that is split.

The the new "child" neuron's attributes:

  • id: random identifier
  • account: random account (that does not yet exist)
  • controller: same as parent neuron
  • hot_keys: same as parent neuron
  • cached_neuron_stake_e8s: set to specified amount that is split from parent minus the transaction fee
  • neuron_fees_e8s: 0
  • created_timestamp_seconds: current time
  • aging_since_timestamp_seconds: same as parent neuron
  • dissolve_state: same as parent neuron
  • followees: same as parent neuron
  • recent_ballots: empty
  • kyc_verified: same as parent neuron
  • transfer: not set
  • maturity_e8s_equivalent: 0
  • not_for_profit: same as parent neuron
  • joined_community_fund_timestamp_seconds: same as parent neuron

Disburse to Neuron

(Intro)

Access control (who can issue this command): The neuron's controller.

Preconditions (other conditions that must hold):

The effect on the neuron's attributes: