Skip to content

network: onion & socks5 support for fiber#1228

Merged
quake merged 24 commits intonervosnetwork:developfrom
Officeyutong:tor-and-proxy-support
Apr 10, 2026
Merged

network: onion & socks5 support for fiber#1228
quake merged 24 commits intonervosnetwork:developfrom
Officeyutong:tor-and-proxy-support

Conversation

@Officeyutong
Copy link
Copy Markdown
Collaborator

@Officeyutong Officeyutong commented Mar 23, 2026

This PR adds onion & socks5 proxy support for fiber, basically based on nervosnetwork/ckb#4733
This enables Fiber nodes to:

  • Route all outbound P2P connections through a SOCKS5 proxy (e.g. Tor)
  • Connect to .onion addresses via a dedicated Tor SOCKS5 proxy
  • Host a Tor onion hidden service, making the node reachable via a .onion address

@Officeyutong Officeyutong marked this pull request as ready for review March 25, 2026 12:06
@Officeyutong Officeyutong requested review from jjyr and quake and removed request for quake March 25, 2026 12:06
@gpBlockchain
Copy link
Copy Markdown
Contributor

lgtm

Copy link
Copy Markdown
Contributor

Copilot AI left a 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 introduces SOCKS5 proxy support (including Tor) and optional Tor v3 onion hidden-service hosting for Fiber’s P2P layer, extending fiber-lib networking/config to support proxying outbound connections and advertising an onion multiaddr.

Changes:

  • Add proxy URL validation and wire SOCKS5 proxy configuration into Tentacle ServiceBuilder.
  • Add Tor controller integration to create/maintain a v3 onion hidden service and announce its /onion3/.../p2p/... address.
  • Extend Fiber config and example config files with proxy and onion sections; add new deps (torut, url, base64).

Reviewed changes

Copilot reviewed 9 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
crates/fiber-lib/src/fiber/proxy.rs Adds SOCKS5 proxy URL validation helper + unit tests.
crates/fiber-lib/src/fiber/onion_service.rs Implements Tor control-port client + onion v3 hidden-service lifecycle.
crates/fiber-lib/src/fiber/network.rs Wires proxy + onion config into network startup, announces onion addr, cancels service on shutdown.
crates/fiber-lib/src/fiber/mod.rs Exposes new proxy/onion_service modules (non-wasm).
crates/fiber-lib/src/fiber/config.rs Adds ProxyConfig + OnionConfig to FiberConfig.
crates/fiber-lib/Cargo.toml Adds base64, torut, url deps for non-wasm builds.
config/testnet/config.yml Documents new proxy/onion config sections (commented examples).
config/mainnet/config.yml Documents new proxy/onion config sections (commented examples).
Cargo.lock Locks new transitive dependencies (torut/base64/url/etc.).
.gitignore Adds /test-config ignore entry.
.github/workflows/openrpc.yml Changes generator workflow to run without --locked.

Comment thread crates/fiber-lib/src/fiber/network.rs Outdated
Comment thread crates/fiber-lib/src/fiber/network.rs Outdated
Comment thread crates/fiber-lib/src/fiber/config.rs Outdated
Comment thread crates/fiber-lib/src/fiber/network.rs
Comment thread .github/workflows/openrpc.yml Outdated
Comment thread crates/fiber-lib/src/fiber/network.rs
Comment thread crates/fiber-lib/src/fiber/network.rs Outdated
Comment thread crates/fiber-lib/src/fiber/network.rs Outdated
Comment thread crates/fiber-lib/src/fiber/onion_service.rs
@Officeyutong Officeyutong force-pushed the tor-and-proxy-support branch from ec25e5f to 411581e Compare March 25, 2026 17:46
Comment thread crates/fiber-lib/src/fiber/network.rs Outdated
Comment thread crates/fiber-lib/src/fiber/network.rs Outdated
Comment thread crates/fiber-lib/src/fiber/network.rs
@Officeyutong Officeyutong requested a review from chenyukang April 2, 2026 05:54
Comment thread config/mainnet/config.yml Outdated
# ## Tor controller hashed password (if HashedControlPassword is set in torrc).
# tor_password: ""
# ## The external port exposed by the onion service. [default: 8115]
# onion_external_port: 8115
Copy link
Copy Markdown
Contributor

@eval-exec eval-exec Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CKB's onion_external_port choose 8115, because ckb's default p2p port number is 8115.
What's fiber's default p2p port number?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's 8228. Fixed now

Comment thread crates/fiber-lib/src/fiber/onion_service.rs Outdated
info!("Tor reconnected, notifying network to reconnect peers");
let _ = reconnect_notify.send(());
}
first_start = false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest move first_start = false to bellow the entier match pattern.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@Officeyutong Officeyutong requested a review from eval-exec April 7, 2026 06:06
Comment thread .gitignore Outdated
baseline.json
current.json
comparison_report.txt
/test-config
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated change?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used this folder to contain config files that enables tor on my local development environment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use local exclude info:

echo test-config>> .git/info/exclude

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now

/// SOCKS5 proxy configuration
#[arg(skip)]
#[serde(default)]
pub proxy: ProxyConfig,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest to add a none wasm cfg condition for these two options

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #[cfg(not(target_arch = "wasm32"))] for these two config section

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can move

ProxyConfig -> proxy.rs
OnionConfig -> onion_service.rs

The two config structure will be gated with the two modules.

});

// Wait for the onion service to successfully register with Tor before
// returning the address, so callers don't advertise an unreachable address.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to add a timeout for waiting?
a Tor instance that is reachable on the control port but never reaches Done can prevent the whole node from starting now.
waiting with timeout error should report with proper error and exit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now

}
Err(err) => {
error!("Failed to start onion service: {}", err);
if let Some(tx) = ready_tx.take() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to retry for the first time error? since I see there is a variable first_start here, but we will return without retry for the first time.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now

Comment thread crates/fiber-lib/src/fiber/network.rs
/// SOCKS5 proxy configuration
#[arg(skip)]
#[serde(default)]
pub proxy: ProxyConfig,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can move

ProxyConfig -> proxy.rs
OnionConfig -> onion_service.rs

The two config structure will be gated with the two modules.

@Officeyutong Officeyutong requested review from chenyukang and jjyr April 9, 2026 11:48
@quake quake merged commit 4934acc into nervosnetwork:develop Apr 10, 2026
39 checks passed
quake added a commit that referenced this pull request Apr 15, 2026
* fix: push limit to DB layer in list_payments to avoid unbounded memory usage (#1261)

* fix: push limit to DB layer in list_payments to avoid unbounded memory usage

get_payment_sessions_with_limit previously called collect_by_prefix
without a limit, loading ALL payment session KV pairs into memory
before applying .filter_map().take(limit) as iterator adapters.

Add PrefixIterator::new_from() for cursor-based lazy iteration, and
prefix_iter/prefix_iter_from helpers to FiberStore trait. Rewrite
get_payment_sessions_with_limit as a simple iterator chain using the
lazy batched PrefixIterator, which fetches only 100 entries at a time
and stops as soon as enough results are collected.

* Update crates/fiber-store/src/iterator.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat: update macOS build configuration for portability (#1237)

* feat: update macOS build configuration for portability

* refactor: simplify macOS build steps by removing Homebrew setup

* renaming for keep portable

* feat: add official Docker image support (#1244)

* feat: add official Docker image support

* ci: publish docker images to ghcr and docker hub

* fix docker image readme

* Bump fiber-rpc-gen to 0.1.22 (#1264)

* network: onion & socks5 support for fiber (#1228)

* onion & socks5 support for fiber

* make CI happy

* Add default configuration

* fix tor service

* use nested structure for onion and proxy config

* send MaintainConnections message to NetworkActor when tor is reconnected

* make fmt happy

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix some issues pointed out by copilot

* fix openroc-json-generator

* update ckb-testtool

* update cargo.lock

* merge newest changes

* fix a race condition in onion service start

* make fmt happy

* Update crates/fiber-lib/src/fiber/onion_service.rs

Co-authored-by: Eval Exec <execvy@gmail.com>

* Change default onion external port

* update

* update .gitignore

* isolate wasm configuration related to proxy and tor

* add timeout check for start_onion_service & retry in `OnionService::start`

* Added 3-second delay before sending MaintainConnections

* move `proxy` and `onion` related configurations to their individual modules

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Eval Exec <execvy@gmail.com>

* Fix fnn-migrate error messages and update README (#1249)

* Initial plan

* fix: update fnn-migrate flag from -p to -d in error message and README

Agent-Logs-Url: https://github.com/gpBlockchain/fiber/sessions/a6b4f2a5-59de-4e8b-a07f-a3ffb49b7a48

Co-authored-by: gpBlockchain <32102187+gpBlockchain@users.noreply.github.com>

* fix: show fiber data directory (without /store) in fnn-migrate error message

Agent-Logs-Url: https://github.com/gpBlockchain/fiber/sessions/0de95c55-8af8-4a5c-b2f7-98b4c62c35b2

Co-authored-by: gpBlockchain <32102187+gpBlockchain@users.noreply.github.com>

* Apply suggestion from @gpBlockchain

* Apply suggestion from @gpBlockchain

* Apply suggestion from @gpBlockchain

* Update crates/fiber-store/src/db_migrate.rs

Co-authored-by: gpBlockchain <32102187+gpBlockchain@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Quake Wang <quake.wang@gmail.com>

* chore(deps): bump tokio from 1.50.0 to 1.51.1

Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.50.0 to 1.51.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](tokio-rs/tokio@tokio-1.50.0...tokio-1.51.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.51.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* docs: refresh public node and network node documentation (#1266)

* rename testnet-nodes.md and add network-nodes.md

* docs: update README network node links

* docs: refine pubkey-based node docs

* docs: clarify node2 rpc discovery in public nodes guide

* fix: abort funding on insufficient UDT cells (#1195) (#1253)

When UDT cells are not yet indexed, the funding transaction builder
would fail with a generic TxBuilderError that was silently swallowed
(empty tx logged and ignored). This left UDT channels permanently
stuck in the negotiating state.

- Add FundingError::InsufficientCells variant that is non-temporary,
  so schedule_funding_retry aborts the channel instead of retrying
- Reclassify AbsentTx as temporary so empty funding results get
  retried via the existing backoff mechanism
- Extract map_tx_builder_error to convert the sentinel UDT message
  into InsufficientCells before it reaches the retry logic
- Move FundingError tests to dedicated tests/error.rs module and add
  coverage for the new error mapping and classification

Co-authored-by: ian <ian@cryptape.com>

* feat: add gossip metrics benchmarks and CI integration (#1177)

* feat: add gossip metrics benchmarks and CI integration

- add gossip protocol metrics counters/histograms and active-sync/query observability

- add criterion gossip benchmarks for multi-node propagation and sync-recovery

- add tests/perf gossip benchmark flows driven by metrics (steady/burst + baseline/compare)

- integrate benchmark CI with metrics-enabled startup and bootstrap gossip regression gating

* fix: stabilize gossip benchmark runs and move gossip perf to dedicated workflow

* chore: ignore generated gossip perf benchmark artifacts

* fix: tighten gossip duplicate/rejected metrics and perf timing

* ci: move perf benchmark artifacts under tests/perf/artifacts

* refactor: move gossip metrics helpers into dedicated modules

* chore(deps): bump rand from 0.8.5 to 0.9.3 in /tests/deploy/udt-init

Bumps [rand](https://github.com/rust-random/rand) from 0.8.5 to 0.9.3.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/0.9.3/CHANGELOG.md)
- [Commits](rust-random/rand@0.8.5...0.9.3)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Trigger gossip sync immediately on peer connection (#1271)

* Trigger gossip sync immediately on peer connection

Send TickNetworkMaintenance to self when a new peer connects, eliminating
the initial 0-60s wait before gossip data sync begins. This is critical
for WASM nodes that need peer address data from gossip shortly after
connecting to a bootnode.

Fixes: #1269

* Fix gossip tick race: gate on control.is_some(), defer from ReceivedControl

Agent-Logs-Url: https://github.com/nervosnetwork/fiber/sessions/5c445ccc-f1ef-4a6d-96aa-4254471fffb9

Co-authored-by: quake <8990+quake@users.noreply.github.com>

* Add regression test for immediate gossip sync on peer connect

Agent-Logs-Url: https://github.com/nervosnetwork/fiber/sessions/42d6ab86-ae76-47da-8ccd-b535b89f7be1

Co-authored-by: quake <8990+quake@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: quake <8990+quake@users.noreply.github.com>

* feat: add addr_type parameter to connect_peer RPC for transport type filtering (#1270)

* feat: add addr_type parameter to connect_peer RPC for transport type filtering

When connect_peer is called with only a pubkey, the node randomly selects
an address from the peer's known addresses. In WASM environments, this may
select a non-WSS address that is unsupported. Add an optional addr_type
parameter (tcp/ws/wss) to allow callers to filter addresses by transport
type before random selection.

* refactor: decouple actor protocol from JSON types and improve error messages

- Introduce MultiAddrTransport enum in fiber-types as the internal
  transport filter type, keeping fiber-json-types::MultiAddrType as the
  RPC-facing type only
- Add From<MultiAddrType> for MultiAddrTransport conversion in
  fiber-json-types convert.rs (behind conversion feature)
- Update NetworkActorCommand::ConnectPeerWithPubkey to use
  MultiAddrTransport instead of fiber_json_types::MultiAddrType
- Convert at the RPC boundary in rpc/peer.rs via .map(Into::into)
- Add NoMatchingAddress(Pubkey, MultiAddrTransport) error variant to
  distinguish 'peer not found' from 'peer has no addresses matching
  the requested transport type'
- Rename matches_addr_type -> matches_addr_transport for clarity

* refactor: use tentacle::utils::TransportType and rename MultiAddrType

Per review: reuse the existing tentacle::utils::TransportType instead
of introducing a custom MultiAddrTransport in fiber-types.

- Remove MultiAddrTransport enum and Display impl from fiber-types
- Remove From<MultiAddrType> conversion from fiber-json-types/convert.rs
- Rename MultiAddrType -> TransportType in fiber-json-types/peer.rs
- Update NetworkActorCommand::ConnectPeerWithPubkey to use
  tentacle::utils::TransportType directly
- Remove cfg(not(wasm32)) gate from TransportType import and find_type()
  (both are available on all targets in tentacle)
- Replace matches_addr_transport() with find_type() == transport
- Add to_transport_type() conversion in rpc/peer.rs at the RPC boundary
- Update NoMatchingAddress error to use tentacle::utils::TransportType
- Update TypeScript types and regenerate RPC docs

* fix: allow DNS-based WSS addresses to pass the private address filter

The private address filter used multiaddr_to_socketaddr() which only
handles Ip4/Ip6 protocols, silently dropping DNS-based addresses like
/dns4/example.com/tcp/443/wss. This prevented WSS addresses from being
broadcast in node announcements.

Add is_addr_reachable() helper that treats Dns4/Dns6 addresses as
always reachable (since DNS implies a public endpoint), while preserving
the existing IP-based reachability check. Applied at all three filter
locations: announcement creation, graph ingestion, and gossip processing.

* feat(cch): default final TLC expiry deltas to 60 hours (#1258)

* feat(cch): default final TLC expiry deltas to 60 hours

Raise DEFAULT_BTC_FINAL_TLC_EXPIRY_DELTA_BLOCKS to 360 (~10 min/block)
and DEFAULT_CKB_FINAL_TLC_EXPIRY_DELTA_SECONDS to 216,000. Update CCH
actor tests that assumed the previous 30h defaults.

Made-with: Cursor

* test(cch): replace expiry magic numbers with named constants

Use BTC_BLOCK_TIME_SECS, DEFAULT_BTC_FINAL_TLC_EXPIRY_DELTA_BLOCKS,
DEFAULT_CKB_FINAL_TLC_EXPIRY_DELTA_SECONDS, and per-test scenario consts
in CCH actor tests.

Made-with: Cursor

---------

Co-authored-by: ian <ian@cryptape.com>

* Local RPC method not found should not return unauthorized (#1235)

* chore: bump version to v0.8.1 (#1274)

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Yukang <moorekang@gmail.com>
Co-authored-by: Officeyutong <yt.xyxx@gmail.com>
Co-authored-by: Eval Exec <execvy@gmail.com>
Co-authored-by: gpBlockchain <32102187+gpBlockchain@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: sunchengzhu <36075573+sunchengzhu@users.noreply.github.com>
Co-authored-by: ian <me@iany.me>
Co-authored-by: ian <ian@cryptape.com>
Co-authored-by: swananan <jt26wzz@gmail.com>
Co-authored-by: quake <8990+quake@users.noreply.github.com>
Co-authored-by: jjy <jjyruby@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants