@dfinity/nns-proto 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,846 @@ package ic_nns_governance.pb.v1;
4
4
 
5
5
  import "base_types.proto";
6
6
  import "ledger.proto";
7
+ import "nervous_system.proto";
8
+ import "nns_common.proto";
9
+ import "swap.proto";
10
+
11
+ // The entity that owns the nodes that run the network.
12
+ //
13
+ // Note that this is different from a node operator, the entity that
14
+ // operates the nodes. In terms of responsibilities, the node operator
15
+ // is responsible for adding/removing and generally making sure that
16
+ // the nodes are working, while the NodeProvider is the entity that
17
+ // is compensated.
18
+ //
19
+ // Note: The NodeOperatorRecord is defined in:
20
+ // rs/protobuf/def/registry/node_operator/v1/node_operator.proto.
21
+ message NodeProvider {
22
+ // The ID of the node provider.
23
+ ic_base_types.pb.v1.PrincipalId id = 1;
24
+
25
+ // The account where rewards earned from providing nodes will be sent.
26
+ ic_ledger.pb.v1.AccountIdentifier reward_account = 2;
27
+ }
28
+
29
+ // Used to update node provider records
30
+ //
31
+ // There is no need to specify a node provider Principal ID here, as Governance
32
+ // uses the Principal ID of the caller as the Node Provider Principal ID.
33
+ message UpdateNodeProvider {
34
+ // The account where rewards earned from providing nodes will be sent.
35
+ ic_ledger.pb.v1.AccountIdentifier reward_account = 1;
36
+ }
37
+
38
+ // Proposal types are organized into topics. Neurons can automatically
39
+ // vote based on following other neurons, and these follow
40
+ // relationships are defined per topic.
41
+ enum Topic {
42
+ // The `Unspecified` topic is used as a fallback when
43
+ // following. That is, if no followees are specified for a given
44
+ // topic, the followees for this topic are used instead.
45
+ TOPIC_UNSPECIFIED = 0;
46
+ // A special topic by means of which a neuron can be managed by the
47
+ // followees for this topic (in this case, there is no fallback to
48
+ // 'unspecified'). Votes on this topic are not included in the
49
+ // voting history of the neuron (cf., `recent_ballots` in `Neuron`).
50
+ //
51
+ // For proposals on this topic, only followees on the 'neuron
52
+ // management' topic of the neuron that the proposals pertains to
53
+ // are allowed to vote.
54
+ //
55
+ // As the set of eligible voters on this topic is restricted,
56
+ // proposals on this topic have a *short voting period*.
57
+ TOPIC_NEURON_MANAGEMENT = 1;
58
+ // All proposals that provide “real time” information about the
59
+ // value of ICP, as measured by an IMF SDR, which allows the NNS to
60
+ // convert ICP to cycles (which power computation) at a rate which
61
+ // keeps their real world cost constant. Votes on this topic are not
62
+ // included in the voting history of the neuron (cf.,
63
+ // `recent_ballots` in `Neuron`).
64
+ //
65
+ // Proposals on this topic have a *short voting period* due to their
66
+ // frequency.
67
+ TOPIC_EXCHANGE_RATE = 2;
68
+ // All proposals that administer network economics, for example,
69
+ // determining what rewards should be paid to node operators.
70
+ TOPIC_NETWORK_ECONOMICS = 3;
71
+ // All proposals that administer governance, for example to freeze
72
+ // malicious canisters that are harming the network.
73
+ TOPIC_GOVERNANCE = 4;
74
+ // All proposals that administer node machines, including, but not
75
+ // limited to, upgrading or configuring the OS, upgrading or
76
+ // configuring the virtual machine framework and upgrading or
77
+ // configuring the node replica software.
78
+ TOPIC_NODE_ADMIN = 5;
79
+ // All proposals that administer network participants, for example,
80
+ // granting and revoking DCIDs (data center identities) or NOIDs
81
+ // (node operator identities).
82
+ TOPIC_PARTICIPANT_MANAGEMENT = 6;
83
+ // All proposals that administer network subnets, for example
84
+ // creating new subnets, adding and removing subnet nodes, and
85
+ // splitting subnets.
86
+ TOPIC_SUBNET_MANAGEMENT = 7;
87
+ // Installing and upgrading “system” canisters that belong to the network.
88
+ // For example, upgrading the NNS.
89
+ TOPIC_NETWORK_CANISTER_MANAGEMENT = 8;
90
+ // Proposals that update KYC information for regulatory purposes,
91
+ // for example during the initial Genesis distribution of ICP in the
92
+ // form of neurons.
93
+ TOPIC_KYC = 9;
94
+ // Topic for proposals to reward node providers.
95
+ TOPIC_NODE_PROVIDER_REWARDS = 10;
96
+
97
+ // IC OS upgrade proposals
98
+ // -----------------------
99
+ // ICP runs on a distributed network of nodes grouped into subnets. Each node runs a stack of
100
+ // operating systems, including HostOS (runs on bare metal) and GuestOS (runs inside HostOS;
101
+ // contains, e.g., the ICP replica process). HostOS and GuestOS are distributed via separate disk
102
+ // images. The umbrella term IC OS refers to the whole stack.
103
+ //
104
+ // The IC OS upgrade process involves two phases, where the first phase is the election of a new
105
+ // IC OS version and the second phase is the deployment of a previously elected IC OS version on
106
+ // all nodes of a subnet or on some number of nodes (including nodes comprising subnets and
107
+ // unassigned nodes).
108
+ //
109
+ // A special case is for API boundary nodes, special nodes that route API requests to a replica
110
+ // of the right subnet. API boundary nodes run a different process than the replica, but their
111
+ // executable is distributed via the same disk image as GuestOS. Therefore, electing a new GuestOS
112
+ // version also results in a new version of boundary node software being elected.
113
+ //
114
+ // Proposals handling the deployment of IC OS to some nodes. It is possible to deploy only
115
+ // the versions of IC OS that are in the set of elected IC OS versions.
116
+ TOPIC_IC_OS_VERSION_DEPLOYMENT = 12;
117
+ // Proposals for changing the set of elected IC OS versions.
118
+ TOPIC_IC_OS_VERSION_ELECTION = 13;
119
+
120
+ // Proposals related to SNS and Community Fund.
121
+ TOPIC_SNS_AND_COMMUNITY_FUND = 14;
122
+ // Proposals related to the management of API Boundary Nodes
123
+ TOPIC_API_BOUNDARY_NODE_MANAGEMENT = 15;
124
+
125
+ // Superseded by SNS_COMMUNITY_FUND.
126
+ reserved 11;
127
+ reserved "TOPIC_SNS_DECENTRALIZATION_SALE";
128
+ }
129
+
130
+ // Every neuron is in one of three states.
131
+ //
132
+ // Note that `Disbursed` is not a state of a neuron, as the neuron is
133
+ // consumed through the act of disbursement (using the method
134
+ // [Governance::disburse]).
135
+ //
136
+ // See [neuron::DissolveState] for detail on how the different states
137
+ // are represented.
138
+ enum NeuronState {
139
+ // Not a valid state. Required by Protobufs.
140
+ NEURON_STATE_UNSPECIFIED = 0;
141
+ // In this state, the neuron is not dissolving and has a specific
142
+ // `dissolve_delay`. It accrues `age` by the passage of time and it
143
+ // can vote if `dissolve_delay` is at least six months. The method
144
+ // [Neuron::start_dissolving] can be called to transfer the neuron
145
+ // to the `Dissolving` state. The method
146
+ // [Neuron::increase_dissolve_delay] can be used to increase the
147
+ // dissolve delay without affecting the state or the age of the
148
+ // neuron.
149
+ NEURON_STATE_NOT_DISSOLVING = 1;
150
+ // In this state, the neuron's `dissolve_delay` decreases with the
151
+ // passage of time. While dissolving, the neuron's age is considered
152
+ // zero. Eventually it will reach the `Dissolved` state. The method
153
+ // [Neuron::stop_dissolving] can be called to transfer the neuron to
154
+ // the `NotDissolving` state, and the neuron will start aging again. The
155
+ // method [Neuron::increase_dissolve_delay] can be used to increase
156
+ // the dissolve delay, but this will not stop the timer or affect
157
+ // the age of the neuron.
158
+ NEURON_STATE_DISSOLVING = 2;
159
+ // In the dissolved state, the neuron's stake can be disbursed using
160
+ // the [Governance::disburse] method. It cannot vote as its
161
+ // `dissolve_delay` is considered to be zero.
162
+ //
163
+ // If the method [Neuron::increase_dissolve_delay] is called in this
164
+ // state, the neuron will no longer be dissolving, with the specified
165
+ // dissolve delay, and will start aging again.
166
+ //
167
+ // Neuron holders have an incentive not to keep neurons in the
168
+ // 'dissolved' state for a long time: if the holders wants to make
169
+ // their tokens liquid, they disburse the neuron's stake, and if
170
+ // they want to earn voting rewards, they increase the dissolve
171
+ // delay. If these incentives turn out to be insufficient, the NNS
172
+ // may decide to impose further restrictions on dissolved neurons.
173
+ NEURON_STATE_DISSOLVED = 3;
174
+
175
+ // The neuron is in spawning state, meaning it's maturity will be
176
+ // converted to ICP according to https://wiki.internetcomputer.org/wiki/Maturity_modulation.
177
+ NEURON_STATE_SPAWNING = 4;
178
+ }
179
+
180
+ // How did a neuron vote in the recent past? This data is used by
181
+ // other neurons to determine what neurons to follow.
182
+ message BallotInfo {
183
+ ic_nns_common.pb.v1.ProposalId proposal_id = 1;
184
+ Vote vote = 2;
185
+ }
186
+
187
+ // The result of querying for the state of a single neuron.
188
+ message NeuronInfo {
189
+ // The exact time at which this data was computed. This means, for
190
+ // example, that the exact time that this neuron will enter the
191
+ // dissolved state, assuming it is currently dissolving, is given
192
+ // by `retrieved_at_timestamp_seconds+dissolve_delay_seconds`.
193
+ uint64 retrieved_at_timestamp_seconds = 1;
194
+ // The current state of the neuron. See [NeuronState] for a
195
+ // description of the different states.
196
+ NeuronState state = 2;
197
+ // The current age of the neuron. See [Neuron::age_seconds]
198
+ // for details on how it is computed.
199
+ uint64 age_seconds = 3;
200
+ // The current dissolve delay of the neuron. See
201
+ // [Neuron::dissolve_delay_seconds] for details on how it is
202
+ // computed.
203
+ uint64 dissolve_delay_seconds = 4;
204
+ // See [Neuron::recent_ballots] for a description.
205
+ repeated BallotInfo recent_ballots = 5;
206
+ // Current voting power of the neuron.
207
+ uint64 voting_power = 6;
208
+ // When the Neuron was created. A neuron can only vote on proposals
209
+ // submitted after its creation date.
210
+ uint64 created_timestamp_seconds = 7;
211
+ // Current stake of the neuron, in e8s.
212
+ uint64 stake_e8s = 8;
213
+ // Timestamp when this neuron joined the community fund.
214
+ optional uint64 joined_community_fund_timestamp_seconds = 9;
215
+ // If this neuron is a known neuron, this is data associated
216
+ // with it, including the neuron's name and (optionally) a description.
217
+ optional KnownNeuronData known_neuron_data = 10;
218
+ // The type of the Neuron. See [NeuronType] for a description
219
+ // of the different states.
220
+ optional NeuronType neuron_type = 11;
221
+ }
222
+
223
+ // A transfer performed from some account to stake a new neuron.
224
+ message NeuronStakeTransfer {
225
+ // When the transfer arrived at the governance canister.
226
+ uint64 transfer_timestamp = 1;
227
+ // The principal that made the transfer.
228
+ ic_base_types.pb.v1.PrincipalId from = 2;
229
+ // The (optional) subaccount from which the transfer was made.
230
+ bytes from_subaccount = 3;
231
+ // The subaccount to which the transfer was made.
232
+ bytes to_subaccount = 4;
233
+ // The amount of stake that was transferred.
234
+ uint64 neuron_stake_e8s = 5;
235
+ // The block height at which the transfer occurred.
236
+ uint64 block_height = 6;
237
+ // The memo sent with the transfer.
238
+ uint64 memo = 7;
239
+ }
240
+
241
+ // This structure represents a neuron "at rest" in governance system of
242
+ // the Internet Computer IC.
243
+ message Neuron {
244
+ // The id of the neuron.
245
+ //
246
+ // This is stored here temporarily, since its also stored on the map
247
+ // that contains neurons.
248
+ //
249
+ // Initialization uses ids for the following graph. We need neurons
250
+ // to come into existence at genesis with pre-chosen ids, so a
251
+ // neuron needs to have an id. We could alternatively choose a
252
+ // unique naming scheme instead and chose the ids on the
253
+ // initialization of the canister.
254
+ ic_nns_common.pb.v1.NeuronId id = 1;
255
+
256
+ // The principal of the ICP ledger account where the locked ICP
257
+ // balance resides. This principal is indistinguishable from one
258
+ // identifying a public key pair, such that those browsing the ICP
259
+ // ledger cannot tell which balances belong to neurons.
260
+ bytes account = 2;
261
+
262
+ // The principal that actually controls the neuron. The principal
263
+ // must identify a public key pair, which acts as a “master key”,
264
+ // such that the corresponding secret key should be kept very
265
+ // secure. The principal may control many neurons.
266
+ ic_base_types.pb.v1.PrincipalId controller = 3;
267
+
268
+ // Keys that can be used to perform actions with limited privileges
269
+ // without exposing the secret key corresponding to the principal
270
+ // e.g. could be a WebAuthn key.
271
+ repeated ic_base_types.pb.v1.PrincipalId hot_keys = 4;
272
+
273
+ // The amount of staked ICP tokens, measured in fractions of 10E-8
274
+ // of an ICP.
275
+ //
276
+ // Cached record of the locked ICP balance on the ICP ledger.
277
+ //
278
+ // For neuron creation: has to contain some minimum amount. A
279
+ // spawned neuron with less stake cannot increase its dissolve
280
+ // delay.
281
+ uint64 cached_neuron_stake_e8s = 5;
282
+
283
+ // The amount of ICP that this neuron has forfeited due to making
284
+ // proposals that were subsequently rejected or from using the
285
+ // 'manage neurons through proposals' functionality. Must be smaller
286
+ // than 'neuron_stake_e8s'. When a neuron is disbursed, these ICP
287
+ // will be burned.
288
+ uint64 neuron_fees_e8s = 6;
289
+
290
+ // When the Neuron was created. A neuron can only vote on proposals
291
+ // submitted after its creation date.
292
+ uint64 created_timestamp_seconds = 7;
293
+
294
+ // The timestamp, in seconds from the Unix epoch, corresponding to
295
+ // the time this neuron has started aging. This is either the
296
+ // creation time or the last time at which the neuron has stopped
297
+ // dissolving.
298
+ //
299
+ // This value is meaningless when the neuron is dissolving, since a
300
+ // dissolving neurons always has age zero. The canonical value of
301
+ // this field for a dissolving neuron is `u64::MAX`.
302
+ uint64 aging_since_timestamp_seconds = 8;
303
+
304
+ // The timestamp, in seconds from the Unix epoch, at which this
305
+ // neuron should be spawned and its maturity converted to ICP
306
+ // according to https://wiki.internetcomputer.org/wiki/Maturity_modulation.
307
+ optional uint64 spawn_at_timestamp_seconds = 19;
308
+
309
+ // At any time, at most one of `when_dissolved` and
310
+ // `dissolve_delay` are specified.
311
+ //
312
+ // `NotDissolving`. This is represented by `dissolve_delay` being
313
+ // set to a non zero value.
314
+ //
315
+ // `Dissolving`. This is represented by `when_dissolved` being
316
+ // set, and this value is in the future.
317
+ //
318
+ // `Dissolved`. All other states represent the dissolved
319
+ // state. That is, (a) `when_dissolved` is set and in the past,
320
+ // (b) `dissolve_delay` is set to zero, (c) neither value is set.
321
+ //
322
+ // Cf. [Neuron::stop_dissolving] and [Neuron::start_dissolving].
323
+ oneof dissolve_state {
324
+ // When the dissolve timer is running, this stores the timestamp,
325
+ // in seconds from the Unix epoch, at which the neuron becomes
326
+ // dissolved.
327
+ //
328
+ // At any time while the neuron is dissolving, the neuron owner
329
+ // may pause dissolving, in which case `dissolve_delay_seconds`
330
+ // will get assigned to: `when_dissolved_timestamp_seconds -
331
+ // <timestamp when the action is taken>`.
332
+ uint64 when_dissolved_timestamp_seconds = 9;
333
+ // When the dissolve timer is stopped, this stores how much time,
334
+ // in seconds, the dissolve timer will be started with. Can be at
335
+ // most 8 years.
336
+ //
337
+ // At any time while in this state, the neuron owner may (re)start
338
+ // dissolving, in which case `when_dissolved_timestamp_seconds`
339
+ // will get assigned to: `<timestamp when the action is taken> +
340
+ // dissolve_delay_seconds`.
341
+ uint64 dissolve_delay_seconds = 10;
342
+ }
343
+
344
+ // Protobuf representing a list of followees of a neuron for a
345
+ // specific topic.
346
+ message Followees {
347
+ repeated ic_nns_common.pb.v1.NeuronId followees = 1;
348
+ }
349
+
350
+ // Map `Topic` to followees. The key is represented by an integer as
351
+ // Protobuf does not support enum keys in maps.
352
+ map<int32, Followees> followees = 11;
353
+
354
+ // Information about how this neuron voted in the recent past. It
355
+ // only contains proposals that the neuron voted yes or no on.
356
+ repeated BallotInfo recent_ballots = 12;
357
+
358
+ // `true` if this neuron has passed KYC, `false` otherwise
359
+ bool kyc_verified = 13;
360
+
361
+ // The record of the transfer that was made to create this neuron.
362
+ NeuronStakeTransfer transfer = 14;
363
+
364
+ // The accumulated unstaked maturity of the neuron, in "e8s equivalent".
365
+ //
366
+ // The unit is "e8s equivalent" to insist that, while this quantity is on
367
+ // the same scale as ICPs, maturity is not directly convertible to ICPs:
368
+ // conversion requires a minting event and the conversion rate is variable.
369
+ uint64 maturity_e8s_equivalent = 15;
370
+
371
+ // The accumulated staked maturity of the neuron, in "e8s equivalent" (see
372
+ // "maturity_e8s_equivalent"). Staked maturity becomes regular maturity once
373
+ // the neuron is dissolved.
374
+ //
375
+ // Contrary to `maturity_e8s_equivalent` this maturity is staked and thus
376
+ // locked until the neuron is dissolved and contributes to voting power
377
+ // and rewards. Once the neuron is dissolved, this maturity will be "moved"
378
+ // to 'maturity_e8s_equivalent' and will be able to be spawned (with maturity
379
+ // modulation).
380
+ optional uint64 staked_maturity_e8s_equivalent = 20;
381
+
382
+ // If set and true the maturity rewarded to this neuron for voting will be
383
+ // automatically staked and will contribute to the neuron's voting power.
384
+ optional bool auto_stake_maturity = 21;
385
+
386
+ // Whether this neuron is "Not for profit", making it dissolvable
387
+ // by voting.
388
+ bool not_for_profit = 16;
389
+
390
+ // If set, this neuron is a member of the Community Fund. This means that when
391
+ // a proposal to open an SNS token swap is executed, maturity from this neuron
392
+ // will be used to participate in the SNS token swap.
393
+ optional uint64 joined_community_fund_timestamp_seconds = 17;
394
+
395
+ // If set, the neuron belongs to the "known neurons". It has been given a name and maybe a description.
396
+ optional KnownNeuronData known_neuron_data = 18;
397
+
398
+ // The type of the Neuron. See [NeuronType] for a description
399
+ // of the different states.
400
+ optional NeuronType neuron_type = 22;
401
+ }
402
+
403
+ // Subset of Neuron that has no collections or big fields that might not exist in most neurons, and
404
+ // the goal is to keep the size of the struct consistent and can be easily stored in a
405
+ // StableBTreeMap. For the meaning of each field, see the Neuron struct.
406
+ message AbridgedNeuron {
407
+ bytes account = 2;
408
+ ic_base_types.pb.v1.PrincipalId controller = 3;
409
+ uint64 cached_neuron_stake_e8s = 5;
410
+ uint64 neuron_fees_e8s = 6;
411
+ uint64 created_timestamp_seconds = 7;
412
+ uint64 aging_since_timestamp_seconds = 8;
413
+ optional uint64 spawn_at_timestamp_seconds = 19;
414
+ oneof dissolve_state {
415
+ uint64 when_dissolved_timestamp_seconds = 9;
416
+ uint64 dissolve_delay_seconds = 10;
417
+ }
418
+ bool kyc_verified = 13;
419
+ uint64 maturity_e8s_equivalent = 15;
420
+ optional uint64 staked_maturity_e8s_equivalent = 20;
421
+ optional bool auto_stake_maturity = 21;
422
+ bool not_for_profit = 16;
423
+ optional uint64 joined_community_fund_timestamp_seconds = 17;
424
+ optional NeuronType neuron_type = 22;
425
+
426
+ reserved 1;
427
+ reserved "id";
428
+ }
429
+
430
+ // Types of a Neuron.
431
+ enum NeuronType {
432
+ // Placeholder value due to the proto3 requirement for a zero default.
433
+ // This is an invalid type; neurons should not be assigned this value.
434
+ NEURON_TYPE_UNSPECIFIED = 0;
435
+
436
+ // Represents neurons initially created for Seed accounts in the
437
+ // Genesis Token Canister, or those descended from such neurons.
438
+ NEURON_TYPE_SEED = 1;
439
+
440
+ // Represents neurons initially created for Early Contributor Token (ECT)
441
+ // accounts in the Genesis Token Canister, or those descended from such neurons.
442
+ NEURON_TYPE_ECT = 2;
443
+ }
444
+
445
+ // The types of votes the Neuron can issue.
446
+ enum Vote {
447
+ // This exists because proto3 defaults to the 0 value on enums.
448
+ // This is not a valid choice, i.e., a vote with this choice will
449
+ // not be counted.
450
+ VOTE_UNSPECIFIED = 0;
451
+ // Vote for the proposal to be adopted.
452
+ VOTE_YES = 1;
453
+ // Vote for the proposal to be rejected.
454
+ VOTE_NO = 2;
455
+ }
456
+
457
+ // List of NNS functions that can be called by proposals.
458
+ enum NnsFunction {
459
+ // This exists because proto3 defaults to the 0 value on enums.
460
+ NNS_FUNCTION_UNSPECIFIED = 0;
461
+ // Combine a specified set of nodes, typically drawn from data centers and
462
+ // operators in such a way as to guarantee their independence, into a new
463
+ // decentralized subnet.
464
+ // The execution of this NNS function first initiates a new instance of
465
+ // the distributed key generation protocol. The transcript of that protocol
466
+ // is written to a new subnet record in the registry, together with initial
467
+ // configuration information for the subnet, from where the nodes comprising
468
+ // the subnet pick it up.
469
+ NNS_FUNCTION_CREATE_SUBNET = 1;
470
+ // Add a new node to a subnet. The node cannot be currently assigned to a
471
+ // subnet.
472
+ // The execution of this proposal changes an existing subnet record to add
473
+ // a node. From the perspective of the NNS, this update is a simple update
474
+ // of the subnet record in the registry.
475
+ NNS_FUNCTION_ADD_NODE_TO_SUBNET = 2;
476
+ // A proposal to add a new canister to be installed and executed in the
477
+ // NNS subnetwork.
478
+ // The root canister, which controls all canisters on the NNS except for
479
+ // itself, handles this proposal type. The call also expects the Wasm module
480
+ // that shall be installed.
481
+ NNS_FUNCTION_NNS_CANISTER_INSTALL = 3;
482
+ // A proposal to upgrade an existing canister in the NNS subnetwork.
483
+ // This proposal type is executed by the root canister. Beyond upgrading
484
+ // the Wasm module of the target canister, the proposal can also set the
485
+ // authorization information and the allocations.
486
+ NNS_FUNCTION_NNS_CANISTER_UPGRADE = 4;
487
+ // A proposal to bless a new version to which the replicas can be
488
+ // upgraded.
489
+ // The proposal registers a replica version (identified by the hash of the
490
+ // installation image) in the registry. Besides creating a record for that
491
+ // version, the proposal also appends that version to the list of "blessed
492
+ // versions" that can be installed on a subnet. By itself, this proposal
493
+ // does not effect any upgrade.
494
+ NNS_FUNCTION_BLESS_REPLICA_VERSION = 5;
495
+ // Update a subnet's recovery CUP (used to recover subnets that have stalled).
496
+ // Nodes that find a recovery CUP for their subnet will load that CUP from
497
+ // the registry and restart the replica from that CUP.
498
+ NNS_FUNCTION_RECOVER_SUBNET = 6;
499
+ // Update a subnet's configuration.
500
+ // This proposal updates the subnet record in the registry, with the changes
501
+ // being picked up by the nodes on the subnet when they reference the
502
+ // respective registry version. Subnet configuration comprises protocol
503
+ // parameters that must be consistent across the subnet (e.g. message sizes).
504
+ NNS_FUNCTION_UPDATE_CONFIG_OF_SUBNET = 7;
505
+ // Assign an identity to a node operator, such as a funding partner,
506
+ // associating key information regarding its ownership, the jurisdiction
507
+ // in which it is located, and other information.
508
+ // The node operator is stored as a record in the registry. It contains
509
+ // the remaining node allowance for that node operator, that is the number
510
+ // of nodes the node operator can still add to the IC. When an additional
511
+ // node is added by the node operator, the remaining allowance is decreased.
512
+ NNS_FUNCTION_ASSIGN_NOID = 8;
513
+ // A proposal to upgrade the root canister in the NNS subnetwork.
514
+ // The proposal is processed by the Lifeline canister, which controls the
515
+ // root canister. The proposal updates the Wasm module as well as the
516
+ // authorization settings.
517
+ NNS_FUNCTION_NNS_ROOT_UPGRADE = 9;
518
+ // Update the ICP/XDR conversion rate.
519
+ // Changes the ICP-to-XDR conversion rate in the governance canister. This
520
+ // setting affects cycles pricing (as the value of cycles shall be constant
521
+ // with respect to IMF SDRs) as well as the rewards paid for nodes, which
522
+ // are expected to be specified in terms of IMF SDRs as well.
523
+ NNS_FUNCTION_ICP_XDR_CONVERSION_RATE = 10;
524
+ // Deploy a GuestOS version to a given subnet. The proposal changes the GuestOS version that is
525
+ // used on the specified subnet. The version must be contained in the list of elected GuestOS
526
+ // versions. The upgrade is completed when the subnet creates the next regular CUP.
527
+ NNS_FUNCTION_DEPLOY_GUESTOS_TO_ALL_SUBNET_NODES = 11;
528
+ // Clear the provisional whitelist.
529
+ // The proposal changes the provisional whitelist to the empty list.
530
+ NNS_FUNCTION_CLEAR_PROVISIONAL_WHITELIST = 12;
531
+ // Removes a node from a subnet. The node must be currently assigned to a
532
+ // subnet.
533
+ // The execution of this proposal changes an existing subnet record to remove
534
+ // a node. From the perspective of the NNS, this update is a simple update
535
+ // of the subnet record in the registry.
536
+ NNS_FUNCTION_REMOVE_NODES_FROM_SUBNET = 13;
537
+ // Informs the cycles minting canister that a certain principal is
538
+ // authorized to use certain subnetworks (from a list). Can also be
539
+ // used to set the "default" list of subnetworks that principals
540
+ // without special authorization are allowed to use.
541
+ NNS_FUNCTION_SET_AUTHORIZED_SUBNETWORKS = 14;
542
+ // Change the Firewall configuration in the registry. (TODO: Remove when IC-1026 is fully integrated)
543
+ NNS_FUNCTION_SET_FIREWALL_CONFIG = 15;
544
+ // Change a Node Operator's allowance in the registry.
545
+ NNS_FUNCTION_UPDATE_NODE_OPERATOR_CONFIG = 16;
546
+ // Stop or start an NNS canister.
547
+ NNS_FUNCTION_STOP_OR_START_NNS_CANISTER = 17;
548
+ // Remove unassigned nodes from the registry.
549
+ NNS_FUNCTION_REMOVE_NODES = 18;
550
+ // Uninstall code of a canister.
551
+ NNS_FUNCTION_UNINSTALL_CODE = 19;
552
+ // Update the node rewards table.
553
+ NNS_FUNCTION_UPDATE_NODE_REWARDS_TABLE = 20;
554
+ // Add or remove Data Center records.
555
+ NNS_FUNCTION_ADD_OR_REMOVE_DATA_CENTERS = 21;
556
+ // (obsolete) Update the config for all unassigned nodes.
557
+ NNS_FUNCTION_UPDATE_UNASSIGNED_NODES_CONFIG = 22;
558
+ // Remove Node Operator from the registry.
559
+ NNS_FUNCTION_REMOVE_NODE_OPERATORS = 23;
560
+ // Update the routing table in the registry.
561
+ NNS_FUNCTION_REROUTE_CANISTER_RANGES = 24;
562
+ // Add firewall rules in the registry
563
+ NNS_FUNCTION_ADD_FIREWALL_RULES = 25;
564
+ // Remove firewall rules in the registry
565
+ NNS_FUNCTION_REMOVE_FIREWALL_RULES = 26;
566
+ // Update firewall rules in the registry
567
+ NNS_FUNCTION_UPDATE_FIREWALL_RULES = 27;
568
+ // Insert or update `canister_migrations` entries.
569
+ NNS_FUNCTION_PREPARE_CANISTER_MIGRATION = 28;
570
+ // Remove `canister_migrations` entries.
571
+ NNS_FUNCTION_COMPLETE_CANISTER_MIGRATION = 29;
572
+ // Add a new SNS canister WASM
573
+ NNS_FUNCTION_ADD_SNS_WASM = 30;
574
+ // Change the subnet node membership. In a way, this function combines the separate
575
+ // functions for adding and removing nodes from the subnet record, but adds the property
576
+ // of atomic node replacement (node swap) on top.
577
+ //
578
+ // The nodes that are being added to the subnet must be currently unassigned.
579
+ // The nodes that are being removed from the subnet must be currently assigned to the subnet.
580
+ NNS_FUNCTION_CHANGE_SUBNET_MEMBERSHIP = 31;
581
+ // Updates the available subnet types in the cycles minting canister.
582
+ NNS_FUNCTION_UPDATE_SUBNET_TYPE = 32;
583
+ // Changes the assignment of subnets to subnet types in the cycles minting
584
+ // canister.
585
+ NNS_FUNCTION_CHANGE_SUBNET_TYPE_ASSIGNMENT = 33;
586
+ // Update the list of SNS subnet IDs that SNS WASM will deploy SNS instances to.
587
+ NNS_FUNCTION_UPDATE_SNS_WASM_SNS_SUBNET_IDS = 34;
588
+ // Update the SNS-wasm canister's list of allowed principals. This list guards which principals can deploy an SNS.
589
+ NNS_FUNCTION_UPDATE_ALLOWED_PRINCIPALS = 35;
590
+ // A proposal to retire previously elected and unused replica versions.
591
+ // The specified versions are removed from the registry and the "blessed versions" record.
592
+ // This ensures that the replica cannot upgrade to these versions anymore.
593
+ NNS_FUNCTION_RETIRE_REPLICA_VERSION = 36;
594
+ // Insert custom upgrade path entries into SNS-W for all SNSes, or for an SNS specified by its governance canister ID.
595
+ NNS_FUNCTION_INSERT_SNS_WASM_UPGRADE_PATH_ENTRIES = 37;
596
+ // A proposal to change the set of elected GuestOS versions. The version to elect (identified by
597
+ // the hash of the installation image) is added to the registry. Besides creating a record for
598
+ // that version, the proposal also appends that version to the list of elected versions that can
599
+ // be installed on nodes of a subnet. Only elected GuestOS versions can be deployed.
600
+ NNS_FUNCTION_REVISE_ELECTED_GUESTOS_VERSIONS = 38;
601
+
602
+ NNS_FUNCTION_BITCOIN_SET_CONFIG = 39;
603
+
604
+ // OBSOLETE: use NNS_FUNCTION_REVISE_ELECTED_HOSTOS_VERSIONS instead
605
+ NNS_FUNCTION_UPDATE_ELECTED_HOSTOS_VERSIONS = 40;
606
+ // OBSOLETE: use NNS_FUNCTION_UPGRADE_HOSTOS_FOR_SOME_NODES instead
607
+ NNS_FUNCTION_UPDATE_NODES_HOSTOS_VERSION = 41;
608
+
609
+ // Uninstall and Install Root with the WASM provided in the function. If InitArgs are provided
610
+ // They will be passed to the canister_init function of the WASM provided.
611
+ // This function is meant as a Break Glass mechanism for when an open call context in
612
+ // the Root canister is preventing root or another canister from upgrading (in the case of proxied calls).
613
+ NNS_FUNCTION_HARD_RESET_NNS_ROOT_TO_VERSION = 42;
614
+
615
+ // A proposal to add a set of new API Boundary Nodes using unassigned nodes
616
+ NNS_FUNCTION_ADD_API_BOUNDARY_NODES = 43;
617
+
618
+ // A proposal to remove a set of API Boundary Nodes, which will designate them as unassigned nodes
619
+ NNS_FUNCTION_REMOVE_API_BOUNDARY_NODES = 44;
620
+
621
+ reserved 45;
622
+ reserved "NNS_FUNCTION_UPDATE_API_BOUNDARY_NODE_DOMAIN";
623
+
624
+ // (obsolete) A proposal to update the version of a set of API Boundary Nodes
625
+ NNS_FUNCTION_UPDATE_API_BOUNDARY_NODES_VERSION = 46;
626
+
627
+ // A proposal to update the version of a set of API Boundary Nodes
628
+ NNS_FUNCTION_DEPLOY_GUESTOS_TO_SOME_API_BOUNDARY_NODES = 47;
629
+
630
+ // A proposal to update the version of all unassigned nodes
631
+ NNS_FUNCTION_DEPLOY_GUESTOS_TO_ALL_UNASSIGNED_NODES = 48;
632
+
633
+ // A proposal to update SSH readonly access for all unassigned nodes
634
+ NNS_FUNCTION_UPDATE_SSH_READONLY_ACCESS_FOR_ALL_UNASSIGNED_NODES = 49;
635
+
636
+ // A proposal to change the set of currently elected HostOS versions, by electing a new version,
637
+ // and/or unelecting some priorly elected versions. HostOS versions are identified by the hash
638
+ // of the installation image. The version to elect is added to the Registry, and the versions
639
+ // to unelect are removed from the Registry, ensuring that HostOS cannot upgrade to these versions
640
+ // anymore. This proposal does not actually perform the upgrade; for deployment of an elected
641
+ // version, please refer to `NNS_FUNCTION_DEPLOY_HOSTOS_TO_SOME_NODES`.
642
+ NNS_FUNCTION_REVISE_ELECTED_HOSTOS_VERSIONS = 50;
643
+
644
+ // Deploy a HostOS version to a given set of nodes. The proposal changes the HostOS version that
645
+ // is used on the specified nodes.
646
+ NNS_FUNCTION_DEPLOY_HOSTOS_TO_SOME_NODES = 51;
647
+ }
648
+
649
+ // Payload of a proposal that calls a function on another NNS
650
+ // canister. The canister and function to call is derived from the
651
+ // `nns_function`.
652
+ message ExecuteNnsFunction {
653
+ // This enum value determines what canister to call and what NNS
654
+ // function to call on that canister.
655
+ NnsFunction nns_function = 1;
656
+ // The payload of the NNS function.
657
+ bytes payload = 2;
658
+ }
659
+
660
+ // If adopted, a motion should guide the future strategy of the
661
+ // Internet Computer ecosystem.
662
+ message Motion {
663
+ // The text of the motion. Maximum 100kib.
664
+ string motion_text = 1;
665
+ }
666
+
667
+ // For all Neurons controlled by the given principals, set their
668
+ // KYC status to `kyc_verified=true`.
669
+ message ApproveGenesisKYC {
670
+ repeated ic_base_types.pb.v1.PrincipalId principals = 1;
671
+ }
672
+
673
+ // Adds and/or removes NodeProviders from the list of current
674
+ // node providers.
675
+ message AddOrRemoveNodeProvider {
676
+ oneof change {
677
+ NodeProvider to_add = 1;
678
+ NodeProvider to_remove = 2;
679
+ }
680
+ }
681
+
682
+ // This proposal payload is used to reward a node provider by minting
683
+ // ICPs directly to the node provider's ledger account, or into a new
684
+ // neuron created on behalf of the node provider.
685
+ message RewardNodeProvider {
686
+ // The NodeProvider to reward.
687
+ NodeProvider node_provider = 1;
688
+ // The amount of e8s to mint to reward the node provider.
689
+ uint64 amount_e8s = 2;
690
+ // This message specifies how to create a new neuron on behalf of
691
+ // the node provider.
692
+ //
693
+ // - The controller of the new neuron is the node provider's
694
+ // principal.
695
+ //
696
+ // - The account is chosen at random.
697
+ //
698
+ // - The stake of the new neuron is `amount_e8s`.
699
+ //
700
+ // - `dissolve_delay_seconds` is as specified in the proto.
701
+ //
702
+ // - `kyc_verified` is set to true, as node providers are
703
+ // (implicitly) KYC'ed.
704
+ //
705
+ // - `not_for_profit` is set to false.
706
+ //
707
+ // - All other values are set as for other neurons: timestamp is
708
+ // now, following is set up per default, maturity is 0, neuron fee
709
+ // is 0.
710
+ message RewardToNeuron {
711
+ uint64 dissolve_delay_seconds = 1;
712
+ }
713
+
714
+ message RewardToAccount {
715
+ ic_ledger.pb.v1.AccountIdentifier to_account = 1;
716
+ }
717
+
718
+ oneof reward_mode {
719
+ // If this is specified, executing this proposal will create a
720
+ // neuron instead of directly minting ICP into the node provider's
721
+ // account.
722
+ RewardToNeuron reward_to_neuron = 4;
723
+ // If this is specified, executing this proposal will mint to the
724
+ // specified account.
725
+ RewardToAccount reward_to_account = 5;
726
+ }
727
+
728
+ reserved 3;
729
+ reserved "create_neuron";
730
+ }
731
+
732
+ message RewardNodeProviders {
733
+ repeated RewardNodeProvider rewards = 1;
734
+
735
+ // If true, reward Node Providers with the rewards returned by the Registry's
736
+ // get_node_providers_monthly_xdr_rewards method
737
+ optional bool use_registry_derived_rewards = 2;
738
+ }
739
+
740
+ // Changes the default followees to match the one provided.
741
+ // This completely replaces the default followees so entries for all
742
+ // Topics (except ManageNeuron) must be provided on each proposal.
743
+ message SetDefaultFollowees {
744
+ map<int32, Neuron.Followees> default_followees = 1;
745
+ }
746
+
747
+ // Obsolete. Superseded by OpenSnsTokenSwap.
748
+ message SetSnsTokenSwapOpenTimeWindow {
749
+ // The swap canister to send the request to.
750
+ ic_base_types.pb.v1.PrincipalId swap_canister_id = 1;
751
+
752
+ // Arguments that get sent to the swap canister when its set_open_time_window
753
+ // Candid method is called.
754
+ ic_sns_swap.pb.v1.SetOpenTimeWindowRequest request = 2;
755
+ }
756
+
757
+ // A proposal is the immutable input of a proposal submission. This contains
758
+ // all the information from the original proposal submission.
759
+ //
760
+ // Making a proposal implicitly votes yes.
761
+ message Proposal {
762
+ // Must be present (enforced at the application layer, not by PB).
763
+ // A brief description of what the proposal does.
764
+ // Size in bytes must be in the interval [5, 256].
765
+ optional string title = 20;
766
+
767
+ // Text providing a short description of the proposal, composed
768
+ // using a maximum of 30000 bytes of characters.
769
+ string summary = 1;
770
+
771
+ // The Web address of additional content required to evaluate the
772
+ // proposal, specified using HTTPS. For example, the address might
773
+ // describe content supporting the assignment of a DCID (data center
774
+ // id) to a new data center. The URL string must not be longer than
775
+ // 2000 bytes.
776
+ string url = 2;
777
+
778
+ // This section describes the action that the proposal proposes to
779
+ // take.
780
+ oneof action {
781
+ // This type of proposal calls a major function on a specified
782
+ // target neuron. Only the followees of the target neuron (on the
783
+ // topic [Topic::ManageNeuron]) may vote on these proposals,
784
+ // which effectively provides the followees with control over the
785
+ // target neuron. This can provide a convenient and highly secure
786
+ // means for a team of individuals to manage an important
787
+ // neuron. For example, a neuron might hold a large balance, or
788
+ // belong to an organization of high repute, and be publicized so
789
+ // that many other neurons can follow its vote. In both cases,
790
+ // managing the private key of the principal securely could be
791
+ // problematic (either a single copy is held, which is very
792
+ // insecure and provides for a single party to take control, or a
793
+ // group of individuals must divide responsibility, for example
794
+ // using threshold cryptography, which is complex and time
795
+ // consuming). To address this, using this proposal type, the
796
+ // important neuron can be configured to follow the neurons
797
+ // controlled by individual members of a team. Now they can submit
798
+ // proposals to make the important neuron perform actions, which
799
+ // are adopted if and only if a majority of them vote to
800
+ // adopt. Nearly any command on the target neuron can be executed,
801
+ // including commands that change the follow rules, allowing the
802
+ // set of team members to be dynamic. Only the final step of
803
+ // dissolving the neuron once its dissolve delay reaches zero
804
+ // cannot be performed using this type of proposal (since this
805
+ // would allow control/“ownership” over the locked balances to be
806
+ // transferred). To prevent a neuron falling under the malign
807
+ // control of the principal’s private key by accident, the private
808
+ // key can be destroyed so that the neuron can only be controlled
809
+ // by its followees, although this makes it impossible to
810
+ // subsequently unlock the balance.
811
+ ManageNeuron manage_neuron = 10;
812
+ // Propose a change to some network parameters of network
813
+ // economics.
814
+ NetworkEconomics manage_network_economics = 12;
815
+ // See [Motion]
816
+ Motion motion = 13;
817
+ // A update affecting something outside of the Governance
818
+ // canister.
819
+ ExecuteNnsFunction execute_nns_function = 14;
820
+ // Approve Genesis KYC for a given list of principals.
821
+ ApproveGenesisKYC approve_genesis_kyc = 15;
822
+ // Add/remove NodeProvider from the list of NodeProviders
823
+ AddOrRemoveNodeProvider add_or_remove_node_provider = 16;
824
+ // Reward a NodeProvider
825
+ RewardNodeProvider reward_node_provider = 17;
826
+ // Set the default following
827
+ SetDefaultFollowees set_default_followees = 18;
828
+ // Reward multiple NodeProvider
829
+ RewardNodeProviders reward_node_providers = 19;
830
+ // Register Known Neuron
831
+ KnownNeuron register_known_neuron = 21;
832
+ // Obsolete. Superseded by CreateServiceNervousSystem. Kept for Candid compatibility.
833
+ SetSnsTokenSwapOpenTimeWindow set_sns_token_swap_open_time_window = 22 [deprecated = true];
834
+ // Call the open method on an SNS swap canister.
835
+ //
836
+ // This is still supported but will soon be superseded by
837
+ // CreateServiceNervousSystem.
838
+ OpenSnsTokenSwap open_sns_token_swap = 23 [deprecated = true];
839
+ // Create a new SNS.
840
+ CreateServiceNervousSystem create_service_nervous_system = 24;
841
+ }
842
+ }
843
+
844
+ // Empty message to use in oneof fields that represent empty
845
+ // enums.
846
+ message Empty {}
7
847
 
8
848
  // All operations that modify the state of an existing neuron are
9
849
  // represented by instances of `ManageNeuron`.
@@ -16,29 +856,54 @@ message ManageNeuron {
16
856
  option (ic_base_types.pb.v1.tui_signed_message) = true;
17
857
 
18
858
  // This is the legacy way to specify neuron IDs that is now discouraged.
19
- ic_base_types.pb.v1.NeuronId id = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
859
+ ic_nns_common.pb.v1.NeuronId id = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
20
860
 
21
861
  // The ID of the neuron to manage. This can either be a subaccount or a neuron ID.
22
862
  oneof neuron_id_or_subaccount {
23
863
  bytes subaccount = 11 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
24
- ic_base_types.pb.v1.NeuronId neuron_id = 12 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
864
+ ic_nns_common.pb.v1.NeuronId neuron_id = 12 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
25
865
  }
26
866
 
867
+ // The dissolve delay of a neuron can be increased up to a maximum
868
+ // of 8 years.
27
869
  message IncreaseDissolveDelay {
870
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
28
871
  uint32 additional_dissolve_delay_seconds = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
29
872
  }
30
-
31
873
  message StartDissolving {}
32
874
  message StopDissolving {}
33
-
875
+ // Add a new hot key that can be used to manage the neuron. This
876
+ // provides an alternative to using the controller principal’s cold key to
877
+ // manage the neuron, which might be onerous and difficult to keep
878
+ // secure, especially if it is used regularly. A hot key might be a
879
+ // WebAuthn key that is maintained inside a user device, such as a
880
+ // smartphone.
34
881
  message AddHotKey {
882
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
35
883
  ic_base_types.pb.v1.PrincipalId new_hot_key = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
36
884
  }
37
-
885
+ // Remove a hot key that has been previously assigned to the neuron.
38
886
  message RemoveHotKey {
887
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
39
888
  ic_base_types.pb.v1.PrincipalId hot_key_to_remove = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
40
889
  }
41
-
890
+ // An (idempotent) alternative to IncreaseDissolveDelay where the dissolve delay
891
+ // is passed as an absolute timestamp in seconds since the unix epoch.
892
+ message SetDissolveTimestamp {
893
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
894
+ uint64 dissolve_timestamp_seconds = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
895
+ }
896
+ // Join the Internet Computer's community fund with this neuron's present and future maturity.
897
+ message JoinCommunityFund {}
898
+ // Leave the Internet Computer's community fund.
899
+ message LeaveCommunityFund {}
900
+ // Changes auto-stake maturity for this Neuron. While on, auto-stake
901
+ // maturity will cause all the maturity generated by voting rewards
902
+ // to this neuron to be automatically staked and contribute to the
903
+ // voting power of the neuron.
904
+ message ChangeAutoStakeMaturity {
905
+ bool requested_setting_for_auto_stake_maturity = 1;
906
+ }
42
907
  // Commands that only configure a given neuron, but do not interact
43
908
  // with the outside world. They all require the caller to be the
44
909
  // controller of the neuron.
@@ -49,60 +914,168 @@ message ManageNeuron {
49
914
  StopDissolving stop_dissolving = 3;
50
915
  AddHotKey add_hot_key = 4;
51
916
  RemoveHotKey remove_hot_key = 5;
917
+ SetDissolveTimestamp set_dissolve_timestamp = 6;
52
918
  JoinCommunityFund join_community_fund = 7;
919
+ LeaveCommunityFund leave_community_fund = 8;
920
+ ChangeAutoStakeMaturity change_auto_stake_maturity = 9;
53
921
  }
54
922
  }
55
-
56
- message Spawn {
57
- ic_base_types.pb.v1.PrincipalId new_controller = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
58
- optional uint64 nonce = 2;
59
- optional uint32 percentage_to_spawn = 3;
60
- }
61
-
923
+ // Disburse this neuron's stake: transfer the staked ICP to the
924
+ // specified account.
62
925
  message Disburse {
63
926
  option (ic_base_types.pb.v1.tui_signed_message) = true;
64
927
  message Amount {
65
928
  option (ic_base_types.pb.v1.tui_signed_message) = true;
66
- uint64 e8s = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true, jstype = JS_STRING];
929
+ uint64 e8s = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
67
930
  }
931
+ // The (optional) amount to transfer. If not specified the cached
932
+ // stake is used.
68
933
  Amount amount = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
934
+ // The principal to which to transfer the stake.
69
935
  ic_ledger.pb.v1.AccountIdentifier to_account = 2 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
70
936
  }
71
937
 
72
- message Follow {
73
- Topic topic = 1;
74
- repeated ic_base_types.pb.v1.NeuronId followees = 2;
75
- }
76
-
77
- message RegisterVote {
78
- ic_base_types.pb.v1.ProposalId proposal = 1;
79
- Vote vote = 2;
938
+ // Split this neuron into two neurons.
939
+ //
940
+ // The child neuron retains the parent neuron's properties.
941
+ message Split {
942
+ // The amount to split to the child neuron.
943
+ uint64 amount_e8s = 1;
80
944
  }
81
945
 
82
946
  // Merge another neuron into this neuron.
83
947
  message Merge {
84
948
  // The neuron to merge stake and maturity from.
85
- ic_base_types.pb.v1.NeuronId source_neuron_id = 1;
949
+ ic_nns_common.pb.v1.NeuronId source_neuron_id = 1;
950
+ }
951
+
952
+ // When the maturity of a neuron has risen above a threshold, it can
953
+ // be instructed to spawn a new neuron. This creates a new neuron
954
+ // that locks a new balance of ICP on the ledger. The new neuron can
955
+ // remain controlled by the same principal as its parent, or be
956
+ // assigned to a new principal.
957
+ message Spawn {
958
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
959
+ // If not set, the spawned neuron will have the same controller as
960
+ // this neuron.
961
+ ic_base_types.pb.v1.PrincipalId new_controller = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
962
+ // The nonce with which to create the subaccount.
963
+ optional uint64 nonce = 2;
964
+ // The percentage to spawn, from 1 to 100 (inclusive).
965
+ optional uint32 percentage_to_spawn = 3;
86
966
  }
87
967
 
968
+ // Merge the maturity of a neuron into the current stake.
969
+ // The caller can choose a percentage of the current maturity to merge into
970
+ // the existing stake. The resulting amount to merge must be greater than
971
+ // or equal to the transaction fee.
88
972
  message MergeMaturity {
89
- uint32 percentage_to_merge = 1;
973
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
974
+ // The percentage to merge, from 1 to 100 (inclusive).
975
+ uint32 percentage_to_merge = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
90
976
  }
91
977
 
92
- message JoinCommunityFund {}
978
+ // Stake the maturity of a neuron.
979
+ // The caller can choose a percentage of of the current maturity to stake.
980
+ // If 'percentage_to_stake' is not provided, all of the neuron's current
981
+ // maturity will be staked.
982
+ message StakeMaturity {
983
+ // The percentage of maturity to stake, from 1 to 100 (inclusive).
984
+ optional uint32 percentage_to_stake = 1;
985
+ }
986
+
987
+ // Disburse a portion of this neuron's stake into another neuron.
988
+ // This allows to split a neuron but with a new dissolve delay
989
+ // and owned by someone else.
990
+ message DisburseToNeuron {
991
+ // The controller of the new neuron (must be set).
992
+ ic_base_types.pb.v1.PrincipalId new_controller = 1;
993
+ // The amount to disburse.
994
+ uint64 amount_e8s = 2;
995
+ // The dissolve delay of the new neuron.
996
+ uint64 dissolve_delay_seconds = 3;
997
+ // Whether the new neuron has been kyc verified.
998
+ bool kyc_verified = 4;
999
+ // The nonce with which to create the subaccount.
1000
+ uint64 nonce = 5;
1001
+ }
1002
+
1003
+ // Add a rule that enables the neuron to vote automatically on
1004
+ // proposals that belong to a specific topic, by specifying a group
1005
+ // of followee neurons whose majority vote is followed. The
1006
+ // configuration of such follow rules can be used to a) distribute
1007
+ // control over voting power amongst multiple entities, b) have a
1008
+ // neuron vote automatically when its owner lacks time to evaluate
1009
+ // newly submitted proposals, c) have a neuron vote automatically
1010
+ // when its own lacks the expertise to evaluate newly submitted
1011
+ // proposals, and d) for other purposes. A follow rule specifies a
1012
+ // set of followees. Once a majority of the followees votes to adopt
1013
+ // or reject a proposal belonging to the specified topic, the neuron
1014
+ // votes the same way. If it becomes impossible for a majority of
1015
+ // the followees to adopt (for example, because they are split 50-50
1016
+ // between adopt and reject), then the neuron votes to reject. If a
1017
+ // rule is specified where the proposal topic is UNSPECIFIED, then it
1018
+ // becomes a catch-all follow rule, which will be used to vote
1019
+ // automatically on proposals belonging to topics for which no
1020
+ // specific rule has been specified.
1021
+ //
1022
+ // If the list 'followees' is empty, this removes following for a
1023
+ // specific topic.
1024
+ message Follow {
1025
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
1026
+ // Topic UNSPECIFIED means add following for the 'catch all'.
1027
+ Topic topic = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
1028
+ repeated ic_nns_common.pb.v1.NeuronId followees = 2 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
1029
+ }
1030
+ // Have the neuron vote to either adopt or reject a proposal with a specified
1031
+ // id.
1032
+ message RegisterVote {
1033
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
1034
+ ic_nns_common.pb.v1.ProposalId proposal = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
1035
+ Vote vote = 2 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
1036
+ }
1037
+
1038
+ // Claim a new neuron or refresh the stake of an existing neuron.
1039
+ message ClaimOrRefresh {
1040
+ message MemoAndController {
1041
+ uint64 memo = 1;
1042
+ ic_base_types.pb.v1.PrincipalId controller = 2;
1043
+ }
1044
+
1045
+ oneof by {
1046
+ // DEPRECATED: Use MemoAndController and omit the controller.
1047
+ uint64 memo = 1;
1048
+
1049
+ // Claim or refresh a neuron, by providing the memo used in the
1050
+ // staking transfer and 'controller' as the principal id used to
1051
+ // calculate the subaccount to which the transfer was made. If
1052
+ // 'controller' is omitted, the principal id of the caller is
1053
+ // used.
1054
+ MemoAndController memo_and_controller = 2;
1055
+
1056
+ // This just serves as a tag to indicate that the neuron should be
1057
+ // refreshed by it's id or subaccount. This does not work to claim
1058
+ // new neurons.
1059
+ Empty neuron_id_or_subaccount = 3;
1060
+ }
1061
+ }
93
1062
 
94
1063
  oneof command {
95
1064
  Configure configure = 2;
96
1065
  Disburse disburse = 3;
97
1066
  Spawn spawn = 4;
98
1067
  Follow follow = 5;
1068
+ Proposal make_proposal = 6;
99
1069
  RegisterVote register_vote = 7;
1070
+ Split split = 8;
1071
+ DisburseToNeuron disburse_to_neuron = 9;
1072
+ ClaimOrRefresh claim_or_refresh = 10;
100
1073
  MergeMaturity merge_maturity = 13;
101
1074
  Merge merge = 14;
1075
+ StakeMaturity stake_maturity = 15;
102
1076
  }
103
1077
  }
104
1078
 
105
-
106
1079
  // The response of the ManageNeuron command
107
1080
  //
108
1081
  // There is a dedicated response type for each `ManageNeuron.command` field
@@ -110,23 +1083,60 @@ message ManageNeuronResponse {
110
1083
  message ConfigureResponse {}
111
1084
 
112
1085
  message DisburseResponse {
113
- uint64 transfer_block_height = 1 [jstype = JS_STRING];
1086
+ // The block height at which the disburse transfer happened
1087
+ uint64 transfer_block_height = 1;
114
1088
  }
115
1089
 
116
1090
  message SpawnResponse {
117
- ic_base_types.pb.v1.NeuronId created_neuron_id = 1;
1091
+ // The ID of the Neuron created from spawning a Neuron
1092
+ ic_nns_common.pb.v1.NeuronId created_neuron_id = 1;
118
1093
  }
119
1094
 
120
1095
  message MergeMaturityResponse {
121
- uint64 merged_maturity_e8s = 1 [jstype = JS_STRING];
122
- uint64 new_stake_e8s = 2 [jstype = JS_STRING];
1096
+ uint64 merged_maturity_e8s = 1;
1097
+ uint64 new_stake_e8s = 2;
1098
+ }
1099
+
1100
+ message StakeMaturityResponse {
1101
+ uint64 maturity_e8s = 1;
1102
+ uint64 staked_maturity_e8s = 2;
123
1103
  }
124
1104
 
125
1105
  message FollowResponse {}
126
1106
 
1107
+ message MakeProposalResponse {
1108
+ // The ID of the created proposal
1109
+ ic_nns_common.pb.v1.ProposalId proposal_id = 1;
1110
+ optional string message = 2;
1111
+ }
1112
+
127
1113
  message RegisterVoteResponse {}
128
1114
 
129
- message MergeResponse {}
1115
+ message SplitResponse {
1116
+ // The ID of the Neuron created from splitting another Neuron
1117
+ ic_nns_common.pb.v1.NeuronId created_neuron_id = 1;
1118
+ }
1119
+
1120
+ // A response for merging or simulating merge neurons
1121
+ message MergeResponse {
1122
+ // The resulting state of the source neuron
1123
+ Neuron source_neuron = 1;
1124
+ // The resulting state of the target neuron
1125
+ Neuron target_neuron = 2;
1126
+ // The NeuronInfo of the source neuron
1127
+ NeuronInfo source_neuron_info = 3;
1128
+ // The NeuronInfo of the target neuron
1129
+ NeuronInfo target_neuron_info = 4;
1130
+ }
1131
+
1132
+ message DisburseToNeuronResponse {
1133
+ // The ID of the Neuron created from disbursing a Neuron
1134
+ ic_nns_common.pb.v1.NeuronId created_neuron_id = 1;
1135
+ }
1136
+
1137
+ message ClaimOrRefreshResponse {
1138
+ ic_nns_common.pb.v1.NeuronId refreshed_neuron_id = 1;
1139
+ }
130
1140
 
131
1141
  oneof command {
132
1142
  GovernanceError error = 1;
@@ -134,160 +1144,1489 @@ message ManageNeuronResponse {
134
1144
  DisburseResponse disburse = 3;
135
1145
  SpawnResponse spawn = 4;
136
1146
  FollowResponse follow = 5;
1147
+ MakeProposalResponse make_proposal = 6;
137
1148
  RegisterVoteResponse register_vote = 7;
1149
+ SplitResponse split = 8;
1150
+ DisburseToNeuronResponse disburse_to_neuron = 9;
1151
+ ClaimOrRefreshResponse claim_or_refresh = 10;
138
1152
  MergeMaturityResponse merge_maturity = 11;
139
1153
  MergeResponse merge = 12;
1154
+ StakeMaturityResponse stake_maturity = 13;
140
1155
  }
141
1156
  }
142
1157
 
143
1158
  message GovernanceError {
144
1159
  enum ErrorType {
145
- ERROR_TYPE_UNSPECIFIED = 0;
146
- // The operation was successfully completed.
147
- ERROR_TYPE_OK = 1;
148
- // This operation is not available, e.g., not implemented.
149
- ERROR_TYPE_UNAVAILABLE = 2;
150
- // The caller is not authorized to perform this operation.
151
- ERROR_TYPE_NOT_AUTHORIZED = 3;
152
- // Some entity required for the operation (for example, a neuron) was not found.
153
- ERROR_TYPE_NOT_FOUND = 4;
154
- // The command was missing or invalid. This is a permanent error.
155
- ERROR_TYPE_INVALID_COMMAND = 5;
156
- // The neuron is dissolving or dissolved and the operation requires it to
157
- // be not dissolving (that is, having a non-zero dissolve delay that is
158
- // accumulating age).
159
- ERROR_TYPE_REQUIRES_NOT_DISSOLVING = 6;
160
- // The neuron is not dissolving or dissolved and the operation requires
161
- // it to be dissolving (that is, having a non-zero dissolve delay with
162
- // zero age that is not accumulating).
163
- ERROR_TYPE_REQUIRES_DISSOLVING = 7;
164
- // The neuron is not dissolving and not dissolved and the operation
165
- // requires it to be dissolved (that is, having a dissolve delay of zero
166
- // and an age of zero).
167
- ERROR_TYPE_REQUIRES_DISSOLVED = 8;
168
- // When adding or removing a hot key: the key to add was already
169
- // present or the key to remove was not present or the key to add
170
- // was invalid or adding another hot key would bring the total
171
- // number of the maximum number of allowed hot keys per neuron.
172
- ERROR_TYPE_HOT_KEY = 9;
173
- // Some canister side resource is exhausted, so this operation cannot be
174
- // performed.
175
- ERROR_TYPE_RESOURCE_EXHAUSTED = 10;
176
- // Some precondition for executing this method was not met (e.g. the
177
- // neuron's desolve time is too short). There could be a change in the
178
- // state of the system such that the operation becomes allowed (e.g. the
179
- // owner of the neuron increases its desolve delay).
180
- ERROR_TYPE_PRECONDITION_FAILED = 11;
181
- // Executing this method failed for some reason external to the
182
- // governance canister.
183
- ERROR_TYPE_EXTERNAL = 12;
184
- // A neuron has an ongoing ledger update and thus can't be
185
- // changed.
186
- ERROR_TYPE_LEDGER_UPDATE_ONGOING = 13;
187
- // There wasn't enough funds to perform the operation.
188
- ERROR_TYPE_INSUFFICIENT_FUNDS = 14;
189
- // The principal provided was invalid.
190
- ERROR_TYPE_INVALID_PRINCIPAL = 15;
191
- // The proposal is defective in some way (e.g. title is too long). If the
192
- // same proposal is submitted again without modification, it will be
193
- // rejected regardless of changes in the system's state (e.g. increasing
194
- // the neuron's desolve delay will not make the proposal acceptable).
195
- ERROR_TYPE_INVALID_PROPOSAL = 16;
196
- // The neuron attempted to join the community fund while already
197
- // a member.
198
- ERROR_TYPE_ALREADY_JOINED_COMMUNITY_FUND = 17;
1160
+ ERROR_TYPE_UNSPECIFIED = 0;
1161
+ // The operation was successfully completed.
1162
+ ERROR_TYPE_OK = 1;
1163
+ // This operation is not available, e.g., not implemented.
1164
+ ERROR_TYPE_UNAVAILABLE = 2;
1165
+ // The caller is not authorized to perform this operation.
1166
+ ERROR_TYPE_NOT_AUTHORIZED = 3;
1167
+ // Some entity required for the operation (for example, a neuron) was not found.
1168
+ ERROR_TYPE_NOT_FOUND = 4;
1169
+ // The command was missing or invalid. This is a permanent error.
1170
+ ERROR_TYPE_INVALID_COMMAND = 5;
1171
+ // The neuron is dissolving or dissolved and the operation requires it to
1172
+ // be not dissolving (that is, having a non-zero dissolve delay that is
1173
+ // accumulating age).
1174
+ ERROR_TYPE_REQUIRES_NOT_DISSOLVING = 6;
1175
+ // The neuron is not dissolving or dissolved and the operation requires
1176
+ // it to be dissolving (that is, having a non-zero dissolve delay with
1177
+ // zero age that is not accumulating).
1178
+ ERROR_TYPE_REQUIRES_DISSOLVING = 7;
1179
+ // The neuron is not dissolving and not dissolved and the operation
1180
+ // requires it to be dissolved (that is, having a dissolve delay of zero
1181
+ // and an age of zero).
1182
+ ERROR_TYPE_REQUIRES_DISSOLVED = 8;
1183
+ // When adding or removing a hot key: the key to add was already
1184
+ // present or the key to remove was not present or the key to add
1185
+ // was invalid or adding another hot key would bring the total
1186
+ // number of the maximum number of allowed hot keys per neuron.
1187
+ ERROR_TYPE_HOT_KEY = 9;
1188
+ // Some canister side resource is exhausted, so this operation cannot be
1189
+ // performed.
1190
+ ERROR_TYPE_RESOURCE_EXHAUSTED = 10;
1191
+ // Some precondition for executing this method was not met (e.g. the
1192
+ // neuron's dissolve time is too short). There could be a change in the
1193
+ // state of the system such that the operation becomes allowed (e.g. the
1194
+ // owner of the neuron increases its dissolve delay).
1195
+ ERROR_TYPE_PRECONDITION_FAILED = 11;
1196
+ // Executing this method failed for some reason external to the
1197
+ // governance canister.
1198
+ ERROR_TYPE_EXTERNAL = 12;
1199
+ // A neuron has an ongoing ledger update and thus can't be
1200
+ // changed.
1201
+ ERROR_TYPE_LEDGER_UPDATE_ONGOING = 13;
1202
+ // There wasn't enough funds to perform the operation.
1203
+ ERROR_TYPE_INSUFFICIENT_FUNDS = 14;
1204
+ // The principal provided was invalid.
1205
+ ERROR_TYPE_INVALID_PRINCIPAL = 15;
1206
+ // The proposal is defective in some way (e.g. title is too long). If the
1207
+ // same proposal is submitted again without modification, it will be
1208
+ // rejected regardless of changes in the system's state (e.g. increasing
1209
+ // the neuron's dissolve delay will not make the proposal acceptable).
1210
+ ERROR_TYPE_INVALID_PROPOSAL = 16;
1211
+ // The neuron attempted to join the community fund while already
1212
+ // a member.
1213
+ ERROR_TYPE_ALREADY_JOINED_COMMUNITY_FUND = 17;
1214
+ // The neuron attempted to leave the community fund but is not a member.
1215
+ ERROR_TYPE_NOT_IN_THE_COMMUNITY_FUND = 18;
199
1216
  }
200
1217
 
201
1218
  ErrorType error_type = 1;
202
1219
  string error_message = 2;
203
1220
  }
204
1221
 
205
- message ListNeurons {
206
- option (ic_base_types.pb.v1.tui_signed_message) = true;
207
- repeated fixed64 neuron_ids = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true, jstype = JS_STRING];
208
- bool include_neurons_readable_by_caller = 2 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
1222
+ message Ballot {
1223
+ Vote vote = 1;
1224
+ uint64 voting_power = 2;
209
1225
  }
210
1226
 
211
- message ListNeuronsResponse {
212
- message NeuronMapEntry {
213
- fixed64 key = 1 [jstype = JS_STRING];
214
- NeuronInfo value = 2;
215
- }
1227
+ // The proposal status, with respect to decision making and execution.
1228
+ // See also ProposalRewardStatus.
1229
+ enum ProposalStatus {
1230
+ PROPOSAL_STATUS_UNSPECIFIED = 0;
216
1231
 
217
- // Was originally `map<fixed64, NeuronInfo> neuron_infos = 1`
218
- // It had to be modified to this form to annotate the key with js_type.
219
- repeated NeuronMapEntry neuron_ids = 1;
220
- repeated Neuron full_neurons = 2;
221
- }
1232
+ // A decision (adopt/reject) has yet to be made.
1233
+ PROPOSAL_STATUS_OPEN = 1;
222
1234
 
223
- message BallotInfo {
224
- ic_base_types.pb.v1.ProposalId proposal_id = 1;
225
- Vote vote = 2;
226
- }
1235
+ // The proposal has been rejected.
1236
+ PROPOSAL_STATUS_REJECTED = 2;
227
1237
 
228
- message NeuronInfo {
229
- uint64 retrieved_at_timestamp_seconds = 1 [jstype = JS_STRING];;
230
- uint64 age_seconds = 3 [jstype = JS_STRING];
231
- uint64 dissolve_delay_seconds = 4 [jstype = JS_STRING];
232
- repeated BallotInfo recent_ballots = 5;
233
- uint64 voting_power = 6 [jstype = JS_STRING];
234
- uint64 created_timestamp_seconds = 7 [jstype = JS_STRING];
235
- }
1238
+ // The proposal has been adopted (sometimes also called
1239
+ // "accepted"). At this time, either execution as not yet started,
1240
+ // or it has but the outcome is not yet known.
1241
+ PROPOSAL_STATUS_ADOPTED = 3;
236
1242
 
237
- message Neuron {
238
- ic_base_types.pb.v1.NeuronId id = 1;
239
- bytes account = 2;
240
- ic_base_types.pb.v1.PrincipalId controller = 3;
241
- repeated ic_base_types.pb.v1.PrincipalId hot_keys = 4;
242
- uint64 cached_neuron_stake_e8s = 5 [jstype = JS_STRING];
243
- uint64 neuron_fees_e8s = 6 [jstype = JS_STRING];
244
- uint64 created_timestamp_seconds = 7 [jstype = JS_STRING];
245
- uint64 aging_since_timestamp_seconds = 8 [jstype = JS_STRING];
246
- optional uint64 spawn_at_timestamp_seconds = 19 [jstype = JS_STRING];
247
- oneof dissolve_state {
248
- uint64 when_dissolved_timestamp_seconds = 9 [jstype = JS_STRING];
249
- uint64 dissolve_delay_seconds = 10 [jstype = JS_STRING];
250
- }
251
- message Followees { repeated ic_base_types.pb.v1.NeuronId followees = 1; }
252
- map<int32, Followees> followees = 11;
253
- repeated BallotInfo recent_ballots = 12;
254
- bool kyc_verified = 13;
255
- NeuronStakeTransfer transfer = 14;
256
- uint64 maturity_e8s_equivalent = 15 [jstype = JS_STRING];
257
- bool not_for_profit = 16;
1243
+ // The proposal was adopted and successfully executed.
1244
+ PROPOSAL_STATUS_EXECUTED = 4;
1245
+
1246
+ // The proposal was adopted, but execution failed.
1247
+ PROPOSAL_STATUS_FAILED = 5;
258
1248
  }
259
1249
 
260
- enum Vote {
261
- VOTE_UNSPECIFIED = 0;
262
- VOTE_YES = 1;
263
- VOTE_NO = 2;
1250
+ // The proposal status, with respect to reward distribution.
1251
+ // See also ProposalStatus.
1252
+ enum ProposalRewardStatus {
1253
+ PROPOSAL_REWARD_STATUS_UNSPECIFIED = 0;
1254
+
1255
+ // The proposal still accept votes, for the purpose of
1256
+ // vote rewards. This implies nothing on the ProposalStatus.
1257
+ PROPOSAL_REWARD_STATUS_ACCEPT_VOTES = 1;
1258
+
1259
+ // The proposal no longer accepts votes. It is due to settle
1260
+ // at the next reward event.
1261
+ PROPOSAL_REWARD_STATUS_READY_TO_SETTLE = 2;
1262
+
1263
+ // The proposal has been taken into account in a reward event.
1264
+ PROPOSAL_REWARD_STATUS_SETTLED = 3;
1265
+
1266
+ // The proposal is not eligible to be taken into account in a reward event.
1267
+ PROPOSAL_REWARD_STATUS_INELIGIBLE = 4;
264
1268
  }
265
1269
 
266
- message NeuronStakeTransfer {
267
- uint64 transfer_timestamp = 1 [jstype = JS_STRING];
268
- ic_base_types.pb.v1.PrincipalId from = 2;
269
- bytes from_subaccount = 3;
270
- bytes to_subaccount = 4;
271
- uint64 neuron_stake_e8s = 5 [jstype = JS_STRING];
272
- uint64 block_height = 6 [jstype = JS_STRING];
273
- uint64 memo = 7 [jstype = JS_STRING];
1270
+ // A tally of votes.
1271
+ message Tally {
1272
+ // When was this tally made
1273
+ uint64 timestamp_seconds = 1;
1274
+
1275
+ // Yeses, in voting power unit.
1276
+ uint64 yes = 2;
1277
+
1278
+ // Noes, in voting power unit.
1279
+ uint64 no = 3;
1280
+
1281
+ // Total voting power unit of eligible neurons.
1282
+ // Should always be greater than or equal to yes + no.
1283
+ uint64 total = 4;
274
1284
  }
275
1285
 
276
- enum Topic {
277
- TOPIC_UNSPECIFIED = 0;
278
- TOPIC_NEURON_MANAGEMENT = 1;
279
- TOPIC_EXCHANGE_RATE = 2;
280
- TOPIC_NETWORK_ECONOMICS = 3;
281
- TOPIC_GOVERNANCE = 4;
282
- TOPIC_NODE_ADMIN = 5;
283
- TOPIC_PARTICIPANT_MANAGEMENT = 6;
284
- TOPIC_SUBNET_MANAGEMENT = 7;
285
- TOPIC_NETWORK_CANISTER_MANAGEMENT = 8;
286
- TOPIC_KYC = 9;
287
- TOPIC_NODE_PROVIDER_REWARDS = 10;
288
- TOPIC_SNS_DECENTRALIZATION_SALE = 11;
289
- TOPIC_SUBNET_REPLICA_VERSION_MANAGEMENT = 12;
290
- TOPIC_REPLICA_VERSION_MANAGEMENT = 13;
291
- TOPIC_SNS_AND_COMMUNITY_FUND = 14;
292
- TOPIC_API_BOUNDARY_NODE_MANAGEMENT = 15;
1286
+ // A ProposalData contains everything related to an open proposal:
1287
+ // the proposal itself (immutable), as well as mutable data such as
1288
+ // ballots.
1289
+ message ProposalData {
1290
+ // This is stored here temporarily. It is also stored on the map
1291
+ // that contains proposals.
1292
+ //
1293
+ // Immutable: The unique id for this proposal.
1294
+ ic_nns_common.pb.v1.ProposalId id = 1;
1295
+
1296
+ // Immutable: The ID of the neuron that made this proposal.
1297
+ ic_nns_common.pb.v1.NeuronId proposer = 2;
1298
+
1299
+ // Immutable: The amount of ICP in E8s to be charged to the proposer if the
1300
+ // proposal is rejected.
1301
+ uint64 reject_cost_e8s = 3;
1302
+
1303
+ // Immutable: The proposal originally submitted.
1304
+ Proposal proposal = 4;
1305
+
1306
+ // Immutable: The timestamp, in seconds from the Unix epoch, when this proposal
1307
+ // was made.
1308
+ uint64 proposal_timestamp_seconds = 5;
1309
+
1310
+ // Map neuron ID to to the neuron's vote and voting power. Only
1311
+ // present for as long as the proposal is not yet settled with
1312
+ // respect to rewards.
1313
+ map<fixed64, Ballot> ballots = 6;
1314
+
1315
+ // Latest tally. Recomputed for every vote. Even after the proposal has been
1316
+ // decided, the latest_tally will still be updated based on the recent vote,
1317
+ // until the voting deadline.
1318
+ Tally latest_tally = 7;
1319
+
1320
+ // If specified: the timestamp when this proposal was adopted or
1321
+ // rejected. If not specified, this proposal is still 'open'.
1322
+ uint64 decided_timestamp_seconds = 8;
1323
+
1324
+ // When an adopted proposal has been executed, this is set to
1325
+ // current timestamp.
1326
+ uint64 executed_timestamp_seconds = 12;
1327
+
1328
+ // When an adopted proposal has failed to be executed, this is set
1329
+ // to the current timestamp.
1330
+ uint64 failed_timestamp_seconds = 13;
1331
+
1332
+ // When an adopted proposal has failed to executed, this is set the
1333
+ // reason for the failure.
1334
+ GovernanceError failure_reason = 15;
1335
+
1336
+ // The reward event round at which rewards for votes on this proposal
1337
+ // was distributed.
1338
+ //
1339
+ // Rounds do not have to be consecutive.
1340
+ //
1341
+ // Rounds start at one: a value of zero indicates that
1342
+ // no reward event taking this proposal into consideration happened yet.
1343
+ //
1344
+ // This field matches field day_after_genesis in RewardEvent.
1345
+ uint64 reward_event_round = 14;
1346
+
1347
+ // Wait-for-quiet state that needs to be saved in stable memory.
1348
+ WaitForQuietState wait_for_quiet_state = 16;
1349
+
1350
+ // SNS Token Swap-related fields
1351
+ // -----------------------------
1352
+
1353
+ // This is populated when an OpenSnsTokenSwap proposal is first made.
1354
+ optional uint64 original_total_community_fund_maturity_e8s_equivalent = 17;
1355
+
1356
+ // This is populated when OpenSnsTokenSwap is executed. It is used when our
1357
+ // conclude_community_fund_participation Candid method is called to either
1358
+ // mint ICP, or restore CF neuron maturity.
1359
+ repeated ic_sns_swap.pb.v1.CfParticipant cf_participants = 18;
1360
+
1361
+ // This gets set to one of the terminal values (i.e. Committed or Aborted)
1362
+ // when the swap canister calls our conclude_community_fund_participation
1363
+ // Candid method. Initially, it is set to Open, because swap is supposed to
1364
+ // enter that state when we call its open Candid method, which is the main
1365
+ // operation in the execution of an OpenSnsTokenSwap proposal.
1366
+ optional ic_sns_swap.pb.v1.Lifecycle sns_token_swap_lifecycle = 19;
1367
+
1368
+ DerivedProposalInformation derived_proposal_information = 20;
1369
+
1370
+ // This structure contains data for settling the Neurons' Fund participation at the end of a swap.
1371
+ //
1372
+ // TODO[NNS1-2566]: deprecate `original_total_community_fund_maturity_e8s_equivalent` and
1373
+ // `cf_participants` and use only this field for managing the Neurons' Fund swap participation.
1374
+ optional NeuronsFundData neurons_fund_data = 21;
1375
+ }
1376
+
1377
+ // This structure contains data for settling the Neurons' Fund participation in an SNS token swap.
1378
+ message NeuronsFundData {
1379
+ // Initial Neurons' Fund reserves computed at the time of execution of the proposal through which
1380
+ // the SNS swap is created.
1381
+ optional NeuronsFundParticipation initial_neurons_fund_participation = 1;
1382
+
1383
+ // Final Neurons' Fund participation computed at the time of swap finalization. This field should
1384
+ // remain unspecified until either (1) the `settle_neurons_fund_participation` function is called
1385
+ // or (2) the NNS handles an error at the SNS deployment stage.
1386
+ //
1387
+ // If specified, this must be a subset of `initial_neurons_fund_participation`.
1388
+ optional NeuronsFundParticipation final_neurons_fund_participation = 2;
1389
+
1390
+ // Refunds for any leftover Neurons' Fund maturity that could not be used to participate in
1391
+ // the swap. This field should remain unspecified `settle_neurons_fund_participation` is called.
1392
+ //
1393
+ // If specified, this must be equal to the following set-difference:
1394
+ // `initial_neurons_fund_participation.neurons_fund_reserves`
1395
+ // set-minus `final_neurons_fund_participation.neurons_fund_reserves`.
1396
+ optional NeuronsFundSnapshot neurons_fund_refunds = 3;
1397
+ }
1398
+
1399
+ // This is a view of the NeuronsFundData returned by API queries and is NOT used for storage.
1400
+ // Currently, the structure is identical to NeuronsFundData, but this may change over time.
1401
+ // Some of the fields, e.g., actual IDs of neurons, are anonymized.
1402
+ message NeuronsFundAuditInfo {
1403
+ // See documentation for NeuronsFundData.neurons_fund_participation
1404
+ optional NeuronsFundParticipation initial_neurons_fund_participation = 1;
1405
+
1406
+ // See documentation for NeuronsFundData.final_neurons_fund_participation
1407
+ optional NeuronsFundParticipation final_neurons_fund_participation = 2;
1408
+
1409
+ // See documentation for NeuronsFundData.neurons_fund_refunds
1410
+ optional NeuronsFundSnapshot neurons_fund_refunds = 3;
1411
+ }
1412
+
1413
+ message GetNeuronsFundAuditInfoRequest {
1414
+ // ID of the NNS proposal that resulted in the creation of the corresponding Swap.
1415
+ optional ic_nns_common.pb.v1.ProposalId nns_proposal_id = 1;
1416
+ }
1417
+
1418
+ message GetNeuronsFundAuditInfoResponse {
1419
+ // Request was completed successfully.
1420
+ message Ok {
1421
+ // Represents public information suitable for auditing Neurons' Fund participation in an SNS swap.
1422
+ optional NeuronsFundAuditInfo neurons_fund_audit_info = 1;
1423
+ }
1424
+
1425
+ oneof result {
1426
+ GovernanceError err = 1;
1427
+ Ok ok = 2;
1428
+ }
1429
+ }
1430
+
1431
+ // Information for deciding how the Neurons' Fund should participate in an SNS Swap.
1432
+ message NeuronsFundParticipation {
1433
+ // The function used in the implementation of Matched Funding.
1434
+ //
1435
+ // If an NNS Governance upgrade takes place *during* a swap, the original "ideal" matched
1436
+ // participation function needs to be recovered at the end of the swap, ensuring e.g., that
1437
+ // the amount of maturity stored in `neurons_fund_snapshot` will not not be exceeded for due to
1438
+ // a change in this function.
1439
+ optional IdealMatchedParticipationFunction ideal_matched_participation_function = 1;
1440
+
1441
+ // The snapshot of the Neurons' Fund allocation of its maximum swap participation amount among
1442
+ // its neurons. This snapshot is computed at the execution time of the NNS proposal leading
1443
+ // to the swap opening.
1444
+ optional NeuronsFundSnapshot neurons_fund_reserves = 2;
1445
+
1446
+ // Absolute constraints for direct participants of this swap needed in Matched Funding
1447
+ // computations.
1448
+ optional SwapParticipationLimits swap_participation_limits = 3;
1449
+
1450
+ // The following fields are provided for auditability.
1451
+
1452
+ // Neurons' Fund participation is computed for this amount of direct participation.
1453
+ optional uint64 direct_participation_icp_e8s = 4;
1454
+
1455
+ // Total amount of maturity in the Neurons' Fund at the time when the Neurons' Fund participation
1456
+ // was created.
1457
+ optional uint64 total_maturity_equivalent_icp_e8s = 5;
1458
+
1459
+ // Maximum amount that the Neurons' Fund will participate with in this SNS swap, regardless of how
1460
+ // large the value of `direct_participation_icp_e8s` is.
1461
+ optional uint64 max_neurons_fund_swap_participation_icp_e8s = 6;
1462
+
1463
+ // How much the Neurons' Fund would ideally like to participate with in this SNS swap, given
1464
+ // the direct participation amount (`direct_participation_icp_e8s`) and matching function
1465
+ // (`ideal_matched_participation_function`).
1466
+ optional uint64 intended_neurons_fund_participation_icp_e8s = 7;
1467
+
1468
+ // How much from `intended_neurons_fund_participation_icp_e8s` was the Neurons' Fund actually able
1469
+ // to allocate, given the specific composition of neurons at the time of execution of the proposal
1470
+ // through which this SNS was created and the participation limits of this SNS.
1471
+ optional uint64 allocated_neurons_fund_participation_icp_e8s = 8;
1472
+ }
1473
+
1474
+ // This function is called "ideal" because it serves as the guideline that the Neurons' Fund will
1475
+ // try to follow, but may deviate from in order to satisfy SNS-specific participation constraints
1476
+ // while allocating its overall participation amount among its neurons' maturity. In contrast,
1477
+ // The "effective" matched participation function `crate::neurons_fund::MatchedParticipationFunction`
1478
+ // is computed *based* on this one.
1479
+ message IdealMatchedParticipationFunction {
1480
+ // The encoding of the "ideal" matched participation function is defined in `crate::neurons_fund`.
1481
+ // In the future, we could change this message to represent full abstract syntactic trees
1482
+ // comprised of elementary mathematical operators, with literals and variables as tree leaves.
1483
+ optional string serialized_representation = 1;
1484
+ }
1485
+
1486
+ // The snapshot of the Neurons' Fund allocation of its maximum swap participation amount among
1487
+ // its neurons. This snapshot is computed at the execution time of the NNS proposal leading
1488
+ // to the swap opening; it is then used at the end of a swap to compute the refund amounts
1489
+ // per Neuron' Fund neuron.
1490
+ message NeuronsFundSnapshot {
1491
+ // Represents one NNS neuron from the Neurons' Fund participating in this swap.
1492
+ message NeuronsFundNeuronPortion {
1493
+ // The NNS neuron ID of the participating neuron.
1494
+ optional ic_nns_common.pb.v1.NeuronId nns_neuron_id = 1;
1495
+ // Portion of maturity taken from this neuron. Must be less than or equal to
1496
+ // `maturity_equivalent_icp_e8s`.
1497
+ optional uint64 amount_icp_e8s = 2;
1498
+ // Overall amount of maturity of the neuron from which this portion is taken.
1499
+ optional uint64 maturity_equivalent_icp_e8s = 3;
1500
+ // The principal that can vote on behalf of this neuron.
1501
+ optional ic_base_types.pb.v1.PrincipalId hotkey_principal = 4;
1502
+ // Whether the portion specified by `amount_icp_e8s` is limited due to SNS-specific
1503
+ // participation constraints.
1504
+ optional bool is_capped = 5;
1505
+ }
1506
+
1507
+ repeated NeuronsFundNeuronPortion neurons_fund_neuron_portions = 1;
1508
+ }
1509
+
1510
+ // Absolute constraints of this swap needed that the Neurons' Fund need to be aware of.
1511
+ // The fields correspond to those in Swap's `Init` message.
1512
+ message SwapParticipationLimits {
1513
+ optional uint64 min_direct_participation_icp_e8s = 1;
1514
+ optional uint64 max_direct_participation_icp_e8s = 2;
1515
+ optional uint64 min_participant_icp_e8s = 3;
1516
+ optional uint64 max_participant_icp_e8s = 4;
1517
+ }
1518
+
1519
+ // This message has a couple of unusual features.
1520
+ //
1521
+ // 1. There is (currently) only one field. We expect that more fields will be
1522
+ // (and possibly other clients) to be able to handle this information in a
1523
+ // generic way, i.e. without having to change their code.
1524
+ //
1525
+ // 2. Fields that might be added later will probably be mutually exclusive with
1526
+ // existing fields. Normally, this would be handled by putting all such
1527
+ // fields into a oneof. However, Candid has a bug where variant is not
1528
+ // handled correctly. Therefore, we refrain from using oneof until we believe
1529
+ // that the fix is very imminent.
1530
+ message DerivedProposalInformation {
1531
+ SwapBackgroundInformation swap_background_information = 1;
1532
+ }
1533
+
1534
+ // Additional information about the SNS that's being "swapped".
1535
+ //
1536
+ // This data is fetched from other canisters. Currently, the swap canister
1537
+ // itself, and the root canister are queried, but additional canisters could be
1538
+ // queried later. In particular, the ID of the root canister is discovered via
1539
+ // the swap canister.
1540
+ //
1541
+ // (See Governance::fetch_swap_background_information for how this is compiled.)
1542
+ message SwapBackgroundInformation {
1543
+ // Obsolete. Superseded by newer fields.
1544
+
1545
+ reserved "sns_root_canister_id";
1546
+ reserved 1;
1547
+ reserved "sns_governance_canister_id";
1548
+ reserved 2;
1549
+ reserved "sns_ledger_canister_id";
1550
+ reserved 3;
1551
+ reserved "sns_ledger_index_canister_id";
1552
+ reserved 4;
1553
+ reserved "sns_ledger_archive_canister_ids";
1554
+ reserved 5;
1555
+ reserved "dapp_canister_ids";
1556
+ reserved 6;
1557
+
1558
+ // In case swap fails/aborts.
1559
+
1560
+ repeated ic_base_types.pb.v1.PrincipalId fallback_controller_principal_ids = 7;
1561
+
1562
+ // Primary Canisters
1563
+
1564
+ CanisterSummary root_canister_summary = 8;
1565
+ CanisterSummary governance_canister_summary = 9;
1566
+ CanisterSummary ledger_canister_summary = 10;
1567
+ CanisterSummary swap_canister_summary = 11;
1568
+
1569
+ // Secondary Canisters
1570
+
1571
+ repeated CanisterSummary ledger_archive_canister_summaries = 12;
1572
+ CanisterSummary ledger_index_canister_summary = 13;
1573
+
1574
+ // Non-SNS Canister(s)
1575
+
1576
+ repeated CanisterSummary dapp_canister_summaries = 14;
1577
+
1578
+ // Transcribed from sns/root.
1579
+ message CanisterSummary {
1580
+ ic_base_types.pb.v1.PrincipalId canister_id = 1;
1581
+ CanisterStatusResultV2 status = 2;
1582
+ }
1583
+
1584
+ message CanisterStatusResultV2 {
1585
+ optional CanisterStatusType status = 1;
1586
+ bytes module_hash = 2;
1587
+
1588
+ // no controller field, because that is obsolete and superseded by the
1589
+ // controllers field within settings.
1590
+
1591
+ repeated ic_base_types.pb.v1.PrincipalId controllers = 3;
1592
+
1593
+ // Resources
1594
+
1595
+ optional uint64 memory_size = 4;
1596
+ optional uint64 cycles = 5;
1597
+ optional uint64 freezing_threshold = 6;
1598
+ optional uint64 idle_cycles_burned_per_day = 7;
1599
+ }
1600
+
1601
+ // A canister can be stopped by calling stop_canister. The effect of
1602
+ // stop_canister can be undone by calling start_canister. Stopping is an
1603
+ // intermediate state where new method calls are rejected, but in-flight
1604
+ // method calls are allowed to be fully serviced.
1605
+ enum CanisterStatusType {
1606
+ CANISTER_STATUS_TYPE_UNSPECIFIED = 0;
1607
+ CANISTER_STATUS_TYPE_RUNNING = 1;
1608
+ CANISTER_STATUS_TYPE_STOPPING = 2;
1609
+ CANISTER_STATUS_TYPE_STOPPED = 3;
1610
+ }
1611
+ }
1612
+
1613
+ // Stores data relevant to the "wait for quiet" implementation.
1614
+ message WaitForQuietState {
1615
+ uint64 current_deadline_timestamp_seconds = 1;
1616
+ }
1617
+
1618
+ // This is a view of the ProposalData returned by API queries and is NOT used
1619
+ // for storage. The ballots are restricted to those of the caller's neurons and
1620
+ // additionally it has the computed fields, topic, status, and reward_status.
1621
+ message ProposalInfo {
1622
+ // The unique id for this proposal.
1623
+ ic_nns_common.pb.v1.ProposalId id = 1;
1624
+
1625
+ // The ID of the neuron that made this proposal.
1626
+ ic_nns_common.pb.v1.NeuronId proposer = 2;
1627
+
1628
+ // The amount of ICP in E8s to be charged to the proposer if the proposal is
1629
+ // rejected.
1630
+ uint64 reject_cost_e8s = 3;
1631
+
1632
+ // The proposal originally submitted.
1633
+ Proposal proposal = 4;
1634
+
1635
+ // The timestamp, in seconds from the Unix epoch, when this proposal was made.
1636
+ uint64 proposal_timestamp_seconds = 5;
1637
+
1638
+ // See [ProposalData::ballots].
1639
+ map<fixed64, Ballot> ballots = 6;
1640
+
1641
+ // See [ProposalData::latest_tally].
1642
+ Tally latest_tally = 7;
1643
+
1644
+ // See [ProposalData::decided_timestamp_seconds].
1645
+ uint64 decided_timestamp_seconds = 8;
1646
+
1647
+ // See [ProposalData::executed_timestamp_seconds].
1648
+ uint64 executed_timestamp_seconds = 12;
1649
+
1650
+ // See [ProposalData::failed_timestamp_seconds].
1651
+ uint64 failed_timestamp_seconds = 13;
1652
+
1653
+ // See [ProposalData::failure_reason].
1654
+ GovernanceError failure_reason = 18;
1655
+
1656
+ // See [ProposalData::reward_event_round].
1657
+ uint64 reward_event_round = 14;
1658
+
1659
+ // Derived - see [Topic] for more information
1660
+ Topic topic = 15;
1661
+
1662
+ // Derived - see [ProposalStatus] for more information
1663
+ ProposalStatus status = 16;
1664
+
1665
+ // Derived - see [ProposalRewardStatus] for more information
1666
+ ProposalRewardStatus reward_status = 17;
1667
+
1668
+ optional uint64 deadline_timestamp_seconds = 19;
1669
+
1670
+ DerivedProposalInformation derived_proposal_information = 20;
1671
+ }
1672
+
1673
+ // Network economics contains the parameters for several operations related
1674
+ // to the economy of the network. When submitting a NetworkEconomics proposal
1675
+ // default values (0) are considered unchanged, so a valid proposal only needs
1676
+ // to set the parameters that it wishes to change.
1677
+ // In other words, it's not possible to set any of the values of
1678
+ // NetworkEconomics to 0.
1679
+ //
1680
+ // NOTE: If adding a value to this proto, make sure there is a corresponding
1681
+ // `if` in Governance::perform_action().
1682
+ message NetworkEconomics {
1683
+ reserved 3, 7;
1684
+ // The number of E8s (10E-8 of an ICP token) that a rejected
1685
+ // proposal will cost.
1686
+ //
1687
+ // This fee should be controlled by an #Economic proposal type.
1688
+ // The fee does not apply for ManageNeuron proposals.
1689
+ uint64 reject_cost_e8s = 1;
1690
+
1691
+ // The minimum number of E8s that can be staked in a neuron.
1692
+ uint64 neuron_minimum_stake_e8s = 2;
1693
+
1694
+ // The number of E8s (10E-8 of an ICP token) that it costs to
1695
+ // employ the 'manage neuron' functionality through proposals. The
1696
+ // cost is incurred by the neuron that makes the 'manage neuron'
1697
+ // proposal and is applied regardless of whether the proposal is
1698
+ // adopted or rejected.
1699
+ uint64 neuron_management_fee_per_proposal_e8s = 4;
1700
+
1701
+ // The minimum number that the ICP/XDR conversion rate can be set to.
1702
+ //
1703
+ // Measured in XDR (the currency code of IMF SDR) to two decimal
1704
+ // places.
1705
+ //
1706
+ // See /rs/protobuf/def/registry/conversion_rate/v1/conversion_rate.proto
1707
+ // for more information on the rate itself.
1708
+ uint64 minimum_icp_xdr_rate = 5;
1709
+
1710
+ // The dissolve delay of a neuron spawned from the maturity of an
1711
+ // existing neuron.
1712
+ uint64 neuron_spawn_dissolve_delay_seconds = 6;
1713
+
1714
+ // The maximum rewards to be distributed to NodeProviders in a single
1715
+ // distribution event, in e8s.
1716
+ uint64 maximum_node_provider_rewards_e8s = 8;
1717
+
1718
+ // The transaction fee that must be paid for each ledger transaction.
1719
+ uint64 transaction_fee_e8s = 9;
1720
+
1721
+ // The maximum number of proposals to keep, per topic for eligible topics.
1722
+ // When the total number of proposals for a given topic is greater than this
1723
+ // number, the oldest proposals that have reached a "final" state
1724
+ // may be deleted.
1725
+ //
1726
+ // If unspecified or zero, all proposals are kept.
1727
+ uint32 max_proposals_to_keep_per_topic = 10;
1728
+
1729
+ // Global Neurons' Fund participation thresholds.
1730
+ optional NeuronsFundEconomics neurons_fund_economics = 11;
1731
+ }
1732
+
1733
+ // The thresholds specify the shape of the ideal matching function used by the Neurons' Fund to
1734
+ // determine how much to contribute for a given direct participation amount. Note that the actual
1735
+ // swap participation is in ICP, whereas these thresholds are specifid in XDR; the conversion rate
1736
+ // is determined at the time of execution of the CreateServiceNervousSystem proposal.
1737
+ message NeuronsFundMatchedFundingCurveCoefficients {
1738
+ // Up to this amount of direct participation, the Neurons' Fund does not contribute to this SNS.
1739
+ optional ic_nervous_system.pb.v1.Decimal contribution_threshold_xdr = 1;
1740
+
1741
+ // Say the direct participation amount is `x_icp`. When `x_icp` equals the equavalent of
1742
+ // `one_third_participation_milestone_xdr` in ICP (we use ICP/XDR conversion data from the CMC),
1743
+ // the Neurons' Fund contributes 50% on top of that amount, so the overall contributions would
1744
+ // be `1.5 * x_icp` of which 1/3 comes from the Neurons' Fund.
1745
+ optional ic_nervous_system.pb.v1.Decimal one_third_participation_milestone_xdr = 2;
1746
+
1747
+ // Say the direct participation amount is `x_icp`. When `x_icp` equals the equavalent of
1748
+ // `full_participation_milestone_xdr` in ICP (we use ICP/XDR conversion data from the CMC),
1749
+ // the Neurons' Fund contributes 100% on top of that amount, so the overall contributions would
1750
+ // be `2.0 * x_icp` of which a half comes from the Neurons' Fund.
1751
+ optional ic_nervous_system.pb.v1.Decimal full_participation_milestone_xdr = 3;
1752
+ }
1753
+
1754
+ // When the Neurons' Fund decides to participates in an SNS swap, the amount of participation is
1755
+ // determined according to the rules of Matched Funding. The amount of ICP tokens contributed by
1756
+ // the Neurons' Fund depends on four factors:
1757
+ // (1) Direct participation amount at the time of the swap's successful finalization.
1758
+ // (2) Amount of maturity held by all eligible neurons that were members of the Neurons' Fund
1759
+ // at the time of the CreateServiceNervousSystem proposal execution.
1760
+ // (3) Global Neurons' Fund participation thresholds, held in this structure (defined in XDR).
1761
+ // (4) ICP/XDR conversion rate at the time of the CreateServiceNervousSystem proposal execution.
1762
+ message NeuronsFundEconomics {
1763
+ // This is a theoretical limit which should be smaller than any realistic amount of maturity
1764
+ // that practically needs to be reserved from the Neurons' Fund for a given SNS swap.
1765
+ optional ic_nervous_system.pb.v1.Decimal max_theoretical_neurons_fund_participation_amount_xdr = 1;
1766
+
1767
+ // Thresholds specifying the shape of the matching function used by the Neurons' Fund to
1768
+ // determine how much to contribute for a given direct participation amount.
1769
+ optional NeuronsFundMatchedFundingCurveCoefficients neurons_fund_matched_funding_curve_coefficients = 2;
1770
+
1771
+ // The minimum value of the ICP/XDR conversion rate used by the Neurons' Fund for converting
1772
+ // XDR values into ICP.
1773
+ optional ic_nervous_system.pb.v1.Percentage minimum_icp_xdr_rate = 3;
1774
+
1775
+ // The maximum value of the ICP/XDR conversion rate used by the Neurons' Fund for converting
1776
+ // XDR values into ICP.
1777
+ optional ic_nervous_system.pb.v1.Percentage maximum_icp_xdr_rate = 4;
1778
+ }
1779
+
1780
+ // A reward event is an event at which neuron maturity is increased
1781
+ message RewardEvent {
1782
+ // This reward event correspond to a time interval that ends at the end of
1783
+ // genesis + day_after_genesis days.
1784
+ //
1785
+ // For instance: when this is 0, this is for a period that ends at genesis -- there can
1786
+ // never be a reward for this.
1787
+ //
1788
+ // When this is 1, this is for the first day after genesis.
1789
+ //
1790
+ // On rare occasions, the reward event may cover several days ending at genesis + day_after_genesis days,
1791
+ // when it was not possible to proceed to a reward event for a while. This makes that day_after_genesis
1792
+ // does not have to be consecutive.
1793
+ uint64 day_after_genesis = 1;
1794
+
1795
+ // The timestamp at which this reward event took place, in seconds since the unix epoch.
1796
+ //
1797
+ // This does not match the date taken into account for reward computation, which
1798
+ // should always be an integer number of days after genesis.
1799
+ uint64 actual_timestamp_seconds = 2;
1800
+
1801
+ // The list of proposals that were taken into account during
1802
+ // this reward event.
1803
+ repeated ic_nns_common.pb.v1.ProposalId settled_proposals = 3;
1804
+
1805
+ // The total amount of reward that was distributed during this reward event.
1806
+ //
1807
+ // The unit is "e8s equivalent" to insist that, while this quantity is on
1808
+ // the same scale as ICPs, maturity is not directly convertible to ICPs:
1809
+ // conversion requires a minting event to spawn a new neuron.
1810
+ uint64 distributed_e8s_equivalent = 4;
1811
+
1812
+ // The total amount of rewards that was available during the reward event.
1813
+ uint64 total_available_e8s_equivalent = 5;
1814
+
1815
+ // The amount of rewards that was available during the last round included in
1816
+ // this event. This will only be different from `total_available_e8s_equivalent`
1817
+ // if there were "rollover rounds" included in this event.
1818
+ optional uint64 latest_round_available_e8s_equivalent = 7;
1819
+
1820
+ // In some cases, the rewards that would have been distributed in one round are
1821
+ // "rolled over" into the next reward event. This field keeps track of how many
1822
+ // rounds have passed since the last time rewards were distributed (rather
1823
+ // than being rolled over).
1824
+ //
1825
+ // For the genesis reward event, this field will be zero.
1826
+ //
1827
+ // In normal operation, this field will almost always be 1. There are two
1828
+ // reasons that rewards might not be distributed in a given round.
1829
+ //
1830
+ // 1. "Missed" rounds: there was a long period when we did calculate rewards
1831
+ // (longer than 1 round). (I.e. distribute_rewards was not called by
1832
+ // heartbeat for whatever reason, most likely some kind of bug.)
1833
+ //
1834
+ // 2. Rollover: We tried to distribute rewards, but there were no proposals
1835
+ // settled to distribute rewards for.
1836
+ //
1837
+ // In both of these cases, the rewards purse rolls over into the next round.
1838
+ optional uint64 rounds_since_last_distribution = 6;
1839
+ }
1840
+
1841
+ message KnownNeuron {
1842
+ ic_nns_common.pb.v1.NeuronId id = 1;
1843
+ KnownNeuronData known_neuron_data = 2;
1844
+ }
1845
+
1846
+ // Known neurons have extra information (a name and optionally a description) that can be used to identify them.
1847
+ message KnownNeuronData {
1848
+ string name = 1;
1849
+ optional string description = 2;
1850
+ }
1851
+
1852
+ // Proposal action to call the "open" method of an SNS token swap canister.
1853
+ message OpenSnsTokenSwap {
1854
+ // The ID of the canister where the command will be sent (assuming that the
1855
+ // proposal is adopted, of course).
1856
+ ic_base_types.pb.v1.PrincipalId target_swap_canister_id = 1;
1857
+
1858
+ // Various limits on the swap.
1859
+ ic_sns_swap.pb.v1.Params params = 2;
1860
+
1861
+ // The amount that the community fund will collectively spend in maturity on
1862
+ // the swap.
1863
+ optional uint64 community_fund_investment_e8s = 3;
1864
+ }
1865
+
1866
+ // Mainly, calls the deploy_new_sns Candid method on the SNS-WASMs canister.
1867
+ // Therefore, most of the fields here have equivalents in SnsInitPayload.
1868
+ // Please, consult the comments therein.
1869
+ message CreateServiceNervousSystem {
1870
+ // Metadata
1871
+ // --------
1872
+
1873
+ optional string name = 1;
1874
+ optional string description = 2;
1875
+ optional string url = 3;
1876
+ ic_nervous_system.pb.v1.Image logo = 4;
1877
+
1878
+ // Canister Control
1879
+ // ----------------
1880
+
1881
+ repeated ic_base_types.pb.v1.PrincipalId fallback_controller_principal_ids = 5;
1882
+
1883
+ repeated ic_nervous_system.pb.v1.Canister dapp_canisters = 6;
1884
+
1885
+ // Initial SNS Tokens and Neurons
1886
+ // ------------------------------
1887
+
1888
+ message InitialTokenDistribution {
1889
+ message DeveloperDistribution {
1890
+ message NeuronDistribution {
1891
+ ic_base_types.pb.v1.PrincipalId controller = 1;
1892
+ ic_nervous_system.pb.v1.Duration dissolve_delay = 2;
1893
+ optional uint64 memo = 3;
1894
+ ic_nervous_system.pb.v1.Tokens stake = 4;
1895
+ ic_nervous_system.pb.v1.Duration vesting_period = 5;
1896
+ }
1897
+
1898
+ repeated NeuronDistribution developer_neurons = 1;
1899
+ }
1900
+
1901
+ DeveloperDistribution developer_distribution = 1;
1902
+
1903
+ message TreasuryDistribution {
1904
+ ic_nervous_system.pb.v1.Tokens total = 1;
1905
+ }
1906
+
1907
+ TreasuryDistribution treasury_distribution = 2;
1908
+
1909
+ message SwapDistribution {
1910
+ ic_nervous_system.pb.v1.Tokens total = 1;
1911
+ }
1912
+
1913
+ SwapDistribution swap_distribution = 3;
1914
+ }
1915
+
1916
+ InitialTokenDistribution initial_token_distribution = 7;
1917
+
1918
+ // Canister Initialization
1919
+ // ------------------------
1920
+
1921
+ message SwapParameters {
1922
+ optional uint64 minimum_participants = 1;
1923
+
1924
+ optional ic_nervous_system.pb.v1.Tokens minimum_icp = 2;
1925
+ optional ic_nervous_system.pb.v1.Tokens maximum_icp = 3;
1926
+
1927
+ optional ic_nervous_system.pb.v1.Tokens minimum_direct_participation_icp = 12;
1928
+ optional ic_nervous_system.pb.v1.Tokens maximum_direct_participation_icp = 13;
1929
+
1930
+ optional ic_nervous_system.pb.v1.Tokens minimum_participant_icp = 4;
1931
+ optional ic_nervous_system.pb.v1.Tokens maximum_participant_icp = 5;
1932
+
1933
+ message NeuronBasketConstructionParameters {
1934
+ optional uint64 count = 1;
1935
+ ic_nervous_system.pb.v1.Duration dissolve_delay_interval = 2;
1936
+ }
1937
+
1938
+ NeuronBasketConstructionParameters neuron_basket_construction_parameters = 6;
1939
+
1940
+ optional string confirmation_text = 7;
1941
+
1942
+ optional ic_nervous_system.pb.v1.Countries restricted_countries = 8;
1943
+
1944
+ // The swap occurs at a specific time of day, in UTC.
1945
+ // It will happen the first time start_time occurs that's at least 24h after
1946
+ // the proposal is adopted.
1947
+ ic_nervous_system.pb.v1.GlobalTimeOfDay start_time = 9;
1948
+ ic_nervous_system.pb.v1.Duration duration = 10;
1949
+
1950
+ // The amount that the Neuron's Fund will collectively spend in maturity on
1951
+ // the swap.
1952
+ optional ic_nervous_system.pb.v1.Tokens neurons_fund_investment_icp = 11;
1953
+
1954
+ // Whether Neurons' Fund participation is requested.
1955
+ // Cannot be set to true until Matched Funding is released
1956
+ optional bool neurons_fund_participation = 14;
1957
+ }
1958
+
1959
+ SwapParameters swap_parameters = 8;
1960
+
1961
+ message LedgerParameters {
1962
+ optional ic_nervous_system.pb.v1.Tokens transaction_fee = 1;
1963
+ optional string token_name = 2;
1964
+ optional string token_symbol = 3;
1965
+ ic_nervous_system.pb.v1.Image token_logo = 4;
1966
+ }
1967
+
1968
+ LedgerParameters ledger_parameters = 9;
1969
+
1970
+ message GovernanceParameters {
1971
+ // Proposal Parameters
1972
+ // -------------------
1973
+
1974
+ ic_nervous_system.pb.v1.Tokens proposal_rejection_fee = 1;
1975
+ ic_nervous_system.pb.v1.Duration proposal_initial_voting_period = 2;
1976
+ ic_nervous_system.pb.v1.Duration proposal_wait_for_quiet_deadline_increase = 3;
1977
+
1978
+ // Neuron Parameters
1979
+ // -----------------
1980
+
1981
+ ic_nervous_system.pb.v1.Tokens neuron_minimum_stake = 4;
1982
+
1983
+ ic_nervous_system.pb.v1.Duration neuron_minimum_dissolve_delay_to_vote = 5;
1984
+ ic_nervous_system.pb.v1.Duration neuron_maximum_dissolve_delay = 6;
1985
+ ic_nervous_system.pb.v1.Percentage neuron_maximum_dissolve_delay_bonus = 7;
1986
+
1987
+ ic_nervous_system.pb.v1.Duration neuron_maximum_age_for_age_bonus = 8;
1988
+ ic_nervous_system.pb.v1.Percentage neuron_maximum_age_bonus = 9;
1989
+
1990
+ // Voting Reward(s) Parameters
1991
+ // ---------------------------
1992
+
1993
+ message VotingRewardParameters {
1994
+ ic_nervous_system.pb.v1.Percentage initial_reward_rate = 1;
1995
+ ic_nervous_system.pb.v1.Percentage final_reward_rate = 2;
1996
+ ic_nervous_system.pb.v1.Duration reward_rate_transition_duration = 3;
1997
+ }
1998
+
1999
+ VotingRewardParameters voting_reward_parameters = 10;
2000
+ }
2001
+
2002
+ GovernanceParameters governance_parameters = 10;
2003
+ }
2004
+
2005
+ // This represents the whole NNS governance system. It contains all
2006
+ // information about the NNS governance system that must be kept
2007
+ // across upgrades of the NNS governance system.
2008
+ message Governance {
2009
+ // Current set of neurons.
2010
+ map<fixed64, Neuron> neurons = 1;
2011
+ // Proposals.
2012
+ map<uint64, ProposalData> proposals = 2;
2013
+ // The transfers that have been made to stake new neurons, but
2014
+ // haven't been claimed by the user, yet.
2015
+ repeated NeuronStakeTransfer to_claim_transfers = 3;
2016
+ // Also known as the 'normal voting period'. The maximum time a
2017
+ // proposal (of a topic with "normal" voting period) is open for
2018
+ // voting. If a proposal has not been decided (adopted or rejected)
2019
+ // within this time since the proposal was made, the proposal is
2020
+ // rejected.
2021
+ //
2022
+ // See also `short_voting_period_seconds`.
2023
+ uint64 wait_for_quiet_threshold_seconds = 5;
2024
+
2025
+ // The network economics configuration parameters.
2026
+ NetworkEconomics economics = 8;
2027
+ // The last reward event. Should never be missing.
2028
+ RewardEvent latest_reward_event = 9;
2029
+
2030
+ // The possible commands that require interaction with the ledger.
2031
+ message NeuronInFlightCommand {
2032
+ // The timestamp at which the command was issued, for debugging
2033
+ // purposes.
2034
+ uint64 timestamp = 1;
2035
+ reserved 6;
2036
+ reserved "claim_or_refresh";
2037
+ reserved 4;
2038
+
2039
+ // A general place holder for sync commands. The neuron lock is
2040
+ // never left holding a sync command (as it either succeeds to
2041
+ // acquire the lock and releases it in the same call, or never
2042
+ // acquires it in the first place), but it still must be acquired
2043
+ // to prevent interleaving with another async command. Thus there's
2044
+ // no value in actually storing the command itself, and this placeholder
2045
+ // can generally be used in all sync cases.
2046
+ message SyncCommand {}
2047
+
2048
+ oneof command {
2049
+ ManageNeuron.Disburse disburse = 2;
2050
+ ManageNeuron.Split split = 3;
2051
+ ManageNeuron.DisburseToNeuron disburse_to_neuron = 5;
2052
+ ManageNeuron.MergeMaturity merge_maturity = 7;
2053
+ ManageNeuron.ClaimOrRefresh claim_or_refresh_neuron = 8;
2054
+ ManageNeuron.Configure configure = 9;
2055
+ ManageNeuron.Merge merge = 10;
2056
+ ic_nns_common.pb.v1.NeuronId spawn = 20;
2057
+ SyncCommand sync_command = 21;
2058
+ }
2059
+ }
2060
+
2061
+ // Set of in-flight neuron ledger commands.
2062
+ //
2063
+ // Whenever we issue a ledger transfer (for disburse, split, spawn etc)
2064
+ // we store it in this map, keyed by the id of the neuron being changed
2065
+ // and remove the entry when it completes.
2066
+ //
2067
+ // An entry being present in this map acts like a "lock" on the neuron
2068
+ // and thus prevents concurrent changes that might happen due to the
2069
+ // interleaving of user requests and callback execution.
2070
+ //
2071
+ // If there are no ongoing requests, this map should be empty.
2072
+ //
2073
+ // If something goes fundamentally wrong (say we trap at some point
2074
+ // after issuing a transfer call) the neuron(s) involved are left in a
2075
+ // "locked" state, meaning new operations can't be applied without
2076
+ // reconciling the state.
2077
+ //
2078
+ // Because we know exactly what was going on, we should have the
2079
+ // information necessary to reconcile the state, using custom code
2080
+ // added on upgrade, if necessary.
2081
+ map<fixed64, NeuronInFlightCommand> in_flight_commands = 10;
2082
+
2083
+ // The timestamp, in seconds since the unix epoch, at which `canister_init` was run for
2084
+ // the governance canister, considered
2085
+ // the genesis of the IC for reward purposes.
2086
+ uint64 genesis_timestamp_seconds = 11;
2087
+
2088
+ // The entities that own the nodes running the IC.
2089
+ repeated NodeProvider node_providers = 12;
2090
+
2091
+ // Default followees
2092
+ //
2093
+ // A map of Topic (as i32) to Neuron id that is set as the default
2094
+ // following for all neurons created post-genesis.
2095
+ //
2096
+ // On initialization it's required that the Neurons present in this
2097
+ // map are present in the initial set of neurons.
2098
+ //
2099
+ // Default following can be changed via proposal.
2100
+ map<int32, Neuron.Followees> default_followees = 13;
2101
+
2102
+ // The maximum time a proposal of a topic with *short voting period*
2103
+ // is open for voting. If a proposal on a topic with short voting
2104
+ // period has not been decided (adopted or rejected) within this
2105
+ // time since the proposal was made, the proposal is rejected.
2106
+ // The short voting period is used for proposals that don't make sense to vote
2107
+ // on if the proposal is "old". For example, proposals to set the exchange
2108
+ // rate should not be voted on if they're days old because exchange rates
2109
+ // fluctuate regularly. Currently, only proposals to set the exchange rate
2110
+ // use the short voting period, and such proposals are deprecated.
2111
+ uint64 short_voting_period_seconds = 14;
2112
+
2113
+ // The maximum time a proposal of a topic with *private voting period*
2114
+ // is open for voting. If a proposal on a topic with short voting
2115
+ // period has not been decided (adopted or rejected) within this
2116
+ // time since the proposal was made, the proposal is rejected.
2117
+ // This is useful for proposals that are for "private matters" like
2118
+ // NeuronManagement proposals. These proposals are not meant to be voted on
2119
+ // by the general public and have limited impact, so a different voting period
2120
+ // is appropriate.
2121
+ optional uint64 neuron_management_voting_period_seconds = 25;
2122
+
2123
+ // Stores metrics that are too costly to compute each time metrics are
2124
+ // requested. For bucketed metrics, keys are bucket IDs, i.e., number of full
2125
+ // half-year dissolve delay intervals of neurons counted towards this bucket.
2126
+ message GovernanceCachedMetrics {
2127
+ uint64 timestamp_seconds = 1;
2128
+ uint64 total_supply_icp = 2;
2129
+ uint64 dissolving_neurons_count = 3;
2130
+ map<uint64, double> dissolving_neurons_e8s_buckets = 4;
2131
+ map<uint64, uint64> dissolving_neurons_count_buckets = 5;
2132
+ uint64 not_dissolving_neurons_count = 6;
2133
+ map<uint64, double> not_dissolving_neurons_e8s_buckets = 7;
2134
+ map<uint64, uint64> not_dissolving_neurons_count_buckets = 8;
2135
+ uint64 dissolved_neurons_count = 9;
2136
+ uint64 dissolved_neurons_e8s = 10;
2137
+ uint64 garbage_collectable_neurons_count = 11;
2138
+ uint64 neurons_with_invalid_stake_count = 12;
2139
+ uint64 total_staked_e8s = 13;
2140
+ uint64 neurons_with_less_than_6_months_dissolve_delay_count = 14;
2141
+ uint64 neurons_with_less_than_6_months_dissolve_delay_e8s = 15;
2142
+ uint64 community_fund_total_staked_e8s = 16;
2143
+ uint64 community_fund_total_maturity_e8s_equivalent = 17;
2144
+ uint64 neurons_fund_total_active_neurons = 25;
2145
+ uint64 total_locked_e8s = 18;
2146
+ uint64 total_maturity_e8s_equivalent = 19;
2147
+ uint64 total_staked_maturity_e8s_equivalent = 20;
2148
+ map<uint64, double> dissolving_neurons_staked_maturity_e8s_equivalent_buckets = 21;
2149
+ uint64 dissolving_neurons_staked_maturity_e8s_equivalent_sum = 22;
2150
+ map<uint64, double> not_dissolving_neurons_staked_maturity_e8s_equivalent_buckets = 23;
2151
+ uint64 not_dissolving_neurons_staked_maturity_e8s_equivalent_sum = 24;
2152
+ uint64 seed_neuron_count = 26;
2153
+ uint64 ect_neuron_count = 27;
2154
+ uint64 total_staked_e8s_seed = 28;
2155
+ uint64 total_staked_e8s_ect = 29;
2156
+ uint64 total_staked_maturity_e8s_equivalent_seed = 30;
2157
+ uint64 total_staked_maturity_e8s_equivalent_ect = 31;
2158
+ map<uint64, double> dissolving_neurons_e8s_buckets_seed = 32;
2159
+ map<uint64, double> dissolving_neurons_e8s_buckets_ect = 33;
2160
+ map<uint64, double> not_dissolving_neurons_e8s_buckets_seed = 34;
2161
+ map<uint64, double> not_dissolving_neurons_e8s_buckets_ect = 35;
2162
+ }
2163
+
2164
+ GovernanceCachedMetrics metrics = 15;
2165
+
2166
+ MostRecentMonthlyNodeProviderRewards most_recent_monthly_node_provider_rewards = 16;
2167
+
2168
+ // Cached value for the maturity modulation as calculated each day.
2169
+ optional int32 cached_daily_maturity_modulation_basis_points = 17;
2170
+
2171
+ // The last time that the maturity modulation value was updated.
2172
+ optional uint64 maturity_modulation_last_updated_at_timestamp_seconds = 18;
2173
+
2174
+ // Whether the heartbeat function is currently spawning neurons, meaning
2175
+ // that it should finish before being called again.
2176
+ optional bool spawning_neurons = 19;
2177
+
2178
+ // Records that making an OpenSnsTokenSwap (OSTS) or CreateServiceNervousSystem (CSNS)
2179
+ // proposal is in progress. We only want one of these to be happening at the same time,
2180
+ // because otherwise, it is error prone to enforce that open OSTS or CSNS proposals are
2181
+ // unique. In particular, the result of checking that the proposal currently being made
2182
+ // would be unique is liable to becoming invalid during an .await.
2183
+ //
2184
+ // This is a temporary measure, because OSTS is part of the SNS flow that will
2185
+ // be replaced by 1-proposal very soon.
2186
+ message MakingSnsProposal {
2187
+ ic_nns_common.pb.v1.NeuronId proposer_id = 1;
2188
+ ic_base_types.pb.v1.PrincipalId caller = 2;
2189
+ Proposal proposal = 3;
2190
+ }
2191
+
2192
+ MakingSnsProposal making_sns_proposal = 20;
2193
+
2194
+ // Progress of a migration that (potentially) is performed over the course of more than one heartbeat call.
2195
+ message Migration {
2196
+ enum MigrationStatus {
2197
+ // Unspecified.
2198
+ MIGRATION_STATUS_UNSPECIFIED = 0;
2199
+ // Migration is in progress.
2200
+ MIGRATION_STATUS_IN_PROGRESS = 1;
2201
+ // Migration succeeded.
2202
+ MIGRATION_STATUS_SUCCEEDED = 2;
2203
+ // Migration failed.
2204
+ MIGRATION_STATUS_FAILED = 3;
2205
+ }
2206
+
2207
+ // Migration status.
2208
+ optional MigrationStatus status = 1;
2209
+
2210
+ // The reason why it failed. Should only be present when the status is FAILED.
2211
+ // This is only for debugging and it should not be used programmatically (other than its presence).
2212
+ optional string failure_reason = 2;
2213
+
2214
+ // Migration progress (cursor).
2215
+ oneof progress {
2216
+ // Last neuron id migrated.
2217
+ ic_nns_common.pb.v1.NeuronId last_neuron_id = 3;
2218
+ }
2219
+ }
2220
+
2221
+ // The status of all on-going (and recently completed) migrations (that take
2222
+ // place over the course of multiple heartbeat calls).
2223
+ //
2224
+ // Each Migration field corresponds to one (ongoing or recently completed) migration.
2225
+ //
2226
+ // After a migration is finished, it should be OK to reserve the tag and lose the data.
2227
+ message Migrations {
2228
+ // Migrates neuron indexes to stable storage.
2229
+ Migration neuron_indexes_migration = 1;
2230
+ Migration copy_inactive_neurons_to_stable_memory_migration = 2;
2231
+
2232
+ // TODO(NNS1-2533): Migration delete_inactive_neurons_from_heap = 3;
2233
+ }
2234
+
2235
+ // Migration related data.
2236
+ Migrations migrations = 21;
2237
+
2238
+ // A map of followees to their followers.
2239
+ message FollowersMap {
2240
+ message Followers {
2241
+ // The followers of the neuron with the given ID.
2242
+ // These values will be non-repeating, and order does not matter.
2243
+ repeated ic_nns_common.pb.v1.NeuronId followers = 1;
2244
+ }
2245
+ // The key is the neuron ID of the followee.
2246
+ map<fixed64, Followers> followers_map = 1;
2247
+ }
2248
+
2249
+ // A Structure used during upgrade to store the index of topics for neurons to their followers.
2250
+ // This is the inverse of what is stored in a Neuron (its followees).
2251
+ map<int32, FollowersMap> topic_followee_index = 22;
2252
+
2253
+ reserved 6;
2254
+ reserved "authz";
2255
+
2256
+ // Reserved id for deprecated `seed_accounts`
2257
+ reserved 23;
2258
+ reserved "seed_accounts";
2259
+
2260
+ // Reserved id for deprecated `genesis_neuron_accounts`
2261
+ reserved 24;
2262
+ reserved "genesis_neuron_accounts";
2263
+
2264
+ // Local cache for XDR-related conversion rates (the source of truth is in the CMC canister).
2265
+ optional XdrConversionRate xdr_conversion_rate = 26;
2266
+
2267
+ // The summary of restore aging event.
2268
+ optional RestoreAgingSummary restore_aging_summary = 27;
2269
+ }
2270
+
2271
+ message XdrConversionRate {
2272
+ /// Time at which this rate has been fetched.
2273
+ optional uint64 timestamp_seconds = 1;
2274
+
2275
+ /// One ICP is worth this number of 1/10,000ths parts of an XDR.
2276
+ optional uint64 xdr_permyriad_per_icp = 2;
2277
+ }
2278
+
2279
+ // Proposals with restricted voting are not included unless the caller
2280
+ // is allowed to vote on them.
2281
+ //
2282
+ // The actual ballots of the proposal are restricted to ballots cast
2283
+ // by the caller.
2284
+ message ListProposalInfo {
2285
+ // Limit on the number of [ProposalInfo] to return. If no value is
2286
+ // specified, or if a value greater than 100 is specified, 100
2287
+ // will be used.
2288
+ uint32 limit = 1;
2289
+ // If specified, only return proposals that are strictly earlier than
2290
+ // the specified proposal according to the proposal ID. If not
2291
+ // specified, start with the most recent proposal.
2292
+ ic_nns_common.pb.v1.ProposalId before_proposal = 2;
2293
+ // Exclude proposals with a topic in this list. This is particularly
2294
+ // useful to exclude proposals on the topics TOPIC_EXCHANGE_RATE and
2295
+ // TOPIC_KYC which most users are not likely to be interested in
2296
+ // seeing.
2297
+ repeated Topic exclude_topic = 3;
2298
+ // Include proposals that have a reward status in this list (see
2299
+ // [ProposalRewardStatus] for more information). If this list is
2300
+ // empty, no restriction is applied. For example, many users listing
2301
+ // proposals will only be interested in proposals for which they can
2302
+ // receive voting rewards, i.e., with reward status
2303
+ // PROPOSAL_REWARD_STATUS_ACCEPT_VOTES.
2304
+ repeated ProposalRewardStatus include_reward_status = 4;
2305
+ // Include proposals that have a status in this list (see
2306
+ // [ProposalStatus] for more information). If this list is empty, no
2307
+ // restriction is applied.
2308
+ repeated ProposalStatus include_status = 5;
2309
+ // Include all ManageNeuron proposals regardless of the visibility of the
2310
+ // proposal to the caller principal. Note that exclude_topic is still
2311
+ // respected even when this option is set to true.
2312
+ optional bool include_all_manage_neuron_proposals = 6;
2313
+ // Omits "large fields" from the response. Currently only omits the
2314
+ // `logo` and `token_logo` field of CreateServiceNervousSystem proposals. This
2315
+ // is useful to improve download times and to ensure that the response to the
2316
+ // request doesn't exceed the message size limit.
2317
+ optional bool omit_large_fields = 7;
2318
+ }
2319
+
2320
+ message ListProposalInfoResponse {
2321
+ repeated ProposalInfo proposal_info = 1;
2322
+ }
2323
+
2324
+ // A request to list neurons. The "requested list", i.e., the list of
2325
+ // neuron IDs to retrieve information about, is the union of the list
2326
+ // of neurons listed in `neuron_ids` and, if `caller_neurons` is true,
2327
+ // the list of neuron IDs of neurons for which the caller is the
2328
+ // controller or one of the hot keys.
2329
+ message ListNeurons {
2330
+ option (ic_base_types.pb.v1.tui_signed_message) = true;
2331
+ // The neurons to get information about. The "requested list"
2332
+ // contains all of these neuron IDs.
2333
+ repeated fixed64 neuron_ids = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
2334
+ // If true, the "requested list" also contains the neuron ID of the
2335
+ // neurons that the calling principal is authorized to read.
2336
+ bool include_neurons_readable_by_caller = 2 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
2337
+ }
2338
+
2339
+ // A response to a `ListNeurons` request.
2340
+ //
2341
+ // The "requested list" is described in `ListNeurons`.
2342
+ message ListNeuronsResponse {
2343
+ // For each neuron ID in the "requested list", if this neuron exists,
2344
+ // its `NeuronInfo` at the time of the call will be in this map.
2345
+ map<fixed64, NeuronInfo> neuron_infos = 1;
2346
+ // For each neuron ID in the "requested list", if the neuron exists,
2347
+ // and the caller is authorized to read the full neuron (controller,
2348
+ // hot key, or controller or hot key of some followee on the
2349
+ // `ManageNeuron` topic).
2350
+ repeated Neuron full_neurons = 2;
2351
+ }
2352
+
2353
+ // A response to "ListKnownNeurons"
2354
+ message ListKnownNeuronsResponse {
2355
+ // List of known neurons.
2356
+ repeated KnownNeuron known_neurons = 1;
2357
+ }
2358
+
2359
+ // Response to list_node_providers
2360
+ message ListNodeProvidersResponse {
2361
+ // List of all "NodeProviders"
2362
+ repeated NodeProvider node_providers = 1;
2363
+ }
2364
+
2365
+ // The arguments to the method `claim_or_refresh_neuron_from_account`.
2366
+ //
2367
+ // DEPRECATED: Use ManageNeuron::ClaimOrRefresh.
2368
+ message ClaimOrRefreshNeuronFromAccount {
2369
+ // The principal for which to refresh the account. If not specified,
2370
+ // defaults to the caller.
2371
+ ic_base_types.pb.v1.PrincipalId controller = 1;
2372
+ // The memo of the staking transaction.
2373
+ uint64 memo = 2;
2374
+ }
2375
+
2376
+ // Response to claim_or_refresh_neuron_from_account.
2377
+ //
2378
+ // DEPRECATED: Use ManageNeuron::ClaimOrRefresh.
2379
+ message ClaimOrRefreshNeuronFromAccountResponse {
2380
+ oneof result {
2381
+ // Specified in case of error.
2382
+ GovernanceError error = 1;
2383
+ // The ID of the neuron that was created or empty in the case of error.
2384
+ ic_nns_common.pb.v1.NeuronId neuron_id = 2;
2385
+ }
2386
+ }
2387
+
2388
+ // The most recent monthly Node Provider rewards
2389
+ message MostRecentMonthlyNodeProviderRewards {
2390
+ uint64 timestamp = 1;
2391
+ repeated RewardNodeProvider rewards = 2;
2392
+ }
2393
+
2394
+ // TODO(NNS1-1589): Until the Jira ticket gets solved, changes here need to be
2395
+ // manually propagated to (sns) swap.proto.
2396
+ // This message is obsolete; please use SettleNeuronsFundParticipation instead.
2397
+ message SettleCommunityFundParticipation {
2398
+ // The caller's principal ID must match the value in the
2399
+ // target_swap_canister_id field in the proposal (more precisely, in the
2400
+ // OpenSnsTokenSwap).
2401
+ optional uint64 open_sns_token_swap_proposal_id = 1;
2402
+
2403
+ // Each of the possibilities here corresponds to one of two ways that a swap
2404
+ // can terminate. See also sns_swap_pb::Lifecycle::is_terminal.
2405
+ oneof result {
2406
+ Committed committed = 2;
2407
+ Aborted aborted = 3;
2408
+ }
2409
+
2410
+ // When this happens, ICP needs to be minted, and sent to the SNS governance
2411
+ // canister's main account on the ICP Ledger. As with Aborted, the amount of
2412
+ // ICP that needs to be minted can be deduced from the ProposalData's
2413
+ // cf_participants field.
2414
+ message Committed {
2415
+ // This is where the minted ICP will be sent. In principal, this could be
2416
+ // fetched using the swap canister's get_state method.
2417
+ ic_base_types.pb.v1.PrincipalId sns_governance_canister_id = 1;
2418
+ // Total contribution amount from direct swap participants.
2419
+ optional uint64 total_direct_contribution_icp_e8s = 2;
2420
+ // Total contribution amount from the Neuron's Fund.
2421
+ // TODO[NNS1-2570]: Ensure this field is set.
2422
+ optional uint64 total_neurons_fund_contribution_icp_e8s = 3;
2423
+ }
2424
+
2425
+ // When this happens, maturity needs to be restored to CF neurons. The amounts
2426
+ // to be refunded can be found in the ProposalData's cf_participants field.
2427
+ message Aborted {}
2428
+ }
2429
+
2430
+ // Request to settle the Neurons' Fund participation in this SNS Swap.
2431
+ //
2432
+ // When a swap ends, the Swap canister notifies the Neurons' Fund of the swap's ultimate result,
2433
+ // which can be either `Committed` or `Aborted`. Note that currently, the Neurons' Fund is managed
2434
+ // by the NNS Governance canister.
2435
+ // * If the result is `Committed`:
2436
+ // - Neurons' Fund computes the "effective" participation amount for each of its neurons (as per
2437
+ // the Matched Funding rules). This computation is based on the total direct participation
2438
+ // amount, which is thus a field of `Committed`.
2439
+ // - Neurons' Fund converts the "effective" amount of maturity into ICP by:
2440
+ // - Requesting the ICP Ledger to mint an appropriate amount of ICP tokens and sending them
2441
+ // to the SNS treasury.
2442
+ // - Refunding whatever maturity is left over (the maximum possible maturity is reserved by
2443
+ // the Neurons' Fund before the swap begins).
2444
+ // - Neurons' Fund returns the Neurons' Fund participants back to the Swap canister
2445
+ // (see SettleNeuronsFundParticipationResponse).
2446
+ // - The Swap canister then creates SNS neurons for the Neurons' Fund participants.
2447
+ // * If the result is Aborted, the Neurons' Fund is refunded for all maturity reserved for this SNS.
2448
+ //
2449
+ // This design assumes trust between the Neurons' Fund and the SNS Swap canisters. In the one hand,
2450
+ // the Swap trusts that the Neurons' Fund sends the correct amount of ICP to the SNS treasury,
2451
+ // and that the Neurons' Fund allocates its participants following the Matched Funding rules. On the
2452
+ // other hand, the Neurons' Fund trusts that the Swap will indeed create appropriate SNS neurons
2453
+ // for the Neurons' Fund participants.
2454
+ //
2455
+ // The justification for this trust assumption is as follows. The Neurons' Fund can be trusted as
2456
+ // it is controlled by the NNS. The SNS Swap can be trusted as it is (1) deployed by SNS-W, which is
2457
+ // also part of the NNS and (2) upgraded via an NNS proposal (unlike all other SNS canisters).
2458
+ //
2459
+ // This request may be submitted only by the Swap canister of an SNS instance created by
2460
+ // a CreateServiceNervousSystem proposal.
2461
+ //
2462
+ // TODO(NNS1-1589): Until the Jira ticket gets solved, changes here need to be
2463
+ // manually propagated to (sns) swap.proto.
2464
+ message SettleNeuronsFundParticipationRequest {
2465
+ // Proposal ID of the CreateServiceNervousSystem proposal that created this SNS instance.
2466
+ optional uint64 nns_proposal_id = 1;
2467
+
2468
+ // Each of the possibilities here corresponds to one of two ways that a swap can terminate.
2469
+ // See also sns_swap_pb::Lifecycle::is_terminal.
2470
+ oneof result {
2471
+ Committed committed = 2;
2472
+ Aborted aborted = 3;
2473
+ }
2474
+
2475
+ // When this happens, the NNS Governance needs to do several things:
2476
+ // (1) Compute the effective amount of ICP per neuron of the Neurons' Fund as a function of
2477
+ // `total_direct_participation_icp_e8s`. The overall Neurons' Fund participation should
2478
+ // equal `total_neurons_fund_contribution_icp_e8s`.
2479
+ // (2) Mint (via the ICP Ledger) and sent to the SNS governance the amount of
2480
+ // `total_neurons_fund_contribution_icp_e8s`.
2481
+ // (3) Respond to this request with `SettleNeuronsFundParticipationResponse`, providing
2482
+ // the set of `NeuronsFundParticipant`s with the effective amount of ICP per neuron,
2483
+ // as computed in step (1).
2484
+ // (4) Refund each neuron of the Neurons' Fund with (reserved - effective) amount of ICP.
2485
+ // Effective amounts depend on `total_direct_participation_icp_e8s` and the participation limits
2486
+ // of a particular SNS instance, namely, each participation must be between
2487
+ // `min_participant_icp_e8s` and `max_participant_icp_e8s`.
2488
+ // - If a neuron of the Neurons' Fund has less than `min_participant_icp_e8s` worth of maturity,
2489
+ // then it is ineligible to participate.
2490
+ // - If a neuron of the Neurons' Fund has more than `max_participant_icp_e8s` worth of maturity,
2491
+ // then its participation amount is limited to `max_participant_icp_e8s`.
2492
+ // Reserved amounts are computed as the minimal upper bound on the effective amounts, i.e., when
2493
+ // the value `total_direct_participation_icp_e8s` reaches its theoretical maximum.
2494
+ message Committed {
2495
+ // This is where the minted ICP will be sent.
2496
+ ic_base_types.pb.v1.PrincipalId sns_governance_canister_id = 1;
2497
+ // Total amount of participation from direct swap participants.
2498
+ optional uint64 total_direct_participation_icp_e8s = 2;
2499
+ // Total amount of participation from the Neurons' Fund.
2500
+ // TODO[NNS1-2570]: Ensure this field is set.
2501
+ optional uint64 total_neurons_fund_participation_icp_e8s = 3;
2502
+ }
2503
+
2504
+ // When this happens, all priorly reserved maturity for this SNS instance needs to be restored to
2505
+ // the Neurons' Fund neurons.
2506
+ message Aborted {}
2507
+ }
2508
+
2509
+ // Handling the Neurons' Fund and transferring some of its maturity to an SNS treasury is
2510
+ // thus the responsibility of the NNS Governance. When a swap succeeds, a Swap canister should send
2511
+ // a `settle_neurons_fund_participation` request to the NNS Governance, specifying its `result`
2512
+ // field as `committed`. The NNS Governance then computes the ultimate distribution of maturity in
2513
+ // the Neurons' Fund. However, this distribution also needs to be made available to the SNS Swap
2514
+ // that will use this information to create SNS neurons of an appropriate size for each
2515
+ // Neurons' Fund (as well as direct) participant. That is why in the `committed` case,
2516
+ // the NNS Governance should populate the `neurons_fund_participants` field, while in the `aborted`
2517
+ // case it should be empty.
2518
+ //
2519
+ // TODO(NNS1-1589): Until the Jira ticket gets solved, changes here need to be
2520
+ // manually propagated to (sns) swap.proto.
2521
+ message SettleNeuronsFundParticipationResponse {
2522
+ // Represents one NNS neuron from the Neurons' Fund participating in this swap.
2523
+ message NeuronsFundNeuron {
2524
+ // The NNS neuron ID of the participating neuron.
2525
+ optional uint64 nns_neuron_id = 1;
2526
+ // The amount of Neurons' Fund participation associated with this neuron.
2527
+ optional uint64 amount_icp_e8s = 2;
2528
+ // The principal that can vote on behalf of this neuron.
2529
+ optional string hotkey_principal = 3;
2530
+ // Whether the amount maturity amount of Neurons' Fund participation associated with this neuron
2531
+ // has been capped to reflect the maximum participation amount for this SNS swap.
2532
+ optional bool is_capped = 4;
2533
+ }
2534
+
2535
+ // Request was completed successfully.
2536
+ message Ok {
2537
+ repeated NeuronsFundNeuron neurons_fund_neuron_portions = 1;
2538
+ }
2539
+
2540
+ oneof result {
2541
+ GovernanceError err = 1;
2542
+ Ok ok = 2;
2543
+ }
2544
+ }
2545
+
2546
+ // Audit events in order to leave an audit trail for certain operations.
2547
+ message AuditEvent {
2548
+ // The timestamp of the event.
2549
+ uint64 timestamp_seconds = 1;
2550
+
2551
+ oneof payload {
2552
+ // Reset aging timestamps for https://forum.dfinity.org/t/icp-neuron-age-is-52-years/21261/26
2553
+ ResetAging reset_aging = 2;
2554
+ // Restore aging timestamp that were incorrectly reset.
2555
+ RestoreAging restore_aging = 3;
2556
+ }
2557
+
2558
+ message ResetAging {
2559
+ // The neuron id whose aging was reset.
2560
+ fixed64 neuron_id = 1;
2561
+
2562
+ // The aging_since_timestamp_seconds before reset.
2563
+ uint64 previous_aging_since_timestamp_seconds = 2;
2564
+
2565
+ // The aging_since_timestamp_seconds after reset.
2566
+ uint64 new_aging_since_timestamp_seconds = 3;
2567
+
2568
+ // Neuron's dissolve state at the time of reset.
2569
+ oneof neuron_dissolve_state {
2570
+ uint64 when_dissolved_timestamp_seconds = 4;
2571
+ uint64 dissolve_delay_seconds = 5;
2572
+ }
2573
+
2574
+ // Neuron's stake at the time of reset.
2575
+ uint64 neuron_stake_e8s = 6;
2576
+ }
2577
+
2578
+ message RestoreAging {
2579
+ // The neuron id whose aging was restored.
2580
+ optional uint64 neuron_id = 1;
2581
+
2582
+ // The aging_since_timestamp_seconds before restore.
2583
+ optional uint64 previous_aging_since_timestamp_seconds = 2;
2584
+
2585
+ // The aging_since_timestamp_seconds after restore.
2586
+ optional uint64 new_aging_since_timestamp_seconds = 3;
2587
+
2588
+ // Neuron's dissolve state at the time of restore.
2589
+ oneof neuron_dissolve_state {
2590
+ uint64 when_dissolved_timestamp_seconds = 4;
2591
+ uint64 dissolve_delay_seconds = 5;
2592
+ }
2593
+
2594
+ // Neuron's stake at the time of restore.
2595
+ optional uint64 neuron_stake_e8s = 6;
2596
+ }
2597
+ }
2598
+
2599
+ // The summary of the restore aging event.
2600
+ message RestoreAgingSummary {
2601
+ // The timestamp of the restore aging event.
2602
+ optional uint64 timestamp_seconds = 1;
2603
+ // Groups of neurons that were considered for restoring their aging.
2604
+ repeated RestoreAgingNeuronGroup groups = 2;
2605
+
2606
+ enum NeuronGroupType {
2607
+ NEURON_GROUP_TYPE_UNSPECIFIED = 0;
2608
+ // The neurons in this group were not pre-aging. We don't restore their aging.
2609
+ NEURON_GROUP_TYPE_NOT_PRE_AGING = 1;
2610
+ // The neurons in this group are dissolving or dissolved. We don't restore their aging because
2611
+ // it's invalid for a dissolving/dissolved neuron to have age.
2612
+ NEURON_GROUP_TYPE_DISSOLVING_OR_DISSOLVED = 2;
2613
+ // The neurons in this group have their stake changed. We restore them to be pre-aged.
2614
+ NEURON_GROUP_TYPE_STAKE_CHANGED = 3;
2615
+ // The neurons in this group have their stake remain the same and aging changed. We restore them
2616
+ // to be pre-aged.
2617
+ NEURON_GROUP_TYPE_STAKE_SAME_AGING_CHANGED = 4;
2618
+ // The neurons in this group have their stake remain the same and aging remain the same. We
2619
+ // restore them to be pre-aged.
2620
+ NEURON_GROUP_TYPE_STAKE_SAME_AGING_SAME = 5;
2621
+ }
2622
+
2623
+ message RestoreAgingNeuronGroup {
2624
+ NeuronGroupType group_type = 1;
2625
+ // The number of neurons in this group.
2626
+ optional uint64 count = 2;
2627
+ // The previous total stake of neurons in this group when the aging was reset.
2628
+ optional uint64 previous_total_stake_e8s = 3;
2629
+ // The current total stake of neurons in this group when considering to restore aging.
2630
+ optional uint64 current_total_stake_e8s = 4;
2631
+ }
293
2632
  }