Skip to content

Commit b657ece

Browse files
committed
Update era reader adapter Cardano chain
The 'bytes' fields must be less than 64 utf-8 bytes in the datum. This problem was fixed by storing the signature in a separate field, and by reducing the size of the serialized era markers.
1 parent b1245b5 commit b657ece

File tree

3 files changed

+84
-25
lines changed

3 files changed

+84
-25
lines changed

mithril-aggregator/src/tools/era.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use mithril_common::{
44
chain_observer::{TxDatumBuilder, TxDatumFieldValue},
55
crypto_helper::{key_encode_hex, EraMarkersSigner},
66
entities::Epoch,
7-
era::{adapters::EraMarkersPayloadCardanoChain, EraMarker, SupportedEra},
7+
era::{
8+
adapters::{EraMarkerItemCardanoChain, EraMarkersPayloadCardanoChain},
9+
SupportedEra,
10+
},
811
};
912

1013
type EraToolsResult<R> = Result<R, Box<dyn Error>>;
@@ -37,8 +40,8 @@ impl EraTools {
3740
let mut era_markers = Vec::new();
3841
for (index, era) in SupportedEra::eras().iter().enumerate() {
3942
let era_marker = match index {
40-
0 => EraMarker::new(&era.to_string(), Some(current_era_epoch)),
41-
1 => EraMarker::new(&era.to_string(), maybe_next_era_epoch),
43+
0 => EraMarkerItemCardanoChain::new(&era.to_string(), Some(current_era_epoch)),
44+
1 => EraMarkerItemCardanoChain::new(&era.to_string(), maybe_next_era_epoch),
4245
_ => Err("too many eras retrieved, can't generate tx datum".to_string())?,
4346
};
4447
era_markers.push(era_marker);
@@ -51,8 +54,12 @@ impl EraTools {
5154

5255
let tx_datum = TxDatumBuilder::new()
5356
.add_field(TxDatumFieldValue::Bytes(
54-
key_encode_hex(era_markers_payload)
55-
.map_err(|e| format!("era markerspayload could not be hex encoded: {e}"))?,
57+
key_encode_hex(era_markers_payload.markers).map_err(|e| {
58+
format!("era markers payload markers could not be hex encoded: {e}")
59+
})?,
60+
))
61+
.add_field(TxDatumFieldValue::Bytes(
62+
era_markers_payload.signature.unwrap_or_default(),
5663
))
5764
.build()?;
5865

mithril-common/src/era/adapters/cardano_chain.rs

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
key_decode_hex, EraMarkersSigner, EraMarkersVerifier, EraMarkersVerifierSignature,
55
EraMarkersVerifierVerificationKey,
66
},
7-
entities::HexEncodedEraMarkersSignature,
7+
entities::{Epoch, HexEncodedEraMarkersSignature},
88
era::{EraMarker, EraReaderAdapter},
99
};
1010
use async_trait::async_trait;
@@ -40,11 +40,45 @@ pub enum EraMarkersPayloadError {
4040
CreateSignature(GeneralError),
4141
}
4242

43+
/// Era marker item
44+
/// Value object that represents a tag of Era change.
45+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46+
pub struct EraMarkerItem {
47+
/// Era name
48+
#[serde(rename = "n")]
49+
pub name: String,
50+
51+
/// Eventual information that advertises the Epoch of transition.
52+
#[serde(rename = "e")]
53+
pub epoch: Option<Epoch>,
54+
}
55+
56+
impl EraMarkerItem {
57+
/// Instantiate a new [EraMarkerItem].
58+
pub fn new(name: &str, epoch: Option<Epoch>) -> Self {
59+
let name = name.to_string();
60+
61+
Self { name, epoch }
62+
}
63+
}
64+
65+
impl From<EraMarker> for EraMarkerItem {
66+
fn from(other: EraMarker) -> EraMarkerItem {
67+
EraMarkerItem::new(&other.name, other.epoch)
68+
}
69+
}
70+
71+
impl From<EraMarkerItem> for EraMarker {
72+
fn from(other: EraMarkerItem) -> EraMarker {
73+
EraMarker::new(&other.name, other.epoch)
74+
}
75+
}
76+
4377
/// Era markers payload
4478
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
4579
pub struct EraMarkersPayload {
4680
/// List of Era markers
47-
pub markers: Vec<EraMarker>,
81+
pub markers: Vec<EraMarkerItem>,
4882

4983
/// Era markers signature
5084
pub signature: Option<HexEncodedEraMarkersSignature>,
@@ -129,17 +163,26 @@ impl EraReaderAdapter for CardanoChainAdapter {
129163
let markers_list = tx_datums
130164
.into_iter()
131165
.filter_map(|datum| {
132-
datum
133-
.get_nth_field_by_type(&TxDatumFieldTypeName::Bytes, 0)
134-
.ok()
135-
})
136-
.filter_map(|field_value| field_value.as_str().map(|s| s.to_string()))
137-
.filter_map(|field_value_str| key_decode_hex(&field_value_str).ok())
138-
.filter_map(|era_markers_payload: EraMarkersPayload| {
139-
era_markers_payload
140-
.verify_signature(self.verification_key)
141-
.ok()
142-
.map(|_| era_markers_payload.markers)
166+
match (
167+
datum.get_nth_field_by_type(&TxDatumFieldTypeName::Bytes, 0),
168+
datum.get_nth_field_by_type(&TxDatumFieldTypeName::Bytes, 1),
169+
) {
170+
(Ok(markers), Ok(signature)) => {
171+
let markers = markers.as_str().map(|s| s.to_string()).unwrap_or_default();
172+
let signature = signature.as_str().map(|s| s.to_string());
173+
match key_decode_hex::<Vec<_>>(&markers) {
174+
Ok(markers) => EraMarkersPayload {
175+
markers: markers.clone(),
176+
signature,
177+
}
178+
.verify_signature(self.verification_key)
179+
.ok()
180+
.map(|_| markers.into_iter().map(|em| em.into()).collect()),
181+
Err(_) => None,
182+
}
183+
}
184+
_ => None,
185+
}
143186
})
144187
.collect::<Vec<Vec<EraMarker>>>();
145188

@@ -160,7 +203,12 @@ mod test {
160203
.into_iter()
161204
.map(|payload| {
162205
TxDatumBuilder::new()
163-
.add_field(TxDatumFieldValue::Bytes(key_encode_hex(payload).unwrap()))
206+
.add_field(TxDatumFieldValue::Bytes(
207+
key_encode_hex(payload.markers).unwrap(),
208+
))
209+
.add_field(TxDatumFieldValue::Bytes(
210+
payload.signature.unwrap_or_default(),
211+
))
164212
.build()
165213
.unwrap()
166214
})
@@ -173,15 +221,15 @@ mod test {
173221
let fake_address = "addr_test_123456".to_string();
174222
let era_marker_payload_1 = EraMarkersPayload {
175223
markers: vec![
176-
EraMarker::new("thales", Some(Epoch(1))),
177-
EraMarker::new("pythagoras", None),
224+
EraMarkerItem::new("thales", Some(Epoch(1))),
225+
EraMarkerItem::new("pythagoras", None),
178226
],
179227
signature: None,
180228
};
181229
let era_marker_payload_2 = EraMarkersPayload {
182230
markers: vec![
183-
EraMarker::new("thales", Some(Epoch(1))),
184-
EraMarker::new("pythagoras", Some(Epoch(2))),
231+
EraMarkerItem::new("thales", Some(Epoch(1))),
232+
EraMarkerItem::new("pythagoras", Some(Epoch(2))),
185233
],
186234
signature: None,
187235
};
@@ -204,7 +252,11 @@ mod test {
204252
.read()
205253
.await
206254
.expect("CardanoChainAdapter read should not fail");
207-
let expected_markers = era_marker_payload_2.markers.to_owned();
255+
let expected_markers = era_marker_payload_2
256+
.markers
257+
.into_iter()
258+
.map(|em| em.into())
259+
.collect::<Vec<EraMarker>>();
208260
assert_eq!(expected_markers, markers);
209261
}
210262
}

mithril-common/src/era/adapters/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub use bootstrap::BootstrapAdapter as EraReaderBootstrapAdapter;
99
pub use builder::{AdapterBuilder as EraReaderAdapterBuilder, AdapterType as EraReaderAdapterType};
1010
pub use cardano_chain::{
1111
CardanoChainAdapter as EraReaderCardanoChainAdapter,
12-
EraMarkersPayload as EraMarkersPayloadCardanoChain,
12+
EraMarkerItem as EraMarkerItemCardanoChain, EraMarkersPayload as EraMarkersPayloadCardanoChain,
1313
};
1414
pub use dummy::DummyAdapter as EraReaderDummyAdapter;
1515
pub use file::FileAdapter as EraReaderFileAdapter;

0 commit comments

Comments
 (0)