Skip to content

Commit 367ab73

Browse files
refactor(nns): Deleted ListNeurons from NNS governance.proto. (dfinity#3546)
Also ListNeuronsResponse. # Motivation/Inspiration I started working on deleting `(deciding|potential)_voting_power` fields from `governance.proto` ([NNS1-3500]). Some of those fields appear in `NeuronInfo`. I looked into that type, and it seems like we could delete it, because AFAICT, it is only used in a couple of response types, such as `ListNeuronsResponse`. Therefore, this indirectly helps with getting rid of `*_voting_power` fields in `governance.proto`. [NNS1-3500]: https://dfinity.atlassian.net/browse/NNS1-3500 We should be able to delete most request and response types from `governance.proto`, because we do not store those in stable memory. This shows how we would delete other request and response types. This also shows that such deletions can be fairly straightforward. # Bonus Changes Switch rosetta from using `//rs/nns/governance` to `//rs/nns/governance/api`. This made it possible to "lock down" //rs/nns/governance, i.e. reduce its visibility. Because [min visibility good]. [min visibility good]: https://bazel.build/concepts/visibility#rule-target-visibility Make aliases generated by rust_canister inherit visibility. This was needed to lock down //rs/nns/governance. # How to Delete Request & Response Types from governance.proto Here is an overview of how this PR was constructed; the same steps can (very likely) be used to delete other request and response types: <ol> <li>Delete the definitions from <code>governance.proto</code>. <li>Delete the conversions in <code>rs/nns/governance/src/pb/conversions.rs</code>. <li>Run <code>bazel build //rs/nns/governance</code>. This will reveal all the places that need to be updated in the main lib. <li>In every file that used the types that were deleted in step 1, <i>replace them with the analogous API types</i>. E.g. the following will probably get you more than 90% of the way there: <pre><code>-use crate::pb::v1::{FooRequest, FooResponse}; +use ic_nns_governance_api::pb::v1::{FooRequest, FooResponse}; </code></pre> The reason this is pretty effective is that the definitions of the API types were simply copied from the Prost-generated type. <li>Fix problems that arise from this replacement. E.g. there may cases where you need to convert from an API type "back" to a Prost-generated type, or the other way around. This is likely the most difficult step. <li>Fix <code>canister.rs</code>. It might well be that the only thing you need to do here is remove some <code>.into()</code>. Those are no longer necessary, because now, they just convert T into T. Ofc, this change is not strictly necessary, but clippy might yell at you, and in any case, it confuses humans when you do <code>.into()</code> even though the object is already of the desired type. <li>Fix tests. Again, we apply steps 3-5, but this time, the goal is to make <code>//rs/nns/governance/...</code> build. </ol> The only "insight" here is that it is fairly easy to replace Prost-generated request and response types with API types. Other than that, these steps are more or less corollaries of "delete request and response types". # Why Min Visibility Good When you want to change something, you won't need to change the whole world. I.e. encapsulation, modularity, loose coupling, non-entanglement. Being able to make changes in the future is extrem imperative, because change is the only constant. This is the exact same rationale that is used to justify [private ALL the things]. [private ALL the things]: https://google.github.io/styleguide/cppguide.html#Access_Control
1 parent 5993fe2 commit 367ab73

File tree

15 files changed

+92
-197
lines changed

15 files changed

+92
-197
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bazel/canisters.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,14 @@ def rust_canister(name, service_file, visibility = ["//visibility:public"], test
135135
native.alias(
136136
name = name,
137137
actual = name + ".wasm",
138+
visibility = visibility,
138139
)
139140

140141
# DID service related targets
141142
native.alias(
142143
name = name + ".didfile",
143144
actual = service_file,
145+
visibility = visibility,
144146
)
145147
did_git_test(
146148
name = name + "_did_git_test",

rs/nns/governance/BUILD.bazel

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,21 @@ load("//bazel:defs.bzl", "rust_bench", "rust_test_suite_with_extra_srcs")
66
load("//bazel:prost.bzl", "generated_files_check")
77
load(":feature_flags.bzl", "test_with_tla")
88

9-
package(default_visibility = ["//visibility:public"])
9+
package(default_visibility = ["//rs/nervous_system:default_visibility"])
1010

11-
exports_files(["canister/governance.did"])
11+
DID_FILES = glob([
12+
"**/*.did",
13+
])
14+
15+
exports_files(
16+
# Notice that governance.proto is NOT included. This is very intentional. We
17+
# only use that for storing things to stable memory, not for communication
18+
# with clients.
19+
DID_FILES,
20+
visibility = [
21+
"//visibility:public",
22+
],
23+
)
1224

1325
# Allows temporarily disabling TLA checks from the command line;
1426
# just pass `--define tla_disabled=true` to your Bazel command
@@ -190,6 +202,7 @@ rust_library(
190202
crate_name = "ic_nns_governance",
191203
proc_macro_deps = MACRO_DEPENDENCIES,
192204
version = "0.9.0",
205+
visibility = ["//visibility:private"],
193206
deps = DEPENDENCIES + [
194207
"@crate_index//:canbench-rs",
195208
],
@@ -225,6 +238,7 @@ rust_canister(
225238
compile_data = ["canister/governance.did"],
226239
proc_macro_deps = MACRO_DEPENDENCIES,
227240
service_file = ":canister/governance.did",
241+
visibility = ["//visibility:public"],
228242
deps = DEPENDENCIES + [
229243
":build_script",
230244
":governance",
@@ -244,6 +258,7 @@ rust_canister(
244258
crate_root = "canister/canister.rs",
245259
proc_macro_deps = MACRO_DEPENDENCIES,
246260
service_file = ":canister/governance_test.did",
261+
visibility = ["//visibility:public"],
247262
deps = DEPENDENCIES + [
248263
":build_script",
249264
":governance--test_feature",

rs/nns/governance/canbench/canbench_results.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ benches:
8585
scopes: {}
8686
list_neurons_heap:
8787
total:
88-
instructions: 4763239
88+
instructions: 4880000
8989
heap_increase: 9
9090
stable_memory_increase: 0
9191
scopes: {}
@@ -104,7 +104,7 @@ benches:
104104
list_neurons_stable:
105105
total:
106106
instructions: 113374022
107-
heap_increase: 5
107+
heap_increase: 4
108108
stable_memory_increase: 0
109109
scopes: {}
110110
list_proposals:

rs/nns/governance/canister/canister.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ fn list_proposals(req: ListProposalInfo) -> ListProposalInfoResponse {
812812
#[query]
813813
fn list_neurons(req: ListNeurons) -> ListNeuronsResponse {
814814
debug_log("list_neurons");
815-
governance().list_neurons(&(req.into()), caller()).into()
815+
governance().list_neurons(&req, caller())
816816
}
817817

818818
#[query]

rs/nns/governance/proto/ic_nns_governance/pb/v1/governance.proto

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,51 +2630,6 @@ message ListProposalInfoResponse {
26302630
repeated ProposalInfo proposal_info = 1;
26312631
}
26322632

2633-
// A request to list neurons. The "requested list", i.e., the list of
2634-
// neuron IDs to retrieve information about, is the union of the list
2635-
// of neurons listed in `neuron_ids` and, if `caller_neurons` is true,
2636-
// the list of neuron IDs of neurons for which the caller is the
2637-
// controller or one of the hot keys.
2638-
message ListNeurons {
2639-
option (ic_base_types.pb.v1.tui_signed_message) = true;
2640-
// The neurons to get information about. The "requested list"
2641-
// contains all of these neuron IDs.
2642-
repeated fixed64 neuron_ids = 1 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
2643-
// If true, the "requested list" also contains the neuron ID of the
2644-
// neurons that the calling principal is authorized to read.
2645-
bool include_neurons_readable_by_caller = 2 [(ic_base_types.pb.v1.tui_signed_display_q2_2021) = true];
2646-
// Whether to also include empty neurons readable by the caller. This field only has an effect
2647-
// when `include_neurons_readable_by_caller` is true. If a neuron's id already exists in the
2648-
// `neuron_ids` field, then the neuron will be included in the response regardless of the value of
2649-
// this field. Since the previous behavior was to always include empty neurons readable by caller,
2650-
// if this field is not provided, it defaults to true, in order to maintain backwards
2651-
// compatibility. Here, being "empty" means 0 stake, 0 maturity and 0 staked maturity.
2652-
optional bool include_empty_neurons_readable_by_caller = 3;
2653-
// If this is set to true, and a neuron in the "requested list" has its
2654-
// visibility set to public, then, it will (also) be included in the
2655-
// full_neurons field in the response (which is of type ListNeuronsResponse).
2656-
// Note that this has no effect on which neurons are in the "requested list".
2657-
// In particular, this does not cause all public neurons to become part of the
2658-
// requested list. In general, you probably want to set this to true, but
2659-
// since this feature was added later, it is opt in to avoid confusing
2660-
// existing (unmigrated) callers.
2661-
optional bool include_public_neurons_in_full_neurons = 4;
2662-
}
2663-
2664-
// A response to a `ListNeurons` request.
2665-
//
2666-
// The "requested list" is described in `ListNeurons`.
2667-
message ListNeuronsResponse {
2668-
// For each neuron ID in the "requested list", if this neuron exists,
2669-
// its `NeuronInfo` at the time of the call will be in this map.
2670-
map<fixed64, NeuronInfo> neuron_infos = 1;
2671-
// For each neuron ID in the "requested list", if the neuron exists,
2672-
// and the caller is authorized to read the full neuron (controller,
2673-
// hot key, or controller or hot key of some followee on the
2674-
// `ManageNeuron` topic).
2675-
repeated Neuron full_neurons = 2;
2676-
}
2677-
26782633
// A response to "ListKnownNeurons"
26792634
message ListKnownNeuronsResponse {
26802635
// List of known neurons.

rs/nns/governance/src/gen/ic_nns_governance.pb.v1.rs

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,72 +3927,6 @@ pub struct ListProposalInfoResponse {
39273927
#[prost(message, repeated, tag = "1")]
39283928
pub proposal_info: ::prost::alloc::vec::Vec<ProposalInfo>,
39293929
}
3930-
/// A request to list neurons. The "requested list", i.e., the list of
3931-
/// neuron IDs to retrieve information about, is the union of the list
3932-
/// of neurons listed in `neuron_ids` and, if `caller_neurons` is true,
3933-
/// the list of neuron IDs of neurons for which the caller is the
3934-
/// controller or one of the hot keys.
3935-
#[derive(
3936-
candid::CandidType,
3937-
candid::Deserialize,
3938-
serde::Serialize,
3939-
comparable::Comparable,
3940-
Clone,
3941-
PartialEq,
3942-
::prost::Message,
3943-
)]
3944-
pub struct ListNeurons {
3945-
/// The neurons to get information about. The "requested list"
3946-
/// contains all of these neuron IDs.
3947-
#[prost(fixed64, repeated, packed = "false", tag = "1")]
3948-
pub neuron_ids: ::prost::alloc::vec::Vec<u64>,
3949-
/// If true, the "requested list" also contains the neuron ID of the
3950-
/// neurons that the calling principal is authorized to read.
3951-
#[prost(bool, tag = "2")]
3952-
pub include_neurons_readable_by_caller: bool,
3953-
/// Whether to also include empty neurons readable by the caller. This field only has an effect
3954-
/// when `include_neurons_readable_by_caller` is true. If a neuron's id already exists in the
3955-
/// `neuron_ids` field, then the neuron will be included in the response regardless of the value of
3956-
/// this field. Since the previous behavior was to always include empty neurons readable by caller,
3957-
/// if this field is not provided, it defaults to true, in order to maintain backwards
3958-
/// compatibility. Here, being "empty" means 0 stake, 0 maturity and 0 staked maturity.
3959-
#[prost(bool, optional, tag = "3")]
3960-
pub include_empty_neurons_readable_by_caller: ::core::option::Option<bool>,
3961-
/// If this is set to true, and a neuron in the "requested list" has its
3962-
/// visibility set to public, then, it will (also) be included in the
3963-
/// full_neurons field in the response (which is of type ListNeuronsResponse).
3964-
/// Note that this has no effect on which neurons are in the "requested list".
3965-
/// In particular, this does not cause all public neurons to become part of the
3966-
/// requested list. In general, you probably want to set this to true, but
3967-
/// since this feature was added later, it is opt in to avoid confusing
3968-
/// existing (unmigrated) callers.
3969-
#[prost(bool, optional, tag = "4")]
3970-
pub include_public_neurons_in_full_neurons: ::core::option::Option<bool>,
3971-
}
3972-
/// A response to a `ListNeurons` request.
3973-
///
3974-
/// The "requested list" is described in `ListNeurons`.
3975-
#[derive(
3976-
candid::CandidType,
3977-
candid::Deserialize,
3978-
serde::Serialize,
3979-
comparable::Comparable,
3980-
Clone,
3981-
PartialEq,
3982-
::prost::Message,
3983-
)]
3984-
pub struct ListNeuronsResponse {
3985-
/// For each neuron ID in the "requested list", if this neuron exists,
3986-
/// its `NeuronInfo` at the time of the call will be in this map.
3987-
#[prost(map = "fixed64, message", tag = "1")]
3988-
pub neuron_infos: ::std::collections::HashMap<u64, NeuronInfo>,
3989-
/// For each neuron ID in the "requested list", if the neuron exists,
3990-
/// and the caller is authorized to read the full neuron (controller,
3991-
/// hot key, or controller or hot key of some followee on the
3992-
/// `ManageNeuron` topic).
3993-
#[prost(message, repeated, tag = "2")]
3994-
pub full_neurons: ::prost::alloc::vec::Vec<Neuron>,
3995-
}
39963930
/// A response to "ListKnownNeurons"
39973931
#[derive(
39983932
candid::CandidType,

rs/nns/governance/src/governance.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ use crate::{
5353
swap_background_information, ArchivedMonthlyNodeProviderRewards, Ballot,
5454
CreateServiceNervousSystem, ExecuteNnsFunction, GetNeuronsFundAuditInfoRequest,
5555
GetNeuronsFundAuditInfoResponse, Governance as GovernanceProto, GovernanceError,
56-
InstallCode, KnownNeuron, ListKnownNeuronsResponse, ListNeurons, ListNeuronsResponse,
57-
ListProposalInfo, ListProposalInfoResponse, ManageNeuron, ManageNeuronResponse,
58-
MonthlyNodeProviderRewards, Motion, NetworkEconomics, Neuron as NeuronProto, NeuronInfo,
59-
NeuronState, NeuronsFundAuditInfo, NeuronsFundData,
56+
InstallCode, KnownNeuron, ListKnownNeuronsResponse, ListProposalInfo,
57+
ListProposalInfoResponse, ManageNeuron, ManageNeuronResponse, MonthlyNodeProviderRewards,
58+
Motion, NetworkEconomics, Neuron as NeuronProto, NeuronInfo, NeuronState,
59+
NeuronsFundAuditInfo, NeuronsFundData,
6060
NeuronsFundEconomics as NeuronsFundNetworkEconomicsPb,
6161
NeuronsFundParticipation as NeuronsFundParticipationPb,
6262
NeuronsFundSnapshot as NeuronsFundSnapshotPb, NnsFunction, NodeProvider, Proposal,
@@ -94,7 +94,11 @@ use ic_nns_constants::{
9494
SUBNET_RENTAL_CANISTER_ID,
9595
};
9696
use ic_nns_governance_api::{
97-
pb::v1::CreateServiceNervousSystem as ApiCreateServiceNervousSystem, proposal_validation,
97+
pb::v1::{
98+
self as api, CreateServiceNervousSystem as ApiCreateServiceNervousSystem, ListNeurons,
99+
ListNeuronsResponse,
100+
},
101+
proposal_validation,
98102
subnet_rental::SubnetRentalRequest,
99103
};
100104
use ic_protobuf::registry::dc::v1::AddOrRemoveDataCentersProposalPayload;
@@ -2470,7 +2474,14 @@ impl Governance {
24702474
// requested_neuron_ids are supplied by the caller.
24712475
let _ignore_when_neuron_not_found = self.with_neuron(&neuron_id, |neuron| {
24722476
// Populate neuron_infos.
2473-
neuron_infos.insert(neuron_id.id, neuron.get_neuron_info(self.voting_power_economics(), now, caller));
2477+
let neuron_info = neuron.get_neuron_info(self.voting_power_economics(), now, caller);
2478+
2479+
// We will be able to get rid of this conversion once we delete
2480+
// NeuronInfo from governance.proto. That should be possible,
2481+
// since we do not store NeuronInfo in stable memory.
2482+
let neuron_info = api::NeuronInfo::from(neuron_info);
2483+
2484+
neuron_infos.insert(neuron_id.id, neuron_info);
24742485

24752486
// Populate full_neurons.
24762487
let let_caller_read_full_neuron =
@@ -2489,7 +2500,7 @@ impl Governance {
24892500
// we need to do a larger refactoring to use the correct API types instead of the internal
24902501
// governance proto at this level.
24912502
proto.recent_ballots = neuron.sorted_recent_ballots();
2492-
full_neurons.push(proto);
2503+
full_neurons.push(api::Neuron::from(proto));
24932504
}
24942505
});
24952506
}

rs/nns/governance/src/governance/benches.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::{
88
pb::v1::{
99
install_code::CanisterInstallMode, neuron::Followees, proposal::Action, Ballot, BallotInfo,
1010
CreateServiceNervousSystem, ExecuteNnsFunction, Governance as GovernanceProto, InstallCode,
11-
KnownNeuron, ListNeurons, ListProposalInfo, NetworkEconomics, Neuron as NeuronProto,
12-
NnsFunction, Proposal, ProposalData, Topic, Vote, VotingPowerEconomics,
11+
KnownNeuron, ListProposalInfo, NetworkEconomics, Neuron as NeuronProto, NnsFunction,
12+
Proposal, ProposalData, Topic, Vote, VotingPowerEconomics,
1313
},
1414
temporarily_disable_allow_active_neurons_in_stable_memory,
1515
temporarily_disable_migrate_active_neurons_to_stable_memory,
@@ -28,6 +28,7 @@ use ic_nns_common::{
2828
types::NeuronId,
2929
};
3030
use ic_nns_constants::GOVERNANCE_CANISTER_ID;
31+
use ic_nns_governance_api::pb::v1::ListNeurons;
3132
use icp_ledger::Subaccount;
3233
use maplit::hashmap;
3334
use rand::{Rng, SeedableRng};

rs/nns/governance/src/pb/conversions.rs

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3759,52 +3759,6 @@ impl From<pb_api::ListProposalInfoResponse> for pb::ListProposalInfoResponse {
37593759
}
37603760
}
37613761

3762-
impl From<pb::ListNeurons> for pb_api::ListNeurons {
3763-
fn from(item: pb::ListNeurons) -> Self {
3764-
Self {
3765-
neuron_ids: item.neuron_ids,
3766-
include_neurons_readable_by_caller: item.include_neurons_readable_by_caller,
3767-
include_empty_neurons_readable_by_caller: item.include_empty_neurons_readable_by_caller,
3768-
include_public_neurons_in_full_neurons: item.include_public_neurons_in_full_neurons,
3769-
}
3770-
}
3771-
}
3772-
impl From<pb_api::ListNeurons> for pb::ListNeurons {
3773-
fn from(item: pb_api::ListNeurons) -> Self {
3774-
Self {
3775-
neuron_ids: item.neuron_ids,
3776-
include_neurons_readable_by_caller: item.include_neurons_readable_by_caller,
3777-
include_empty_neurons_readable_by_caller: item.include_empty_neurons_readable_by_caller,
3778-
include_public_neurons_in_full_neurons: item.include_public_neurons_in_full_neurons,
3779-
}
3780-
}
3781-
}
3782-
3783-
impl From<pb::ListNeuronsResponse> for pb_api::ListNeuronsResponse {
3784-
fn from(item: pb::ListNeuronsResponse) -> Self {
3785-
Self {
3786-
neuron_infos: item
3787-
.neuron_infos
3788-
.into_iter()
3789-
.map(|(k, v)| (k, v.into()))
3790-
.collect(),
3791-
full_neurons: item.full_neurons.into_iter().map(|x| x.into()).collect(),
3792-
}
3793-
}
3794-
}
3795-
impl From<pb_api::ListNeuronsResponse> for pb::ListNeuronsResponse {
3796-
fn from(item: pb_api::ListNeuronsResponse) -> Self {
3797-
Self {
3798-
neuron_infos: item
3799-
.neuron_infos
3800-
.into_iter()
3801-
.map(|(k, v)| (k, v.into()))
3802-
.collect(),
3803-
full_neurons: item.full_neurons.into_iter().map(|x| x.into()).collect(),
3804-
}
3805-
}
3806-
}
3807-
38083762
impl From<pb::ListKnownNeuronsResponse> for pb_api::ListKnownNeuronsResponse {
38093763
fn from(item: pb::ListKnownNeuronsResponse) -> Self {
38103764
Self {

0 commit comments

Comments
 (0)