Rough Ideas for Paid CJDNS Access

This is a work-in-progress idea for making paid CJDNS access practical. My goal is still to promote free, ubiquitous Hyperboria access with paid gateways to the clearnet, and I don’t invest any kind of faith or dependency in making automatic for-pay peering work within the next five years. However, what I’m proposing actually works at my level of the software stack as well, and will hopefully be useful long before anyone integrates it into CJDNS.

It fundamentally comes down to speed tests and price signalling. Since the former is more universally applicable, including my business model, I’ll tackle that part first before moving on to the more thoughtful, free-market-y part.

Speed Tests

Who is the producer, and who is the consumer?

The way that current ISPs price their plans, leads us to think that what you’re paying for is megabytes, or at least megabytes per second. This is a bit challenged by a simple example in mesh networking.

Two nodes discover each other through autopeering. One wants to mostly transmit information and recieve a little. The other wants to mostly receive information, and transmit a little. Which is the customer?

Rather than let you puzzle on this, I’m going to just go ahead and spoil the answer for you. It’s a trick question. But without it as a parable, it’s not obviously a trick question. The real answer is that we don’t have the relevant data to make that determination - which begs the further question, what data do we need to answer this? Or less contextually…

What are you really paying for, when you pay for internet?

I’ll spoil this one too. You’re not paying for megabytes. You’re paying for access and speed - you’re paying for routes.

This is not only retrospectively obvious, it also helps us visualize a proper cost model. When you’re choosing among one or more paid peers (where “none of these are worth the money” is always an implicit option), you need to be able to figure out how good a deal something is, and now we have something to weigh against the cost. Except, you still need some way to determine route quality…

Determining route quality - without free trials

First, a note on the idea of free trials. It works for some industries, it’s bullshit for others. If you can meet your needs with free samples, and there’s nothing stopping you from going from one cart to another snarfing stuff down until the security guards show up, why would you ever pay? So if we can solve the problem without free samples opening us up to mooching, so much the better, and luckily we can.

At a high level, route quality is a pretty simple matter. You have speed test services that follow a known standard, like ping for bandwidth testing, that includes a mutual signing of the results at the end of the test (including the timestamps on each end). You can then hand that over to potential peers to show off your connection speed. Because of the cryptographic properties of CJDNS being tied to IP address, you have an assurance that the node you are talking to is the one that achieved the speeds listed in the signed report.

On the client end, you can take in the reports for each of your potential peers, ask for additional reports to be made if you don’t trust any of the speedtest servers that those peers are using (or if you consider the existing reports to be too out of date), and make an algorithmic judgement call based on the price and route quality of each option.

Choosing the best route

There are two ways I can think of that seem like nicely configurable ways to choose the ideal route. So I’ll bring up three. You’ll understand it when you get there.


A fairly comprehensible way to handle this is to store routes in an SQLite database as they’re discovered, and use an SQL query as your configuration for determining which route to choose.

FROM routes SELECT id WHERE 2.50 > chunksize_USD LIMIT 1 ORDER BY latency ASC

Python or Lua script

Pick some de-facto language to embed and use in your route acquisition daemon.

def choose_route(available):

Defer to an external executable

This smoothly encompasses both the above approaches, and more, with a loosely-coupled interface for choosing a route. Any binary or script that fits that TBD interface can fulfill that purpose, by any means the authors feel like.

Making payments

My intention is to make it easy for each selling node to host a Niknak API server. The speed reports can be a standardized part of the description of the item, which also has a standardized name or SKU. A connecting node can quickly and anonymously scan for route sellers among its direct peers, and buy time or bandwidth via Bitcoin.

This is already the sales model we’re using for CVIs, albeit in a less-automated sort of way. It can be tested and hardened for months or years before being hooked into CJDNS’s RPC mechanisms.

Isn’t this complicated? (Actual complaint by cjd in IRC, and a fair one)

Yes. This kind of thing is inherently complicated. It’s naively optimistic to think that you can have some sort of automated mesh ISP payment system, and not have to worry about complication. There’s a limit to how simple you can make something like this.

What’s important regarding complication, here, is not the total complication, but where the complication lies. Instead of putting that complication in CJDNS, for example, we move it all externally to systems designed for internet transactions, which then hook into CJDNS with a stable API, and can be used for other hooks as well. In the case of CVI gateways, we’d be using those hooks to control gateway access. In CJDNS, you’d be using it to control a DPRW - Direct Peer Routing Whitelist.

Offline Bitcoin Transactions

While more exotic solutions such as gift card codes may be accepted in the future, the natural choice for such a payment system is Bitcoin. At first it seems like a dealbreaker, trying to use Bitcoin before you have internet access - a chicken and egg problem, if you will - but as long as you already have the software installed, and money in a local wallet, Bitcoin is perfectly capable of working for this sort of thing.

  1. Create and load a wallet beforehand (this guide is somewhat applicable)
  2. When you need to make a paid peer later, the daemon will find the best available deal per your config criteria
  3. A popup will display on your computer, with the details of the transaction.
  4. You create a signed transaction in your Bitcoin software of choice, according to those details.
  5. The last bit of info in the popup includes instructions for sending the transaction. Follow those instructions.
  6. Your deal is confirmed by the NikNak server, and the bitcoin transaction is broadcast. The provider has no motivation NOT to send the transaction, that’s analogous to not depositing a check.
  7. You’re added to that node’s DPRW, which allows you to access the greater Hyperboria network.

At some point, the transactional steps could be automated, especially for small chunk sizes (see below).

Security tip: If a paid peer claims that it needs another transaction and doesn’t give you internet service, it’s probably a scam. But the good news is that the transaction data includes the timecode, so you can send them as many copies of the transaction as you want, and they can only enact it once.

Chunk size

Service is sold in increments arbitrarily called “chunks.” How much a chunk is worth varies by plan and provider. Chunk size is the payment granularity. So if a service product on a NikNak server is priced at 0.001 BTC for 20 minutes of service, that is a chunk size of 0.001 BTC. For simplicity, we make no effort to refund unused service - if you only use the internet for 10 minutes, that’s still 0.001 BTC. However, on non-skeevy servers, your credit will still be preserved for unused time or data. Useless if you’re just passing through and the node isn’t part of a larger provider network, but not a bad deal for stable arrangements.

This is why chunk size is an important factor in deciding which route to use. You should never go for a plan with a large chunk size until you trust that provider to not run away cackling with your money. You can probably afford to lose 30 cents. You probably can’t afford to lose 30 dollars.

Service loops

This brings us back to the problem of “who is the customer, who is the provider.” Let’s say Alice’s node is solely connected to Bob’s node, and Bob is connected to Charlie, who is part of the larger network, with multiple connections. Essentially, a penninsula where Alice is buying internet from Bob and Bob is buying internet from Charlie.

Alice decides to screw around with the local network, just for kicks. She runs a few speed tests with popular speed test servers, building up a decent portfolio with her route through Bob. Then she sets up her NikNak server and so on, advertising a connection that is crummier quality than Bob’s connection through Charlie, but much, much cheaper. Bob’s daemon sees this, falls for the honeypot of sweet deals, and stops getting internet through Charlie, trying to get it through Alice instead. The two of them are no longer a penninsula, they become an isolated island with no connection to the outside world.

This would automatically fix itself pretty quickly

First of all, this wouldn’t last forever. While Charlie can keep refreshing his speed test reports, Alice can’t, and eventually they will be older than Bob considers valid. He will switch back to Charlie. His software may also give Alice’s IP a bad mark in some local or distributed database, preventing the same problem from happening again.

With sufficiently smart software, it’s preventable in the first place

You can prevent this kind of abuse, to some degree, by doing an analysis of the routing table to see if it’s plausible to get internet through a given source. While this still certainly isn’t foolproof - the most unflinching example is the node that’s perfectly capable of routing to the rest of the world, but decides not to even after taking people’s money - it would cut out some abuse, including our penninsula example.

The rest is dependent on developing a shaming system to report bad actors in the paid internet biz - something that businesses generally need to be accountable in general anyways.


In general, loops will be prevented as long as each node sells at profit or break-even prices. Price will ripple outwards and upwards from cheap, competing high-bandwidth mainlines. Things can still be temporarily screwed up by someone intentionally operating at a loss, like Alice in the above example, but such an interruption would only be temporary, and the software stack would be continuously improved to predict and avoid such problems.

Price will also slowly trend down with competition towards some low equillibrium, in many cases simply becoming free. Competition becomes more limited by geography than price, so it only takes one enterprising neighbor to pressure everybody’s prices down. This is what slowly cuts into margins and normalizes prices toward zero, although by that time, the provider’s hardware costs will likely have been fully subsidized.


We can pioneer the technology with the software stack I’m already in the process of building, harden it in RI and similar gateway businesses, and then eventually use it at the CJDNS level with minimal added complexity to CJDNS.