Skip to content

Commit 91a9a8c

Browse files
committed
add stolen_uris field
1 parent ef6fb13 commit 91a9a8c

File tree

2 files changed

+84
-13
lines changed

2 files changed

+84
-13
lines changed

rust/rbac-registration/src/cardano/cip509/utils/cip134_uri_set.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ impl Cip0134UriSet {
6666
&self.0.c_uris
6767
}
6868

69+
/// Returns an iterator over of `Cip0134Uri`.
70+
pub fn values(&self) -> impl Iterator<Item = &Cip0134Uri> {
71+
self.x_uris()
72+
.values()
73+
.chain(self.c_uris().values())
74+
.flat_map(|uris| uris.iter())
75+
}
76+
6977
/// Returns `true` if both x509 and c509 certificate maps are empty.
7078
#[must_use]
7179
pub fn is_empty(&self) -> bool {
@@ -90,7 +98,7 @@ impl Cip0134UriSet {
9098
result
9199
}
92100

93-
/// Returns a list of stake addresses by the given role.
101+
/// Returns a set of stake addresses by the given role.
94102
#[must_use]
95103
pub fn role_stake_addresses(
96104
&self,
@@ -107,13 +115,10 @@ impl Cip0134UriSet {
107115
.collect()
108116
}
109117

110-
/// Returns a list of all stake addresses.
118+
/// Returns a set of all stake addresses.
111119
#[must_use]
112120
pub fn stake_addresses(&self) -> HashSet<StakeAddress> {
113-
self.x_uris()
114-
.values()
115-
.chain(self.c_uris().values())
116-
.flat_map(|uris| uris.iter())
121+
self.values()
117122
.filter_map(|uri| {
118123
match uri.address() {
119124
Address::Stake(a) => Some(a.clone().into()),

rust/rbac-registration/src/registration/cardano/mod.rs

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use std::{
99

1010
use anyhow::Context;
1111
use c509_certificate::c509::C509;
12-
use cardano_blockchain_types::{hashes::TransactionId, Point, StakeAddress, TxnIndex};
12+
use cardano_blockchain_types::{
13+
hashes::TransactionId, pallas_addresses::Address, Cip0134Uri, Point, StakeAddress, TxnIndex,
14+
};
1315
use catalyst_types::{
1416
catalyst_id::{key_rotation::KeyRotation, role_index::RoleId, CatalystId},
1517
conversion::zero_out_last_n_bytes,
@@ -344,10 +346,29 @@ impl RegistrationChain {
344346
.and_then(|rdr| rdr.encryption_key_from_rotation(rotation))
345347
}
346348

347-
/// Returns all stake addresses associated to this registration.
349+
/// Returns all stake addresses associated to this chain.
348350
#[must_use]
349351
pub fn stake_addresses(&self) -> HashSet<StakeAddress> {
350-
self.inner.certificate_uris.stake_addresses()
352+
let stolen_stake_addresses = self
353+
.inner
354+
.stolen_uris
355+
.iter()
356+
.flat_map(|v| {
357+
v.data().iter().filter_map(|uri| {
358+
match uri.address() {
359+
Address::Stake(a) => Some(a.clone().into()),
360+
_ => None,
361+
}
362+
})
363+
})
364+
.collect();
365+
366+
self.inner
367+
.certificate_uris
368+
.stake_addresses()
369+
.difference(&stolen_stake_addresses)
370+
.cloned()
371+
.collect()
351372
}
352373
}
353374

@@ -376,6 +397,9 @@ struct RegistrationChainInner {
376397
/// List of point + transaction index, and certificate key hash.
377398
revocations: Vec<PointData<CertKeyHash>>,
378399

400+
/// URIs which are stolen by another registration chains.
401+
stolen_uris: Vec<PointData<Box<[Cip0134Uri]>>>,
402+
379403
// Role
380404
/// Map of role number to list point + transaction index, and role data.
381405
/// Record history of the whole role data in point in time.
@@ -494,6 +518,7 @@ impl RegistrationChainInner {
494518
certificate_uris,
495519
simple_keys,
496520
revocations,
521+
stolen_uris: vec![],
497522
role_data_history,
498523
role_data_record,
499524
payment_history,
@@ -514,10 +539,25 @@ impl RegistrationChainInner {
514539
let mut new_inner = self.clone();
515540

516541
let Some(prv_tx_id) = cip509.previous_transaction() else {
517-
cip509
518-
.report()
519-
.missing_field("previous transaction ID", context);
520-
return None;
542+
if let Some(cat_id) = cip509.catalyst_id() {
543+
if cat_id == &self.catalyst_id {
544+
cip509.report().functional_validation(
545+
&format!(
546+
"Trying to apply the first registration to the assosiated {} again",
547+
cat_id.as_short_id()
548+
),
549+
"It isn't allowed to submit first registration twice",
550+
);
551+
return None;
552+
}
553+
554+
return new_inner.update_cause_another_chain(cip509);
555+
} else {
556+
cip509
557+
.report()
558+
.missing_field("previous transaction ID", context);
559+
return None;
560+
}
521561
};
522562

523563
// Previous transaction ID in the CIP509 should equal to the current transaction ID
@@ -603,6 +643,32 @@ impl RegistrationChainInner {
603643
Some(new_inner)
604644
}
605645

646+
/// Update the registration chain with the `cip509` assosiated to another chain.
647+
/// This is the case when registration for different chain affecting the current one,
648+
/// by invalidating some data for the current registration chain (stoling stake
649+
/// addresses etc.).
650+
///
651+
/// The provided `cip509` should be fully validated by another chain before trying to
652+
/// submit to the current one.
653+
#[must_use]
654+
fn update_cause_another_chain(
655+
mut self,
656+
cip509: &Cip509,
657+
) -> Option<Self> {
658+
if let Some(uri_set) = cip509.certificate_uris() {
659+
let origin = cip509.origin().clone();
660+
self.stolen_uris.push(PointData::new(
661+
origin,
662+
uri_set
663+
.values()
664+
.cloned()
665+
.collect::<Vec<_>>()
666+
.into_boxed_slice(),
667+
));
668+
}
669+
Some(self)
670+
}
671+
606672
/// Get the latest signing public key for a role.
607673
/// Returns the public key and the rotation,`None` if not found.
608674
#[must_use]

0 commit comments

Comments
 (0)