Skip to content
Merged
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
1,553 changes: 694 additions & 859 deletions hermes/Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion hermes/Earthfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
VERSION 0.8

IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust:v3.5.14 AS rust-ci
IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust:v3.5.17 AS rust-ci
#IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust:feat/disallow-debug-format AS rust-ci

# Use when debugging cat-ci locally.
Expand Down
16 changes: 13 additions & 3 deletions hermes/apps/athena/modules/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ VERSION 0.8

# Catalyst CI Rust Environment - provides pre-configured Rust toolchain with WASM support
# This includes: rustc, cargo, wasm32-wasip2 target, optimization tools, and build utilities
IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust:v3.5.14 AS rust-ci

IMPORT github.com/input-output-hk/catalyst-ci/earthly/rust:v3.5.17 AS rust-ci

# Alternative for local catalyst-ci debugging (uncomment when needed):
# IMPORT ../../../catalyst-ci/earthly/rust AS rust-ci
Expand Down Expand Up @@ -138,4 +137,15 @@ save-local-hermes:

# Save the binary to local filesystem for development use
# This makes it available at ./hermes in the calling directory
SAVE ARTIFACT hermes AS LOCAL ./hermes
SAVE ARTIFACT hermes AS LOCAL ./hermes

# Build wasm32-wasip2 for each modules
modules-build-wasm32-wasip2:
BUILD ./rbac-registration+build-rbac-registration
BUILD ./rbac-registration-indexer+build-rbac-registration-indexer
BUILD ./http-proxy+build-http-proxy

# Run build modules wasm32-wasip2 for the specify architect
# Comment this out if it take long time for CI to build.
build-all-host-modules-build-wasm32-wasip2:
BUILD --platform=linux/amd64 --platform=linux/arm64 +modules-build-wasm32-wasip2
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ strum = "0.27.2"
strum_macros = "0.27.2"

cardano-blockchain-types = { version = "0.0.6", git = "https://github.com/input-output-hk/catalyst-libs", tag = "cardano-blockchain-types/v0.0.6" }
rbac-registration = { version = "0.0.9", git = "https://github.com/input-output-hk/catalyst-libs", tag = "rbac-registration/v0.0.9" }
catalyst-types = { version = "0.0.6", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.6" }
rbac-registration = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "rbac-registration/v0.0.10" }
catalyst-types = { version = "0.0.7", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.7" }
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rbac_registration::{
cardano::cip509::{Cip0134UriSet, Cip509},
};
use serde_json::json;
use utils::{cardano::block::build_block, log::log_error};
use utils::{cardano::block::build_block, log::log_error, problem_report::problem_report_to_json};

use crate::{
database::{
Expand All @@ -55,7 +55,7 @@ use crate::{
utils::log::log_info,
};

use hermes::{cardano, sqlite::api::Statement};
use hermes::cardano;

struct RbacRegistrationComponent;

Expand Down Expand Up @@ -121,7 +121,7 @@ impl exports::hermes::cardano::event_on_block::Guest for RbacRegistrationCompone
};

// ------- Extract and insert RBAC registrations into DB -------
for reg in registrations.clone() {
for reg in registrations {
// Data needed for db
let txn_id: Vec<u8> = reg.txn_hash().into();
let catalyst_id: Option<String> =
Expand All @@ -130,11 +130,7 @@ impl exports::hermes::cardano::event_on_block::Guest for RbacRegistrationCompone
let txn_idx: u16 = reg.origin().txn_index().into();
let purpose: Option<String> = reg.purpose().map(|p| p.to_string());
let prv_txn_id: Option<Vec<u8>> = reg.previous_transaction().map(|p| p.into());
let problem_report: Option<String> = reg
.report()
.is_problematic()
.then(|| serde_json::to_string(&reg.report()).ok())
.flatten();
let problem_report: Option<String> = problem_report_to_json(reg.report());
// Can contain multiple stake addresses
let stake_addresses = reg
.certificate_uris()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//! Utilities

pub(crate) mod cardano;
pub(crate) mod log;
pub(crate) mod problem_report;
pub(crate) mod value;
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! Problem report utils.

use catalyst_types::problem_report::ProblemReport;

/// Converts problem report to JSON.
pub(crate) fn problem_report_to_json(report: &ProblemReport) -> Option<String> {
if !report.is_problematic() {
return None;
}
let mut obj = serde_json::json!({
"context": report.context(),
});

let entries: Vec<_> = report
.entries()
.map(|elem| {
elem.map(|entry| {
let mut obj = serde_json::json!({
"msg": entry.context(),
});

if let Some(map) = obj.as_object_mut() {
match entry.kind() {
catalyst_types::problem_report::Kind::MissingField { field } => {
map.insert("kind".to_string(), serde_json::json!("MissingField"));
map.insert("field".to_string(), serde_json::json!(field));
},
catalyst_types::problem_report::Kind::UnknownField { field, value } => {
map.insert("kind".to_string(), serde_json::json!("UnknownField"));
map.insert("field".to_string(), serde_json::json!(field));
map.insert("value".to_string(), serde_json::json!(value));
},
catalyst_types::problem_report::Kind::InvalidValue {
field,
value,
constraint,
} => {
map.insert("kind".to_string(), serde_json::json!("InvalidValue"));
map.insert("field".to_string(), serde_json::json!(field));
map.insert("value".to_string(), serde_json::json!(value));
map.insert("constraint".to_string(), serde_json::json!(constraint));
},
catalyst_types::problem_report::Kind::InvalidEncoding {
field,
encoded,
expected,
} => {
map.insert("kind".to_string(), serde_json::json!("InvalidEncoding"));
map.insert("field".to_string(), serde_json::json!(field));
map.insert("encoded".to_string(), serde_json::json!(encoded));
map.insert("expected".to_string(), serde_json::json!(expected));
},
catalyst_types::problem_report::Kind::FunctionalValidation {
explanation,
} => {
map.insert(
"kind".to_string(),
serde_json::json!("FunctionalValidation"),
);
map.insert("explanation".to_string(), serde_json::json!(explanation));
},
catalyst_types::problem_report::Kind::DuplicateField {
field,
description,
} => {
map.insert("kind".to_string(), serde_json::json!("DuplicateField"));
map.insert("field".to_string(), serde_json::json!(field));
map.insert("description".to_string(), serde_json::json!(description));
},
catalyst_types::problem_report::Kind::ConversionError {
field,
value,
expected_type,
} => {
map.insert("kind".to_string(), serde_json::json!("ConversionError"));
map.insert("field".to_string(), serde_json::json!(field));
map.insert("value".to_string(), serde_json::json!(value));
map.insert(
"expected_type".to_string(),
serde_json::json!(expected_type),
);
},
catalyst_types::problem_report::Kind::Other { description } => {
map.insert("kind".to_string(), serde_json::json!("Other"));
map.insert("description".to_string(), serde_json::json!(description));
},
}
}

obj
})
})
.collect();

let report_json = serde_json::json!({
"context": report.context(),
"entries": entries
});

serde_json::to_string(&report_json).ok()
}
4 changes: 2 additions & 2 deletions hermes/apps/athena/modules/rbac-registration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ strum = "0.27.2"
strum_macros = "0.27.2"

cardano-blockchain-types = { version = "0.0.6", git = "https://github.com/input-output-hk/catalyst-libs", tag = "cardano-blockchain-types/v0.0.6" }
rbac-registration = { version = "0.0.9", git = "https://github.com/input-output-hk/catalyst-libs", tag = "rbac-registration/v0.0.9" }
catalyst-types = { version = "0.0.6", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.6" }
rbac-registration = { version = "0.0.10", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "rbac-registration/v0.0.10" }
catalyst-types = { version = "0.0.7", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.7" }
6 changes: 3 additions & 3 deletions hermes/bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ path = "tests/integration/tests/mod.rs"
[dependencies]
# Catalyst Internal Crates
hermes-ipfs = { version = "0.0.5", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "hermes-ipfs/v0.0.5" }
cardano-blockchain-types = { version = "0.0.5", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-blockchain-types-v0.0.5" }
cardano-chain-follower = { version = "0.0.11", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-chain-follower-v0.0.11" }
catalyst-types = { version = "0.0.6", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types-v0.0.6" }
cardano-blockchain-types = { version = "0.0.6", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-blockchain-types/v0.0.6" }
cardano-chain-follower = { version = "0.0.14", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cardano-chain-follower/v0.0.14" }
catalyst-types = { version = "0.0.7", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.7" }

# HDF5 is consumed using a git tag, because the latest release is very old, but the code is much more advanced.
hdf5 = { package = "hdf5-metno", version = "0.10.1", features = [ "static", "blosc", "blosc-zstd" ] }
Expand Down
2 changes: 1 addition & 1 deletion hermes/bin/src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl FromStr for LogLevel {
"info" => Ok(LogLevel::Info),
"debug" => Ok(LogLevel::Debug),
"trace" => Ok(LogLevel::Trace),
_ => Err(anyhow::anyhow!("Invalid log level string: {}", s)),
_ => Err(anyhow::anyhow!("Invalid log level string: {s}")),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions hermes/bin/src/packaging/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ impl ApplicationPackage {
anyhow::ensure!(
&expected_payload == signature_payload,
"Application package signature payload mismatch.\nExpected: {}\nGot: {}",
expected_payload.to_json().to_string(),
signature_payload.to_json().to_string()
expected_payload.to_json(),
signature_payload.to_json()
);
signature.verify()?;
Ok(())
Expand Down
4 changes: 2 additions & 2 deletions hermes/bin/src/packaging/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ impl ModulePackage {
anyhow::ensure!(
&expected_payload == signature_payload,
"Module package signature payload mismatch.\nExpected: {}\nGot: {}",
expected_payload.to_json().to_string(),
signature_payload.to_json().to_string()
expected_payload.to_json(),
signature_payload.to_json()
);
signature.verify()?;
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion hermes/bin/src/runtime_extensions/hermes/cardano/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ impl HostSubscriptionId for HermesRuntimeContext {
) -> wasmtime::Result<CardanoNetwork> {
let mut app_state = STATE.subscription_id.get_app_state(self.app_name())?;
let network = app_state.get_object(&self_)?;
Ok((*network).into())
Ok((*network).try_into()?)
}

/// Unsubscribing block event of this `subscription-id` instance.
Expand Down
5 changes: 4 additions & 1 deletion hermes/bin/src/runtime_extensions/hermes/cardano/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ pub(crate) fn new_context(ctx: &crate::runtime_context::HermesRuntimeContext) {
pub enum CardanoError {
/// Network not supported.
#[error("Network {0} is not supported")]
NetworkNotSupported(u32),
NetworkNotSupported(u64),
/// Unknown network.
#[error("Unknown network")]
UnknownNetwork,
}

#[cfg(not(debug_assertions))]
Expand Down
14 changes: 10 additions & 4 deletions hermes/bin/src/runtime_extensions/hermes/cardano/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,18 @@ pub(crate) fn sync_slot_to_point(
}
}

impl From<cardano_blockchain_types::Network> for CardanoNetwork {
fn from(network: cardano_blockchain_types::Network) -> Self {
match network {
impl TryFrom<cardano_blockchain_types::Network> for CardanoNetwork {
type Error = CardanoError;

fn try_from(network: cardano_blockchain_types::Network) -> Result<Self, Self::Error> {
Ok(match network {
cardano_blockchain_types::Network::Mainnet => CardanoNetwork::Mainnet,
cardano_blockchain_types::Network::Preprod => CardanoNetwork::Preprod,
cardano_blockchain_types::Network::Preview => CardanoNetwork::Preview,
}
cardano_blockchain_types::Network::Devnet { magic, .. } => {
CardanoNetwork::TestnetMagic(magic)
},
_ => return Err(CardanoError::UnknownNetwork),
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ fn validate_redirect_location(
config: &RedirectConfig,
) -> anyhow::Result<()> {
let url =
Url::parse(location).map_err(|_| anyhow::anyhow!("Invalid redirect URL: {}", location))?;
Url::parse(location).map_err(|_| anyhow::anyhow!("Invalid redirect URL: {location}"))?;

validate_scheme(&url, config)?;
validate_host(&url, config)?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,13 @@ where B: Body {
"Cross-Origin-Opener-Policy",
"same-origin"
.parse()
.map_err(|e| anyhow!("Invalid COOP header value: {}", e))?,
.map_err(|e| anyhow!("Invalid COOP header value: {e}"))?,
);
headers.insert(
"Cross-Origin-Embedder-Policy",
"require-corp"
.parse()
.map_err(|e| anyhow!("Invalid COEP header value: {}", e))?,
.map_err(|e| anyhow!("Invalid COEP header value: {e}"))?,
);

Ok(response)
Expand Down
2 changes: 1 addition & 1 deletion hermes/bin/src/runtime_extensions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod wasi;

/// Advise Runtime Extensions of a new context
pub(crate) fn new_context(ctx: &crate::runtime_context::HermesRuntimeContext) {
span!(Level::INFO, "Context Span", ctx = %ctx).in_scope(|| {
span!(Level::DEBUG, "Context Span", ctx = %ctx).in_scope(|| {
hermes::new_context(ctx);
wasi::new_context(ctx);
});
Expand Down
8 changes: 2 additions & 6 deletions hermes/bin/src/wasm/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,8 @@ impl Engine {
config.wasm_component_model(true);
config.consume_fuel(false);

let engine = WasmEngine::new(&config).map_err(|e| {
anyhow!(
"Incorrect `wasmtime::Engine` configuration: {}",
e.to_string()
)
})?;
let engine = WasmEngine::new(&config)
.map_err(|e| anyhow!("Incorrect `wasmtime::Engine` configuration: {e}",))?;

Ok(Self(engine))
}
Expand Down
8 changes: 4 additions & 4 deletions hermes/bin/src/wasm/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl Module {
) -> anyhow::Result<Self> {
let engine = Engine::new()?;
let wasm_module = WasmModule::new(&engine, module_bytes)
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {}", e.to_string()))?;
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {e}"))?;

let mut linker = WasmLinker::new(&engine);
linker
Expand All @@ -118,10 +118,10 @@ impl Module {
&LinkOptions::default(),
|state: &mut HermesRuntimeContext| state,
)
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {}", e.to_string()))?;
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {e}"))?;
let pre_instance = linker
.instantiate_pre(&wasm_module)
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {}", e.to_string()))?;
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {e}"))?;

let id = ModuleId(Ulid::generate());

Expand Down Expand Up @@ -231,7 +231,7 @@ impl Module {
.pre_instance
.clone()
.instantiate(&mut store)
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {}", e.to_string()))?;
.map_err(|e| anyhow::anyhow!("Bad WASM module:\n {e}"))?;

event.execute(&mut ModuleInstance { store, instance })?;

Expand Down
2 changes: 1 addition & 1 deletion hermes/bin/tests/integration/tests/utils/hermes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn run_app(
let output = child.wait_with_output()?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(anyhow::anyhow!("App failed with error: {}", stderr));
return Err(anyhow::anyhow!("App failed with error: {stderr}"));
}

Ok(String::from_utf8_lossy(&output.stdout).to_string())
Expand Down
5 changes: 4 additions & 1 deletion hermes/deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ targets = [

[advisories]
version = 2
ignore = []
ignore = [
"RUSTSEC-2025-0067",
"RUSTSEC-2025-0068",
]

[bans]
multiple-versions = "warn"
Expand Down
Loading
Loading