upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-05 12:03:52 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-05 12:03:52 +0000
commit339b0c02f2cec25ae804dc882f5ce7d1dd58b9a6 (patch)
treee3d80676913de96c2ac75eb2dc9a8954c88ab633
parentef7ba7c59b8e0b6369f63b8a46e202693963d92b (diff)
rename sunc_bootstrap_relay_url
-rw-r--r--.env.example41
-rw-r--r--docs/explanation/grasp-02-proactive-sync.md7
-rw-r--r--docs/reference/configuration.md17
-rw-r--r--src/config.rs10
-rw-r--r--src/http/nip11.rs6
-rw-r--r--src/main.rs8
-rw-r--r--src/sync/manager.rs33
-rw-r--r--tests/common/relay.rs14
-rw-r--r--tests/proactive_sync_multi.rs2
9 files changed, 90 insertions, 48 deletions
diff --git a/.env.example b/.env.example
index 9207dc4..7545d03 100644
--- a/.env.example
+++ b/.env.example
@@ -100,12 +100,45 @@
100# RUST_LOG=info 100# RUST_LOG=info
101 101
102# ============================================================================ 102# ============================================================================
103# FUTURE/PLANNED OPTIONS (not yet implemented) 103# PROACTIVE SYNC (GRASP-02)
104# ============================================================================ 104# ============================================================================
105 105
106# Proactive sync settings (GRASP-02) 106# Bootstrap relay URL for initial sync (optional)
107# NGIT_PROACTIVE_SYNC_ENABLED=true 107# Additional relays are automatically discovered from repository announcements
108# NGIT_PROACTIVE_SYNC_INTERVAL_SECS=3600 108# that list our service domain.
109# CLI: --sync-bootstrap-relay-url <url>
110# Default: (none - relay discovery from stored announcements only)
111# NGIT_SYNC_BOOTSTRAP_RELAY_URL=wss://relay.example.com
112
113# Maximum backoff time in seconds for sync relay reconnection
114# CLI: --sync-max-backoff-secs <seconds>
115# Default: 3600 (1 hour)
116# NGIT_SYNC_MAX_BACKOFF_SECS=3600
117
118# Delay in seconds before running startup catchup
119# CLI: --sync-startup-delay-secs <seconds>
120# Default: 30
121# NGIT_SYNC_STARTUP_DELAY_SECS=30
122
123# Delay in seconds before running reconnect catchup
124# CLI: --sync-reconnect-delay-secs <seconds>
125# Default: 10
126# NGIT_SYNC_RECONNECT_DELAY_SECS=10
127
128# Number of days to look back for reconnect catchup
129# CLI: --sync-reconnect-lookback-days <days>
130# Default: 3
131# NGIT_SYNC_RECONNECT_LOOKBACK_DAYS=3
132
133# Maximum startup jitter in milliseconds for sync connections
134# Set to 0 to disable jitter (useful for testing)
135# CLI: --sync-startup-jitter-ms <ms>
136# Default: 10000 (10 seconds)
137# NGIT_SYNC_STARTUP_JITTER_MS=10000
138
139# ============================================================================
140# FUTURE/PLANNED OPTIONS (not yet implemented)
141# ============================================================================
109 142
110# Archive mode (GRASP-05) 143# Archive mode (GRASP-05)
111# NGIT_ARCHIVE_MODE=false \ No newline at end of file 144# NGIT_ARCHIVE_MODE=false \ No newline at end of file
diff --git a/docs/explanation/grasp-02-proactive-sync.md b/docs/explanation/grasp-02-proactive-sync.md
index 98531ec..666b048 100644
--- a/docs/explanation/grasp-02-proactive-sync.md
+++ b/docs/explanation/grasp-02-proactive-sync.md
@@ -758,7 +758,8 @@ The implementation closely follows the design document with the following comple
758 758
759#### Phase 1: Basic Sync (commit b167f1b) 759#### Phase 1: Basic Sync (commit b167f1b)
760- [`SyncManager`](../../src/sync/manager.rs) - Main coordinator for proactive sync 760- [`SyncManager`](../../src/sync/manager.rs) - Main coordinator for proactive sync
761- Single relay sync via `NGIT_SYNC_RELAY_URL` configuration 761- Bootstrap relay sync via `NGIT_SYNC_BOOTSTRAP_RELAY_URL` configuration
762- Dynamic relay discovery from repository announcements that list our service
762- Event validation through existing [`Nip34WritePolicy`](../../src/nostr/builder.rs) 763- Event validation through existing [`Nip34WritePolicy`](../../src/nostr/builder.rs)
763 764
764#### Phase 2: Three-Layer Filters (commit bf558b0) 765#### Phase 2: Three-Layer Filters (commit bf558b0)
@@ -844,12 +845,14 @@ All configuration via environment variables or CLI flags:
844 845
845| Option | Type | Default | Description | 846| Option | Type | Default | Description |
846|--------|------|---------|-------------| 847|--------|------|---------|-------------|
847| `NGIT_SYNC_RELAY_URL` | String | None | Primary sync relay URL | 848| `NGIT_SYNC_BOOTSTRAP_RELAY_URL` | String | None | Bootstrap relay URL for initial sync |
848| `NGIT_SYNC_MAX_BACKOFF_SECS` | u64 | 3600 | Max backoff delay (seconds) | 849| `NGIT_SYNC_MAX_BACKOFF_SECS` | u64 | 3600 | Max backoff delay (seconds) |
849| `NGIT_SYNC_STARTUP_DELAY_SECS` | u64 | 30 | Catchup delay after startup | 850| `NGIT_SYNC_STARTUP_DELAY_SECS` | u64 | 30 | Catchup delay after startup |
850| `NGIT_SYNC_RECONNECT_DELAY_SECS` | u64 | 10 | Catchup delay after reconnect | 851| `NGIT_SYNC_RECONNECT_DELAY_SECS` | u64 | 10 | Catchup delay after reconnect |
851| `NGIT_SYNC_RECONNECT_LOOKBACK_DAYS` | u64 | 3 | Days to look back on reconnect | 852| `NGIT_SYNC_RECONNECT_LOOKBACK_DAYS` | u64 | 3 | Days to look back on reconnect |
852 853
854**Note:** Additional relays are automatically discovered from repository announcements (kind 30617) that list our service domain. The bootstrap relay provides an initial sync source but is not required - sync will discover relays from stored announcements.
855
853### Module Structure (As Implemented) 856### Module Structure (As Implemented)
854 857
855``` 858```
diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md
index 80ae45c..204fbd1 100644
--- a/docs/reference/configuration.md
+++ b/docs/reference/configuration.md
@@ -269,28 +269,29 @@ NGIT_DATABASE_BACKEND=lmdb
269 269
270These options configure the proactive sync feature that synchronizes events from other relays. 270These options configure the proactive sync feature that synchronizes events from other relays.
271 271
272#### `NGIT_SYNC_RELAY_URL` 272#### `NGIT_SYNC_BOOTSTRAP_RELAY_URL`
273 273
274**Description:** URL of the primary relay to sync events from 274**Description:** URL of the bootstrap relay to initially sync events from
275**Type:** String (WebSocket URL) 275**Type:** String (WebSocket URL)
276**Default:** None (sync disabled) 276**Default:** None (relay discovery only)
277**Required:** No 277**Required:** No
278 278
279**Examples:** 279**Examples:**
280```bash 280```bash
281# Sync from a public relay 281# Sync from a public relay
282NGIT_SYNC_RELAY_URL=wss://relay.example.com 282NGIT_SYNC_BOOTSTRAP_RELAY_URL=wss://relay.example.com
283 283
284# Sync from another GRASP relay 284# Sync from another GRASP relay
285NGIT_SYNC_RELAY_URL=wss://git.nostr.dev 285NGIT_SYNC_BOOTSTRAP_RELAY_URL=wss://git.nostr.dev
286 286
287# Local testing 287# Local testing
288NGIT_SYNC_RELAY_URL=ws://127.0.0.1:8081 288NGIT_SYNC_BOOTSTRAP_RELAY_URL=ws://127.0.0.1:8081
289``` 289```
290 290
291**Notes:** 291**Notes:**
292- When set, enables proactive sync feature 292- Bootstrap relay provides initial sync source on startup
293- The relay will discover additional relays from repository announcements 293- Additional relays are **automatically discovered** from repository announcements that list our service
294- Even without a bootstrap relay, sync will discover relays from stored announcements
294- Synced events go through the same validation as directly-submitted events 295- Synced events go through the same validation as directly-submitted events
295- Use WebSocket protocol (`ws://` or `wss://`) 296- Use WebSocket protocol (`ws://` or `wss://`)
296 297
diff --git a/src/config.rs b/src/config.rs
index 07e67c8..69a160a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -84,9 +84,10 @@ pub struct Config {
84 #[arg(long = "metrics-top-n-repos", env = "NGIT_METRICS_TOP_N_REPOS", default_value_t = 10)] 84 #[arg(long = "metrics-top-n-repos", env = "NGIT_METRICS_TOP_N_REPOS", default_value_t = 10)]
85 pub metrics_top_n_repos: usize, 85 pub metrics_top_n_repos: usize,
86 86
87 /// URL of relay to sync kind 30617 events from (optional, enables proactive sync) 87 /// URL of bootstrap relay to sync from on startup (optional)
88 #[arg(long, env = "NGIT_SYNC_RELAY_URL")] 88 /// Sync discovers additional relays from repository announcements that list our service
89 pub sync_relay_url: Option<String>, 89 #[arg(long, env = "NGIT_SYNC_BOOTSTRAP_RELAY_URL")]
90 pub sync_bootstrap_relay_url: Option<String>,
90 91
91 /// Maximum backoff time in seconds for sync relay reconnection (default: 3600 = 1 hour) 92 /// Maximum backoff time in seconds for sync relay reconnection (default: 3600 = 1 hour)
92 #[arg(long, env = "NGIT_SYNC_MAX_BACKOFF_SECS", default_value_t = 3600)] 93 #[arg(long, env = "NGIT_SYNC_MAX_BACKOFF_SECS", default_value_t = 3600)]
@@ -163,11 +164,12 @@ impl Config {
163 metrics_enabled: true, 164 metrics_enabled: true,
164 metrics_connection_per_ip_abuse_threshold: 10, 165 metrics_connection_per_ip_abuse_threshold: 10,
165 metrics_top_n_repos: 10, 166 metrics_top_n_repos: 10,
166 sync_relay_url: None, 167 sync_bootstrap_relay_url: None,
167 sync_max_backoff_secs: 3600, 168 sync_max_backoff_secs: 3600,
168 sync_startup_delay_secs: 30, 169 sync_startup_delay_secs: 30,
169 sync_reconnect_delay_secs: 10, 170 sync_reconnect_delay_secs: 10,
170 sync_reconnect_lookback_days: 3, 171 sync_reconnect_lookback_days: 3,
172 sync_startup_jitter_ms: 10_000,
171 } 173 }
172 } 174 }
173} 175}
diff --git a/src/http/nip11.rs b/src/http/nip11.rs
index 5d362bb..80165ee 100644
--- a/src/http/nip11.rs
+++ b/src/http/nip11.rs
@@ -105,11 +105,12 @@ mod tests {
105 metrics_enabled: true, 105 metrics_enabled: true,
106 metrics_connection_per_ip_abuse_threshold: 10, 106 metrics_connection_per_ip_abuse_threshold: 10,
107 metrics_top_n_repos: 10, 107 metrics_top_n_repos: 10,
108 sync_relay_url: None, 108 sync_bootstrap_relay_url: None,
109 sync_max_backoff_secs: 3600, 109 sync_max_backoff_secs: 3600,
110 sync_startup_delay_secs: 30, 110 sync_startup_delay_secs: 30,
111 sync_reconnect_delay_secs: 10, 111 sync_reconnect_delay_secs: 10,
112 sync_reconnect_lookback_days: 3, 112 sync_reconnect_lookback_days: 3,
113 sync_startup_jitter_ms: 10_000,
113 }; 114 };
114 115
115 let doc = RelayInformationDocument::from_config(&config); 116 let doc = RelayInformationDocument::from_config(&config);
@@ -144,11 +145,12 @@ mod tests {
144 metrics_enabled: true, 145 metrics_enabled: true,
145 metrics_connection_per_ip_abuse_threshold: 10, 146 metrics_connection_per_ip_abuse_threshold: 10,
146 metrics_top_n_repos: 10, 147 metrics_top_n_repos: 10,
147 sync_relay_url: None, 148 sync_bootstrap_relay_url: None,
148 sync_max_backoff_secs: 3600, 149 sync_max_backoff_secs: 3600,
149 sync_startup_delay_secs: 30, 150 sync_startup_delay_secs: 30,
150 sync_reconnect_delay_secs: 10, 151 sync_reconnect_delay_secs: 10,
151 sync_reconnect_lookback_days: 3, 152 sync_reconnect_lookback_days: 3,
153 sync_startup_jitter_ms: 10_000,
152 }; 154 };
153 155
154 let doc = RelayInformationDocument::from_config(&config); 156 let doc = RelayInformationDocument::from_config(&config);
diff --git a/src/main.rs b/src/main.rs
index 9273afd..f887e42 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -52,17 +52,17 @@ async fn main() -> Result<()> {
52 ); 52 );
53 53
54 // Start SyncManager for proactive sync (Phase 2: multi-relay support, Phase 3: health tracking) 54 // Start SyncManager for proactive sync (Phase 2: multi-relay support, Phase 3: health tracking)
55 // Even without initial sync_relay_url, SyncManager can discover relays from stored announcements 55 // Even without bootstrap relay, SyncManager discovers relays from stored announcements
56 let sync_manager = SyncManager::new( 56 let sync_manager = SyncManager::new(
57 config.sync_relay_url.clone(), 57 config.sync_bootstrap_relay_url.clone(),
58 config.domain.clone(), 58 config.domain.clone(),
59 relay_with_db.database.clone(), 59 relay_with_db.database.clone(),
60 relay_with_db.write_policy.clone(), 60 relay_with_db.write_policy.clone(),
61 &config, 61 &config,
62 ); 62 );
63 63
64 if config.sync_relay_url.is_some() { 64 if config.sync_bootstrap_relay_url.is_some() {
65 info!("Starting proactive sync from: {:?}", config.sync_relay_url); 65 info!("Starting proactive sync with bootstrap relay: {:?}", config.sync_bootstrap_relay_url);
66 } else { 66 } else {
67 info!("Proactive sync enabled (will discover relays from stored announcements)"); 67 info!("Proactive sync enabled (will discover relays from stored announcements)");
68 } 68 }
diff --git a/src/sync/manager.rs b/src/sync/manager.rs
index 6fcfcd7..96bf0f4 100644
--- a/src/sync/manager.rs
+++ b/src/sync/manager.rs
@@ -60,8 +60,9 @@ fn get_sync_source_addr(bind_address: &str) -> SocketAddr {
60 60
61/// Coordinates proactive sync from configured and discovered relays 61/// Coordinates proactive sync from configured and discovered relays
62pub struct SyncManager { 62pub struct SyncManager {
63 /// Initial relay URL to sync from (from config) 63 /// Bootstrap relay URL for initial sync (from config)
64 initial_relay_url: Option<String>, 64 /// Additional relays are discovered from repository announcements that list our service
65 bootstrap_relay_url: Option<String>,
65 /// Our relay's domain (for filtering) 66 /// Our relay's domain (for filtering)
66 relay_domain: String, 67 relay_domain: String,
67 /// Database for storing accepted events 68 /// Database for storing accepted events
@@ -82,20 +83,20 @@ impl SyncManager {
82 /// Create a new SyncManager 83 /// Create a new SyncManager
83 /// 84 ///
84 /// # Arguments 85 /// # Arguments
85 /// * `initial_relay_url` - Optional initial relay URL from config 86 /// * `bootstrap_relay_url` - Optional bootstrap relay URL from config
86 /// * `relay_domain` - Our relay's domain (used to exclude self from sync) 87 /// * `relay_domain` - Our relay's domain (used to exclude self from sync)
87 /// * `database` - Shared database for storing events and querying announcements 88 /// * `database` - Shared database for storing events and querying announcements
88 /// * `write_policy` - Write policy for validating synced events 89 /// * `write_policy` - Write policy for validating synced events
89 /// * `config` - Configuration for health tracking settings 90 /// * `config` - Configuration for health tracking settings
90 pub fn new( 91 pub fn new(
91 initial_relay_url: Option<String>, 92 bootstrap_relay_url: Option<String>,
92 relay_domain: String, 93 relay_domain: String,
93 database: SharedDatabase, 94 database: SharedDatabase,
94 write_policy: Nip34WritePolicy, 95 write_policy: Nip34WritePolicy,
95 config: &Config, 96 config: &Config,
96 ) -> Self { 97 ) -> Self {
97 Self { 98 Self {
98 initial_relay_url, 99 bootstrap_relay_url,
99 relay_domain, 100 relay_domain,
100 database, 101 database,
101 write_policy, 102 write_policy,
@@ -109,14 +110,14 @@ impl SyncManager {
109 /// Create a new SyncManager with metrics 110 /// Create a new SyncManager with metrics
110 /// 111 ///
111 /// # Arguments 112 /// # Arguments
112 /// * `initial_relay_url` - Optional initial relay URL from config 113 /// * `bootstrap_relay_url` - Optional bootstrap relay URL from config
113 /// * `relay_domain` - Our relay's domain (used to exclude self from sync) 114 /// * `relay_domain` - Our relay's domain (used to exclude self from sync)
114 /// * `database` - Shared database for storing events and querying announcements 115 /// * `database` - Shared database for storing events and querying announcements
115 /// * `write_policy` - Write policy for validating synced events 116 /// * `write_policy` - Write policy for validating synced events
116 /// * `config` - Configuration for health tracking settings 117 /// * `config` - Configuration for health tracking settings
117 /// * `metrics` - Sync metrics for Prometheus 118 /// * `metrics` - Sync metrics for Prometheus
118 pub fn with_metrics( 119 pub fn with_metrics(
119 initial_relay_url: Option<String>, 120 bootstrap_relay_url: Option<String>,
120 relay_domain: String, 121 relay_domain: String,
121 database: SharedDatabase, 122 database: SharedDatabase,
122 write_policy: Nip34WritePolicy, 123 write_policy: Nip34WritePolicy,
@@ -124,7 +125,7 @@ impl SyncManager {
124 metrics: SyncMetrics, 125 metrics: SyncMetrics,
125 ) -> Self { 126 ) -> Self {
126 Self { 127 Self {
127 initial_relay_url, 128 bootstrap_relay_url,
128 relay_domain, 129 relay_domain,
129 database, 130 database,
130 write_policy, 131 write_policy,
@@ -137,14 +138,14 @@ impl SyncManager {
137 138
138 /// Create a SyncManager with a single relay URL (Phase 1 compatibility) 139 /// Create a SyncManager with a single relay URL (Phase 1 compatibility)
139 pub fn with_single_relay( 140 pub fn with_single_relay(
140 sync_relay_url: String, 141 bootstrap_url: String,
141 database: SharedDatabase, 142 database: SharedDatabase,
142 write_policy: Nip34WritePolicy, 143 write_policy: Nip34WritePolicy,
143 ) -> Self { 144 ) -> Self {
144 // Extract domain from URL for filtering 145 // Extract domain from URL for filtering
145 let relay_domain = extract_domain_from_url(&sync_relay_url).unwrap_or_default(); 146 let relay_domain = extract_domain_from_url(&bootstrap_url).unwrap_or_default();
146 Self { 147 Self {
147 initial_relay_url: Some(sync_relay_url), 148 bootstrap_relay_url: Some(bootstrap_url),
148 relay_domain, 149 relay_domain,
149 database, 150 database,
150 write_policy, 151 write_policy,
@@ -176,9 +177,9 @@ impl SyncManager {
176 /// and processes incoming events. Runs indefinitely until cancelled. 177 /// and processes incoming events. Runs indefinitely until cancelled.
177 pub async fn run(self) { 178 pub async fn run(self) {
178 tracing::info!( 179 tracing::info!(
179 "Starting SyncManager (domain: {}, initial relay: {:?})", 180 "Starting SyncManager (domain: {}, bootstrap relay: {:?})",
180 self.relay_domain, 181 self.relay_domain,
181 self.initial_relay_url 182 self.bootstrap_relay_url
182 ); 183 );
183 184
184 // Create the filter service 185 // Create the filter service
@@ -196,13 +197,13 @@ impl SyncManager {
196 // Collect all relays to connect to 197 // Collect all relays to connect to
197 let mut relays_to_connect: Vec<String> = Vec::new(); 198 let mut relays_to_connect: Vec<String> = Vec::new();
198 199
199 // Start with initial relay if configured 200 // Start with bootstrap relay if configured
200 if let Some(ref url) = self.initial_relay_url { 201 if let Some(ref url) = self.bootstrap_relay_url {
201 if !self.is_own_relay(url) { 202 if !self.is_own_relay(url) {
202 relays_to_connect.push(url.clone()); 203 relays_to_connect.push(url.clone());
203 active_relays.insert(url.clone()); 204 active_relays.insert(url.clone());
204 } else { 205 } else {
205 tracing::info!("Skipping initial relay (is our own relay): {}", url); 206 tracing::info!("Skipping bootstrap relay (is our own relay): {}", url);
206 } 207 }
207 } 208 }
208 209
diff --git a/tests/common/relay.rs b/tests/common/relay.rs
index 21d6deb..dbfd8de 100644
--- a/tests/common/relay.rs
+++ b/tests/common/relay.rs
@@ -41,7 +41,7 @@ impl TestRelay {
41 Self::start_with_options(port, None).await 41 Self::start_with_options(port, None).await
42 } 42 }
43 43
44 /// Start relay with sync from another relay 44 /// Start relay with sync from another relay (bootstrap relay)
45 /// 45 ///
46 /// # Example 46 /// # Example
47 /// 47 ///
@@ -57,12 +57,12 @@ impl TestRelay {
57 /// source.stop().await; 57 /// source.stop().await;
58 /// } 58 /// }
59 /// ``` 59 /// ```
60 pub async fn start_with_sync(sync_relay_url: &str) -> Self { 60 pub async fn start_with_sync(bootstrap_relay_url: &str) -> Self {
61 Self::start_with_options(Self::find_free_port(), Some(sync_relay_url.to_string())).await 61 Self::start_with_options(Self::find_free_port(), Some(bootstrap_relay_url.to_string())).await
62 } 62 }
63 63
64 /// Start relay with options 64 /// Start relay with options
65 async fn start_with_options(port: u16, sync_relay_url: Option<String>) -> Self { 65 async fn start_with_options(port: u16, bootstrap_relay_url: Option<String>) -> Self {
66 let bind_address = format!("127.0.0.1:{}", port); 66 let bind_address = format!("127.0.0.1:{}", port);
67 let url = format!("ws://127.0.0.1:{}", port); 67 let url = format!("ws://127.0.0.1:{}", port);
68 68
@@ -97,9 +97,9 @@ impl TestRelay {
97 .stdout(Stdio::null()) 97 .stdout(Stdio::null())
98 .stderr(Stdio::null()); 98 .stderr(Stdio::null());
99 99
100 // Add sync relay URL if provided 100 // Add bootstrap relay URL if provided
101 if let Some(ref sync_url) = sync_relay_url { 101 if let Some(ref bootstrap_url) = bootstrap_relay_url {
102 cmd.env("NGIT_SYNC_RELAY_URL", sync_url); 102 cmd.env("NGIT_SYNC_BOOTSTRAP_RELAY_URL", bootstrap_url);
103 } 103 }
104 104
105 let process = cmd.spawn().expect("Failed to start relay process"); 105 let process = cmd.spawn().expect("Failed to start relay process");
diff --git a/tests/proactive_sync_multi.rs b/tests/proactive_sync_multi.rs
index ee29f24..e07ddbe 100644
--- a/tests/proactive_sync_multi.rs
+++ b/tests/proactive_sync_multi.rs
@@ -170,7 +170,7 @@ async fn test_sync_configuration_applied() {
170 tokio::time::sleep(Duration::from_millis(300)).await; 170 tokio::time::sleep(Duration::from_millis(300)).await;
171 171
172 // Both relays should be running 172 // Both relays should be running
173 // The sync relay has NGIT_SYNC_RELAY_URL set (verified by relay starting) 173 // The sync relay has NGIT_SYNC_BOOTSTRAP_RELAY_URL set (verified by relay starting)
174 174
175 let client_source = Client::default(); 175 let client_source = Client::default();
176 client_source 176 client_source