Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 49 additions & 21 deletions rust/rbac-registration/src/cardano/cip509/cip509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use catalyst_types::{
uuid::UuidV4,
};
use cbork_utils::decode_helper::{decode_bytes, decode_helper, decode_map_len};
use ed25519_dalek::VerifyingKey;
use minicbor::{
decode::{self},
Decode, Decoder,
Expand All @@ -32,6 +33,7 @@ use uuid::Uuid;

use crate::cardano::cip509::{
decode_context::DecodeContext,
extract_key,
rbac::Cip509RbacMetadata,
types::{PaymentHistory, TxInputHash, ValidationSignature},
utils::Cip0134UriSet,
Expand All @@ -40,7 +42,7 @@ use crate::cardano::cip509::{
validate_txn_inputs_hash,
},
x509_chunks::X509Chunks,
Payment, PointTxnIdx, RoleData,
C509Cert, LocalRefInt, Payment, PointTxnIdx, RoleData, SimplePublicKeyType, X509DerCert,
};

/// A x509 metadata envelope.
Expand Down Expand Up @@ -227,6 +229,48 @@ impl Cip509 {
self.metadata.as_ref().and_then(|m| m.role_data.get(&role))
}

/// Returns signing public key for a role.
/// Would return only signing public keys for the present ceritificates,
/// if certificate marked as deleted or undefined it would be skipped.
#[must_use]
pub(crate) fn signing_pk_for_role(
&self,
role: RoleId,
) -> Option<VerifyingKey> {
self.metadata.as_ref().and_then(|m| {
let key_ref = m.role_data.get(&role).and_then(|d| d.signing_key())?;
match key_ref.local_ref {
LocalRefInt::X509Certs => {
m.x509_certs.get(key_ref.key_offset).and_then(|c| {
if let X509DerCert::X509Cert(c) = c {
extract_key::x509_key(&c).ok()
} else {
None
}
})
},
LocalRefInt::C509Certs => {
m.c509_certs.get(key_ref.key_offset).and_then(|c| {
if let C509Cert::C509Certificate(c) = c {
extract_key::c509_key(&c).ok()
} else {
None
}
})
},
LocalRefInt::PubKeys => {
m.pub_keys.get(key_ref.key_offset).and_then(|c| {
if let SimplePublicKeyType::Ed25519(c) = c {
Some(c.clone())
} else {
None
}
})
},
}
})
}

/// Returns a purpose of this registration.
#[must_use]
pub fn purpose(&self) -> Option<UuidV4> {
Expand Down Expand Up @@ -313,26 +357,10 @@ impl Cip509 {
.unwrap_or_default()
}

/// Returns `Cip509` fields consuming the structure if it was successfully decoded and
/// validated otherwise return the problem report that contains all the encountered
/// issues.
///
/// # Errors
///
/// - `Err(ProblemReport)`
pub fn consume(self) -> Result<(UuidV4, Cip509RbacMetadata, PaymentHistory), ProblemReport> {
match (
self.purpose,
self.txn_inputs_hash,
self.metadata,
self.validation_signature,
) {
(Some(purpose), Some(_), Some(metadata), Some(_)) if !self.report.is_problematic() => {
Ok((purpose, metadata, self.payment_history))
},

_ => Err(self.report),
}
/// Returns a payment history map.
#[must_use]
pub fn payment_history(&self) -> &PaymentHistory {
&self.payment_history
}
}

Expand Down
17 changes: 11 additions & 6 deletions rust/rbac-registration/src/cardano/cip509/utils/cip134_uri_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ impl Cip0134UriSet {
&self.0.c_uris
}

/// Returns an iterator over of `Cip0134Uri`.
pub fn values(&self) -> impl Iterator<Item = &Cip0134Uri> {
self.x_uris()
.values()
.chain(self.c_uris().values())
.flat_map(|uris| uris.iter())
}

/// Returns `true` if both x509 and c509 certificate maps are empty.
#[must_use]
pub fn is_empty(&self) -> bool {
Expand All @@ -90,7 +98,7 @@ impl Cip0134UriSet {
result
}

/// Returns a list of stake addresses by the given role.
/// Returns a set of stake addresses by the given role.
#[must_use]
pub fn role_stake_addresses(
&self,
Expand All @@ -107,13 +115,10 @@ impl Cip0134UriSet {
.collect()
}

/// Returns a list of all stake addresses.
/// Returns a set of all stake addresses.
#[must_use]
pub fn stake_addresses(&self) -> HashSet<StakeAddress> {
self.x_uris()
.values()
.chain(self.c_uris().values())
.flat_map(|uris| uris.iter())
self.values()
.filter_map(|uri| {
match uri.address() {
Address::Stake(a) => Some(a.clone().into()),
Expand Down
8 changes: 3 additions & 5 deletions rust/rbac-registration/src/cardano/cip509/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,8 +593,7 @@ mod tests {
assert_eq!(origin.txn_index(), data.txn_index);
assert_eq!(origin.point().slot_or_default(), data.slot);

// The consume function must return the problem report contained within the registration.
let report = registration.consume().unwrap_err();
let report = registration.report();
assert!(report.is_problematic());
let report = format!("{report:?}");
assert!(report.contains("is not present in the transaction witness set, and can not be verified as owned and spendable"));
Expand All @@ -616,7 +615,7 @@ mod tests {
assert_eq!(origin.txn_index(), data.txn_index);
assert_eq!(origin.point().slot_or_default(), data.slot);

let report = registration.consume().unwrap_err();
let report = registration.report();
assert!(report.is_problematic());
let report = format!("{report:?}");
assert!(report
Expand All @@ -637,8 +636,7 @@ mod tests {
assert_eq!(origin.txn_index(), data.txn_index);
assert_eq!(origin.point().slot_or_default(), data.slot);

// The consume function must return the problem report contained within the registration.
let report = registration.consume().unwrap_err();
let report = registration.report();
assert!(report.is_problematic());
let report = format!("{report:?}");
assert!(report.contains("Unknown role found: 4"));
Expand Down
15 changes: 8 additions & 7 deletions rust/rbac-registration/src/providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub trait RbacRegistrationProvider {
/// for the given Catalyst ID.
fn chain(
&self,
id: CatalystId,
id: &CatalystId,
) -> impl Future<Output = anyhow::Result<Option<RegistrationChain>>> + Send;

/// Returns `true` if a chain with the given Catalyst ID already exists.
Expand All @@ -24,24 +24,25 @@ pub trait RbacRegistrationProvider {
/// chain.
fn is_chain_known(
&self,
id: CatalystId,
id: &CatalystId,
) -> impl Future<Output = anyhow::Result<bool>> + Send;

/// Returns a Catalyst ID corresponding to the given stake address.
fn catalyst_id_from_stake_address(
/// Returns a current valid registration chain corresponding to the given stake
/// address.
fn chain_from_stake_address(
&self,
address: &StakeAddress,
) -> impl Future<Output = anyhow::Result<Option<CatalystId>>> + Send;
) -> impl Future<Output = anyhow::Result<Option<RegistrationChain>>> + Send;

/// Returns a Catalyst ID corresponding to the given public key.
fn catalyst_id_from_public_key(
&self,
key: VerifyingKey,
key: &VerifyingKey,
) -> impl Future<Output = anyhow::Result<Option<CatalystId>>> + Send;

/// Returns a Catalyst ID corresponding to the given transaction hash.
fn catalyst_id_from_txn_id(
&self,
txn_id: TransactionId,
txn_id: &TransactionId,
) -> impl Future<Output = anyhow::Result<Option<CatalystId>>> + Send;
}
Loading