Skip to content

Commit 430747f

Browse files
authored
Merge pull request #211 from input-output-hk/greg/182/aggregate_store_layer
add generic adapters for Pending Certificates Store
2 parents c714964 + 325f163 commit 430747f

File tree

17 files changed

+658
-8
lines changed

17 files changed

+658
-8
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-aggregator/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ futures = "0.3"
3434
reqwest = { version = "0.11", features = ["json"] }
3535
config = "0.13.1"
3636
blake2 = "0.9.2"
37+
glob = "0.3"
3738

3839
[dev-dependencies]
3940
mockall = "0.11.0"

mithril-aggregator/config/dev.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"network": "testnet",
33
"url_snapshot_manifest": "https://storage.googleapis.com/cardano-testnet/snapshots.json",
44
"snapshot_store_type": "local",
5-
"snapshot_uploader_type": "local"
6-
}
5+
"snapshot_uploader_type": "local",
6+
"pending_certificate_store_directory": "/tmp/mithril/cert_db"
7+
}

mithril-aggregator/config/testnet.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"network": "testnet",
33
"url_snapshot_manifest": "https://storage.googleapis.com/cardano-testnet/snapshots.json",
44
"snapshot_store_type": "gcp",
5-
"snapshot_uploader_type": "gcp"
5+
"snapshot_uploader_type": "gcp",
6+
"pending_certificate_store_directory": "./mithril/cert_db"
67
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
use super::{AdapterError, StoreAdapter};
2+
use async_trait::async_trait;
3+
4+
pub struct DumbStoreAdapter<K, R> {
5+
last_key: Option<K>,
6+
last_certificate: Option<R>,
7+
}
8+
9+
impl<K, R> DumbStoreAdapter<K, R> {
10+
pub fn new() -> Self {
11+
Self {
12+
last_key: None,
13+
last_certificate: None,
14+
}
15+
}
16+
}
17+
18+
#[async_trait]
19+
impl<K, R> StoreAdapter for DumbStoreAdapter<K, R>
20+
where
21+
R: Clone + Send + Sync,
22+
K: PartialEq + Clone + Send + Sync,
23+
{
24+
type Key = K;
25+
type Record = R;
26+
27+
async fn store_record(
28+
&mut self,
29+
key: &Self::Key,
30+
record: &Self::Record,
31+
) -> Result<(), AdapterError> {
32+
let key = key.clone();
33+
let record = record.clone();
34+
35+
self.last_key = Some(key);
36+
self.last_certificate = Some(record);
37+
38+
Ok(())
39+
}
40+
41+
async fn get_record(&self, key: &Self::Key) -> Result<Option<Self::Record>, AdapterError> {
42+
if self.record_exists(key).await? {
43+
Ok(self.last_certificate.as_ref().cloned())
44+
} else {
45+
Ok(None)
46+
}
47+
}
48+
49+
async fn record_exists(&self, key: &Self::Key) -> Result<bool, AdapterError> {
50+
Ok(self.last_key.is_some() && self.last_key.as_ref().unwrap() == key)
51+
}
52+
53+
async fn get_last_n_records(
54+
&self,
55+
how_many: usize,
56+
) -> Result<Vec<(Self::Key, Self::Record)>, AdapterError> {
57+
if how_many > 0 {
58+
match &self.last_key {
59+
Some(_key) => Ok(vec![(
60+
self.last_key.as_ref().cloned().unwrap(),
61+
self.last_certificate.as_ref().cloned().unwrap(),
62+
)]),
63+
None => Ok(Vec::new()),
64+
}
65+
} else {
66+
Ok(Vec::new())
67+
}
68+
}
69+
}
70+
71+
#[cfg(test)]
72+
mod tests {
73+
74+
use super::*;
75+
76+
#[tokio::test]
77+
async fn test_with_no_record_exists() {
78+
let adapter: DumbStoreAdapter<u64, String> = DumbStoreAdapter::new();
79+
80+
assert!(!adapter.record_exists(&1).await.unwrap());
81+
}
82+
83+
#[tokio::test]
84+
async fn test_with_no_record_get() {
85+
let adapter: DumbStoreAdapter<u64, String> = DumbStoreAdapter::new();
86+
87+
assert!(adapter.get_record(&1).await.unwrap().is_none());
88+
}
89+
90+
#[tokio::test]
91+
async fn test_write_record() {
92+
let mut adapter: DumbStoreAdapter<u64, String> = DumbStoreAdapter::new();
93+
94+
assert!(adapter
95+
.store_record(&1, &"record".to_string())
96+
.await
97+
.is_ok());
98+
assert_eq!(
99+
"record".to_owned(),
100+
adapter.get_record(&1).await.unwrap().unwrap()
101+
);
102+
}
103+
104+
#[tokio::test]
105+
async fn test_list_with_no_record() {
106+
let adapter: DumbStoreAdapter<u64, String> = DumbStoreAdapter::new();
107+
108+
assert_eq!(0, adapter.get_last_n_records(10).await.unwrap().len());
109+
}
110+
111+
#[tokio::test]
112+
async fn test_list_with_records() {
113+
let mut adapter: DumbStoreAdapter<u64, String> = DumbStoreAdapter::new();
114+
let _res = adapter
115+
.store_record(&1, &"record".to_string())
116+
.await
117+
.unwrap();
118+
let list = adapter.get_last_n_records(10).await.unwrap();
119+
120+
assert_eq!(1, list.len());
121+
122+
let (key, record) = &list[0];
123+
124+
assert_eq!(&1, key);
125+
assert_eq!(&("record".to_owned()), record);
126+
}
127+
128+
#[tokio::test]
129+
async fn test_list_with_last_zero() {
130+
let mut adapter: DumbStoreAdapter<u64, String> = DumbStoreAdapter::new();
131+
let _res = adapter
132+
.store_record(&1, &"record".to_string())
133+
.await
134+
.unwrap();
135+
let list = adapter.get_last_n_records(0).await.unwrap();
136+
137+
assert_eq!(0, list.len());
138+
}
139+
}

0 commit comments

Comments
 (0)