Skip to content

Commit 8d65b08

Browse files
committed
Add chain observer models
1 parent a4aa755 commit 8d65b08

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

mithril-common/src/chain_observer/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ mod cli_observer;
44
#[cfg(any(test, feature = "test_only"))]
55
mod fake_observer;
66
mod interface;
7+
mod model;
78

89
pub use cli_observer::{CardanoCliChainObserver, CardanoCliRunner};
910
#[cfg(any(test, feature = "test_only"))]
1011
pub use fake_observer::FakeObserver;
1112
pub use interface::{ChainObserver, ChainObserverError};
13+
pub use model::{ChainAddress, TxDatum};
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
use serde_json::Value;
2+
use std::{collections::HashMap, error::Error as StdError};
3+
use thiserror::Error;
4+
5+
/// [ChainAddress] represents an on chain address
6+
pub type ChainAddress = String;
7+
8+
/// [TxDatum] related errors.
9+
#[derive(Debug, Error)]
10+
pub enum TxDatumError {
11+
/// Generic [TxDatum] error.
12+
#[error("general error {0}")]
13+
_General(Box<dyn StdError + Sync + Send>),
14+
15+
/// Error raised when the content could not be parsed.
16+
#[error("could not parse content: {0}")]
17+
InvalidContent(Box<dyn StdError + Sync + Send>),
18+
}
19+
20+
/// [TxDatum] represents transaction Datum
21+
#[derive(Debug, Clone, PartialEq, Eq)]
22+
pub struct TxDatum(pub String);
23+
24+
impl TxDatum {
25+
/// Retrieves the ith field of the datum with given type
26+
pub fn get_field_raw_value(
27+
&self,
28+
type_name: &str,
29+
index: usize,
30+
) -> Result<Value, Box<dyn StdError>> {
31+
let tx_datum_raw = &self.0;
32+
let v: HashMap<String, Value> = serde_json::from_str(tx_datum_raw).map_err(|e| {
33+
TxDatumError::InvalidContent(
34+
format!("Error: {e:?}, tx datum was = '{tx_datum_raw}'").into(),
35+
)
36+
})?;
37+
let fields = v.get("fields").ok_or_else(|| {
38+
TxDatumError::InvalidContent(
39+
format!("Error: missing 'fields' entry, tx datum was = '{tx_datum_raw}'").into(),
40+
)
41+
})?.as_array().ok_or_else(|| {
42+
TxDatumError::InvalidContent(
43+
format!("Error: 'fields' entry is not correctly structured, tx datum was = '{tx_datum_raw}'").into(),
44+
)
45+
})?;
46+
let field_value = fields
47+
.iter()
48+
.filter(|&field| field.get(type_name).is_some())
49+
.nth(index)
50+
.ok_or_else(|| {
51+
TxDatumError::InvalidContent(
52+
format!(
53+
"Error: missing field at index {index}, tx datum was = '{tx_datum_raw}'"
54+
)
55+
.into(),
56+
)
57+
})?
58+
.get(type_name)
59+
.unwrap();
60+
61+
Ok(field_value.to_owned())
62+
}
63+
}
64+
65+
#[cfg(test)]
66+
mod test {
67+
use super::*;
68+
69+
fn dummy_tx_datum() -> TxDatum {
70+
TxDatum("{\"constructor\":0,\"fields\":[{\"bytes\":\"bytes0\"}, {\"int\":0}, {\"int\":1}, {\"bytes\":\"bytes1\"}, {\"bytes\":\"bytes2\"}, {\"int\":2}]}".to_string())
71+
}
72+
73+
#[test]
74+
fn test_can_retrieve_field_raw_value_bytes() {
75+
let tx_datum = dummy_tx_datum();
76+
assert_eq!(
77+
"bytes0",
78+
tx_datum
79+
.get_field_raw_value("bytes", 0)
80+
.unwrap()
81+
.as_str()
82+
.unwrap()
83+
);
84+
assert_eq!(
85+
"bytes1",
86+
tx_datum
87+
.get_field_raw_value("bytes", 1)
88+
.unwrap()
89+
.as_str()
90+
.unwrap()
91+
);
92+
assert_eq!(
93+
"bytes2",
94+
tx_datum
95+
.get_field_raw_value("bytes", 2)
96+
.unwrap()
97+
.as_str()
98+
.unwrap()
99+
);
100+
tx_datum
101+
.get_field_raw_value("bytes", 100)
102+
.expect_err("should have returned an error");
103+
}
104+
105+
#[test]
106+
fn test_can_retrieve_field_raw_value_int() {
107+
let tx_datum = dummy_tx_datum();
108+
assert_eq!(
109+
0,
110+
tx_datum
111+
.get_field_raw_value("int", 0)
112+
.unwrap()
113+
.as_u64()
114+
.unwrap()
115+
);
116+
assert_eq!(
117+
1,
118+
tx_datum
119+
.get_field_raw_value("int", 1)
120+
.unwrap()
121+
.as_u64()
122+
.unwrap()
123+
);
124+
assert_eq!(
125+
2,
126+
tx_datum
127+
.get_field_raw_value("int", 2)
128+
.unwrap()
129+
.as_u64()
130+
.unwrap()
131+
);
132+
tx_datum
133+
.get_field_raw_value("int", 100)
134+
.expect_err("should have returned an error");
135+
}
136+
}

0 commit comments

Comments
 (0)