Skip to content

Implement chain adapter to read on chain protocol configurations - #3482

Open
turmelclem wants to merge 7 commits into
mainfrom
ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2
Open

Implement chain adapter to read on chain protocol configurations#3482
turmelclem wants to merge 7 commits into
mainfrom
ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2

Conversation

@turmelclem

@turmelclem turmelclem commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Content

This PR includes modification to implement chain adapater to read on chain protocol configurations :

  • Implement on-chain reader for protocol configurations
  • move mechanism checking configuration consistency in model
  • add markers implementation of MithrilNetworkConfigurationProvider
  • Implement a protocol configuration builder (used by Signer and Aggregator)
  • Wire MarkersMithrilNetworkConfigurationProvider in the Signer
  • Wire MarkersMithrilNetworkConfigurationProvider instead of local impl for leader aggregator
    • tests have been adapted to read protocol configurations from makers instead of aggregator configuration
  • Refactor usage of parameters for protocol-configuration commands

Pre-submit checklist

  • Branch
    • Tests are provided (if possible)
    • Crates versions are updated (if relevant)
    • CHANGELOG file is updated (if relevant)
    • Commit sequence broadly makes sense
    • Key commits have useful messages
  • PR
    • All check jobs of the CI have succeeded
    • Self-reviewed the diff
    • Useful pull request description
    • Reviewer requested
  • Documentation
    • Update README file (if relevant)
    • Update documentation website (if relevant)
    • Add dev blog post (if relevant)
    • Add ADR blog post or Dev ADR entry (if relevant)
    • No new TODOs introduced

Relates to #3393

@turmelclem
turmelclem force-pushed the ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2 branch from 4f87a71 to cb72f72 Compare August 17, 2026 09:56
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

Test Results

     5 files     209 suites   58m 46s ⏱️
 3 381 tests  3 381 ✅ 0 💤 0 ❌
11 256 runs  11 256 ✅ 0 💤 0 ❌

Results for commit 551848d.

♻️ This comment has been updated with latest results.

@turmelclem
turmelclem force-pushed the ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2 branch from cb72f72 to 9a7ac9a Compare August 17, 2026 16:10
Comment thread internal/mithril-protocol-config/src/builder.rs Fixed
Comment thread internal/mithril-protocol-config/src/builder.rs Fixed
Comment thread internal/mithril-protocol-config/src/builder.rs Fixed
Comment thread internal/mithril-protocol-config/src/builder.rs Fixed
Comment thread internal/mithril-protocol-config/src/builder.rs Fixed
Comment thread internal/mithril-protocol-config/src/builder.rs Fixed
@turmelclem turmelclem self-assigned this Aug 18, 2026
@turmelclem
turmelclem force-pushed the ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2 branch from 9a7ac9a to 4a79c83 Compare August 18, 2026 16:36
Comment thread mithril-aggregator/tests/genesis_to_signing.rs Fixed
@turmelclem
turmelclem force-pushed the ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2 branch from 4a79c83 to 192a144 Compare August 19, 2026 09:59
Comment thread mithril-signer/src/configuration.rs Fixed
@turmelclem
turmelclem force-pushed the ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2 branch from 192a144 to 38c6548 Compare August 19, 2026 12:25
@turmelclem
turmelclem marked this pull request as ready for review August 19, 2026 13:06
@turmelclem
turmelclem force-pushed the ctl/3393-implement-chain-adapater-to-read-on-chain-protocol-configurations-2 branch from 38c6548 to 551848d Compare August 19, 2026 13:09
}

/// Verify the signature of a signed protocol configuration markers payload
pub fn verify_signature(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this method should be tested, at least with a roundtrip test (create a full message with at least two markers and a legitimate signature, then run this method).

Comment on lines +4 to +17
use mithril_common::entities::Epoch;
use std::collections::BTreeMap;
use std::sync::Arc;

use crate::cardano_chain::message::{
ProtocolConfigurationForEpochMessage, ProtocolConfigurationMarker,
};
use crate::cardano_chain::payload::SignedProtocolConfigurationMarkersPayload;
use crate::interface::ProtocolConfigurationMarkersReader;
use crate::model::{ConfigurationResolverFromMarkers, ProtocolConfigurationForEpoch};
use mithril_cardano_node_chain::chain_observer::ChainObserver;
use mithril_cardano_node_chain::entities::ChainAddress;
use mithril_common::StdResult;
use mithril_cardano_node_chain::entities::{ChainAddress, TxDatumFieldTypeName};
use mithril_common::crypto_helper::ProtocolConfigurationMarkersVerifierVerificationKey;

use crate::interface::ProtocolConfigurationMarkersReader;
use crate::model::ConfigurationResolverFromMarkers;
use mithril_common::{StdError, StdResult};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some import issues here (epoch in the wrong block, use crate mixed up)

Comment on lines +46 to +67
let markers_list = tx_datums
.into_iter()
.filter_map(|datum| datum.get_fields_by_type(&TxDatumFieldTypeName::Bytes).ok())
.map(|fields| {
fields
.iter()
.filter_map(|field_value| field_value.as_str().map(|s| s.to_string()))
.collect::<Vec<String>>()
.join("")
})
.filter_map(|field_value_str| {
SignedProtocolConfigurationMarkersPayload::from_json_hex(&field_value_str).ok()
})
.filter_map(|markers_payload| {
markers_payload
.verify_signature(self.verification_key)
.ok()
.map(|_| markers_payload.markers)
})
.collect::<Vec<Vec<ProtocolConfigurationMarker>>>();

let last_markers = markers_list.first().cloned().unwrap_or_default();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be more efficient to only read the first item? Is there any reason to collecting them all?

Suggested change
let markers_list = tx_datums
.into_iter()
.filter_map(|datum| datum.get_fields_by_type(&TxDatumFieldTypeName::Bytes).ok())
.map(|fields| {
fields
.iter()
.filter_map(|field_value| field_value.as_str().map(|s| s.to_string()))
.collect::<Vec<String>>()
.join("")
})
.filter_map(|field_value_str| {
SignedProtocolConfigurationMarkersPayload::from_json_hex(&field_value_str).ok()
})
.filter_map(|markers_payload| {
markers_payload
.verify_signature(self.verification_key)
.ok()
.map(|_| markers_payload.markers)
})
.collect::<Vec<Vec<ProtocolConfigurationMarker>>>();
let last_markers = markers_list.first().cloned().unwrap_or_default();
let last_markers: Vec<ProtocolConfigurationMarker> = tx_datums
.into_iter()
.filter_map(|datum| datum.get_fields_by_type(&TxDatumFieldTypeName::Bytes).ok())
.map(|fields| {
fields
.iter()
.filter_map(|field_value| field_value.as_str().map(|s| s.to_string()))
.collect::<Vec<String>>()
.join("")
})
.filter_map(|field_value_str| {
SignedProtocolConfigurationMarkersPayload::from_json_hex(&field_value_str).ok()
})
.filter_map(|markers_payload| {
markers_payload
.verify_signature(self.verification_key)
.ok()
.map(|_| markers_payload.markers)
})
.next()
.unwrap_or_default();

Comment on lines +74 to +80
.map_err(|e| {
StdError::msg(format!(
"ProtocolConfigurationForEpochMessage for Epoch({}) could not be decoded from cbor hex: {}",
marker.epoch,
e
))
})?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a some incompatibility with anyhow context for this convoluted map?

Suggested change
.map_err(|e| {
StdError::msg(format!(
"ProtocolConfigurationForEpochMessage for Epoch({}) could not be decoded from cbor hex: {}",
marker.epoch,
e
))
})?
.with_context(|| {
format!(
"ProtocolConfigurationForEpochMessage for Epoch({}) could not be decoded from cbor hex",
marker.epoch,
)
})?

}

#[tokio::test]
async fn test_cardano_chain_reader() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name is too broad, here is a tentative name:

Suggested change
async fn test_cardano_chain_reader() {
async fn markers_signed_by_third_parties_are_rejected() {

Comment on lines +3 to +6
use mithril_cli_helper::{register_config_value, serde_deserialization};
use mithril_dmq::DmqNetwork;
use mithril_doc::{Documenter, DocumenterDefault, StructDoc};
use mithril_protocol_config::builder::AdapterConfig;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use this opportunity to move those mithril_* uses below

Comment on lines +18 to +20
}
pub mod protocol_configuration {
use super::*;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oups, missing line breaks

Suggested change
}
pub mod protocol_configuration {
use super::*;
}
pub mod protocol_configuration {
use super::*;

self.root_logger(),
));

let protocol_configuration_adapter = build_protocol_configuration_adapter(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should adapt the signer integration tests as well?

Comment on lines 40 to 47
cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig {
security_parameter: BlockNumberOffset(0),
step: BlockNumber(30),
}),
cardano_blocks_transactions_signing_config: Some(CardanoBlocksTransactionsSigningConfig {
security_parameter: BlockNumberOffset(0),
step: BlockNumber(24),
}),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you should remove those configurations?


use anyhow::Context;
use config::{ConfigError, Map, Source, Value, ValueKind};
use mithril_protocol_config::builder::AdapterConfig;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this mithril import should be below

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements on-chain protocol configuration retrieval for signers and leader aggregators.

Changes:

  • Adds signed Cardano marker decoding, verification, and configuration resolution.
  • Wires marker-backed providers through signer and aggregator dependency injection.
  • Updates CLI configuration and integration tests for marker-based settings.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
mithril-signer/src/dependency_injection/builder.rs Wires marker-based configuration into signer services.
mithril-signer/src/configuration.rs Adds protocol reader adapter configuration.
mithril-common/src/crypto_helper/mod.rs Exports protocol-configuration crypto aliases.
mithril-common/src/crypto_helper/ed25519_alias.rs Defines marker verifier aliases.
mithril-aggregator/tests/test_extensions/runtime_tester.rs Injects marker-reader test doubles.
mithril-aggregator/tests/signed_entity_support.rs Migrates signed-entity test configuration.
mithril-aggregator/tests/prove_transactions.rs Supplies transaction marker configuration.
mithril-aggregator/tests/prove_blocks_transactions.rs Supplies block-transaction marker configuration.
mithril-aggregator/tests/open_message_newer_exists.rs Migrates open-message test configuration.
mithril-aggregator/tests/open_message_expiration.rs Migrates expiration test configuration.
mithril-aggregator/tests/leader_signed_entity_config_propagation.rs Tests marker-backed configuration propagation.
mithril-aggregator/tests/genesis_to_signing.rs Migrates genesis transition setup.
mithril-aggregator/tests/era_checker.rs Supplies marker configuration to era tests.
mithril-aggregator/tests/create_certificate.rs Migrates certificate creation configuration.
mithril-aggregator/tests/create_certificate_with_buffered_signatures.rs Migrates buffered-signature setup.
mithril-aggregator/tests/create_certificate_follower.rs Updates leader/follower marker setup.
mithril-aggregator/tests/certificate_chain.rs Migrates certificate-chain configuration.
mithril-aggregator/tests/cardano_stake_distribution_verify_stakes.rs Migrates stake verification configuration.
mithril-aggregator/src/dependency_injection/builder/support/compatibility.rs Removes the former reader construction path.
mithril-aggregator/src/dependency_injection/builder/enablers/epoch.rs Builds marker-backed network configuration providers.
mithril-aggregator/src/configuration.rs Adds adapter configuration and updates samples.
mithril-aggregator/src/commands/protocol_configuration_command.rs Refactors protocol-configuration command parameters.
internal/mithril-protocol-config/src/test/mod.rs Exports test helpers.
internal/mithril-protocol-config/src/test/helper.rs Adds protocol configuration fixtures.
internal/mithril-protocol-config/src/test/double/fake_markers_reader.rs Adds default fake marker data.
internal/mithril-protocol-config/src/model.rs Centralizes consistency handling and conversion.
internal/mithril-protocol-config/src/markers.rs Implements the marker-backed provider.
internal/mithril-protocol-config/src/lib.rs Exposes builder and marker modules.
internal/mithril-protocol-config/src/http.rs Reuses model-level consistency handling.
internal/mithril-protocol-config/src/cardano_chain/protocol_configuration_reader.rs Reads and verifies on-chain marker datums.
internal/mithril-protocol-config/src/cardano_chain/payload.rs Verifies signed marker payloads.
internal/mithril-protocol-config/src/cardano_chain/message.rs Converts decoded messages into domain models.
internal/mithril-protocol-config/src/builder.rs Builds configured marker readers.
Suppressed comments (3)

internal/mithril-protocol-config/src/markers.rs:154

  • Test names must describe behavior without a test_ prefix. Rename this test accordingly.
    async fn test_get_network_configuration_removes_unavailable_discriminants_when_config_missing()

internal/mithril-protocol-config/src/cardano_chain/protocol_configuration_reader.rs:179

  • Test names must describe behavior without a test_ prefix. Rename this test accordingly.
    async fn test_cardano_chain_reader_should_throw_error_on_invalid_cbor() {

internal/mithril-protocol-config/src/test/helper.rs:56

  • This helper also builds an invalid domain model because phi_f = 1.2 is outside the accepted (0, 1] range. Keep the message and model helpers valid and consistent.
            phi_f: 1.2,

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

})
.collect::<Vec<Vec<ProtocolConfigurationMarker>>>();

let last_markers = markers_list.first().cloned().unwrap_or_default();
SignedEntityTypeDiscriminants::CardanoTransactions,
]),
cardano_blocks_transactions: None,
cardano_transactions: None,
Comment on lines +39 to +40
cardano_blocks_transactions: None,
cardano_transactions: None,
protocol_parameters: ProtocolParametersMessage {
k: conf as u64,
m: conf as u64,
phi_f: 1.2,
}

#[tokio::test]
async fn test_get_network_configuration_retrieve_configurations_for_aggregation_next_aggregation_and_registration()
}
}

/// A epoch configuration used for the CBOR HEX representation in the [ProtocolConfigurationMarker]
use mithril_protocol_config::model::{
ConfigurationResolverFromMarkers, ProtocolConfigurationForEpoch,
};
use std::collections::{BTreeMap, BTreeSet};

/// Protocol configuration reader adapter configuration
#[example = "\
- cardano-chain:<br/>`{ \"type\": \"cardano-chain\", \"address\": \"test_address\", \"verification_key\": \"136372c3138312c3138382c3130352c3233312c3135\" }`<br/>\

/// Protocol configuration reader adapter configuration
#[example = "\
- cardano-chain:<br/>`{ \"type\": \"cardano-chain\", \"address\": \"test_address\", \"verification_key\": \"136372c3138312c3138382c3130352c3233312c3135\" }`<br/>\
/// Protocol configuration reader adapter configuration
#[example = "\
`{ \"address\": \"address\", \"verification_key\": \"key\" }`\
- cardano-chain:<br/>`{ \"type\": \"cardano-chain\", \"address\": \"test_address\", \"verification_key\": \"136372c3138312c3138382c3130352c3233312c3135\" }`<br/>\
@turmelclem turmelclem changed the title Implement chain adapater to read on chain protocol configurations Implement chain adapter to read on chain protocol configurations Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants