-
Notifications
You must be signed in to change notification settings - Fork 325
/
governance.proto
3034 lines (2647 loc) · 129 KB
/
governance.proto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
syntax = "proto3";
package ic_nns_governance.pb.v1;
import "ic_base_types/pb/v1/types.proto";
import "ic_ledger/pb/v1/types.proto";
import "ic_nervous_system/pb/v1/nervous_system.proto";
import "ic_nns_common/pb/v1/types.proto";
import "ic_sns_swap/pb/v1/swap.proto";
// The entity that owns the nodes that run the network.
//
// Note that this is different from a node operator, the entity that
// operates the nodes. In terms of responsibilities, the node operator
// is responsible for adding/removing and generally making sure that
// the nodes are working, while the NodeProvider is the entity that
// is compensated.
//
// Note: The NodeOperatorRecord is defined in:
// rs/protobuf/def/registry/node_operator/v1/node_operator.proto.
message NodeProvider {
// The ID of the node provider.
ic_base_types.pb.v1.PrincipalId id = 1;
// The account where rewards earned from providing nodes will be sent.
ic_ledger.pb.v1.AccountIdentifier reward_account = 2;
}
// Used to update node provider records
//
// There is no need to specify a node provider Principal ID here, as Governance
// uses the Principal ID of the caller as the Node Provider Principal ID.
message UpdateNodeProvider {
// The account where rewards earned from providing nodes will be sent.
ic_ledger.pb.v1.AccountIdentifier reward_account = 1;
}
// Proposal types are organized into topics. Neurons can automatically
// vote based on following other neurons, and these follow
// relationships are defined per topic.
enum Topic {
// The `Unspecified` topic is used as a fallback when
// following. That is, if no followees are specified for a given
// topic, the followees for this topic are used instead.
TOPIC_UNSPECIFIED = 0;
// A special topic by means of which a neuron can be managed by the
// followees for this topic (in this case, there is no fallback to
// 'unspecified'). Votes on this topic are not included in the
// voting history of the neuron (cf., `recent_ballots` in `Neuron`).
//
// For proposals on this topic, only followees on the 'neuron
// management' topic of the neuron that the proposals pertains to
// are allowed to vote.
//
// As the set of eligible voters on this topic is restricted,
// proposals on this topic have a *short voting period*.
TOPIC_NEURON_MANAGEMENT = 1;
// All proposals that provide “real time” information about the
// value of ICP, as measured by an IMF SDR, which allows the NNS to
// convert ICP to cycles (which power computation) at a rate which
// keeps their real world cost constant. Votes on this topic are not
// included in the voting history of the neuron (cf.,
// `recent_ballots` in `Neuron`).
//
// Proposals on this topic have a *short voting period* due to their
// frequency.
TOPIC_EXCHANGE_RATE = 2;
// All proposals that administer network economics, for example,
// determining what rewards should be paid to node operators.
TOPIC_NETWORK_ECONOMICS = 3;
// All proposals that administer governance, for example to freeze
// malicious canisters that are harming the network.
TOPIC_GOVERNANCE = 4;
// All proposals that administer node machines, including, but not
// limited to, upgrading or configuring the OS, upgrading or
// configuring the virtual machine framework and upgrading or
// configuring the node replica software.
TOPIC_NODE_ADMIN = 5;
// All proposals that administer network participants, for example,
// granting and revoking DCIDs (data center identities) or NOIDs
// (node operator identities).
TOPIC_PARTICIPANT_MANAGEMENT = 6;
// All proposals that administer network subnets, for example
// creating new subnets, adding and removing subnet nodes, and
// splitting subnets.
TOPIC_SUBNET_MANAGEMENT = 7;
// All proposals to manage NNS-controlled canisters not covered by other topics (Protocol Canister
// Management or Service Nervous System Management).
TOPIC_NETWORK_CANISTER_MANAGEMENT = 8;
// Proposals that update KYC information for regulatory purposes,
// for example during the initial Genesis distribution of ICP in the
// form of neurons.
TOPIC_KYC = 9;
// Topic for proposals to reward node providers.
TOPIC_NODE_PROVIDER_REWARDS = 10;
// IC OS upgrade proposals
// -----------------------
// ICP runs on a distributed network of nodes grouped into subnets. Each node runs a stack of
// operating systems, including HostOS (runs on bare metal) and GuestOS (runs inside HostOS;
// contains, e.g., the ICP replica process). HostOS and GuestOS are distributed via separate disk
// images. The umbrella term IC OS refers to the whole stack.
//
// The IC OS upgrade process involves two phases, where the first phase is the election of a new
// IC OS version and the second phase is the deployment of a previously elected IC OS version on
// all nodes of a subnet or on some number of nodes (including nodes comprising subnets and
// unassigned nodes).
//
// A special case is for API boundary nodes, special nodes that route API requests to a replica
// of the right subnet. API boundary nodes run a different process than the replica, but their
// executable is distributed via the same disk image as GuestOS. Therefore, electing a new GuestOS
// version also results in a new version of boundary node software being elected.
//
// Proposals handling the deployment of IC OS to some nodes. It is possible to deploy only
// the versions of IC OS that are in the set of elected IC OS versions.
TOPIC_IC_OS_VERSION_DEPLOYMENT = 12;
// Proposals for changing the set of elected IC OS versions.
TOPIC_IC_OS_VERSION_ELECTION = 13;
// Proposals related to SNS and Community Fund.
TOPIC_SNS_AND_COMMUNITY_FUND = 14;
// Proposals related to the management of API Boundary Nodes
TOPIC_API_BOUNDARY_NODE_MANAGEMENT = 15;
// Proposals related to subnet rental.
TOPIC_SUBNET_RENTAL = 16;
// All proposals to manage protocol canisters, which are considered part of the ICP protocol and
// are essential for its proper functioning.
TOPIC_PROTOCOL_CANISTER_MANAGEMENT = 17;
// All proposals to manage the canisters of service nervous systems (SNS), including upgrading
// relevant canisters and managing SNS framework canister WASMs through SNS-W.
TOPIC_SERVICE_NERVOUS_SYSTEM_MANAGEMENT = 18;
// Superseded by SNS_COMMUNITY_FUND.
reserved 11;
reserved "TOPIC_SNS_DECENTRALIZATION_SALE";
}
// Every neuron is in one of three states.
//
// Note that `Disbursed` is not a state of a neuron, as the neuron is
// consumed through the act of disbursement (using the method
// [Governance::disburse]).
//
// See [neuron::DissolveState] for detail on how the different states
// are represented.
enum NeuronState {
// Not a valid state. Required by Protobufs.
NEURON_STATE_UNSPECIFIED = 0;
// In this state, the neuron is not dissolving and has a specific
// `dissolve_delay`. It accrues `age` by the passage of time and it
// can vote if `dissolve_delay` is at least six months. The method
// [Neuron::start_dissolving] can be called to transfer the neuron
// to the `Dissolving` state. The method
// [Neuron::increase_dissolve_delay] can be used to increase the
// dissolve delay without affecting the state or the age of the
// neuron.
NEURON_STATE_NOT_DISSOLVING = 1;
// In this state, the neuron's `dissolve_delay` decreases with the
// passage of time. While dissolving, the neuron's age is considered
// zero. Eventually it will reach the `Dissolved` state. The method
// [Neuron::stop_dissolving] can be called to transfer the neuron to
// the `NotDissolving` state, and the neuron will start aging again. The
// method [Neuron::increase_dissolve_delay] can be used to increase
// the dissolve delay, but this will not stop the timer or affect
// the age of the neuron.
NEURON_STATE_DISSOLVING = 2;
// In the dissolved state, the neuron's stake can be disbursed using
// the [Governance::disburse] method. It cannot vote as its
// `dissolve_delay` is considered to be zero.
//
// If the method [Neuron::increase_dissolve_delay] is called in this
// state, the neuron will no longer be dissolving, with the specified
// dissolve delay, and will start aging again.
//
// Neuron holders have an incentive not to keep neurons in the
// 'dissolved' state for a long time: if the holders wants to make
// their tokens liquid, they disburse the neuron's stake, and if
// they want to earn voting rewards, they increase the dissolve
// delay. If these incentives turn out to be insufficient, the NNS
// may decide to impose further restrictions on dissolved neurons.
NEURON_STATE_DISSOLVED = 3;
// The neuron is in spawning state, meaning it's maturity will be
// converted to ICP according to https://wiki.internetcomputer.org/wiki/Maturity_modulation.
NEURON_STATE_SPAWNING = 4;
}
// How did a neuron vote in the recent past? This data is used by
// other neurons to determine what neurons to follow.
message BallotInfo {
ic_nns_common.pb.v1.ProposalId proposal_id = 1;
Vote vote = 2;
}
// Controls how much information non-controller and non-hot-key principals can
// see about this neuron. Currently, if a neuron is private, recent_ballots and
// joined_community_fund_timestamp_seconds are redacted when being read by an
// unprivileged principal.
//
// https://forum.dfinity.org/t/request-for-comments-api-changes-for-public-private-neurons/33360
//
// As of Jul 19, this is not yet enforced, but will be once the plan described
// above is fully executed.
enum Visibility {
VISIBILITY_UNSPECIFIED = 0;
VISIBILITY_PRIVATE = 1;
VISIBILITY_PUBLIC = 2;
}
// The result of querying for the state of a single neuron.
message NeuronInfo {
// The exact time at which this data was computed. This means, for
// example, that the exact time that this neuron will enter the
// dissolved state, assuming it is currently dissolving, is given
// by `retrieved_at_timestamp_seconds+dissolve_delay_seconds`.
uint64 retrieved_at_timestamp_seconds = 1;
// The current state of the neuron. See [NeuronState] for a
// description of the different states.
NeuronState state = 2;
// The current age of the neuron. See [Neuron::age_seconds]
// for details on how it is computed.
uint64 age_seconds = 3;
// The current dissolve delay of the neuron. See
// [Neuron::dissolve_delay_seconds] for details on how it is
// computed.
uint64 dissolve_delay_seconds = 4;
// See [Neuron::recent_ballots] for a description.
repeated BallotInfo recent_ballots = 5;
// Current voting power of the neuron.
uint64 voting_power = 6;
// When the Neuron was created. A neuron can only vote on proposals
// submitted after its creation date.
uint64 created_timestamp_seconds = 7;
// Current stake of the neuron, in e8s.
uint64 stake_e8s = 8;
// Timestamp when this neuron joined the community fund.
optional uint64 joined_community_fund_timestamp_seconds = 9;
// If this neuron is a known neuron, this is data associated
// with it, including the neuron's name and (optionally) a description.
optional KnownNeuronData known_neuron_data = 10;
// The type of the Neuron. See [NeuronType] for a description
// of the different states.
optional NeuronType neuron_type = 11;
// See the Visibility enum.
optional Visibility visibility = 12;
// The last time that voting power was "refreshed". There are two ways to
// refresh the voting power of a neuron: set following, or vote directly. In
// the future, there will be a dedicated API for refreshing. Note that direct
// voting implies that refresh also occurs when a proposal is created, because
// direct voting is part of proposal creation.
//
// Effect: When this becomes > 6 months ago, the amount of voting power that
// this neuron can exercise decreases linearly down to 0 over the course of 1
// month. After that, following is cleared, except for ManageNeuron proposals.
//
// This will always be populated. If the underlying neuron was never
// refreshed, this will be set to 2024-11-05T00:00:01 UTC (1730764801 seconds
// after the UNIX epoch).
optional uint64 voting_power_refreshed_timestamp_seconds = 13;
// See the analogous field in Nueron.
optional uint64 deciding_voting_power = 14;
// See the analogous field in Neuron.
optional uint64 potential_voting_power = 15;
}
// A transfer performed from some account to stake a new neuron.
message NeuronStakeTransfer {
// When the transfer arrived at the governance canister.
uint64 transfer_timestamp = 1;
// The principal that made the transfer.
ic_base_types.pb.v1.PrincipalId from = 2;
// The (optional) subaccount from which the transfer was made.
bytes from_subaccount = 3;
// The subaccount to which the transfer was made.
bytes to_subaccount = 4;
// The amount of stake that was transferred.
uint64 neuron_stake_e8s = 5;
// The block height at which the transfer occurred.
uint64 block_height = 6;
// The memo sent with the transfer.
uint64 memo = 7;
}
// This structure represents a neuron "at rest" in governance system of
// the Internet Computer IC.
message Neuron {
// The id of the neuron.
//
// This is stored here temporarily, since its also stored on the map
// that contains neurons.
//
// Initialization uses ids for the following graph. We need neurons
// to come into existence at genesis with pre-chosen ids, so a
// neuron needs to have an id. We could alternatively choose a
// unique naming scheme instead and chose the ids on the
// initialization of the canister.
ic_nns_common.pb.v1.NeuronId id = 1;
// The principal of the ICP ledger account where the locked ICP
// balance resides. This principal is indistinguishable from one
// identifying a public key pair, such that those browsing the ICP
// ledger cannot tell which balances belong to neurons.
bytes account = 2;
// The principal that actually controls the neuron. The principal
// must identify a public key pair, which acts as a “master key”,
// such that the corresponding secret key should be kept very
// secure. The principal may control many neurons.
ic_base_types.pb.v1.PrincipalId controller = 3;
// Keys that can be used to perform actions with limited privileges
// without exposing the secret key corresponding to the principal
// e.g. could be a WebAuthn key.
repeated ic_base_types.pb.v1.PrincipalId hot_keys = 4;
// The amount of staked ICP tokens, measured in fractions of 10E-8
// of an ICP.
//
// Cached record of the locked ICP balance on the ICP ledger.
//
// For neuron creation: has to contain some minimum amount. A
// spawned neuron with less stake cannot increase its dissolve
// delay.
uint64 cached_neuron_stake_e8s = 5;
// The amount of ICP that this neuron has forfeited due to making
// proposals that were subsequently rejected or from using the
// 'manage neurons through proposals' functionality. Must be smaller
// than 'neuron_stake_e8s'. When a neuron is disbursed, these ICP
// will be burned.
uint64 neuron_fees_e8s = 6;
// When the Neuron was created. A neuron can only vote on proposals
// submitted after its creation date.
uint64 created_timestamp_seconds = 7;
// The timestamp, in seconds from the Unix epoch, corresponding to
// the time this neuron has started aging. This is either the
// creation time or the last time at which the neuron has stopped
// dissolving.
//
// This value is meaningless when the neuron is dissolving, since a
// dissolving neurons always has age zero. The canonical value of
// this field for a dissolving neuron is `u64::MAX`.
uint64 aging_since_timestamp_seconds = 8;
// The timestamp, in seconds from the Unix epoch, at which this
// neuron should be spawned and its maturity converted to ICP
// according to https://wiki.internetcomputer.org/wiki/Maturity_modulation.
optional uint64 spawn_at_timestamp_seconds = 19;
// At any time, at most one of `when_dissolved` and
// `dissolve_delay` are specified.
//
// `NotDissolving`. This is represented by `dissolve_delay` being
// set to a non zero value.
//
// `Dissolving`. This is represented by `when_dissolved` being
// set, and this value is in the future.
//
// `Dissolved`. All other states represent the dissolved
// state. That is, (a) `when_dissolved` is set and in the past,
// (b) `dissolve_delay` is set to zero, (c) neither value is set.
//
// Cf. [Neuron::stop_dissolving] and [Neuron::start_dissolving].
oneof dissolve_state {
// When the dissolve timer is running, this stores the timestamp,
// in seconds from the Unix epoch, at which the neuron becomes
// dissolved.
//
// At any time while the neuron is dissolving, the neuron owner
// may pause dissolving, in which case `dissolve_delay_seconds`
// will get assigned to: `when_dissolved_timestamp_seconds -
// <timestamp when the action is taken>`.
uint64 when_dissolved_timestamp_seconds = 9;
// When the dissolve timer is stopped, this stores how much time,
// in seconds, the dissolve timer will be started with. Can be at
// most 8 years.
//
// At any time while in this state, the neuron owner may (re)start
// dissolving, in which case `when_dissolved_timestamp_seconds`
// will get assigned to: `<timestamp when the action is taken> +
// dissolve_delay_seconds`.
uint64 dissolve_delay_seconds = 10;
}
// Protobuf representing a list of followees of a neuron for a
// specific topic.
message Followees {
repeated ic_nns_common.pb.v1.NeuronId followees = 1;
}
// Map `Topic` to followees. The key is represented by an integer as
// Protobuf does not support enum keys in maps.
map<int32, Followees> followees = 11;
// Information about how this neuron voted in the recent past. It
// only contains proposals that the neuron voted yes or no on.
repeated BallotInfo recent_ballots = 12;
// `true` if this neuron has passed KYC, `false` otherwise
bool kyc_verified = 13;
// The record of the transfer that was made to create this neuron.
NeuronStakeTransfer transfer = 14;
// The accumulated unstaked maturity of the neuron, in "e8s equivalent".
//
// The unit is "e8s equivalent" to insist that, while this quantity is on
// the same scale as ICPs, maturity is not directly convertible to ICPs:
// conversion requires a minting event and the conversion rate is variable.
uint64 maturity_e8s_equivalent = 15;
// The accumulated staked maturity of the neuron, in "e8s equivalent" (see
// "maturity_e8s_equivalent"). Staked maturity becomes regular maturity once
// the neuron is dissolved.
//
// Contrary to `maturity_e8s_equivalent` this maturity is staked and thus
// locked until the neuron is dissolved and contributes to voting power
// and rewards. Once the neuron is dissolved, this maturity will be "moved"
// to 'maturity_e8s_equivalent' and will be able to be spawned (with maturity
// modulation).
optional uint64 staked_maturity_e8s_equivalent = 20;
// If set and true the maturity rewarded to this neuron for voting will be
// automatically staked and will contribute to the neuron's voting power.
optional bool auto_stake_maturity = 21;
// Whether this neuron is "Not for profit", making it dissolvable
// by voting.
bool not_for_profit = 16;
// If set, this neuron is a member of the Community Fund. This means that when
// a proposal to open an SNS token swap is executed, maturity from this neuron
// will be used to participate in the SNS token swap.
optional uint64 joined_community_fund_timestamp_seconds = 17;
// If set, the neuron belongs to the "known neurons". It has been given a name and maybe a description.
optional KnownNeuronData known_neuron_data = 18;
// The type of the Neuron. See [NeuronType] for a description
// of the different states.
optional NeuronType neuron_type = 22;
// See the Visibility enum.
optional Visibility visibility = 23;
// The last time that voting power was "refreshed". There are two ways to
// refresh the voting power of a neuron: set following, or vote directly. In
// the future, there will be a dedicated API for refreshing. Note that direct
// voting implies that refresh also occurs when a proposal is created, because
// direct voting is part of proposal creation.
//
// Effect: When this becomes > 6 months ago, the amount of voting power that
// this neuron can exercise decreases linearly down to 0 over the course of 1
// month. After that, following is cleared, except for ManageNeuron proposals.
//
// This will always be populated. If the underlying neuron was never
// refreshed, this will be set to 2024-11-05T00:00:01 UTC (1730764801 seconds
// after the UNIX epoch).
optional uint64 voting_power_refreshed_timestamp_seconds = 24;
// The index of the next entry in the recent_ballots list that will be
// used for the circular buffer. This is used to determine which entry
// to overwrite next.
optional uint32 recent_ballots_next_entry_index = 25;
// The amount of "sway" this neuron has when voting on proposals.
//
// When a proposal is created, each eligible neuron gets a "blank" ballot. The
// amount of voting power in that ballot is set to the neuron's deciding
// voting power at the time of proposal creation. There are two ways that a
// proposal can become decided:
//
// 1. Early: Either more than half of the total voting power in the ballots
// votes in favor (then the proposal is approved), or at least half of the
// votal voting power in the ballots votes against (then, the proposal is
// rejected).
//
// 2. The proposal's voting deadline is reached. At that point, if there is
// more voting power in favor than against, and at least 3% of the total
// voting power voted in favor, then the proposal is approved. Otherwise, it
// is rejected.
//
// If a neuron regularly refreshes its voting power, this has the same value
// as potential_voting_power. Actions that cause a refresh are as follows:
//
// 1. voting directly (not via following)
// 2. set following
// 3. refresh voting power
//
// (All of these actions are performed via the manage_neuron method.)
//
// However, if a neuron has not refreshed in a "long" time, this will be less
// than potential voting power. See VotingPowerEconomics. As a further result
// of less deciding voting power, not only does it have less influence on the
// outcome of proposals, the neuron receives less voting rewards (when it
// votes indirectly via following).
//
// For details, see https://dashboard.internetcomputer.org/proposal/132411.
//
// Per NNS policy, this is opt. Nevertheless, it will never be null.
optional uint64 deciding_voting_power = 26;
// The amount of "sway" this neuron can have if it refreshes its voting power
// frequently enough.
//
// Unlike deciding_voting_power, this does NOT take refreshing into account.
// Rather, this only takes three factors into account:
//
// 1. (Net) staked amount - This is the "base" of a neuron's voting power.
// This primarily consists of the neuron's ICP balance.
//
// 2. Age - Neurons with more age have more voting power (all else being
// equal).
//
// 3. Dissolve delay - Neurons with longer dissolve delay have more voting
// power (all else being equal). Neurons with a dissolve delay of less
// than six months are not eligible to vote. Therefore, such neurons
// are considered to have 0 voting power.
//
// Per NNS policy, this is opt. Nevertheless, it will never be null.
optional uint64 potential_voting_power = 27;
}
// Subset of Neuron that has no collections or big fields that might not exist in most neurons, and
// the goal is to keep the size of the struct consistent and can be easily stored in a
// StableBTreeMap. For the meaning of each field, see the Neuron struct.
message AbridgedNeuron {
bytes account = 2;
ic_base_types.pb.v1.PrincipalId controller = 3;
uint64 cached_neuron_stake_e8s = 5;
uint64 neuron_fees_e8s = 6;
uint64 created_timestamp_seconds = 7;
uint64 aging_since_timestamp_seconds = 8;
optional uint64 spawn_at_timestamp_seconds = 19;
oneof dissolve_state {
uint64 when_dissolved_timestamp_seconds = 9;
uint64 dissolve_delay_seconds = 10;
}
bool kyc_verified = 13;
uint64 maturity_e8s_equivalent = 15;
optional uint64 staked_maturity_e8s_equivalent = 20;
optional bool auto_stake_maturity = 21;
bool not_for_profit = 16;
optional uint64 joined_community_fund_timestamp_seconds = 17;
optional NeuronType neuron_type = 22;
optional Visibility visibility = 23;
optional uint64 voting_power_refreshed_timestamp_seconds = 24;
optional uint32 recent_ballots_next_entry_index = 25;
reserved 1;
reserved "id";
}
// Types of a Neuron.
enum NeuronType {
// Placeholder value due to the proto3 requirement for a zero default.
// This is an invalid type; neurons should not be assigned this value.
NEURON_TYPE_UNSPECIFIED = 0;
// Represents neurons initially created for Seed accounts in the
// Genesis Token Canister, or those descended from such neurons.
NEURON_TYPE_SEED = 1;
// Represents neurons initially created for Early Contributor Token (ECT)
// accounts in the Genesis Token Canister, or those descended from such neurons.
NEURON_TYPE_ECT = 2;
}
// The types of votes the Neuron can issue.
enum Vote {
// This exists because proto3 defaults to the 0 value on enums.
// This is not a valid choice, i.e., a vote with this choice will
// not be counted.
VOTE_UNSPECIFIED = 0;
// Vote for the proposal to be adopted.
VOTE_YES = 1;
// Vote for the proposal to be rejected.
VOTE_NO = 2;
}
// List of NNS functions that can be called by proposals.
enum NnsFunction {
// This exists because proto3 defaults to the 0 value on enums.
NNS_FUNCTION_UNSPECIFIED = 0;
// Combine a specified set of nodes, typically drawn from data centers and
// operators in such a way as to guarantee their independence, into a new
// decentralized subnet.
// The execution of this NNS function first initiates a new instance of
// the distributed key generation protocol. The transcript of that protocol
// is written to a new subnet record in the registry, together with initial
// configuration information for the subnet, from where the nodes comprising
// the subnet pick it up.
NNS_FUNCTION_CREATE_SUBNET = 1;
// Add a new node to a subnet. The node cannot be currently assigned to a
// subnet.
// The execution of this proposal changes an existing subnet record to add
// a node. From the perspective of the NNS, this update is a simple update
// of the subnet record in the registry.
NNS_FUNCTION_ADD_NODE_TO_SUBNET = 2;
// A proposal to add a new canister to be installed and executed in the
// NNS subnetwork.
// The root canister, which controls all canisters on the NNS except for
// itself, handles this proposal type. The call also expects the Wasm module
// that shall be installed.
NNS_FUNCTION_NNS_CANISTER_INSTALL = 3;
// A proposal to upgrade an existing canister in the NNS subnetwork.
// This proposal type is executed by the root canister. Beyond upgrading
// the Wasm module of the target canister, the proposal can also set the
// authorization information and the allocations.
NNS_FUNCTION_NNS_CANISTER_UPGRADE = 4;
// A proposal to bless a new version to which the replicas can be
// upgraded.
// The proposal registers a replica version (identified by the hash of the
// installation image) in the registry. Besides creating a record for that
// version, the proposal also appends that version to the list of "blessed
// versions" that can be installed on a subnet. By itself, this proposal
// does not effect any upgrade.
NNS_FUNCTION_BLESS_REPLICA_VERSION = 5;
// Update a subnet's recovery CUP (used to recover subnets that have stalled).
// Nodes that find a recovery CUP for their subnet will load that CUP from
// the registry and restart the replica from that CUP.
NNS_FUNCTION_RECOVER_SUBNET = 6;
// Update a subnet's configuration.
// This proposal updates the subnet record in the registry, with the changes
// being picked up by the nodes on the subnet when they reference the
// respective registry version. Subnet configuration comprises protocol
// parameters that must be consistent across the subnet (e.g. message sizes).
NNS_FUNCTION_UPDATE_CONFIG_OF_SUBNET = 7;
// Assign an identity to a node operator, such as a funding partner,
// associating key information regarding its ownership, the jurisdiction
// in which it is located, and other information.
// The node operator is stored as a record in the registry. It contains
// the remaining node allowance for that node operator, that is the number
// of nodes the node operator can still add to the IC. When an additional
// node is added by the node operator, the remaining allowance is decreased.
NNS_FUNCTION_ASSIGN_NOID = 8;
// A proposal to upgrade the root canister in the NNS subnetwork.
// The proposal is processed by the Lifeline canister, which controls the
// root canister. The proposal updates the Wasm module as well as the
// authorization settings.
NNS_FUNCTION_NNS_ROOT_UPGRADE = 9;
// Update the ICP/XDR conversion rate.
// Changes the ICP-to-XDR conversion rate in the governance canister. This
// setting affects cycles pricing (as the value of cycles shall be constant
// with respect to IMF SDRs) as well as the rewards paid for nodes, which
// are expected to be specified in terms of IMF SDRs as well.
NNS_FUNCTION_ICP_XDR_CONVERSION_RATE = 10;
// Deploy a GuestOS version to a given subnet. The proposal changes the GuestOS version that is
// used on the specified subnet. The version must be contained in the list of elected GuestOS
// versions. The upgrade is completed when the subnet creates the next regular CUP.
NNS_FUNCTION_DEPLOY_GUESTOS_TO_ALL_SUBNET_NODES = 11;
// Clear the provisional whitelist.
// The proposal changes the provisional whitelist to the empty list.
NNS_FUNCTION_CLEAR_PROVISIONAL_WHITELIST = 12;
// Removes a node from a subnet. The node must be currently assigned to a
// subnet.
// The execution of this proposal changes an existing subnet record to remove
// a node. From the perspective of the NNS, this update is a simple update
// of the subnet record in the registry.
NNS_FUNCTION_REMOVE_NODES_FROM_SUBNET = 13;
// Informs the cycles minting canister that a certain principal is
// authorized to use certain subnetworks (from a list). Can also be
// used to set the "default" list of subnetworks that principals
// without special authorization are allowed to use.
NNS_FUNCTION_SET_AUTHORIZED_SUBNETWORKS = 14;
// Change the Firewall configuration in the registry. (TODO: Remove when IC-1026 is fully integrated)
NNS_FUNCTION_SET_FIREWALL_CONFIG = 15;
// Change a Node Operator's allowance in the registry.
NNS_FUNCTION_UPDATE_NODE_OPERATOR_CONFIG = 16;
// Stop or start an NNS canister.
NNS_FUNCTION_STOP_OR_START_NNS_CANISTER = 17;
// Remove unassigned nodes from the registry.
NNS_FUNCTION_REMOVE_NODES = 18;
// Uninstall code of a canister.
NNS_FUNCTION_UNINSTALL_CODE = 19;
// Update the node rewards table.
NNS_FUNCTION_UPDATE_NODE_REWARDS_TABLE = 20;
// Add or remove Data Center records.
NNS_FUNCTION_ADD_OR_REMOVE_DATA_CENTERS = 21;
// (obsolete) Update the config for all unassigned nodes.
NNS_FUNCTION_UPDATE_UNASSIGNED_NODES_CONFIG = 22;
// Remove Node Operator from the registry.
NNS_FUNCTION_REMOVE_NODE_OPERATORS = 23;
// Update the routing table in the registry.
NNS_FUNCTION_REROUTE_CANISTER_RANGES = 24;
// Add firewall rules in the registry
NNS_FUNCTION_ADD_FIREWALL_RULES = 25;
// Remove firewall rules in the registry
NNS_FUNCTION_REMOVE_FIREWALL_RULES = 26;
// Update firewall rules in the registry
NNS_FUNCTION_UPDATE_FIREWALL_RULES = 27;
// Insert or update `canister_migrations` entries.
NNS_FUNCTION_PREPARE_CANISTER_MIGRATION = 28;
// Remove `canister_migrations` entries.
NNS_FUNCTION_COMPLETE_CANISTER_MIGRATION = 29;
// Add a new SNS canister WASM
NNS_FUNCTION_ADD_SNS_WASM = 30;
// Change the subnet node membership. In a way, this function combines the separate
// functions for adding and removing nodes from the subnet record, but adds the property
// of atomic node replacement (node swap) on top.
//
// The nodes that are being added to the subnet must be currently unassigned.
// The nodes that are being removed from the subnet must be currently assigned to the subnet.
NNS_FUNCTION_CHANGE_SUBNET_MEMBERSHIP = 31;
// Updates the available subnet types in the cycles minting canister.
NNS_FUNCTION_UPDATE_SUBNET_TYPE = 32;
// Changes the assignment of subnets to subnet types in the cycles minting
// canister.
NNS_FUNCTION_CHANGE_SUBNET_TYPE_ASSIGNMENT = 33;
// Update the list of SNS subnet IDs that SNS WASM will deploy SNS instances to.
NNS_FUNCTION_UPDATE_SNS_WASM_SNS_SUBNET_IDS = 34;
// Update the SNS-wasm canister's list of allowed principals. This list guards which principals can deploy an SNS.
NNS_FUNCTION_UPDATE_ALLOWED_PRINCIPALS = 35;
// A proposal to retire previously elected and unused replica versions.
// The specified versions are removed from the registry and the "blessed versions" record.
// This ensures that the replica cannot upgrade to these versions anymore.
NNS_FUNCTION_RETIRE_REPLICA_VERSION = 36;
// Insert custom upgrade path entries into SNS-W for all SNSes, or for an SNS specified by its governance canister ID.
NNS_FUNCTION_INSERT_SNS_WASM_UPGRADE_PATH_ENTRIES = 37;
// A proposal to change the set of elected GuestOS versions. The version to elect (identified by
// the hash of the installation image) is added to the registry. Besides creating a record for
// that version, the proposal also appends that version to the list of elected versions that can
// be installed on nodes of a subnet. Only elected GuestOS versions can be deployed.
NNS_FUNCTION_REVISE_ELECTED_GUESTOS_VERSIONS = 38;
NNS_FUNCTION_BITCOIN_SET_CONFIG = 39;
// OBSOLETE: use NNS_FUNCTION_REVISE_ELECTED_HOSTOS_VERSIONS instead
NNS_FUNCTION_UPDATE_ELECTED_HOSTOS_VERSIONS = 40;
// OBSOLETE: use NNS_FUNCTION_UPGRADE_HOSTOS_FOR_SOME_NODES instead
NNS_FUNCTION_UPDATE_NODES_HOSTOS_VERSION = 41;
// Uninstall and Install Root with the WASM provided in the function. If InitArgs are provided
// They will be passed to the canister_init function of the WASM provided.
// This function is meant as a Break Glass mechanism for when an open call context in
// the Root canister is preventing root or another canister from upgrading (in the case of proxied calls).
NNS_FUNCTION_HARD_RESET_NNS_ROOT_TO_VERSION = 42;
// A proposal to add a set of new API Boundary Nodes using unassigned nodes
NNS_FUNCTION_ADD_API_BOUNDARY_NODES = 43;
// A proposal to remove a set of API Boundary Nodes, which will designate them as unassigned nodes
NNS_FUNCTION_REMOVE_API_BOUNDARY_NODES = 44;
reserved 45;
reserved "NNS_FUNCTION_UPDATE_API_BOUNDARY_NODE_DOMAIN";
// (obsolete) A proposal to update the version of a set of API Boundary Nodes
NNS_FUNCTION_UPDATE_API_BOUNDARY_NODES_VERSION = 46;
// A proposal to update the version of a set of API Boundary Nodes
NNS_FUNCTION_DEPLOY_GUESTOS_TO_SOME_API_BOUNDARY_NODES = 47;
// A proposal to update the version of all unassigned nodes
NNS_FUNCTION_DEPLOY_GUESTOS_TO_ALL_UNASSIGNED_NODES = 48;
// A proposal to update SSH readonly access for all unassigned nodes
NNS_FUNCTION_UPDATE_SSH_READONLY_ACCESS_FOR_ALL_UNASSIGNED_NODES = 49;
// A proposal to change the set of currently elected HostOS versions, by electing a new version,
// and/or unelecting some priorly elected versions. HostOS versions are identified by the hash
// of the installation image. The version to elect is added to the Registry, and the versions
// to unelect are removed from the Registry, ensuring that HostOS cannot upgrade to these versions
// anymore. This proposal does not actually perform the upgrade; for deployment of an elected
// version, please refer to `NNS_FUNCTION_DEPLOY_HOSTOS_TO_SOME_NODES`.
NNS_FUNCTION_REVISE_ELECTED_HOSTOS_VERSIONS = 50;
// Deploy a HostOS version to a given set of nodes. The proposal changes the HostOS version that
// is used on the specified nodes.
NNS_FUNCTION_DEPLOY_HOSTOS_TO_SOME_NODES = 51;
// The proposal requests a subnet rental.
NNS_FUNCTION_SUBNET_RENTAL_REQUEST = 52;
}
// Payload of a proposal that calls a function on another NNS
// canister. The canister and function to call is derived from the
// `nns_function`.
message ExecuteNnsFunction {
// This enum value determines what canister to call and what NNS
// function to call on that canister.
NnsFunction nns_function = 1;
// The payload of the NNS function.
bytes payload = 2;
}
// If adopted, a motion should guide the future strategy of the
// Internet Computer ecosystem.
message Motion {
// The text of the motion. Maximum 100kib.
string motion_text = 1;
}
// For all Neurons controlled by the given principals, set their
// KYC status to `kyc_verified=true`.
message ApproveGenesisKYC {
repeated ic_base_types.pb.v1.PrincipalId principals = 1;
}
// Adds and/or removes NodeProviders from the list of current
// node providers.
message AddOrRemoveNodeProvider {
oneof change {
NodeProvider to_add = 1;
NodeProvider to_remove = 2;
}
}
// This proposal payload is used to reward a node provider by minting
// ICPs directly to the node provider's ledger account, or into a new
// neuron created on behalf of the node provider.
message RewardNodeProvider {
// The NodeProvider to reward.
NodeProvider node_provider = 1;
// The amount of e8s to mint to reward the node provider.
uint64 amount_e8s = 2;
// This message specifies how to create a new neuron on behalf of
// the node provider.
//
// - The controller of the new neuron is the node provider's
// principal.
//
// - The account is chosen at random.
//
// - The stake of the new neuron is `amount_e8s`.
//
// - `dissolve_delay_seconds` is as specified in the proto.
//
// - `kyc_verified` is set to true, as node providers are
// (implicitly) KYC'ed.
//
// - `not_for_profit` is set to false.
//
// - All other values are set as for other neurons: timestamp is
// now, following is set up per default, maturity is 0, neuron fee
// is 0.
message RewardToNeuron {
uint64 dissolve_delay_seconds = 1;
}
message RewardToAccount {
ic_ledger.pb.v1.AccountIdentifier to_account = 1;
}
oneof reward_mode {
// If this is specified, executing this proposal will create a
// neuron instead of directly minting ICP into the node provider's
// account.
RewardToNeuron reward_to_neuron = 4;
// If this is specified, executing this proposal will mint to the
// specified account.
RewardToAccount reward_to_account = 5;
}
reserved 3;
reserved "create_neuron";
}
message RewardNodeProviders {
repeated RewardNodeProvider rewards = 1;
// If true, reward Node Providers with the rewards returned by the Registry's
// get_node_providers_monthly_xdr_rewards method
optional bool use_registry_derived_rewards = 2;
}
// Changes the default followees to match the one provided.
// This completely replaces the default followees so entries for all
// Topics (except ManageNeuron) must be provided on each proposal.
message SetDefaultFollowees {
map<int32, Neuron.Followees> default_followees = 1;
}
// Obsolete. Superseded by OpenSnsTokenSwap.
message SetSnsTokenSwapOpenTimeWindow {
// The swap canister to send the request to.
ic_base_types.pb.v1.PrincipalId swap_canister_id = 1;
// Arguments that get sent to the swap canister when its set_open_time_window
// Candid method is called.
ic_sns_swap.pb.v1.SetOpenTimeWindowRequest request = 2;
}
// A proposal is the immutable input of a proposal submission. This contains
// all the information from the original proposal submission.
//
// Making a proposal implicitly votes yes.
message Proposal {
// Must be present (enforced at the application layer, not by PB).
// A brief description of what the proposal does.
// Size in bytes must be in the interval [5, 256].
optional string title = 20;
// Text providing a short description of the proposal, composed
// using a maximum of 30000 bytes of characters.
string summary = 1;
// The Web address of additional content required to evaluate the
// proposal, specified using HTTPS. For example, the address might
// describe content supporting the assignment of a DCID (data center
// id) to a new data center. The URL string must not be longer than
// 2000 bytes.
string url = 2;
// This section describes the action that the proposal proposes to
// take.
oneof action {
// This type of proposal calls a major function on a specified
// target neuron. Only the followees of the target neuron (on the
// topic [Topic::ManageNeuron]) may vote on these proposals,
// which effectively provides the followees with control over the
// target neuron. This can provide a convenient and highly secure
// means for a team of individuals to manage an important
// neuron. For example, a neuron might hold a large balance, or
// belong to an organization of high repute, and be publicized so
// that many other neurons can follow its vote. In both cases,
// managing the private key of the principal securely could be
// problematic (either a single copy is held, which is very
// insecure and provides for a single party to take control, or a
// group of individuals must divide responsibility, for example
// using threshold cryptography, which is complex and time
// consuming). To address this, using this proposal type, the
// important neuron can be configured to follow the neurons
// controlled by individual members of a team. Now they can submit
// proposals to make the important neuron perform actions, which
// are adopted if and only if a majority of them vote to
// adopt. Nearly any command on the target neuron can be executed,
// including commands that change the follow rules, allowing the
// set of team members to be dynamic. Only the final step of
// dissolving the neuron once its dissolve delay reaches zero
// cannot be performed using this type of proposal (since this
// would allow control/“ownership” over the locked balances to be
// transferred). To prevent a neuron falling under the malign
// control of the principal’s private key by accident, the private
// key can be destroyed so that the neuron can only be controlled
// by its followees, although this makes it impossible to
// subsequently unlock the balance.
ManageNeuron manage_neuron = 10;
// Propose a change to some network parameters of network
// economics.
NetworkEconomics manage_network_economics = 12;
// See [Motion]
Motion motion = 13;
// A update affecting something outside of the Governance
// canister.
ExecuteNnsFunction execute_nns_function = 14;
// Approve Genesis KYC for a given list of principals.
ApproveGenesisKYC approve_genesis_kyc = 15;
// Add/remove NodeProvider from the list of NodeProviders
AddOrRemoveNodeProvider add_or_remove_node_provider = 16;
// Reward a NodeProvider
RewardNodeProvider reward_node_provider = 17;
// Set the default following
SetDefaultFollowees set_default_followees = 18;
// Reward multiple NodeProvider
RewardNodeProviders reward_node_providers = 19;
// Register Known Neuron
KnownNeuron register_known_neuron = 21;
// Obsolete. Superseded by CreateServiceNervousSystem. Kept for Candid compatibility.
SetSnsTokenSwapOpenTimeWindow set_sns_token_swap_open_time_window = 22 [deprecated = true];
// Call the open method on an SNS swap canister.
//
// This is still supported but will soon be superseded by
// CreateServiceNervousSystem.
OpenSnsTokenSwap open_sns_token_swap = 23 [deprecated = true];
// Create a new SNS.
CreateServiceNervousSystem create_service_nervous_system = 24;
// Install, reinstall or upgrade the code of a canister that is controlled by the NNS.
InstallCode install_code = 25;
// Stop or start a canister that is controlled by the NNS.
StopOrStartCanister stop_or_start_canister = 26;
// Update the settings of a canister that is controlled by the NNS.
UpdateCanisterSettings update_canister_settings = 27;
}
}
// Empty message to use in oneof fields that represent empty
// enums.
message Empty {}
// All operations that modify the state of an existing neuron are
// represented by instances of `ManageNeuron`.
//
// All commands are available to the `controller` of the neuron. In
// addition, commands related to voting, i.g., [manage_neuron::Follow]
// and [manage_neuron::RegisterVote], are also available to the
// registered hot keys of the neuron.
message ManageNeuron {
option (ic_base_types.pb.v1.tui_signed_message) = true;
// This is the legacy way to specify neuron IDs that is now discouraged.
ic_nns_common.pb.v1.NeuronId id = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
// The ID of the neuron to manage. This can either be a subaccount or a neuron ID.
oneof neuron_id_or_subaccount {