gemini-capsule

My gemini capsule
git clone git://jb55.com/gemini-capsule
Log | Files | Refs

2021-11-06-airgapped-bitcoin-node-nncp.gmi (6293B)


      1 # Building an airgapped bitcoin node with NNCP
      2 
      3 I have been playing with NNCP recently, it's a modern take on UUCP, which stands for Unix-to-Unix copy. UUCP was used before the internet for syncing mail between machines. You would use your phone line and modem to literally dial another machine, sync mail and perform commands, and then hang up.
      4 
      5 => http://www.nncpgo.org NNCP
      6 
      7 UUCP made sense in a world where things weren't always connected and online. There are still situations where you might not want to be always online. The internet is a distracting place, more and more people are finding the urge to disconnect.  Connectivity isn't always the best in remote places of the world. Bandwidth might be poor, especially with satellite or radio links.
      8 
      9 What if we designed our protocols to be delay and low-bandwidth tolerant? What if you could fire and forget instant messages, emails, bitcoin transactions, etc, while you are offline?
     10 
     11 NNCP makes all of this easy! You can pipe data into it, the data gets saved into a local queue, ready to be synced with other nodes. Here are some of the use cases listed on the NNCP website:
     12 
     13 * Occasional connection to mail server
     14 * Lightweight fast POP3/IMAP4 replacement
     15 * Unreliable/expensive communication link
     16 * Slow/expensive link for high-volume data, bad QoS
     17 * Extreme terrestrial environments, no link
     18 * One-way broadcasting communications
     19 * Satellite links
     20 * Private, isolated MitM/Sybil-resistant networks
     21 * Highly secure isolated air-gap computers
     22 * Network censorship bypassing, health
     23 * Reconnaissance, spying, intelligence, covert agents
     24 * Cheap night transfers
     25 * Multicast flooding transmission
     26 
     27 => http://www.nncpgo.org/Use-cases.html NNCP Use cases
     28 
     29 I wanted to see if I could use NNCP to create an airgapped, offline bitcoin node that could still stay in sync with the bitcoin network. NNCP made this super easy.
     30 
     31 First of all, why would you want an airgapped bitcoin node? For the truly paranoid, having private keys attached to a general purpose computer that can connect to the internet is pretty sketchy. If at any point your computer gets compromised by malware or hackers, then say goodbye to your money. These days I just use a hardware wallet, which is like a small airgapped node, but if you're in a pinch and have a spare laptop lying around, then an airgapped computer will work just as well.
     32 
     33 One issue with an airgapped node is, how do you stay in sync with the network? Your bitcoin node builds the current state of the ledger by appending blocks to what Satoshi originally called a "timechain". Bitcoiners use the term timechain these days to distinguish from all of the cargo-cult "blockchain" shitcoinery that has spawned since Satoshi's original invention. If you don't have the latest state of the ledger, stored in something called the UTXO set, then your client might not show you your true balance. One of your UTXOs might have already been spent. If you're not in sync with network, there's no way to know if a transaction you're creating is even valid! You could be double-spending an already spent coin!
     34 
     35 So having the latest UTXO state is pretty important when spending your bitcoin, but how do we get a fully synced bitcoin node on an airgapped computer? We will be using NNCP to do this course!
     36 
     37 To start, you need a trusted node to sync from. Luckily I already had a full archival node on my local network so I started with that. Next to my full archival node I created a new bitcoin node with pruning turned on. Once my pruned node fully synced, it's block and utxo state was small enough that I could copy it to a usb drive. This is the initial data I used to bootstrap my airgapped node.
     38 
     39 Now, here's where NNCP comes in. We want to incrementally transfer blocks to our airgapped node. On our online node, we run a single command:
     40 
     41 ```
     42 for i in $(seq 708560 $(bitcoin-cli getblockcount)); do
     43   bitcoin-cli getblock $(bitcoin-cli getblockhash $i) 0 |
     44   xxd -r -p |
     45   nncp-exec airgapnode block; done
     46 ```
     47 
     48 where 708560 is the last height synced on the airgapped node. Each call to nncp-exec queues a block to be processed on the airgapped side. nncp-exec takes a HANDLER argument, in this case called `block`. The HANDLER is an identifier that will tell our airgapped node what command to run for each block.
     49 
     50 When we are ready to sync to our node, we call nncp-bundle:
     51 
     52 ```
     53 $ nncp-bundle -tx -delete airgapnode > /usb/block-packets
     54 ```
     55 
     56 This commands packages up our block packets into a file that we can store on a USB drive to sneakernet to our airgapped node. Once we plug our USB into our airgapped node, we run nncp-bundle to receive these packets:
     57 
     58 ```
     59 $ nncp-bundle -rx < /usb/block-packets
     60 ```
     61 
     62 This copies the block packets into our local spool, ready for processing. Before we process the packets, we need to set up our block handler called `blocksubmit`:
     63 
     64 ```
     65 
     66 #!/usr/bin/env bash
     67 set -eou pipefail
     68 
     69 res=$(xxd -p | tr -d '\n' | bitcoin-cli -stdin submitblock)
     70 
     71 # don't drop the block packet if it's out of order
     72 if [ $res == "prev-blk-not-found" ]; then
     73 	exit 42
     74 fi
     75 ```
     76 
     77 This script takes a raw block as input, converts it to hex, and passes it to bitcoin's `submitblock` rpc.
     78 
     79 Now all we have to do is run `nncp-toss`. This processes our sneakernet packets and runs the blocksubmit handler for each `nncp-exec` we originally called:
     80 
     81 ```
     82 $ nncp-toss
     83 2021-11-07T02:47:21Z Got exec from monad to block (322 KiB)
     84 2021-11-07T02:47:21Z Got exec from monad to block (773 KiB)
     85 2021-11-07T02:47:21Z Got exec from monad to block (1.1 MiB)
     86 2021-11-07T02:47:21Z Got exec from monad to block (1.1 MiB)
     87 2021-11-07T02:47:21Z Got exec from monad to block (1.1 MiB)
     88 ```
     89 
     90 and we're done, our offline bitcoin node is now up to date with the bitcoin network!
     91 
     92 I'm interested to see what else I can use NNCP for. It's just a general tool for building store-and-forward protocols. Next I'm thinking about converting my email setup to use NNCP, instead of relying on the buggy mail syncing tools I'm using now.
     93 
     94 One day I imagine a world where I can do most day-to-day tasks seamlessly offline. NNCP is one step toward this future. I can't imagine not using tools like this in low bandwidth meshnets, space, and perhaps even between planets. We might have to start thinking about these things sooner or later!