All articles

Knock, knock. Kaspa nodes behind home routers learn to answer the door

A small house-shaped home router with two antennas and its red front door swinging open, beside the headline Knock, knock.
Illustration by kaspa.news, AI-generated.

Most Kaspa nodes running at home can call out to the network but can't take a call. Ori Newman wants to change that. He has opened a large change to Rusty Kaspa, the main Kaspa node software, that lets two of these home nodes connect straight to each other, with a public node only helping them find the way in (PR #1165). Michael Sutton's verdict was short. "This is strategic stuff" (reply).

The change also carries a story about credit. It builds on more than a year of work by Luke Dunshea, a Kaspa community member who built his first working version with AI coding tools and kept testing it until this summer. coderofstuff, one of the Rusty Kaspa developers, says Luke deserves to be named as a co-author.

The change is not merged and is not in any release yet. Its automated tests pass, and node runners can only try it by building it from source.

Ori Newman on Telegram

A phone that can call out but can't take calls

Every node needs other nodes to talk to. It downloads new blocks from them and passes on what it receives. A node can connect in two directions. It can dial out to another node, or another node can dial in to it.

Nodes at home usually manage only the first. Your home router gives every device in the house a private address that only makes sense inside the house. To the outside world, the whole household shares the router's one public address. The router also blocks any connection that someone outside tries to start, which is a good thing for your laptop and your smart fridge. For a Kaspa node it means other nodes can't reach it unless its owner opens a port on the router by hand, and most people never do.

Luke explained it with a phone. "A private node today is like a phone that can make calls but cannot receive them" (post). Two such phones can't call each other at all. So private nodes all lean on the smaller group of public nodes, the ones that can accept incoming connections, and those public nodes carry a big share of the network's traffic.

Sutton described the goal when he first raised the idea. He wanted a stronger network "w/o requiring all nodes to be public (something that some node operators/setups will never obtain/want)" (proposal). Some routers simply won't open a port. Some internet providers put whole neighbourhoods behind one shared address. And some people don't want to change their router settings at all.

How the door gets opened

The trick is called hole punching. Routers block connections that start outside, but they let replies in. If your node sends a packet to another node, your router expects an answer from that node and lets it through. Now imagine both nodes send each other a packet at the same moment. Each router sees an outgoing packet and then a reply, so both let the traffic in. Neither owner had to touch anything.

The hard part is timing. Both nodes have to know each other's public address and fire at the same moment. That needs a middleman, and in Ori's design the middleman is any public Kaspa node that offers to act as a relay.

Here is how two home nodes, call them A and B, would connect.

First, both connect to the network as they do today, by dialling out to public nodes. Along the way they learn which public nodes are willing to act as relays.

Second, B books a spot with one of those relays, called its home relay. B then tells the network where it can be reached through that relay, and the address spreads to other nodes like any other node address.

Third, A tries to reach B the normal way. If that fails, A asks B's home relay to put them in touch. The relay opens a short line between them that lasts at most 10 seconds and carries at most 1 MiB of data, enough to swap addresses and agree on timing.

Finally, A and B send packets to each other at the same moment. If both routers let the traffic through, A and B now have a direct connection. Only then do they start the normal Kaspa handshake and begin swapping blocks and transactions.

The relay never carries blocks or transactions. If the direct connection can't be made, the attempt simply fails, and the node goes on using its normal connections. Kaspa messages never fall back to travelling through the relay (how it works).

All of this happens on its own. There is no setting to switch on, no address to copy and no relay to pick. The node runs it alongside its normal connections from the moment it starts.

The building blocks come from libp2p, a widely used set of networking tools for peer-to-peer software. Ori's code uses its relay and hole-punching parts and connects them to the protocol Kaspa nodes already use to talk to each other.

More than a year in the making

Sutton put out the original call in October 2025. He had found that hole punching existed, tried a quick version himself, and saw that it was harder than it looked. He asked for a volunteer and called the task high priority. He also gave a number that made it worth the effort. Hole punching "does not work in all network setups, but even the reported 60% success rate will be a tremendous boost for kaspa, reducing the load from public nodes" (proposal).

Michael Sutton on Telegram

IzioDev volunteered first. Less than three weeks later, Luke posted for the first time in the R&D chat. "Long time lurker, first time poster," he wrote. He was open about how he had done it. "I cannot code in Rust (but i'm learning) but i have become pretty good at codegen, so i assembled a team of devs (Claude Code, Codex, Gemini lol) and we banged this out." His version already got two private nodes to complete the Kaspa handshake and talk directly (post). Sutton called it "a special skill, to get llms to work for you at this level."

What followed was months of slow, careful work. Luke rebuilt his test lab on a home server with two routers set up to behave like typical home routers (update), rewrote the code into a cleaner version, and worked through the design with IzioDev, who drew diagrams of how the pieces should fit together. By August this year it worked automatically on a development network, and Luke asked for volunteers to run it on mainnet (call for testers). He explained the whole idea to non-technical readers on X in a long post he called "NAT 101", and ended it with a line about who started it. "Michael started this initiative, and I'm just trying to contribute in whatever ways I can."

This month, Ori opened his version. "Inspired by @elldeeone's implementation, I tried to minimize changes to the codebase. I also used UDP hole punching because it's considered more reliable and doesn't require special support from NATs" (announcement). That is the main technical difference. Luke's version punched holes for TCP, the kind of connection Kaspa nodes use today. Ori's version uses UDP and the QUIC protocol built on top of it, an option Maxim Biriukov had raised on the first day of the discussion (reply).

Two days later, coderofstuff made the case for Luke.

coderofstuff on Telegram

He pointed out that Luke had gone through several versions and asked the community to test them, and that the development network for DAGKnight, a planned upgrade to how Kaspa orders blocks, has been running Luke's code "since early this year." As opened, the PR's commits carry only Ori's name. coderofstuff said he was unsure how much Ori's code shares with Luke's, but wanted Luke's work recognised "as a form of coauthorship to this PR if this is what's merged."

Limits built in

Letting home nodes accept connections opens a new door, so the change comes with limits on how wide it opens.

A node can fill at most half of its outgoing connections through hole punching. With the default of eight, that is four. The rest are left for normal connections, which the node spreads across different parts of the internet on purpose. Sutton raised this in his first proposal. No single public node should end up forming too large a share of any node's connections, because a node surrounded by one party's machines could be fed a false picture of the network, an attack known as an eclipse attack (proposal notes).

Incoming hole-punched connections are capped at 16 by default. A node runner can lower that number or set it to zero to refuse them completely. Each relay accepts at most 256 bookings and 256 open lines at once, and no more than four of each from any single node. A node also creates a fresh network identity every time it starts and keeps its key only in memory.

What node runners should know

Nothing changes yet. The code is still waiting for review and is not part of a release, and nobody has given a date for one. It also won't work everywhere. Hole punching depends on the routers and internet providers on both sides, and some of them will block it whatever the node does.

When it does ship, nodes will use a second port for this traffic, port 16112 on mainnet next to the usual 16111. A home node needs no changes to its router. Someone who wants their public node to serve as a relay will need to allow UDP traffic on that port. IzioDev, who is testing it, found one more catch. Nodes running behind a reverse proxy may need QUIC switched on in the proxy settings (tip).

When IzioDev offered to run live tests, Ori said yes and went back to fix a few failing tests first. Two days later he reported back to IzioDev with one word. "Fixed" (reply).

More Kaspa Articles

All articles