Skip to content

Commit cc60932

Browse files
committed
Stop using blessed versions list in the registry
1 parent 8e58e06 commit cc60932

20 files changed

+270
-406
lines changed

rs/nns/integration_tests/src/upgrades_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ fn test_submit_and_accept_update_elected_replica_versions_proposal() {
166166
),
167167
(
168168
bless_version_payload(""),
169-
Some("Blessed an empty version ID"),
169+
Some("Elected an empty version ID"),
170170
),
171171
(
172172
update_versions_payload(

rs/registry/canister/src/invariants/assignment.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use ic_base_types::{NodeId, PrincipalId};
44

55
use super::{
66
common::{
7-
InvariantCheckError, RegistrySnapshot, get_api_boundary_node_records_from_snapshot,
8-
get_node_records_from_snapshot,
7+
InvariantCheckError, RegistrySnapshot, get_all_node_records,
8+
get_api_boundary_node_records_from_snapshot,
99
},
1010
subnet::get_subnet_records_map,
1111
};
@@ -30,7 +30,7 @@ pub(crate) fn check_node_assignment_invariants(
3030
.into_keys()
3131
.collect();
3232

33-
let errors: Vec<String> = get_node_records_from_snapshot(snapshot).keys().map(|node_id| {
33+
let errors: Vec<String> = get_all_node_records(snapshot).iter().map(|(node_id, _)| {
3434
let (is_replica, is_api_boundary_node) = (
3535
replicas.contains(node_id),
3636
api_boundary_nodes.contains(node_id),

rs/registry/canister/src/invariants/common.rs

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ use std::{
88
use ic_base_types::{NodeId, PrincipalId, SubnetId};
99
use ic_protobuf::registry::{
1010
api_boundary_node::v1::ApiBoundaryNodeRecord, crypto::v1::ChainKeyEnabledSubnetList,
11-
hostos_version::v1::HostosVersionRecord, node::v1::NodeRecord, subnet::v1::SubnetListRecord,
11+
hostos_version::v1::HostosVersionRecord, node::v1::NodeRecord,
12+
replica_version::v1::ReplicaVersionRecord, subnet::v1::SubnetListRecord,
1213
};
1314
use ic_registry_keys::{
14-
CHAIN_KEY_ENABLED_SUBNET_LIST_KEY_PREFIX, HOSTOS_VERSION_KEY_PREFIX, NODE_RECORD_KEY_PREFIX,
15-
get_api_boundary_node_record_node_id, get_node_record_node_id, make_node_record_key,
16-
make_subnet_list_record_key,
15+
CHAIN_KEY_ENABLED_SUBNET_LIST_KEY_PREFIX, HOSTOS_VERSION_KEY_PREFIX,
16+
REPLICA_VERSION_KEY_PREFIX, get_api_boundary_node_record_node_id, get_node_record_node_id,
17+
make_node_record_key, make_subnet_list_record_key,
1718
};
1819
use prost::Message;
1920
use url::Url;
@@ -46,17 +47,36 @@ impl error::Error for InvariantCheckError {
4647
}
4748

4849
/// Returns all node records in the snapshot.
49-
pub(crate) fn get_all_node_records(snapshot: &RegistrySnapshot) -> Vec<NodeRecord> {
50-
let mut nodes: Vec<NodeRecord> = Vec::new();
50+
pub(crate) fn get_all_node_records(snapshot: &RegistrySnapshot) -> Vec<(NodeId, NodeRecord)> {
51+
let mut nodes = Vec::new();
5152
for (k, v) in snapshot {
52-
if k.starts_with(NODE_RECORD_KEY_PREFIX.as_bytes()) {
53+
if let Some(id) = get_node_record_node_id(str::from_utf8(k).unwrap()) {
5354
let record = NodeRecord::decode(v.as_slice()).unwrap();
54-
nodes.push(record);
55+
nodes.push((NodeId::from(id), record));
5556
}
5657
}
58+
5759
nodes
5860
}
5961

62+
/// Returns all replica version records in the snapshot.
63+
pub(crate) fn get_all_replica_version_records(
64+
snapshot: &RegistrySnapshot,
65+
) -> Vec<(String, ReplicaVersionRecord)> {
66+
let mut replica_versions = Vec::new();
67+
for (k, v) in snapshot {
68+
if let Some(key) = str::from_utf8(k)
69+
.unwrap()
70+
.strip_prefix(REPLICA_VERSION_KEY_PREFIX)
71+
{
72+
let record = ReplicaVersionRecord::decode(v.as_slice()).unwrap();
73+
replica_versions.push((key.to_owned(), record));
74+
}
75+
}
76+
77+
replica_versions
78+
}
79+
6080
pub(crate) fn get_value_from_snapshot<T: Message + Default>(
6181
snapshot: &RegistrySnapshot,
6282
key: String,
@@ -96,41 +116,13 @@ pub(crate) fn get_all_hostos_version_records(
96116
snapshot: &RegistrySnapshot,
97117
) -> Vec<HostosVersionRecord> {
98118
let mut result = Vec::new();
99-
for key in snapshot.keys() {
100-
let hostos_version_key = String::from_utf8(key.clone()).unwrap();
101-
if hostos_version_key.starts_with(HOSTOS_VERSION_KEY_PREFIX) {
102-
let hostos_version_record = match snapshot.get(key) {
103-
Some(hostos_version_record_bytes) => {
104-
HostosVersionRecord::decode(hostos_version_record_bytes.as_slice()).unwrap()
105-
}
106-
None => panic!("Cannot fetch HostosVersionRecord for an existing key"),
107-
};
119+
for (k, v) in snapshot {
120+
if k.starts_with(HOSTOS_VERSION_KEY_PREFIX.as_bytes()) {
121+
let hostos_version_record = HostosVersionRecord::decode(v.as_slice()).unwrap();
108122
result.push(hostos_version_record);
109123
}
110124
}
111-
result
112-
}
113125

114-
/// Returns all node records from the snapshot.
115-
pub(crate) fn get_node_records_from_snapshot(
116-
snapshot: &RegistrySnapshot,
117-
) -> BTreeMap<NodeId, NodeRecord> {
118-
let mut result = BTreeMap::<NodeId, NodeRecord>::new();
119-
for key in snapshot.keys() {
120-
if let Some(principal_id) =
121-
get_node_record_node_id(String::from_utf8(key.clone()).unwrap().as_str())
122-
{
123-
// This is indeed a node record
124-
let node_record = match snapshot.get(key) {
125-
Some(node_record_bytes) => {
126-
NodeRecord::decode(node_record_bytes.as_slice()).unwrap()
127-
}
128-
None => panic!("Cannot fetch node record for an existing key"),
129-
};
130-
let node_id = NodeId::from(principal_id);
131-
result.insert(node_id, node_record);
132-
}
133-
}
134126
result
135127
}
136128

rs/registry/canister/src/invariants/crypto.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::common::LOG_PREFIX;
22
use crate::invariants::{
33
common::{
4-
InvariantCheckError, RegistrySnapshot, get_node_records_from_snapshot,
5-
get_subnet_ids_from_snapshot, get_value_from_snapshot,
4+
InvariantCheckError, RegistrySnapshot, get_all_node_records, get_subnet_ids_from_snapshot,
5+
get_value_from_snapshot,
66
},
77
subnet::get_subnet_records_map,
88
};
@@ -75,13 +75,13 @@ fn check_node_crypto_keys_exist_and_are_unique(
7575
snapshot: &RegistrySnapshot,
7676
) -> Result<(), InvariantCheckError> {
7777
println!("{LOG_PREFIX}node_crypto_keys_invariants_check_start");
78-
let nodes = get_node_records_from_snapshot(snapshot);
78+
let nodes = get_all_node_records(snapshot);
7979
let (pks, certs) = get_all_nodes_public_keys_and_certs(snapshot)?;
8080

8181
let mut ok_node_count = 0;
8282
let mut bad_node_count = 0;
8383
let mut maybe_error: Option<Result<(), InvariantCheckError>> = None;
84-
for node_id in nodes.keys() {
84+
for node_id in nodes.iter().map(|(k, _)| k) {
8585
// Check that all the nodes' keys and certs are present, and node_id is consistent
8686
match node_has_all_keys_and_cert_and_valid_node_id(node_id, &pks, &certs) {
8787
Ok(()) => ok_node_count += 1,

rs/registry/canister/src/invariants/endpoint.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use crate::invariants::common::{
2-
InvariantCheckError, RegistrySnapshot, get_node_records_from_snapshot,
3-
};
1+
use crate::invariants::common::{InvariantCheckError, RegistrySnapshot, get_all_node_records};
42

53
use std::{
64
convert::TryFrom,
@@ -31,7 +29,7 @@ pub(crate) fn check_endpoint_invariants(
3129
strict: bool,
3230
) -> Result<(), InvariantCheckError> {
3331
let mut valid_endpoints = BTreeSet::<(IpAddr, u16)>::new();
34-
let node_records = get_node_records_from_snapshot(snapshot);
32+
let node_records = get_all_node_records(snapshot);
3533
let common_error_prefix = format!(
3634
"Invariant violation detected among {} node records",
3735
node_records.len()

rs/registry/canister/src/invariants/firewall.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::invariants::common::{
2-
InvariantCheckError, RegistrySnapshot, get_node_records_from_snapshot,
3-
get_subnet_ids_from_snapshot, get_value_from_snapshot,
2+
InvariantCheckError, RegistrySnapshot, get_all_node_records, get_subnet_ids_from_snapshot,
3+
get_value_from_snapshot,
44
};
55

66
use std::{
@@ -36,7 +36,7 @@ pub(crate) fn check_firewall_invariants(
3636
) -> Result<(), InvariantCheckError> {
3737
validate_firewall_rule_principals(snapshot)?;
3838

39-
for node_id in get_node_records_from_snapshot(snapshot).keys() {
39+
for node_id in get_all_node_records(snapshot).iter().map(|(k, _)| k) {
4040
let node_ruleset = get_node_firewall_rules(snapshot, node_id);
4141
validate_firewall_ruleset(node_ruleset)?;
4242
}
@@ -63,8 +63,9 @@ pub(crate) fn check_firewall_invariants(
6363
fn validate_firewall_rule_principals(
6464
snapshot: &RegistrySnapshot,
6565
) -> Result<(), InvariantCheckError> {
66-
let mut principal_ids: BTreeSet<PrincipalId> = get_node_records_from_snapshot(snapshot)
67-
.keys()
66+
let mut principal_ids: BTreeSet<PrincipalId> = get_all_node_records(snapshot)
67+
.iter()
68+
.map(|(k, _)| k)
6869
.map(|s| s.get())
6970
.collect();
7071

rs/registry/canister/src/invariants/hostos_version.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::invariants::common::{
22
InvariantCheckError, RegistrySnapshot, assert_valid_urls_and_hash,
3-
get_all_hostos_version_records, get_node_records_from_snapshot, get_value_from_snapshot,
3+
get_all_hostos_version_records, get_all_node_records, get_value_from_snapshot,
44
};
55

66
use ic_protobuf::registry::hostos_version::v1::HostosVersionRecord;
@@ -55,8 +55,8 @@ fn get_hostos_version_record(snapshot: &RegistrySnapshot, version: String) -> Ho
5555
/// Returns the list of HostOS versions where each version is referred to
5656
/// by at least one node.
5757
fn get_all_hostos_versions_of_nodes(snapshot: &RegistrySnapshot) -> Vec<String> {
58-
get_node_records_from_snapshot(snapshot)
59-
.values()
60-
.filter_map(|node_record| node_record.hostos_version_id.clone())
58+
get_all_node_records(snapshot)
59+
.iter()
60+
.filter_map(|(_, node_record)| node_record.hostos_version_id.clone())
6161
.collect()
6262
}

rs/registry/canister/src/invariants/node_operator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub(crate) fn check_node_operator_invariants(
1414
strict: bool,
1515
) -> Result<(), InvariantCheckError> {
1616
if strict {
17-
for node_record in get_all_node_records(snapshot) {
17+
for (_, node_record) in get_all_node_records(snapshot) {
1818
let node_operator_id = PrincipalId::try_from(node_record.node_operator_id).unwrap();
1919
let key = make_node_operator_record_key(node_operator_id);
2020
match snapshot.get(key.as_bytes()) {

rs/registry/canister/src/invariants/node_record.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
1-
use std::collections::{BTreeMap, HashMap};
1+
use std::collections::HashMap;
22

33
use ic_base_types::NodeId;
44
use ic_nns_common::registry::MAX_NUM_SSH_KEYS;
55
use ic_protobuf::registry::node::v1::NodeRecord;
66

7-
use crate::invariants::common::{
8-
InvariantCheckError, RegistrySnapshot, get_node_records_from_snapshot,
9-
};
7+
use crate::invariants::common::{InvariantCheckError, RegistrySnapshot, get_all_node_records};
108

119
pub(crate) fn check_node_record_invariants(
1210
snapshot: &RegistrySnapshot,
1311
) -> Result<(), InvariantCheckError> {
14-
let node_records = get_node_records_from_snapshot(snapshot);
12+
let node_records = get_all_node_records(snapshot);
1513

1614
check_ssh_key_limits(&node_records)?;
1715
check_chip_ids_are_unique(&node_records)?;
1816

1917
Ok(())
2018
}
2119

22-
fn check_ssh_key_limits(
23-
node_records: &BTreeMap<NodeId, NodeRecord>,
24-
) -> Result<(), InvariantCheckError> {
25-
for node_record in node_records.values() {
20+
fn check_ssh_key_limits(node_records: &[(NodeId, NodeRecord)]) -> Result<(), InvariantCheckError> {
21+
for node_record in node_records.iter().map(|(_, v)| v) {
2622
// Enforce that the ssh_node_state_write_access field does not have too many elements.
2723
if node_record.ssh_node_state_write_access.len() > MAX_NUM_SSH_KEYS {
2824
return Err(InvariantCheckError {
@@ -47,7 +43,7 @@ fn check_ssh_key_limits(
4743
}
4844

4945
fn check_chip_ids_are_unique(
50-
node_records: &BTreeMap<NodeId, NodeRecord>,
46+
node_records: &[(NodeId, NodeRecord)],
5147
) -> Result<(), InvariantCheckError> {
5248
let mut chip_id_to_node: HashMap<Vec<u8>, NodeId> = HashMap::new();
5349

0 commit comments

Comments
 (0)