Skip to content

Commit b1f1cd4

Browse files
committed
feat(client): implement basic aggregator discoverer
1 parent def6df0 commit b1f1cd4

8 files changed

+43
-10
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-client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ flate2 = { version = "1.1.4", optional = true }
5959
flume = { version = "0.11.1", optional = true }
6060
futures = "0.3.31"
6161
mithril-common = { path = "../mithril-common", version = ">=0.6", default-features = false }
62+
mithril-aggregator-discovery = { path = "../internal/mithril-aggregator-discovery", features = ["rand"] }
6263
reqwest = { workspace = true, default-features = false, features = [
6364
"charset",
6465
"http2",

mithril-client/src/client.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use anyhow::{Context, anyhow};
22
#[cfg(feature = "fs")]
33
use chrono::Utc;
4+
use mithril_aggregator_discovery::{
5+
AggregatorDiscoverer, HttpConfigAggregatorDiscoverer, MithrilNetwork,
6+
};
47
use mithril_common::messages::AggregatorCapabilities;
58
use reqwest::Url;
69
use serde::{Deserialize, Serialize};
@@ -44,7 +47,7 @@ const fn one_week_in_seconds() -> u32 {
4447
/// The type of discovery to use to find the aggregator to connect to.
4548
pub enum AggregatorDiscoveryType {
4649
/// Automatically discover the aggregator.
47-
Automatic,
50+
Automatic(MithrilNetwork),
4851
/// Use a specific URL to connect to the aggregator.
4952
Url(String),
5053
}
@@ -175,6 +178,7 @@ impl Client {
175178
pub struct ClientBuilder {
176179
aggregator_discovery: AggregatorDiscoveryType,
177180
aggregator_capabilities: Option<AggregatorCapabilities>,
181+
aggregator_discoverer: Option<Arc<dyn AggregatorDiscoverer>>,
178182
genesis_verification_key: Option<GenesisVerificationKey>,
179183
origin_tag: Option<String>,
180184
client_type: Option<String>,
@@ -196,16 +200,19 @@ impl ClientBuilder {
196200
/// Constructs a new `ClientBuilder` that fetches data from the aggregator at the given
197201
/// endpoint and with the given genesis verification key.
198202
pub fn aggregator(endpoint: &str, genesis_verification_key: &str) -> ClientBuilder {
199-
Self::new(AggregatorDiscoveryType::Url(endpoint.to_string())).with_genesis_verification_key(
200-
GenesisVerificationKey::JsonHex(genesis_verification_key.to_string()),
201-
)
203+
Self::new(AggregatorDiscoveryType::Url(endpoint.to_string()))
204+
.with_genesis_verification_key(GenesisVerificationKey::JsonHex(
205+
genesis_verification_key.to_string(),
206+
))
207+
.with_aggregator_discoverer(Arc::new(HttpConfigAggregatorDiscoverer::default()))
202208
}
203209

204210
/// Constructs a new `ClientBuilder` without any dependency set.
205211
pub fn new(aggregator_discovery: AggregatorDiscoveryType) -> ClientBuilder {
206212
Self {
207213
aggregator_discovery,
208214
aggregator_capabilities: None,
215+
aggregator_discoverer: None,
209216
genesis_verification_key: None,
210217
origin_tag: None,
211218
client_type: None,
@@ -241,11 +248,21 @@ impl ClientBuilder {
241248
self
242249
}
243250

251+
/// Sets the aggregator discoverer to use to find the aggregator endpoint when in automatic discovery.
252+
pub fn with_aggregator_discoverer(
253+
mut self,
254+
discoverer: Arc<dyn AggregatorDiscoverer>,
255+
) -> ClientBuilder {
256+
self.aggregator_discoverer = Some(discoverer);
257+
258+
self
259+
}
260+
244261
/// Returns a `Client` that uses the dependencies provided to this `ClientBuilder`.
245262
///
246263
/// The builder will try to create the missing dependencies using default implementations
247264
/// if possible.
248-
pub fn build(self) -> MithrilResult<Client> {
265+
pub async fn build(self) -> MithrilResult<Client> {
249266
let logger = self
250267
.logger
251268
.clone()
@@ -264,7 +281,7 @@ impl ClientBuilder {
264281
let feedback_sender = FeedbackSender::new(&self.feedback_receivers);
265282

266283
let aggregator_client = match self.aggregator_client {
267-
None => Arc::new(self.build_aggregator_client(logger.clone())?),
284+
None => Arc::new(self.build_aggregator_client(logger.clone()).await?),
268285
Some(client) => client,
269286
};
270287

@@ -367,15 +384,24 @@ impl ClientBuilder {
367384
})
368385
}
369386

370-
fn build_aggregator_client(
387+
async fn build_aggregator_client(
371388
&self,
372389
logger: Logger,
373390
) -> Result<AggregatorHTTPClient, anyhow::Error> {
374391
let aggregator_endpoint = match self.aggregator_discovery {
375392
AggregatorDiscoveryType::Url(ref url) => url.clone(),
376-
AggregatorDiscoveryType::Automatic => {
377-
todo!("Implement automatic aggregator discovery")
378-
}
393+
AggregatorDiscoveryType::Automatic(ref network) => match &self.aggregator_discoverer {
394+
Some(discoverer) => discoverer
395+
.get_available_aggregators(network.to_owned())
396+
.await
397+
.with_context(|| "Discovering aggregator endpoint failed")?
398+
.next()
399+
.unwrap()
400+
.into(),
401+
None => {
402+
return Err(anyhow!("The aggregator discoverer must be provided to build the client with automatic discovery using the 'with_aggregator_discoverer' function").into());
403+
}
404+
},
379405
};
380406
let endpoint_url = Url::parse(&aggregator_endpoint).with_context(|| {
381407
format!("Invalid aggregator endpoint, it must be a correctly formed url: '{aggregator_endpoint}'")

mithril-client/tests/cardano_db_snapshot_list_get_download_verify.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ async fn cardano_db_snapshot_list_get_download_verify() {
6363
extensions::test_logger(),
6464
)))
6565
.build()
66+
.await
6667
.expect("Should be able to create a Client");
6768

6869
let cardano_db_snapshots = client

mithril-client/tests/cardano_transaction_proof.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ async fn cardano_transaction_proof_get_validate() {
2222
FakeCertificateVerifier::build_that_validate_any_certificate(),
2323
)
2424
.build()
25+
.await
2526
.expect("Should be able to create a Client");
2627
let cardano_transaction_client = client.cardano_transaction();
2728

mithril-client/tests/certificate_get_list.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async fn certificate_get_list() {
1616
let client =
1717
ClientBuilder::aggregator(&fake_aggregator.server_root_url(), genesis_verification_key)
1818
.build()
19+
.await
1920
.expect("Should be able to create a Client");
2021

2122
let certificates = client

mithril-client/tests/mithril_stake_distribution_list_get_show_verify.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ async fn mithril_stake_distribution_list_get_show_verify() {
2121
FakeCertificateVerifier::build_that_validate_any_certificate(),
2222
)
2323
.build()
24+
.await
2425
.expect("Should be able to create a Client");
2526
let mithril_stake_distribution_client = client.mithril_stake_distribution();
2627

mithril-client/tests/snapshot_list_get_show_download_verify.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ async fn snapshot_list_get_show_download_verify() {
5050
)))
5151
.with_logger(extensions::test_logger())
5252
.build()
53+
.await
5354
.expect("Should be able to create a Client");
5455

5556
let snapshots = client

0 commit comments

Comments
 (0)