Implement chain adapater to read on chain protocol configurations - #3482
Implement chain adapater to read on chain protocol configurations#3482turmelclem wants to merge 7 commits into
Conversation
4f87a71 to
cb72f72
Compare
Test Results 5 files 209 suites 58m 46s ⏱️ Results for commit 551848d. ♻️ This comment has been updated with latest results. |
cb72f72 to
9a7ac9a
Compare
9a7ac9a to
4a79c83
Compare
4a79c83 to
192a144
Compare
192a144 to
38c6548
Compare
…nsistency in model
…kConfigurationProvider
…figurationProvider instead of local impl for leader aggregator
…guration commands
38c6548 to
551848d
Compare
| } | ||
|
|
||
| /// Verify the signature of a signed protocol configuration markers payload | ||
| pub fn verify_signature( |
There was a problem hiding this comment.
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).
| 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}; |
There was a problem hiding this comment.
Some import issues here (epoch in the wrong block, use crate mixed up)
| 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(); |
There was a problem hiding this comment.
Wouldn't it be more efficient to only read the first item? Is there any reason to collecting them all?
| 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(); |
| .map_err(|e| { | ||
| StdError::msg(format!( | ||
| "ProtocolConfigurationForEpochMessage for Epoch({}) could not be decoded from cbor hex: {}", | ||
| marker.epoch, | ||
| e | ||
| )) | ||
| })? |
There was a problem hiding this comment.
Is there a some incompatibility with anyhow context for this convoluted map?
| .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() { |
There was a problem hiding this comment.
The test name is too broad, here is a tentative name:
| async fn test_cardano_chain_reader() { | |
| async fn markers_signed_by_third_parties_are_rejected() { |
| 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; |
There was a problem hiding this comment.
You could use this opportunity to move those mithril_* uses below
| } | ||
| pub mod protocol_configuration { | ||
| use super::*; |
There was a problem hiding this comment.
Oups, missing line breaks
| } | |
| pub mod protocol_configuration { | |
| use super::*; | |
| } | |
| pub mod protocol_configuration { | |
| use super::*; | |
| self.root_logger(), | ||
| )); | ||
|
|
||
| let protocol_configuration_adapter = build_protocol_configuration_adapter( |
There was a problem hiding this comment.
I wonder if we should adapt the signer integration tests as well?
| 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), | ||
| }), |
There was a problem hiding this comment.
Maybe you should remove those configurations?
|
|
||
| use anyhow::Context; | ||
| use config::{ConfigError, Map, Source, Value, ValueKind}; | ||
| use mithril_protocol_config::builder::AdapterConfig; |
There was a problem hiding this comment.
this mithril import should be below
Content
This PR includes modification to implement chain adapater to read on chain protocol configurations :
MithrilNetworkConfigurationProviderMarkersMithrilNetworkConfigurationProviderin the SignerMarkersMithrilNetworkConfigurationProviderinstead of local impl for leader aggregatorprotocol-configurationcommandsPre-submit checklist
Relates to #3393