Skip to content

Commit ba6ad3e

Browse files
Mr-Leshiyapskhemrafal-chbkioshn
authored
feat(rust/rbac-registration): RBAC refactoring feature branch (#630)
* feat(rust/rbac-registration): Add provider trait for `RegistrationChain` (#586) * initial * feat: provider * feat: update chain * feat: start_new_chain * feat: merge validation result struct into cip509 * feat: exports * feat: return new chain * chore: return success object * fix: older version * feat: cat id in payload * fix: new version * chore: lintfix * chore: remove persistent arguments * tmp * chore: complete moving to central module * feat: ref fn * chore: merge methods * chore: minor * feat: export modified chains * chore: minor comment * chore: rbac update logic * chore: isolation * chore: validation and lintfix * docs: remove error doc * chore: minor refactor * fix: comments * chore: validation function return * Update rust/rbac-registration/src/providers.rs Co-authored-by: Alex Pozhylenkov <leshiy12345678@gmail.com> --------- Co-authored-by: Alex Pozhylenkov <leshiy12345678@gmail.com> * feat(rust/rbac-registration): RBAC stolen `StakeAddress` handling. (#631) * wip * wip * wip * wip * revert * wip * add stolen_uris field * wip * wip * wip * fix * wip * wip * fix spelling * fix * wip * wip * wip * wip * cleanup * fix test * fix clippy * wip * wip * fix * wip * fix clippy * fix * wip * wip * fix clippy * make Cip0134UriSet private (#655) * wip (#658) * Update rust/rbac-registration/src/registration/cardano/mod.rs Co-authored-by: Rafał Chabowski <rafal.chabowski@iohk.io> * fix suggestions * wip * fix clippy * comments fixes * rename state to Provider * fix fmt * cleanup `check_signing_public_key` * Update rust/rbac-registration/src/cardano/cip509/cip509.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> * fix fmt * fix fmt --------- Co-authored-by: Apisit Ritruengroj <38898766+apskhem@users.noreply.github.com> Co-authored-by: Rafał Chabowski <rafal.chabowski@iohk.io> Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com>
1 parent 0c33096 commit ba6ad3e

File tree

10 files changed

+513
-174
lines changed

10 files changed

+513
-174
lines changed

rust/rbac-registration/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ thiserror = "2.0.11"
3434

3535
c509-certificate = { version = "0.0.3", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "c509-certificate-v0.0.3" }
3636
cbork-utils = { version = "0.0.2", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-utils-v0.0.2" }
37-
cardano-blockchain-types = { version = "0.0.8", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-blockchain-types/v0.0.8" }
37+
cardano-blockchain-types = { version = "0.0.9", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-blockchain-types/v0.0.9" }
3838
catalyst-types = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.10" }

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

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

1010
use anyhow::{Context, anyhow};
1111
use cardano_blockchain_types::{
12-
MetadatumLabel, MultiEraBlock, TxnIndex,
12+
MetadatumLabel, MultiEraBlock, StakeAddress, TxnIndex,
1313
hashes::{BLAKE_2B256_SIZE, Blake2b256Hash, TransactionId},
1414
pallas_addresses::{Address, ShelleyAddress},
1515
pallas_primitives::{Nullable, conway},
@@ -22,6 +22,7 @@ use catalyst_types::{
2222
uuid::UuidV4,
2323
};
2424
use cbork_utils::decode_helper::{decode_bytes, decode_helper, decode_map_len};
25+
use ed25519_dalek::VerifyingKey;
2526
use minicbor::{
2627
Decode, Decoder,
2728
decode::{self},
@@ -31,8 +32,9 @@ use tracing::warn;
3132
use uuid::Uuid;
3233

3334
use crate::cardano::cip509::{
34-
Payment, PointTxnIdx, RoleData,
35+
C509Cert, LocalRefInt, Payment, PointTxnIdx, RoleData, SimplePublicKeyType, X509DerCert,
3536
decode_context::DecodeContext,
37+
extract_key,
3638
rbac::Cip509RbacMetadata,
3739
types::{PaymentHistory, TxInputHash, ValidationSignature},
3840
utils::Cip0134UriSet,
@@ -80,7 +82,8 @@ pub struct Cip509 {
8082
origin: PointTxnIdx,
8183
/// A catalyst ID.
8284
///
83-
/// This field is only present in role 0 registrations.
85+
/// This field is only present in role 0 registrations and only for the first
86+
/// registration, which defines a `CatalystId` for the chain.
8487
catalyst_id: Option<CatalystId>,
8588
/// Raw aux data associated with the transaction that CIP509 is attached to,
8689
raw_aux_data: Vec<u8>,
@@ -180,6 +183,12 @@ impl Cip509 {
180183
validate_self_sign_cert(metadata, &report);
181184
}
182185

186+
// We want to keep `catalyst_id` field only for the first registration,
187+
// which starts a new chain
188+
if cip509.prv_tx_id.is_some() {
189+
cip509.catalyst_id = None;
190+
}
191+
183192
Ok(Some(cip509))
184193
}
185194

@@ -227,6 +236,49 @@ impl Cip509 {
227236
self.metadata.as_ref().and_then(|m| m.role_data.get(&role))
228237
}
229238

239+
/// Returns signing public key for a role.
240+
/// Would return only signing public keys for the present certificates,
241+
/// if certificates or simple public key is marked as deleted or undefined it would be
242+
/// skipped.
243+
#[must_use]
244+
pub fn signing_public_key_for_role(
245+
&self,
246+
role: RoleId,
247+
) -> Option<VerifyingKey> {
248+
self.metadata.as_ref().and_then(|m| {
249+
let key_ref = m.role_data.get(&role).and_then(|d| d.signing_key())?;
250+
match key_ref.local_ref {
251+
LocalRefInt::X509Certs => {
252+
m.x509_certs.get(key_ref.key_offset).and_then(|c| {
253+
if let X509DerCert::X509Cert(c) = c {
254+
extract_key::x509_key(c).ok()
255+
} else {
256+
None
257+
}
258+
})
259+
},
260+
LocalRefInt::C509Certs => {
261+
m.c509_certs.get(key_ref.key_offset).and_then(|c| {
262+
if let C509Cert::C509Certificate(c) = c {
263+
extract_key::c509_key(c).ok()
264+
} else {
265+
None
266+
}
267+
})
268+
},
269+
LocalRefInt::PubKeys => {
270+
m.pub_keys.get(key_ref.key_offset).and_then(|c| {
271+
if let SimplePublicKeyType::Ed25519(c) = c {
272+
Some(*c)
273+
} else {
274+
None
275+
}
276+
})
277+
},
278+
}
279+
})
280+
}
281+
230282
/// Returns a purpose of this registration.
231283
#[must_use]
232284
pub fn purpose(&self) -> Option<UuidV4> {
@@ -269,24 +321,13 @@ impl Cip509 {
269321
self.txn_inputs_hash.as_ref()
270322
}
271323

272-
/// Returns a Catalyst ID of this registration if role 0 is present.
324+
/// Returns a Catalyst ID of this registration if role 0 is present and if its a first
325+
/// registration, which defines a `CatalystId` for the chain.
273326
#[must_use]
274327
pub fn catalyst_id(&self) -> Option<&CatalystId> {
275328
self.catalyst_id.as_ref()
276329
}
277330

278-
/// Returns a list of addresses extracted from certificate URIs of a specific role.
279-
#[must_use]
280-
pub fn certificate_addresses(
281-
&self,
282-
role: usize,
283-
) -> HashSet<Address> {
284-
self.metadata
285-
.as_ref()
286-
.map(|m| m.certificate_uris.role_addresses(role))
287-
.unwrap_or_default()
288-
}
289-
290331
/// Return validation signature.
291332
#[must_use]
292333
pub fn validation_signature(&self) -> Option<&ValidationSignature> {
@@ -305,26 +346,18 @@ impl Cip509 {
305346
self.metadata.as_ref()
306347
}
307348

308-
/// Returns `Cip509` fields consuming the structure if it was successfully decoded and
309-
/// validated otherwise return the problem report that contains all the encountered
310-
/// issues.
311-
///
312-
/// # Errors
313-
///
314-
/// - `Err(ProblemReport)`
315-
pub fn consume(self) -> Result<(UuidV4, Cip509RbacMetadata, PaymentHistory), ProblemReport> {
316-
match (
317-
self.purpose,
318-
self.txn_inputs_hash,
319-
self.metadata,
320-
self.validation_signature,
321-
) {
322-
(Some(purpose), Some(_), Some(metadata), Some(_)) if !self.report.is_problematic() => {
323-
Ok((purpose, metadata, self.payment_history))
324-
},
349+
/// Returns a set of stake addresses.
350+
#[must_use]
351+
pub fn stake_addresses(&self) -> HashSet<StakeAddress> {
352+
self.certificate_uris()
353+
.map(Cip0134UriSet::active_stake_addresses)
354+
.unwrap_or_default()
355+
}
325356

326-
_ => Err(self.report),
327-
}
357+
/// Returns a payment history map.
358+
#[must_use]
359+
pub fn payment_history(&self) -> &PaymentHistory {
360+
&self.payment_history
328361
}
329362
}
330363

rust/rbac-registration/src/cardano/cip509/rbac/metadata.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,31 @@ use crate::cardano::cip509::{
2828
#[allow(clippy::module_name_repetitions)]
2929
pub struct Cip509RbacMetadata {
3030
/// A potentially empty list of x509 certificates.
31-
pub x509_certs: Vec<X509DerCert>,
31+
pub(crate) x509_certs: Vec<X509DerCert>,
3232
/// A potentially empty list of c509 certificates.
33-
pub c509_certs: Vec<C509Cert>,
33+
pub(crate) c509_certs: Vec<C509Cert>,
3434
/// A set of URIs contained in both x509 and c509 certificates.
3535
///
3636
/// URIs from different certificate types are stored separately and certificate
3737
/// indexes are preserved too.
3838
///
3939
/// This field isn't present in the encoded format and is populated by processing both
4040
/// `x509_certs` and `c509_certs` fields.
41-
pub certificate_uris: Cip0134UriSet,
41+
pub(crate) certificate_uris: Cip0134UriSet,
4242
/// A list of public keys that can be used instead of storing full certificates.
4343
///
4444
/// Check [this section] to understand how certificates and the public keys list are
4545
/// related.
4646
///
4747
/// [this section]: https://github.com/input-output-hk/catalyst-CIPs/tree/x509-role-registration-metadata/CIP-XXXX#storing-certificates-and-public-key
48-
pub pub_keys: Vec<SimplePublicKeyType>,
48+
pub(crate) pub_keys: Vec<SimplePublicKeyType>,
4949
/// A potentially empty list of revoked certificates.
50-
pub revocation_list: Vec<CertKeyHash>,
50+
pub(crate) revocation_list: Vec<CertKeyHash>,
5151
/// A potentially empty role data.
52-
pub role_data: HashMap<RoleId, RoleData>,
52+
pub(crate) role_data: HashMap<RoleId, RoleData>,
5353
/// Optional map of purpose key data.
5454
/// Empty map if no purpose key data is present.
55-
pub purpose_key_data: HashMap<u16, Vec<u8>>,
55+
pub(crate) purpose_key_data: HashMap<u16, Vec<u8>>,
5656
}
5757

5858
/// The first valid purpose key.

rust/rbac-registration/src/cardano/cip509/types/cert_or_pk.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub enum CertOrPk {
2121

2222
impl CertOrPk {
2323
/// Extract public key from the given certificate or public key.
24-
pub(crate) fn extract_pk(&self) -> Option<VerifyingKey> {
24+
pub(crate) fn extract_public_key(&self) -> Option<VerifyingKey> {
2525
match self {
2626
CertOrPk::X509(Some(x509)) => extract_key::x509_key(x509).ok(),
2727
CertOrPk::C509(Some(c509)) => extract_key::c509_key(c509).ok(),

0 commit comments

Comments
 (0)