Skip to content

Commit 70b8f91

Browse files
committed
Store key ids in HashSets
This should speed up any key membership lookups.
1 parent d51f4a8 commit 70b8f91

File tree

3 files changed

+69
-71
lines changed

3 files changed

+69
-71
lines changed

tuf/src/interchange/cjson/shims.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ pub struct RoleDefinition {
116116

117117
impl RoleDefinition {
118118
pub fn from(role: &metadata::RoleDefinition) -> Result<Self> {
119-
let key_ids = role.key_ids().to_vec();
119+
let mut key_ids = role.key_ids().iter().cloned().collect::<Vec<_>>();
120+
key_ids.sort();
120121

121122
Ok(RoleDefinition {
122123
threshold: role.threshold(),
@@ -125,29 +126,23 @@ impl RoleDefinition {
125126
}
126127

127128
pub fn try_into(self) -> Result<metadata::RoleDefinition> {
128-
let vec_len = self.key_ids.len();
129-
if vec_len < 1 {
129+
let key_ids_len = self.key_ids.len();
130+
if key_ids_len < 1 {
130131
return Err(Error::Encoding(
131132
"Role defined with no assoiciated key IDs.".into(),
132133
));
133134
}
134135

135-
let mut seen = HashSet::new();
136-
let mut dupes = 0;
137-
for key_id in self.key_ids.iter() {
138-
if !seen.insert(key_id) {
139-
dupes += 1;
140-
}
141-
}
136+
let key_ids = self.key_ids.into_iter().collect::<HashSet<_>>();
142137

143-
if dupes != 0 {
138+
if key_ids.len() != key_ids_len {
144139
return Err(Error::Encoding(format!(
145140
"Found {} duplicate key IDs.",
146-
dupes
141+
key_ids_len - key_ids.len()
147142
)));
148143
}
149144

150-
metadata::RoleDefinition::new(self.threshold, self.key_ids)
145+
metadata::RoleDefinition::new(self.threshold, key_ids)
151146
}
152147
}
153148

tuf/src/metadata.rs

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -601,13 +601,13 @@ pub struct RootMetadataBuilder {
601601
consistent_snapshot: bool,
602602
keys: HashMap<KeyId, PublicKey>,
603603
root_threshold: u32,
604-
root_key_ids: Vec<KeyId>,
604+
root_key_ids: HashSet<KeyId>,
605605
snapshot_threshold: u32,
606-
snapshot_key_ids: Vec<KeyId>,
606+
snapshot_key_ids: HashSet<KeyId>,
607607
targets_threshold: u32,
608-
targets_key_ids: Vec<KeyId>,
608+
targets_key_ids: HashSet<KeyId>,
609609
timestamp_threshold: u32,
610-
timestamp_key_ids: Vec<KeyId>,
610+
timestamp_key_ids: HashSet<KeyId>,
611611
}
612612

613613
impl RootMetadataBuilder {
@@ -624,13 +624,13 @@ impl RootMetadataBuilder {
624624
consistent_snapshot: true,
625625
keys: HashMap::new(),
626626
root_threshold: 1,
627-
root_key_ids: Vec::new(),
627+
root_key_ids: HashSet::new(),
628628
snapshot_threshold: 1,
629-
snapshot_key_ids: Vec::new(),
629+
snapshot_key_ids: HashSet::new(),
630630
targets_threshold: 1,
631-
targets_key_ids: Vec::new(),
631+
targets_key_ids: HashSet::new(),
632632
timestamp_threshold: 1,
633-
timestamp_key_ids: Vec::new(),
633+
timestamp_key_ids: HashSet::new(),
634634
}
635635
}
636636

@@ -662,7 +662,7 @@ impl RootMetadataBuilder {
662662
pub fn root_key(mut self, public_key: PublicKey) -> Self {
663663
let key_id = public_key.key_id().clone();
664664
self.keys.insert(key_id.clone(), public_key);
665-
self.root_key_ids.push(key_id);
665+
self.root_key_ids.insert(key_id);
666666
self
667667
}
668668

@@ -676,7 +676,7 @@ impl RootMetadataBuilder {
676676
pub fn snapshot_key(mut self, public_key: PublicKey) -> Self {
677677
let key_id = public_key.key_id().clone();
678678
self.keys.insert(key_id.clone(), public_key);
679-
self.snapshot_key_ids.push(key_id);
679+
self.snapshot_key_ids.insert(key_id);
680680
self
681681
}
682682

@@ -690,7 +690,7 @@ impl RootMetadataBuilder {
690690
pub fn targets_key(mut self, public_key: PublicKey) -> Self {
691691
let key_id = public_key.key_id().clone();
692692
self.keys.insert(key_id.clone(), public_key);
693-
self.targets_key_ids.push(key_id);
693+
self.targets_key_ids.insert(key_id);
694694
self
695695
}
696696

@@ -704,7 +704,7 @@ impl RootMetadataBuilder {
704704
pub fn timestamp_key(mut self, public_key: PublicKey) -> Self {
705705
let key_id = public_key.key_id().clone();
706706
self.keys.insert(key_id.clone(), public_key);
707-
self.timestamp_key_ids.push(key_id);
707+
self.timestamp_key_ids.insert(key_id);
708708
self
709709
}
710710

@@ -813,46 +813,34 @@ impl RootMetadata {
813813

814814
/// An iterator over all the trusted root public keys.
815815
pub fn root_keys(&self) -> impl Iterator<Item = &PublicKey> {
816-
self.keys().iter().filter_map(move |(k, v)| {
817-
if self.root.key_ids().contains(k) {
818-
Some(v)
819-
} else {
820-
None
821-
}
822-
})
823-
}
824-
825-
/// An iterator over all the trusted snapshot public keys.
826-
pub fn snapshot_keys(&self) -> impl Iterator<Item = &PublicKey> {
827-
self.keys().iter().filter_map(move |(k, v)| {
828-
if self.snapshot.key_ids().contains(k) {
829-
Some(v)
830-
} else {
831-
None
832-
}
833-
})
816+
self.root
817+
.key_ids()
818+
.iter()
819+
.filter_map(|key_id| self.keys.get(key_id))
834820
}
835821

836822
/// An iterator over all the trusted targets public keys.
837823
pub fn targets_keys(&self) -> impl Iterator<Item = &PublicKey> {
838-
self.keys().iter().filter_map(move |(k, v)| {
839-
if self.targets.key_ids().contains(k) {
840-
Some(v)
841-
} else {
842-
None
843-
}
844-
})
824+
self.targets
825+
.key_ids()
826+
.iter()
827+
.filter_map(|key_id| self.keys.get(key_id))
828+
}
829+
830+
/// An iterator over all the trusted snapshot public keys.
831+
pub fn snapshot_keys(&self) -> impl Iterator<Item = &PublicKey> {
832+
self.snapshot
833+
.key_ids()
834+
.iter()
835+
.filter_map(|key_id| self.keys.get(key_id))
845836
}
846837

847838
/// An iterator over all the trusted timestamp public keys.
848839
pub fn timestamp_keys(&self) -> impl Iterator<Item = &PublicKey> {
849-
self.keys().iter().filter_map(move |(k, v)| {
850-
if self.timestamp.key_ids().contains(k) {
851-
Some(v)
852-
} else {
853-
None
854-
}
855-
})
840+
self.timestamp
841+
.key_ids()
842+
.iter()
843+
.filter_map(|key_id| self.keys.get(key_id))
856844
}
857845

858846
/// An immutable reference to the root role's definition.
@@ -912,12 +900,12 @@ impl<'de> Deserialize<'de> for RootMetadata {
912900
#[derive(Clone, Debug, PartialEq, Eq)]
913901
pub struct RoleDefinition {
914902
threshold: u32,
915-
key_ids: Vec<KeyId>,
903+
key_ids: HashSet<KeyId>,
916904
}
917905

918906
impl RoleDefinition {
919-
/// Create a new `RoleDefinition` with a given threshold and set of authorized `KeyID`s.
920-
pub fn new(threshold: u32, key_ids: Vec<KeyId>) -> Result<Self> {
907+
/// Create a new [RoleDefinition] with a given threshold and set of authorized [KeyID]s.
908+
pub fn new(threshold: u32, key_ids: HashSet<KeyId>) -> Result<Self> {
921909
if threshold < 1 {
922910
return Err(Error::IllegalArgument(format!("Threshold: {}", threshold)));
923911
}
@@ -945,7 +933,7 @@ impl RoleDefinition {
945933
}
946934

947935
/// An immutable reference to the set of `KeyID`s that are authorized to sign the role.
948-
pub fn key_ids(&self) -> &[KeyId] {
936+
pub fn key_ids(&self) -> &HashSet<KeyId> {
949937
&self.key_ids
950938
}
951939
}
@@ -2412,7 +2400,7 @@ mod test {
24122400
#[test]
24132401
fn serde_role_definition() {
24142402
// keyid ordering must be preserved.
2415-
let keyids = vec![
2403+
let keyids = hashset![
24162404
KeyId::from_str("40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53")
24172405
.unwrap(),
24182406
KeyId::from_str("01892c662c8cd79fab20edec21de1dcb8b75d9353103face7fe086ff5c0098e4")
@@ -2424,8 +2412,8 @@ mod test {
24242412
let jsn = json!({
24252413
"threshold": 3,
24262414
"keyids": [
2427-
"40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53",
24282415
"01892c662c8cd79fab20edec21de1dcb8b75d9353103face7fe086ff5c0098e4",
2416+
"40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53",
24292417
"4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db",
24302418
],
24312419
});
@@ -3389,7 +3377,7 @@ mod test {
33893377
fn deserialize_json_role_definition_illegal_threshold() {
33903378
let role_def = RoleDefinition::new(
33913379
1,
3392-
vec![Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
3380+
hashset![Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
33933381
.unwrap()
33943382
.public()
33953383
.key_id()
@@ -3407,7 +3395,7 @@ mod test {
34073395

34083396
let role_def = RoleDefinition::new(
34093397
2,
3410-
vec![
3398+
hashset![
34113399
Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
34123400
.unwrap()
34133401
.public()
@@ -3457,7 +3445,7 @@ mod test {
34573445
.public()
34583446
.key_id()
34593447
.clone();
3460-
let role_def = RoleDefinition::new(1, vec![key_id.clone()]).unwrap();
3448+
let role_def = RoleDefinition::new(1, hashset![key_id.clone()]).unwrap();
34613449
let mut jsn = serde_json::to_value(&role_def).unwrap();
34623450

34633451
match jsn.as_object_mut() {

tuf/src/repo_builder.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ where
228228
return true;
229229
}
230230

231-
for &key in &self.trusted_root_keys {
232-
if !root.root_keys().any(|x| x == key.public()) {
231+
for key in &self.trusted_root_keys {
232+
if root.root().key_ids().get(key.public().key_id()).is_none() {
233233
return true;
234234
}
235235
}
@@ -238,7 +238,12 @@ where
238238
}
239239
fn targets_keys_changed(&self, root: &Verified<RootMetadata>) -> bool {
240240
for key in &self.trusted_targets_keys {
241-
if !root.targets_keys().any(|x| x == key.public()) {
241+
if root
242+
.targets()
243+
.key_ids()
244+
.get(key.public().key_id())
245+
.is_none()
246+
{
242247
return true;
243248
}
244249
}
@@ -248,7 +253,12 @@ where
248253

249254
fn snapshot_keys_changed(&self, root: &Verified<RootMetadata>) -> bool {
250255
for key in &self.trusted_snapshot_keys {
251-
if !root.snapshot_keys().any(|x| x == key.public()) {
256+
if root
257+
.snapshot()
258+
.key_ids()
259+
.get(key.public().key_id())
260+
.is_none()
261+
{
252262
return true;
253263
}
254264
}
@@ -258,7 +268,12 @@ where
258268

259269
fn timestamp_keys_changed(&self, root: &Verified<RootMetadata>) -> bool {
260270
for key in &self.trusted_timestamp_keys {
261-
if !root.timestamp_keys().any(|x| x == key.public()) {
271+
if root
272+
.timestamp()
273+
.key_ids()
274+
.get(key.public().key_id())
275+
.is_none()
276+
{
262277
return true;
263278
}
264279
}

0 commit comments

Comments
 (0)