# Patch 1 of 5 — Bug Fix: `ar_http_iface_server.erl` > **Context for this agent**: This is part of a patchset adding optional TLS > to the Arweave p2p network. Nodes gossip TLS public keys (SPKI) via a signed > `GET /peers/keys` endpoint. Peers that learn a SPKI connect over TLS with > SPKI pinning. Fully backwards-compatible — nodes without TLS are unaffected. > Ask anything: "why did they do X?", "would approach Y work?", "explain Z differently." ## What This Patch Does Pre-existing runtime crash, independent of the TLS gossip feature. Commit `b07b1d8` converted `TransportOpts` from a proplist to a map, but left the TLS listener path using `++` (list-append) on it. Maps don't support `++`, so starting the node with TLS configured would crash at runtime. The fix moves `certfile` and `keyfile` into `socket_opts` inside the map — the correct ranch/cowboy API for map-style transport options. ## Why It's in This PR It's a real bug that affects anyone using the existing `tls_cert_file` / `tls_key_file` config today (from PR #505, 2023). Since this PR adds TLS connectivity, leaving a crash in the TLS listener path would be confusing. The PR description calls it out explicitly with the offending commit hash. ## Norm-Check: `cowboy:start_tls` call shape After b07b1d8, `TransportOpts` is a map. `start_clear` and `start_tls` both accept map-style opts. Per ranch docs, TLS-specific socket options (cert, key) go in the `socket_opts` key inside the map, not appended with `++`. ```erlang %% BEFORE (crashes — can't ++ a map) cowboy:start_tls(ar_http_iface_listener, TransportOpts ++ [ {certfile, TlsCertfilePath}, {keyfile, TlsKeyfilePath} ], ProtocolOpts) %% AFTER (correct map form) cowboy:start_tls(ar_http_iface_listener, TransportOpts#{socket_opts => [ {port, Config#config.port}, {certfile, TlsCertfilePath}, {keyfile, TlsKeyfilePath} ]}, ProtocolOpts) ``` ## Project File Listings ``` apps/arweave/src/ (~130 .erl files, prefix ar_*) ar_cli_parser.erl ar_http.erl ar_http_iface_client.erl ar_http_iface_middleware.erl ar_http_iface_server.erl ar_peers.erl ar_sup.erl ar_tls.erl <- NEW ar_util.erl ar_wallet.erl apps/arweave/test/ (~50 _tests.erl files) ar_config_tests.erl ar_http_iface_tests.erl ar_http_util_tests.erl ar_semaphore_tests.erl ar_tls_tests.erl <- NEW ar_wallet_tests.erl apps/arweave_config/include/ arweave_config.hrl <- modified arweave_config_spec.hrl ``` ## The Patch ```diff %% BUG FIX (standalone): apps/arweave/src/ar_http_iface_server.erl %% %% Pre-existing crash: commit b07b1d8 converted TransportOpts to a map but left %% the TLS listener path using old proplist `++` syntax, which crashes at runtime. %% Fix moves cert/key into socket_opts inside the map, per ranch docs. %% %% This change is fully independent of the TLS gossip feature and can be %% reviewed, understood, and applied on its own. diff --git a/apps/arweave/src/ar_http_iface_server.erl b/apps/arweave/src/ar_http_iface_server.erl index 7a6c78c..74f8c16 100644 --- a/apps/arweave/src/ar_http_iface_server.erl +++ b/apps/arweave/src/ar_http_iface_server.erl @@ -128,10 +128,16 @@ start_http_iface_listener(Config) -> not_set -> cowboy:start_clear(ar_http_iface_listener, TransportOpts, ProtocolOpts); _ -> - cowboy:start_tls(ar_http_iface_listener, TransportOpts ++ [ - {certfile, TlsCertfilePath}, - {keyfile, TlsKeyfilePath} - ], ProtocolOpts) + %% Fix: b07b1d8 converted TransportOpts to a map but left the TLS + %% path using the old proplist ++ style, which crashes at runtime. + %% Cert/key go into socket_opts alongside the port, per ranch docs. + cowboy:start_tls(ar_http_iface_listener, + TransportOpts#{socket_opts => [ + {port, Config#config.port}, + {certfile, TlsCertfilePath}, + {keyfile, TlsKeyfilePath} + ]}, + ProtocolOpts) end. name_route([]) -> ```