@@ -415,6 +415,272 @@ address and port, exposing the _protected_ RPC endpoint.
415415
416416---
417417
418+ ## RPC Provider Nodes
419+
420+ RPC provider nodes (relay nodes) serve public JSON-RPC traffic on behalf of the
421+ network. They differ from follow nodes in two key ways:
422+
423+ 1 . ** Direct peering** — they connect to network sentries via devp2p (EL) and
424+ libp2p (CL), rather than using follow-mode HTTP/WebSocket endpoints.
425+ 2 . ** Public exposure** — they expose RPC endpoints to the public internet,
426+ requiring a more restrictive configuration.
427+
428+ This section covers the configuration specific to RPC provider nodes. It assumes
429+ you have completed the initial setup steps from [ Binaries] ( #binaries ) (paths,
430+ directories, snapshots, consensus init). For EL ↔ CL communication options (IPC
431+ vs RPC), see the [ Binaries] ( #binaries ) and [ Separated hosts] ( #separated-hosts )
432+ sections.
433+
434+ ### RPC namespaces
435+
436+ Only the following namespaces may be exposed:
437+
438+ ``` text
439+ eth,net,web3,rpc
440+ ```
441+
442+ All other namespaces ** must not** be enabled. Specifically, the following are
443+ prohibited: ` txpool ` , ` debug ` , ` trace ` , ` admin ` , ` flashbots ` , ` mev ` , ` ots ` .
444+
445+ ``` bash
446+ --http.api eth,net,web3,rpc
447+ --ws.api eth,net,web3,rpc
448+ --public-api
449+ ```
450+
451+ The ` --public-api ` flag enforces these restrictions at runtime: it hides
452+ pending-transaction RPCs and warns at startup if ` --http.api ` or ` --ws.api `
453+ exposes namespaces outside the safe set.
454+
455+ To verify, call ` rpc_modules ` :
456+
457+ ``` bash
458+ curl -s -X POST http://localhost:8545 \
459+ -H " Content-Type: application/json" \
460+ -d ' {"jsonrpc":"2.0","method":"rpc_modules","params":[],"id":1}' | jq .result
461+ ```
462+
463+ Expected output (the ` arc ` namespace is added automatically by ` --enable-arc-rpc ` ):
464+
465+ ``` json
466+ {
467+ "arc" : " 1.0" ,
468+ "net" : " 1.0" ,
469+ "rpc" : " 1.0" ,
470+ "eth" : " 1.0" ,
471+ "web3" : " 1.0"
472+ }
473+ ```
474+
475+ If you see ` txpool ` , ` debug ` , ` trace ` , ` admin ` , or any other unexpected
476+ namespace, the node is misconfigured.
477+
478+ ### Arc RPC extension
479+
480+ The ` --enable-arc-rpc ` flag adds a custom ` arc ` JSON-RPC namespace with two
481+ methods:
482+
483+ - ` arc_getCertificate(height) ` — returns the BFT commit certificate for a given
484+ block height
485+ - ` arc_getVersion() ` — returns build and version information
486+
487+ The EL proxies certificate requests to the co-located CL's REST API, defaulting
488+ to ` http://127.0.0.1:31000 ` . Override with ` --arc-rpc-upstream-url ` or the
489+ ` ARC_RPC_UPSTREAM_URL ` environment variable if the CL listens on a different
490+ address. Your load balancer must allow ` arc_getCertificate ` on the EL's RPC port
491+ (8545).
492+
493+ ` arc_getCertificate ` responses are safe to cache by height at the edge — once a
494+ block is finalized, any valid certificate for that height is valid indefinitely.
495+ The same applies to ` eth_getBlockByNumber ` — finalized block payloads are
496+ immutable and safe to cache by block number.
497+
498+ ### Transaction propagation
499+
500+ Transactions must only be propagated to trusted peers:
501+
502+ ``` bash
503+ --tx-propagation-policy Trusted
504+ ```
505+
506+ ### Peering
507+
508+ Use ` --trusted-peers ` with the enode URLs provided during onboarding:
509+
510+ ``` bash
511+ --trusted-peers < ENODE_URLS>
512+ ```
513+
514+ RPC nodes run as full nodes:
515+
516+ ``` bash
517+ --full
518+ ```
519+
520+ ### Prohibited configuration
521+
522+ Do ** not** use any of the following:
523+
524+ | Flag / Feature | Reason |
525+ | --------------------------------- | ----------------------------------------------------- |
526+ | ` --rpc.forwarder ` | Request forwarding to upstream must not be configured |
527+ | Bundle APIs | Bundle submission endpoints must not be exposed |
528+ | ` --http.api all ` / ` --ws.api all ` | Exposes prohibited namespaces |
529+
530+ ### Firewall and network
531+
532+ | Port | Service | Protocol | Exposure |
533+ | ----- | ----------------------- | --------- | --------------------------------------------------------------------- |
534+ | 8545 | EL HTTP RPC | TCP | ** Public** — serves end users and permissionless nodes |
535+ | 8546 | EL WebSocket RPC | TCP | ** Public** — serves end users and permissionless nodes |
536+ | 30303 | EL P2P (devp2p) | TCP + UDP | ** Public** — allows permissionless nodes to gossip transactions |
537+ | 27000 | CL P2P (libp2p) | TCP | ** Restricted** — allow only IPs of peers provided during onboarding |
538+ | 8551 | EL Engine API (authrpc) | TCP | ** Internal only** — CL-to-EL communication, never expose externally |
539+ | 31000 | CL RPC | TCP | ** Internal only** — required for CL operation, never expose externally|
540+
541+ Key rules:
542+
543+ - RPC ports (8545, 8546) and EL P2P port (30303) are the ** only** ports that
544+ should be open to the public internet.
545+ - CL P2P port (27000) must be reachable by network sentries but ** not** by the
546+ general public. Use IP allowlisting or the ` --p2p.persistent-peers-only ` flag.
547+ - Engine API (8551) and CL RPC (31000) must ** never** be exposed outside the
548+ host. Bind to ` 127.0.0.1 ` if EL and CL are colocated, or use a private
549+ network interface.
550+ - If you enable metrics (` --metrics ` for both EL and CL), restrict the metrics
551+ ports accordingly.
552+ - Deploy a reverse proxy or load balancer in front of ports 8545 and 8546 with
553+ rate limiting, request size limits, and connection throttling. The node itself
554+ does not enforce per-client request limits, so without an external layer,
555+ a single client can saturate the RPC interface.
556+
557+ ### Consensus layer configuration
558+
559+ The CL on an RPC node syncs decided blocks from sentry endpoints rather than
560+ using follow mode:
561+
562+ ``` bash
563+ --p2p.persistent-peers < SENTRY_MULTIADDRS>
564+ ```
565+
566+ Replace ` <SENTRY_MULTIADDRS> ` with the peer multiaddrs provided during onboarding.
567+
568+ To restrict CL P2P to only the configured persistent peers (recommended, since
569+ RPC nodes should only communicate with sentries):
570+
571+ ``` bash
572+ --p2p.persistent-peers-only
573+ ```
574+
575+ The ` --rpc.addr ` flag is ** required** when ` --enable-arc-rpc ` is enabled on the
576+ EL:
577+
578+ ``` bash
579+ --rpc.addr=127.0.0.1:31000
580+ ```
581+
582+ #### Sync-only mode
583+
584+ By default the CL participates in the consensus protocol. To run a node that
585+ only syncs blocks without participating in consensus (recommended for RPC
586+ nodes):
587+
588+ ``` bash
589+ --no-consensus
590+ ```
591+
592+ When set, the node only runs the synchronization protocol and does not subscribe
593+ to consensus-related gossip topics.
594+
595+ ### Complete example
596+
597+ This example uses IPC for EL ↔ CL communication (recommended when colocated).
598+ See [ Separated hosts] ( #separated-hosts ) for the RPC alternative.
599+
600+ ``` bash
601+ # Execution Layer (start first)
602+ arc-node-execution node \
603+ --chain=arc-testnet \
604+ --datadir=$ARC_EXECUTION \
605+ --trusted-peers < ENODE_URLS> \
606+ --full \
607+ --http --http.addr=0.0.0.0 --http.port=8545 \
608+ --http.api eth,net,web3,rpc \
609+ --ws --ws.addr=0.0.0.0 --ws.port=8546 \
610+ --ws.api eth,net,web3,rpc \
611+ --enable-arc-rpc \
612+ --public-api \
613+ --tx-propagation-policy Trusted \
614+ --metrics 127.0.0.1:9001 \
615+ --ipcpath=$ARC_RUN /reth.ipc \
616+ --auth-ipc \
617+ --auth-ipc.path=$ARC_RUN /auth.ipc
618+
619+ # Consensus Layer (start after EL is healthy)
620+ arc-node-consensus start \
621+ --home=$ARC_CONSENSUS \
622+ --p2p.persistent-peers < SENTRY_MULTIADDRS> \
623+ --p2p.persistent-peers-only \
624+ --rpc.addr=127.0.0.1:31000 \
625+ --eth-socket=$ARC_RUN /reth.ipc \
626+ --execution-socket=$ARC_RUN /auth.ipc \
627+ --no-consensus \
628+ --metrics 127.0.0.1:29000
629+ ```
630+
631+ ** Important notes:**
632+
633+ - Start the EL first. The CL connects to the EL on startup, so it will fail if
634+ the EL is not running.
635+ - The ` --rpc.addr ` flag on the CL is ** required** because of the EL
636+ ` --enable-arc-rpc ` flag.
637+ - When using IPC, both processes must have read/write access to the socket
638+ directory. If running in containers, mount the same directory into both.
639+
640+ ### Checklist
641+
642+ ** General:**
643+
644+ - [ ] ` arc-node-consensus init ` has been run
645+ - [ ] ` --http.api ` and ` --ws.api ` set to ` eth,net,web3,rpc ` only
646+ - [ ] Prohibited namespaces (` txpool ` , ` debug ` , ` trace ` , ` admin ` , ` flashbots ` , ` mev ` , ` ots ` ) return "Method not found"
647+ - [ ] ` --enable-arc-rpc ` is set and ` arc_getCertificate ` is accessible on port 8545
648+ - [ ] ` --public-api ` is set on the EL
649+ - [ ] Pending-transaction RPCs are hidden — verify with:
650+ ``` bash
651+ curl -s -X POST http://localhost:8545 \
652+ -H " Content-Type: application/json" \
653+ -d ' {"jsonrpc":"2.0","method":"eth_newPendingTransactionFilter","params":[],"id":1}' \
654+ | jq .error
655+ ```
656+ This should return an error (code ` -32001 ` ), not a filter ID.
657+ - [ ] ` --tx-propagation-policy Trusted ` is set
658+ - [ ] ` --rpc.forwarder ` is ** not** configured
659+ - [ ] No bundle APIs are exposed
660+ - [ ] ` --trusted-peers ` is set to the enode URLs provided during onboarding
661+ - [ ] ` --full ` is set on the EL
662+ - [ ] Ports 8545, 8546 and 30303 are open to the public internet
663+ - [ ] Port 27000 (CL P2P) is restricted to peer IPs provided during onboarding
664+ - [ ] Engine API (8551, if using RPC) and CL RPC (31000) are not externally accessible
665+ - [ ] CL has ` --rpc.addr ` set
666+ - [ ] CL has ` --no-consensus ` set (recommended)
667+
668+ ** If using IPC:**
669+
670+ - [ ] JWT secret is ** not** configured (mutually exclusive with IPC)
671+ - [ ] EL has ` --ipcpath ` , ` --auth-ipc ` , and ` --auth-ipc.path ` set
672+ - [ ] CL has ` --eth-socket ` and ` --execution-socket ` set
673+ - [ ] Both processes can read/write the socket directory
674+
675+ ** If using RPC:**
676+
677+ - [ ] JWT secret file has been generated and is accessible to both EL and CL
678+ - [ ] EL exposes auth RPC via ` --authrpc.addr ` , ` --authrpc.port ` , and ` --authrpc.jwtsecret `
679+ - [ ] CL connects to EL via ` --eth-rpc-endpoint ` , ` --execution-endpoint ` , and ` --execution-jwt `
680+ - [ ] ` --arc-rpc-upstream-url ` points to the CL's RPC address (the default ` http://127.0.0.1:31000 ` only works when colocated)
681+
682+ ---
683+
418684## Operational Guide
419685
420686### System Requirements
0 commit comments