Skip to content

Commit 22dd049

Browse files
apskhemMr-Leshiy
andauthored
refactor(cat-gateway): Modify signed_doc::EnvVars.admin_keys a single value CatalystId (#3662)
* initial * feat: admin * fix: comments * chore: bump --------- Co-authored-by: Alex Pozhylenkov <[email protected]>
1 parent 3bb045e commit 22dd049

File tree

6 files changed

+56
-74
lines changed

6 files changed

+56
-74
lines changed

catalyst-gateway/bin/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ repository.workspace = true
1515
workspace = true
1616

1717
[dependencies]
18-
cardano-chain-follower = { version = "0.0.17", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-chain-follower/v0.0.17" }
19-
rbac-registration = { version = "0.0.13", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "rbac-registration/v0.0.13" }
20-
catalyst-signed-doc = { version = "0.0.9", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-signed-doc/v0.0.9" }
18+
cardano-chain-follower = { version = "0.0.18", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-chain-follower/v0.0.18" }
19+
rbac-registration = { version = "0.0.14", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "rbac-registration/v0.0.14" }
20+
catalyst-signed-doc = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-signed-doc/v0.0.10" }
2121
catalyst-signed-doc-v1 = { package = "catalyst-signed-doc", version = "0.0.4", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-signed-doc/v.0.0.4" }
2222
c509-certificate = { version = "0.0.3", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "c509-certificate-v0.0.3" }
23-
catalyst-types = { version = "0.0.9", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.9" }
23+
catalyst-types = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.10" }
2424

2525
clap = { version = "4.5.20", features = ["derive", "env"] }
2626
tracing = { version = "0.1.40", features = ["log"] }

catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::{fmt::Debug, sync::Arc};
44

55
use cardano_chain_follower::{pallas_addresses::Address, Cip36, Slot, TxnIndex, VotingPubKey};
6+
use poem_openapi::types::ToJSON;
67
use scylla::{client::session::Session, value::MaybeUnset, SerializeRow};
78
use tracing::error;
89

@@ -11,6 +12,7 @@ use crate::{
1112
index::queries::{PreparedQueries, SizedBatch},
1213
types::{DbSlot, DbTxnIndex},
1314
},
15+
service::common::objects::generic::problem_report::ProblemReport,
1416
settings::cassandra_db,
1517
};
1618

@@ -86,13 +88,7 @@ impl Params {
8688
.unwrap_or_default();
8789
let is_cip36 = cip36.is_cip36().map_or(MaybeUnset::Unset, MaybeUnset::Set);
8890
let payment_address = cip36.payment_address().map_or(Vec::new(), Address::to_vec);
89-
let problem_report = serde_json::to_string(cip36.err_report()).unwrap_or_else(|e| {
90-
error!(
91-
"Failed to serialize problem report: {e:?}. Report = {:?}",
92-
cip36.err_report()
93-
);
94-
String::new()
95-
});
91+
let problem_report = ProblemReport::from(cip36.err_report().clone()).to_json_string();
9692

9793
Params {
9894
stake_public_key,

catalyst-gateway/bin/src/service/api/documents/common/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use catalyst_signed_doc::CatalystSignedDocument;
66
use crate::{
77
db::event::{error::NotFoundError, signed_docs::FullSignedDoc},
88
service::common::auth::rbac::token::CatalystRBACTokenV1,
9-
settings::Settings,
9+
settings::{admin::get_admin_key, Settings},
1010
};
1111

1212
/// A wrapper struct to unify both implementations of `CatalystSignedDocumentProvider` and
@@ -68,9 +68,13 @@ impl catalyst_signed_doc::providers::CatalystIdProvider for ValidationProvider {
6868
&self,
6969
kid: &catalyst_signed_doc::CatalystId,
7070
) -> anyhow::Result<Option<ed25519_dalek::VerifyingKey>> {
71-
self.verifying_key_provider
72-
.try_get_registered_key(kid)
73-
.await
71+
if kid.is_admin() {
72+
Ok(get_admin_key(kid))
73+
} else {
74+
self.verifying_key_provider
75+
.try_get_registered_key(kid)
76+
.await
77+
}
7478
}
7579
}
7680

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//! Helpers related to the Admin Role.
2+
3+
use ed25519_dalek::VerifyingKey;
4+
5+
use crate::settings::ENV_VARS;
6+
7+
/// Returns the Admin's role0 public key if the given Catalyst ID matches with the
8+
/// assigned Admin Catalyst ID.
9+
pub(crate) fn get_admin_key(cat_id: &catalyst_signed_doc::CatalystId) -> Option<VerifyingKey> {
10+
let admin_key = ENV_VARS.signed_doc.admin_key();
11+
if let Some(admin_key) = admin_key {
12+
if cat_id == admin_key {
13+
return Some(admin_key.role0_pk());
14+
}
15+
}
16+
17+
None
18+
}

catalyst-gateway/bin/src/settings/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::{
2121
utils::blake2b_hash::generate_uuid_string_from_data,
2222
};
2323

24+
pub(crate) mod admin;
2425
pub(crate) mod cardano_assets_cache;
2526
pub(crate) mod cassandra_db;
2627
pub(crate) mod chain_follower;
Lines changed: 22 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//! Command line and environment variable settings for the Catalyst Signed Docs
22
3-
use std::{collections::HashMap, str::FromStr, time::Duration};
4-
5-
use hex::FromHex;
6-
use itertools::Itertools;
3+
use std::{str::FromStr, time::Duration};
74

85
use super::str_env_var::StringEnvVar;
96

@@ -22,10 +19,9 @@ pub(crate) struct EnvVars {
2219
/// The Catalyst Signed Document threshold, document cannot be too far behind.
2320
past_threshold: Duration,
2421

25-
/// The Catalyst Signed Document Admin keys map from the `SIGNED_DOC_ADMIN_KEYS` env
26-
/// var. Each Admin key entry is a pair of `CatalystId` string and hex encoded
27-
/// `VerifyingKey` separated by ';' character.
28-
admin_keys: HashMap<catalyst_signed_doc::CatalystId, ed25519_dalek::VerifyingKey>,
22+
/// The Catalyst Signed Document Admin Catalyst ID from the `SIGNED_DOC_ADMIN_KEYS`
23+
/// env.
24+
admin_key: Option<catalyst_signed_doc::CatalystId>,
2925
}
3026

3127
impl EnvVars {
@@ -37,16 +33,20 @@ impl EnvVars {
3733
let past_threshold =
3834
StringEnvVar::new_as_duration("SIGNED_DOC_PAST_THRESHOLD", DEFAULT_PAST_THRESHOLD);
3935

40-
let admin_keys = string_to_admin_keys(
36+
let admin_key = string_to_catalyst_id(
4137
&StringEnvVar::new_optional("SIGNED_DOC_ADMIN_KEYS", false)
4238
.map(|v| v.as_string())
4339
.unwrap_or_default(),
4440
);
4541

42+
if admin_key.is_none() {
43+
tracing::error!("Missing or invalid Catalyst ID for Admin. This is required.");
44+
}
45+
4646
Self {
4747
future_threshold,
4848
past_threshold,
49-
admin_keys,
49+
admin_key,
5050
}
5151
}
5252

@@ -62,58 +62,21 @@ impl EnvVars {
6262
self.past_threshold
6363
}
6464

65-
/// The Catalyst Signed Document Admin keys map.
65+
/// The Catalyst Signed Document Admin key.
6666
#[allow(dead_code)]
67-
pub(crate) fn admin_keys(
68-
&self
69-
) -> &HashMap<catalyst_signed_doc::CatalystId, ed25519_dalek::VerifyingKey> {
70-
&self.admin_keys
67+
pub(crate) fn admin_key(&self) -> Option<&catalyst_signed_doc::CatalystId> {
68+
self.admin_key.as_ref()
7169
}
7270
}
7371

74-
/// Transform a string list of admin keys into a map.
75-
/// Each Admin key entry is a pair of `CatalystId` string and hex encoded
76-
/// `VerifyingKey` separated by ';' character.
77-
fn string_to_admin_keys(
78-
admin_keys: &str
79-
) -> HashMap<catalyst_signed_doc::CatalystId, ed25519_dalek::VerifyingKey> {
80-
admin_keys
81-
.split(',')
82-
// filters out at the beginning all empty entries, because they all would be invalid and
83-
// filtered out anyway
84-
.filter(|s| !s.is_empty())
85-
.filter_map(|s| {
86-
// split `CatalystId` and `VerifyingKey` by `;` character.
87-
let Some((id, key)) = s.split(';').collect_tuple() else {
88-
tracing::error!(entry = s, "Invalid admin key entry");
89-
return None;
90-
};
91-
92-
let id = catalyst_signed_doc::CatalystId::from_str(id)
93-
.inspect_err(|err| {
94-
tracing::error!(
95-
err = ?err,
96-
"Cannot parse Admin CatalystId entry, skipping the value..."
97-
);
98-
})
99-
.ok()?;
100-
101-
// Strip the prefix and convert to 32 bytes array
102-
let key = key
103-
.strip_prefix("0x")
104-
.ok_or(anyhow::anyhow!(
105-
"Admin key hex value does not start with '0x'"
106-
))
107-
.and_then(|s| Ok(Vec::from_hex(s)?))
108-
.and_then(|bytes| Ok(bytes.as_slice().try_into()?))
109-
.inspect_err(|err| {
110-
tracing::error!(
111-
err = ?err,
112-
"Cannot parse Admin VerifyingKey entry, skipping the value..."
113-
);
114-
})
115-
.ok()?;
116-
Some((id, key))
72+
/// Convert an Envvar into the Catalyst ID type, `None` if missing or invalid value.
73+
fn string_to_catalyst_id(s: &str) -> Option<catalyst_signed_doc::CatalystId> {
74+
catalyst_signed_doc::CatalystId::from_str(s)
75+
.inspect_err(|err| {
76+
tracing::error!(
77+
err = ?err,
78+
"Cannot parse Admin CatalystId entry"
79+
);
11780
})
118-
.collect()
81+
.ok()
11982
}

0 commit comments

Comments
 (0)