Adventures on Planet Earth

a Bitcoin node using Raspberry Pi

Sample output during the node synchronisation process :

{
  "chain": "main",
  "blocks": 351405,
  "headers": 511505,
  "bestblockhash": "00000000000000000e713b8f3b5f52e57585122dc4ffa50b98f5be2e98d4aeca",
  "difficulty": 49446390688.24144,
  "mediantime": 1428593574,
  "verificationprogress": 0.2167161316271393,
  "chainwork": "00000000000000000000000000000000000000000006053b6a72e765d904063c",
  "pruned": false,
  "softforks": [
    {
      "id": "bip34",
      "version": 2,
      "reject": {
        "status": true
      }
    },
    {
      "id": "bip66",
      "version": 3,
      "reject": {
        "status": false
      }
    },
    {
      "id": "bip65",
      "version": 4,
      "reject": {
        "status": false
      }
    }
  ],
  "bip9_softforks": {
    "csv": {
      "status": "defined",
      "startTime": 1462060800,
      "timeout": 1493596800,
      "since": 0
    },
    "segwit": {
      "status": "defined",
      "startTime": 1479168000,
      "timeout": 1510704000,
      "since": 0
    }
  }
}

An exercise to traverse a little more of the crypto learning curve.

At present there are two branches of the Bitcoin blockchain - Bitcoin Core and a hard fork of the blockchain named Bitcoin Cash. Which is the 'real' Bitcoin (as described in the original Satoshi whitepaper) is debated by some. Bitcoin is a public blockchain and Bitcoin Core has the largest nodal network. This installation covers Bitcoin Core.

Bitcoin Core is the “official” or “reference” bitcoin client. Among other functions, this client can maintain a complete blockchain (not just headers), validate and transmit transactions, discover and maintain connections to peers - a full node.

From a more philosophical viewpoint, these nodes can be compared to representatives in a democracy. When determining the level of success achieved by an attempted hard fork it ultimately comes down to the desires of the full nodes i.e. choosing which version of Bitcoin software to run on a full node is a vote (https://bitcoinmagazine.com/articles/you-really-should-run-full-bitcoin-node-heres-why/).

The following procedure is the result of a trial an error process using sections of installation recipes already on the internet. Problems may arise when installing on different hardware and/or a different version of the Bitcoin client. There is an easier and more direct route - download the appropriate software and just run the GUI on a standard desktop computer, but where’s the fun in that?

Hardware:

  • Raspberry Pi 2 model B running Raspbian OS
  • SD card (just large enough to hold the OS)
  • Power adaptor 5V 2.0A
  • External HDD 3.5” with independent power supply
  • USB Wifi adaptor (or just an ethernet cable connected directly to the internet router)

NOTE: powering a 2.5” HDD directly by the Pi will result in a low power warning (lightning symbol) in the top right corner of the screen, and the Bitcoin client will occasionally crash.

Hardware for setup process:

  • HDMI-in screen (the ‘head’)
  • HDMI cable
  • USB keyboard
  • USB mouse
  • Another computer with SD card port (in this case one running MacOSX)

Setup process:

Download the Raspbian OS https://www.raspberrypi.org/downloads/raspbian/ and check whether the hash matches that on the downloads page, or another source.

openssl sha -sha256 /folder/2017-09-07-raspbian-stretch.zip  

Uncompress the file to reveal the OS image.

Insert the SD card and locate it.

diskutil list

e.g.

/dev/disk3 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *63.9 GB    disk3
   1:                 DOS_FAT_32 U                       63.8 GB    disk3s1

Unmount the appropriate volume. The IDENTIFIER number depends on the order in which storage devices were detected by the system e.g. disk3.

diskutil umountDisk /dev/disk3

Burn the image 2017-09-07-raspbian-stretch.img to the SD card using the appropriate path to the .img file (bs for read/write speed, conv to convert the file in a specific manner)

sudo dd if=2017-09-07-raspbian-stretch.img of=/dev/disk3 bs=1m conv=noerror,sync

Ctrl-T to check progress - which can be very slow for larger capacity SD cards.

If successful, the logical volume created will mount as ‘boot’ and will need to be unmounted.

diskutil umountDisk /dev/disk3

Remove the SD card, plug it into the pi, connect the external drive and boot the pi.

Once the GUI has loaded, use Ctrl-Alt T to launch a terminal window, locate the external drive and format it. It may show up show as /dev/sda and knowing the drive capacity will help identify it (-l to list).

sudo fdisk -l
sudo mkfs.ext4 /dev/sda

Create a folder in the home directory to store the Blockchain, mount the external drive at this location so that anything saved in this folder actually saves to the HDD, then change permissions to enable correct access rights (775 for general files when working in a group, -t for type of filesystem)

mkdir /home/pi/bitcoinData/

sudo mount -t ext4 /dev/sda /home/pi/bitcoinData/

sudo chmod 775 /home/pi/bitcoinData/

Setup the HDD to auto mount at boot by altering the following file.

sudo nano /etc/fstab

Enter the following line as the last row of text.

/dev/sda    /home/pi/bitcoinData    ext4    defaults    0   0  

Ctrl-X and then Y to save the file and exit. Reboot and the external drive will automatically mount to /home/pi/bitcoinData

sudo reboot

Connect the Pi to the WiFi or directly to the router - may as well do this through the GUI as the Pi still defaults to it on bootup.

Bring up the terminal again and configure the pi as follows

sudo raspi-config

Select the following

() -> Advanced options -> Expand File System - click OK to ensure full use of the SD card space
() -> Boot Options -> Desktop/CLI -> Console Autologin  
() -> Boot Options -> disable splash screen
() -> Interfacing Options -> Enable SSH to be able to access a headless Pi
() -> Overclock -> Set to High to speed up synchronisation of the node (this can be disabled after sync)
() -> Advanced options -> Memory Split -> reduce GPU memory to 16MB for a headless configuration    
() -> Hostname -> change to e.g. "fullnode"

Note: the GPU memory can be set to 0 for a headless node. This can be done later on by SSH into the pi.

Exit and select the option to reboot.

Change password for the pi to something unique and complex. The default is ‘raspberry’.

passwd

Update the OS by first updating the list of available packages and their versions, and then installing newer versions of packages already installed. Run the second command a couple times if errors are reported.

sudo apt-get update

sudo apt-get upgrade -y

A bitcoin client is the end-user software that facilitates private key generation, private key security, and payment sending on behalf of that private key.

Bitcoin Core (Bitcoin-Qt has been rebranded to Bitcoin Core) is the third Bitcoin client. bitcoind is a program that implements the Bitcoin remote procedure call (RPC) protocol - a protocol that one authenticated bitcoin client can use to request a service from another. bitcoind is bundled with Bitcoin Core.

Bitcoin Core requires many software libraries that don't come packaged by default. The first one, build-essential, enables software to be compiled from source.

sudo apt-get install build-essential

Other dependencies need to be installed for bitcoind (details of packages here https://packages.debian.org/jessie/libevent-dev).

sudo apt-get install autoconf libevent-dev libtool libssl-dev libboost-all-dev libminiupnpc-dev -y

Run the following command if there are problems downloading and installing these dependencies.

sudo apt-get install —-fix-missing

The swap file size should be increased to 1024 MB to make sure there is enough memory for the installation. Change the default size to CONF_SWAPSIZE=1024 in the following file. This can be returned back to default later.

sudo nano /etc/dphys-swapfile

Ctrl+X then Y to exit, then turn on the swap.

sudo dphys-swapfile setup

sudo dphys-swapfile swapon

The original Bitcoin client stores private key information in a file named wallet.dat (located on the HDD mounted at /home/pi/bitcoinData) and the format of this file is Berkeley DB. To store the block chain, Satoshi chose to use Berkeley DB as a way to index from transactions to the blocks they appeared in. Bitcoin Core relies on an old version of the Berkeley Database that is not available as a standard package and needs to be installed separately.

Create and navigate to a folder for binary files.

mkdir ~/bin

cd ~/bin

Download and verify Berkeley DB 4.8 source package (-c to check)

wget http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz
echo ‘12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef  db-4.8.30.NC.tar.gz’ | sha256sum -c

The last command should return a value of db-4.8.30.NC.tar.gz: OK.

Following the standard configure/make/install process (https://robots.thoughtbot.com/the-magic-behind-configure-make-make-install), unpack (-x to extract, -z to use gzip for files with extension .gz, -v for verbose operation, -f for the archive file) and configure the Berkeley DB (options here https://docs.oracle.com/cd/E17275_01/html/programmer_reference/build_unix_conf.html)

tar -xzvf db-4.8.30.NC.tar.gz
cd ~/bin/db-4.8.30.NC/build_unix/
../dist/configure --enable-cxx

Build and install the database (-j4 for all CPU cores)

make -j4
sudo make install

Clone the authoritative source repository from GitHub and build Bitcoin Core from source code (-b to point to a named branch of code). The release used was v0.15.0.1 and the build process uses the autogen/configure/make system.

The autogen.sh script creates a set of automatic configuration scripts that will check the system to determine the correct settings and ensure all all necessary libraries are present. One of these scripts is ‘configure’ which allows options to customise the build process for different systems.

cd ~/bin

git clone -b v0.15.1 https://github.com/bitcoin/bitcoin

cd bitcoin/

./autogen.sh

sudo apt-get install libdb++-dev -y

./configure CPPFLAGS="-I/usr/local/BerkeleyDB.4.8/include -O2" LDFLAGS="-L/usr/local/BerkeleyDB.4.8/lib" --enable-upnp-default

-upnp (universal plug and play) should get through the routers firewall and allow incoming connections to be forwarded from port 8333 to the raspberry pi. Thats the uppercase letter ‘O’ not a zero.

Compile the executables and then install them.

make 
sudo make install

Navigate to the bitcoin data directory and use the nano text editor to create the Bitcoin Configuration file bitcoin.conf at this location (where the blockchain will be stored).

cd /home/pi/bitcoinData

sudo nano bitcoin.conf

This will open a blank text editor where the following parameters should be entered as a minimum, replacing the defaults with something unique and complex. The password controls access to the application programming interface. The alertnotify parameter will allow emails notifications should a problem arise. The txindex parameter will allow a complete transaction database to be built.

rpcuser= thisisdefaulttext
rpcpassword= thisisdefaulttext
alertnotify=echo %s | mail -s "Bitcoin Alert" thisisdefaulttext@thisisdefaulttext.com
txindex=1 

Return the swap file back to its default settings (-x to execute the permission change only if the file has execute permission for the user, -a for all swap areas)

sudo chmod -x /etc/init.d/dphys-swapfile
sudo swapoff -a
sudo rm /var/swap

Delete ~/bin folder and all subfolders to save space (-r to delete subfolders, -f to force confirmations)

sudo rm -r -f /home/pi/bin

Start a bitcoind daemon and specify the location of the HDD mounting point where the blockchain data is to be located (this parameter could also go in the bitcoin.conf file).

sudo bitcoind -datadir=/home/pi/bitcoinData -daemon

To check synchronisation status on a snapshot basis:

sudo bitcoin-cli -datadir=/home/pi/bitcoinData getblockchaininfo

To check synchronisation status on a periodic basis with all progress highlighted:

watch -d  sudo bitcoin-cli -datadir=/home/pi/bitcoinData getblockchaininfo

Ctrl-C to interrupt. It will take weeks to synchronise…

The synchronisation process itself is very demanding on the Pi hardware. If it completes without crashing, the next step will be to test connections and go headless - covered in Part Two.

Further reading:

  • Bitcoin Core client: https://bitcoin.org/en/bitcoin-core/
  • Mastering Bitcoin, Andreas M. Antonopoulos, 2015 : https://github.com/bitcoinbook/bitcoinbook
  • Bitcoin Wiki : https://en.bitcoin.it/wiki/Main_Page
  • Market overview : https://coin360.io