Skip to content

Commit e348a95

Browse files
authored
Fix multi-proxy support in local_net. (#4372)
## Motivation There are several bugs related to proxies in the `local_net` setup, some of which are causing error messages like: ``` forward_notifications{…}: linera_rpc::grpc::server: proxy: could not send notification error=status: Unavailable, message: "tcp connect error" ``` The tests pass anyway because only the first proxy is actually used. ## Proposal Fix the bugs. ## Test Plan The tests now pass without those errors, even if I use multiple proxies. (We don't, by default.) ## Release Plan - Nothing to do / These changes follow the usual release cycle. ## Links - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
1 parent d2b0085 commit e348a95

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

linera-service/src/cli_wrappers/local_net.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -234,25 +234,24 @@ pub enum Database {
234234

235235
/// The processes of a running validator.
236236
struct Validator {
237-
proxy: Child,
237+
proxies: Vec<Child>,
238238
servers: Vec<Child>,
239239
exporters: Vec<Child>,
240240
}
241241

242242
impl Validator {
243-
fn new(proxy: Child) -> Self {
243+
fn new() -> Self {
244244
Self {
245-
proxy,
245+
proxies: vec![],
246246
servers: vec![],
247247
exporters: vec![],
248248
}
249249
}
250250

251251
async fn terminate(&mut self) -> Result<()> {
252-
self.proxy
253-
.kill()
254-
.await
255-
.context("terminating validator proxy")?;
252+
for proxy in &mut self.proxies {
253+
proxy.kill().await.context("terminating validator proxy")?;
254+
}
256255
for server in &mut self.servers {
257256
server
258257
.kill()
@@ -262,6 +261,10 @@ impl Validator {
262261
Ok(())
263262
}
264263

264+
fn add_proxy(&mut self, proxy: Child) {
265+
self.proxies.push(proxy)
266+
}
267+
265268
fn add_server(&mut self, server: Child) {
266269
self.servers.push(server)
267270
}
@@ -281,7 +284,9 @@ impl Validator {
281284
}
282285

283286
fn ensure_is_running(&mut self) -> Result<()> {
284-
self.proxy.ensure_is_running()?;
287+
for proxy in &mut self.proxies {
288+
proxy.ensure_is_running()?;
289+
}
285290
for child in &mut self.servers {
286291
child.ensure_is_running()?;
287292
}
@@ -333,8 +338,8 @@ impl LineraNetConfig for LocalNetConfig {
333338
self.testing_prng_seed,
334339
self.namespace,
335340
self.num_initial_validators,
336-
self.num_shards,
337341
self.num_proxies,
342+
self.num_shards,
338343
storage_config,
339344
self.cross_chain_config,
340345
self.path_provider,
@@ -448,23 +453,23 @@ impl LocalNet {
448453
}
449454

450455
fn proxy_internal_port(&self, validator: usize, proxy_id: usize) -> usize {
451-
10000 + validator * self.num_shards + proxy_id + 1
456+
10000 + validator * self.num_proxies + proxy_id + 1
452457
}
453458

454459
fn shard_metrics_port(&self, validator: usize, shard: usize) -> usize {
455460
11000 + validator * self.num_shards + shard + 1
456461
}
457462

458463
fn proxy_metrics_port(&self, validator: usize, proxy_id: usize) -> usize {
459-
12000 + validator * self.num_shards + proxy_id + 1
464+
12000 + validator * self.num_proxies + proxy_id + 1
460465
}
461466

462467
fn block_exporter_port(&self, validator: usize, exporter_id: usize) -> usize {
463468
12000 + validator * self.num_shards + exporter_id + 1
464469
}
465470

466471
pub fn proxy_public_port(&self, validator: usize, proxy_id: usize) -> usize {
467-
FIRST_PUBLIC_PORT + validator * self.num_shards + proxy_id + 1
472+
FIRST_PUBLIC_PORT + validator * self.num_proxies + proxy_id + 1
468473
}
469474

470475
pub fn first_public_port() -> usize {
@@ -497,6 +502,7 @@ impl LocalNet {
497502
);
498503

499504
for k in 0..self.num_proxies {
505+
let public_port = self.proxy_public_port(n, k);
500506
let internal_port = self.proxy_internal_port(n, k);
501507
let metrics_port = self.proxy_metrics_port(n, k);
502508
// In the local network, the validator ingress is
@@ -506,7 +512,7 @@ impl LocalNet {
506512
r#"
507513
[[proxies]]
508514
host = "{internal_host}"
509-
public_port = {port}
515+
public_port = {public_port}
510516
private_port = {internal_port}
511517
metrics_host = "{external_host}"
512518
metrics_port = {metrics_port}
@@ -699,7 +705,7 @@ impl LocalNet {
699705
Ok(())
700706
}
701707

702-
async fn run_proxy(&mut self, validator: usize) -> Result<Child> {
708+
async fn run_proxy(&mut self, validator: usize, proxy_id: usize) -> Result<Child> {
703709
let storage = self
704710
.initialized_validator_storages
705711
.get(&validator)
@@ -709,9 +715,10 @@ impl LocalNet {
709715
.await?
710716
.arg(format!("server_{}.json", validator))
711717
.args(["--storage", &storage.to_string()])
718+
.args(["--id", &proxy_id.to_string()])
712719
.spawn_into()?;
713720

714-
let port = self.proxy_public_port(validator, 0);
721+
let port = self.proxy_public_port(validator, proxy_id);
715722
let nickname = format!("validator proxy {validator}");
716723
match self.network.external {
717724
Network::Grpc => {
@@ -917,8 +924,11 @@ impl LocalNet {
917924
/// Restart a validator. This is similar to `start_validator` except that the
918925
/// database was already initialized once.
919926
pub async fn restart_validator(&mut self, index: usize) -> Result<()> {
920-
let proxy = self.run_proxy(index).await?;
921-
let mut validator = Validator::new(proxy);
927+
let mut validator = Validator::new();
928+
for k in 0..self.num_proxies {
929+
let proxy = self.run_proxy(index, k).await?;
930+
validator.add_proxy(proxy);
931+
}
922932
for shard in 0..self.num_shards {
923933
let server = self.run_server(index, shard).await?;
924934
validator.add_server(server);

0 commit comments

Comments
 (0)