-
Notifications
You must be signed in to change notification settings - Fork 2
feat: support SP-to-SP fetch via host.docker.internal resolution #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ADVANCED_README.md
Outdated
| - Preserves Portainer for persistent access | ||
| - Clears run ID | ||
|
|
||
| ### Pausing and Resuming (Resource Saving) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm learning that this might not be all that good, Curio doesn't seem to like sleeping, its harmony task heartbeat seems to get out of whack and it needs a restart so I might have to remove these instructions, or at least provide curio restart instructions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to remove this section, I haven't been able to make pause & resume work well for me. I'd prefer a full start/stop that doesn't do the whole deployment cycle I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enables SP-to-SP (Service Provider to Service Provider) data fetching by using host.docker.internal as a hostname that resolves to localhost from both the host machine and inside Docker containers. The changes ensure that service URLs registered in the SP registry work across different network contexts. Additionally, the default number of Curio service providers is increased from 1 to 2 to better simulate durability requirements.
Changes:
- Increases default SP count from 1 to 2 to simulate durability requirements
- Adds a pre-startup check that validates
host.docker.internalresolves to localhost, with clear error messages and setup instructions - Updates service URLs to use
host.docker.internalinstead oflocalhostfor cross-container compatibility - Adds
CURIO_PULL_ALLOW_INSECURE=1environment variable to allow HTTP connections in devnet - Adds
--add-host=host.docker.internal:host-gatewayto Curio containers for proper hostname resolution
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/config.rs | Updates default approved_pdp_sp_count and active_pdp_sp_count from 1 to 2 |
| src/commands/start/mod.rs | Adds check_host_docker_internal function to validate hostname resolution before startup |
| src/commands/start/pdp_service_provider/pdp_service_provider_step.rs | Changes service URL from localhost to host.docker.internal for cross-container compatibility |
| src/commands/start/curio/db_setup.rs | Adds CURIO_PULL_ALLOW_INSECURE environment variable for insecure HTTP sources |
| src/commands/start/curio/daemon.rs | Adds --add-host Docker flag to enable host.docker.internal resolution in containers |
| README.md | Documents the host.docker.internal prerequisite with setup instructions |
| README_ADVANCED.md | Adds detailed Yugabyte database query examples and clarifies multi-SP setup |
| for (sp_index, sp_address, sp_eth_address, pdp_port, should_approve) in sp_data { | ||
| let service_url = format!("http://localhost:{}", pdp_port); | ||
| // Use host.docker.internal so the URL works from both host and containers | ||
| let service_url = format!("http://host.docker.internal:{}", pdp_port); |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string "host.docker.internal" is repeated multiple times throughout the codebase (in this file, pdp_service_provider_step.rs, and daemon.rs). According to the coding guidelines, magic names should be defined as constants. Consider defining a constant like DOCKER_HOST_INTERNAL at the module or crate level to avoid repetition and make future changes easier.
| "--network".to_string(), | ||
| pdp_miner_network_name(run_id, sp_index), | ||
| // Enable host.docker.internal for SP-to-SP fetch (resolves to host gateway) | ||
| "--add-host=host.docker.internal:host-gateway".to_string(), |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Docker argument "--add-host=host.docker.internal:host-gateway" contains the magic name "host.docker.internal" which is used in multiple places. According to the coding guidelines, all magic names should be constants. Consider defining a constant for this Docker argument or for the hostname component to ensure consistency across the codebase.
| fn check_host_docker_internal() -> Result<(), Box<dyn std::error::Error>> { | ||
| info!("Checking host.docker.internal resolution..."); | ||
|
|
||
| // Try to resolve host.docker.internal:80 (port doesn't matter, just need DNS resolution) | ||
| match "host.docker.internal:80".to_socket_addrs() { | ||
| Ok(mut addrs) => { | ||
| // Check if any resolved address is 127.0.0.1 | ||
| let is_localhost = addrs.any(|addr| addr.ip().is_loopback()); | ||
|
|
||
| if is_localhost { | ||
| info!("✓ host.docker.internal resolves to localhost"); | ||
| Ok(()) | ||
| } else { | ||
| error!("════════════════════════════════════════════════════════════════════"); | ||
| error!("ERROR: host.docker.internal does not resolve to localhost (127.0.0.1)"); | ||
| error!("════════════════════════════════════════════════════════════════════"); | ||
| error!(""); | ||
| error!("SP-to-SP fetch requires host.docker.internal to resolve to 127.0.0.1"); | ||
| error!("so that registered SP URLs work from both host and containers."); | ||
| error!(""); | ||
| error!("To fix this, add the following line to /etc/hosts:"); | ||
| error!(""); | ||
| error!(" 127.0.0.1 host.docker.internal"); | ||
| error!(""); | ||
| error!("You can do this with:"); | ||
| error!(" echo '127.0.0.1 host.docker.internal' | sudo tee -a /etc/hosts"); | ||
| error!(""); | ||
| error!("════════════════════════════════════════════════════════════════════"); | ||
| Err("host.docker.internal must resolve to 127.0.0.1".into()) | ||
| } | ||
| } | ||
| Err(_) => { | ||
| error!("════════════════════════════════════════════════════════════════════"); | ||
| error!("ERROR: host.docker.internal does not resolve"); | ||
| error!("════════════════════════════════════════════════════════════════════"); | ||
| error!(""); | ||
| error!("SP-to-SP fetch requires host.docker.internal to resolve to 127.0.0.1"); | ||
| error!("so that registered SP URLs work from both host and containers."); | ||
| error!(""); | ||
| error!("Add the following line to /etc/hosts:"); | ||
| error!(""); | ||
| error!(" 127.0.0.1 host.docker.internal"); | ||
| error!(""); | ||
| error!("You can do this with:"); | ||
| error!(" echo '127.0.0.1 host.docker.internal' | sudo tee -a /etc/hosts"); | ||
| error!(""); | ||
| error!("For GitHub Actions, add this step before running foc-devnet:"); | ||
| error!(" - run: echo '127.0.0.1 host.docker.internal' | sudo tee -a /etc/hosts"); | ||
| error!(""); | ||
| error!("════════════════════════════════════════════════════════════════════"); | ||
| Err("host.docker.internal must be resolvable".into()) | ||
| } | ||
| } | ||
| } |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check_host_docker_internal function exceeds the 15-line limit specified in the coding guidelines. This 53-line function should be decomposed into smaller functions. Consider extracting the error message generation into a separate function and the resolution check logic into another function.
| info!("Checking host.docker.internal resolution..."); | ||
|
|
||
| // Try to resolve host.docker.internal:80 (port doesn't matter, just need DNS resolution) | ||
| match "host.docker.internal:80".to_socket_addrs() { |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The port number 80 used in "host.docker.internal:80" should be defined as a constant per the coding guidelines which require all magic numbers to be constants. Consider defining a constant like DNS_CHECK_PORT at the module level.
Inter-SP Communication Solution AnalysisTL;DRWhere we are: The fix: Use The ProblemSo here's the thing: Docker networking makes this tricky. You've got SPs running in containers that need to:
But
Docker DNS names ( The Solution:
|
|
So @rvagg can't give official-in-github approval because he's the original author of the draft. I think the next steps are:
|
|
@redpanda-f : I assume you'll go through the copilot comments and see which ones are relevant and resolve accordingly. |
Draft to start with because I'm still testing with this but it does work as is for now.
I'm testing FilOzone/synapse-sdk#544 & filecoin-project/curio#864, which will end up being default behaviour so we need to account for it here. The challenge I'm solving for here is that I need the Curio nodes to be able to talk to each other, for the host to talk to the Curio nodes, and the SP registry to provide a
serviceUrlthat works inside the containers and outside. Unfortunately I don't think there's a clean Docker way to achieve this that works across Linux and macOS so instead I'm going with the default Docker internal host naming ofhost.docker.internaland requiring that the host also know that name for its own localhost. This is a solution I've found various people using online to achieve something like this.foc-devnet will now check that you have that set up before proceeding and tell you how to fix it if it's needed.
Note also we're doing a default of 2 Curio nodes here to simulate the durability requirements that we need to achieve, so this will also be standard going forward.