Skip to content

Commit f882047

Browse files
authored
feat(PocketIC): PocketIc::make_live_with_params takes optional IP address (#4488)
This PR makes the HTTP gateway IP address configurable when using the function `PocketIc::make_live_with_params` to create an HTTP gateway for a PocketIC instance. The const `EXPECTED_SERVER_VERSION` is made public so that clients can download a matching server version based on this constant.
1 parent c603b56 commit f882047

File tree

4 files changed

+51
-29
lines changed

4 files changed

+51
-29
lines changed

Diff for: packages/pocket-ic/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717

1818
### Changed
1919
- The functions `PocketIcBuilder::with_nns_subnet`, `PocketIcBuilder::with_sns_subnet`, `PocketIcBuilder::with_ii_subnet`, `PocketIcBuilder::with_fiduciary_subnet`, and `PocketIcBuilder::with_bitcoin_subnet` do not add a new empty subnet if a subnet of the corresponding kind has already been specified (e.g., with state loaded from a given state directory).
20+
- The function `PocketIc::make_live_with_params` takes an optional IP address to which the HTTP gateway should bind.
2021

2122

2223

Diff for: packages/pocket-ic/src/lib.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ use slog::Level;
7979
use std::os::unix::fs::OpenOptionsExt;
8080
use std::{
8181
fs::OpenOptions,
82-
net::SocketAddr,
82+
net::{IpAddr, SocketAddr},
8383
path::PathBuf,
8484
process::Command,
8585
sync::{mpsc::channel, Arc},
@@ -97,7 +97,7 @@ use wslpath::windows_to_wsl;
9797
pub mod common;
9898
pub mod nonblocking;
9999

100-
const EXPECTED_SERVER_VERSION: &str = "8.0.0";
100+
pub const EXPECTED_SERVER_VERSION: &str = "8.0.0";
101101

102102
// the default timeout of a PocketIC operation
103103
const DEFAULT_MAX_REQUEST_TIME_MS: u64 = 300_000;
@@ -559,38 +559,42 @@ impl PocketIc {
559559
self.pocket_ic.url()
560560
}
561561

562-
/// Creates an HTTP gateway for this IC instance
563-
/// listening on an optionally specified port
564-
/// and configures the IC instance to make progress
565-
/// automatically, i.e., periodically update the time
566-
/// of the IC to the real time and execute rounds on the subnets.
567-
/// Returns the URL at which `/api/v2` requests
562+
/// Creates an HTTP gateway for this PocketIC instance binding to `127.0.0.1`
563+
/// and an optionally specified port (defaults to choosing an arbitrary unassigned port);
564+
/// listening on `localhost`;
565+
/// and configures the PocketIC instance to make progress automatically, i.e.,
566+
/// periodically update the time of the PocketIC instance to the real time
567+
/// and process messages on the PocketIC instance.
568+
/// Returns the URL at which `/api/v2` and `/api/v3` requests
568569
/// for this instance can be made.
569570
#[instrument(skip(self), fields(instance_id=self.pocket_ic.instance_id))]
570571
pub fn make_live(&mut self, listen_at: Option<u16>) -> Url {
571572
let runtime = self.runtime.clone();
572573
runtime.block_on(async { self.pocket_ic.make_live(listen_at).await })
573574
}
574575

575-
/// Creates an HTTP gateway for this PocketIC instance listening
576-
/// on an optionally specified port (defaults to choosing an arbitrary unassigned port)
577-
/// and optionally specified domains (default to `localhost`)
576+
/// Creates an HTTP gateway for this PocketIC instance binding
577+
/// to an optionally specified IP address (defaults to `127.0.0.1`)
578+
/// and port (defaults to choosing an arbitrary unassigned port);
579+
/// listening on optionally specified domains (default to `localhost`);
578580
/// and using an optionally specified TLS certificate (if provided, an HTTPS gateway is created)
579581
/// and configures the PocketIC instance to make progress automatically, i.e.,
580-
/// periodically update the time of the PocketIC instance to the real time and execute rounds on the subnets.
581-
/// Returns the URL at which `/api/v2` requests
582+
/// periodically update the time of the PocketIC instance to the real time
583+
/// and process messages on the PocketIC instance.
584+
/// Returns the URL at which `/api/v2` and `/api/v3` requests
582585
/// for this instance can be made.
583586
#[instrument(skip(self), fields(instance_id=self.pocket_ic.instance_id))]
584587
pub async fn make_live_with_params(
585588
&mut self,
589+
ip_addr: Option<IpAddr>,
586590
listen_at: Option<u16>,
587591
domains: Option<Vec<String>>,
588592
https_config: Option<HttpsConfig>,
589593
) -> Url {
590594
let runtime = self.runtime.clone();
591595
runtime.block_on(async {
592596
self.pocket_ic
593-
.make_live_with_params(listen_at, domains, https_config)
597+
.make_live_with_params(ip_addr, listen_at, domains, https_config)
594598
.await
595599
})
596600
}

Diff for: packages/pocket-ic/src/nonblocking.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use sha2::{Digest, Sha256};
3535
use slog::Level;
3636
use std::fs::File;
3737
use std::future::Future;
38-
use std::net::SocketAddr;
38+
use std::net::{IpAddr, SocketAddr};
3939
use std::path::PathBuf;
4040
use std::time::{Duration, SystemTime};
4141
use tracing::{debug, instrument, warn};
@@ -356,28 +356,34 @@ impl PocketIc {
356356
.map(|res| Url::parse(&format!("http://{}:{}/", LOCALHOST, res.port)).unwrap())
357357
}
358358

359-
/// Creates an HTTP gateway for this PocketIC instance listening
360-
/// on an optionally specified port (defaults to choosing an arbitrary unassigned port)
359+
/// Creates an HTTP gateway for this PocketIC instance binding to `127.0.0.1`
360+
/// and an optionally specified port (defaults to choosing an arbitrary unassigned port);
361+
/// listening on `localhost`;
361362
/// and configures the PocketIC instance to make progress automatically, i.e.,
362-
/// periodically update the time of the PocketIC instance to the real time and execute rounds on the subnets.
363-
/// Returns the URL at which `/api/v2` requests
363+
/// periodically update the time of the PocketIC instance to the real time
364+
/// and process messages on the PocketIC instance.
365+
/// Returns the URL at which `/api/v2` and `/api/v3` requests
364366
/// for this instance can be made.
365367
#[instrument(skip(self), fields(instance_id=self.instance_id))]
366368
pub async fn make_live(&mut self, listen_at: Option<u16>) -> Url {
367-
self.make_live_with_params(listen_at, None, None).await
369+
self.make_live_with_params(None, listen_at, None, None)
370+
.await
368371
}
369372

370-
/// Creates an HTTP gateway for this PocketIC instance listening
371-
/// on an optionally specified port (defaults to choosing an arbitrary unassigned port)
372-
/// and optionally specified domains (default to `localhost`)
373+
/// Creates an HTTP gateway for this PocketIC instance binding
374+
/// to an optionally specified IP address (defaults to `127.0.0.1`)
375+
/// and port (defaults to choosing an arbitrary unassigned port);
376+
/// listening on optionally specified domains (default to `localhost`);
373377
/// and using an optionally specified TLS certificate (if provided, an HTTPS gateway is created)
374378
/// and configures the PocketIC instance to make progress automatically, i.e.,
375-
/// periodically update the time of the PocketIC instance to the real time and execute rounds on the subnets.
376-
/// Returns the URL at which `/api/v2` requests
379+
/// periodically update the time of the PocketIC instance to the real time
380+
/// and process messages on the PocketIC instance.
381+
/// Returns the URL at which `/api/v2` and `/api/v3` requests
377382
/// for this instance can be made.
378383
#[instrument(skip(self), fields(instance_id=self.instance_id))]
379384
pub async fn make_live_with_params(
380385
&mut self,
386+
ip_addr: Option<IpAddr>,
381387
listen_at: Option<u16>,
382388
domains: Option<Vec<String>>,
383389
https_config: Option<HttpsConfig>,
@@ -386,19 +392,25 @@ impl PocketIc {
386392
return url;
387393
}
388394
self.auto_progress().await;
389-
self.start_http_gateway(listen_at, domains, https_config)
390-
.await
395+
self.start_http_gateway(
396+
ip_addr.map(|ip_addr| ip_addr.to_string()),
397+
listen_at,
398+
domains,
399+
https_config,
400+
)
401+
.await
391402
}
392403

393404
async fn start_http_gateway(
394405
&mut self,
406+
ip_addr: Option<String>,
395407
port: Option<u16>,
396408
domains: Option<Vec<String>>,
397409
https_config: Option<HttpsConfig>,
398410
) -> Url {
399411
let endpoint = self.server_url.join("http_gateway").unwrap();
400412
let http_gateway_config = HttpGatewayConfig {
401-
ip_addr: None,
413+
ip_addr,
402414
port,
403415
forward_to: HttpGatewayBackend::PocketIcInstance(self.instance_id),
404416
domains: domains.clone(),

Diff for: rs/pocket_ic_server/tests/test.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,12 @@ async fn test_gateway(server_url: Url, https: bool) {
349349
None
350350
};
351351
let port = pic
352-
.make_live_with_params(None, domains.clone(), https_config.clone())
352+
.make_live_with_params(
353+
Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
354+
None,
355+
domains.clone(),
356+
https_config.clone(),
357+
)
353358
.await
354359
.port_or_known_default()
355360
.unwrap();

0 commit comments

Comments
 (0)