Cross Compiling the Substrate-Node-Template to ARMv7
The Raspberry Pi is an unbelievably versatile piece of hardware. It can be used to build robots and automate boring tasks like watering your plants, turning on lights and music and much more. But can it also run a substrate based blockchain? The answer is yes!
First of all we need a little bit of time. There are two compile steps included that could take 30min of your CPU time each! But the steps are straightforward and you might be able to complete this guide with investing 10min of work and maybe an hour of compile time.
Second of all we need hardware! That includes a system on which we compile our binary. Since we don’t want to wait a couple of days for our binary, we don’t compile the binary on the Raspberry Pi directly. We use an Ubuntu Server 20.04 with a rather beefy CPU for compiling. The second piece of hardware is of course the Raspberry Pi. We use a Raspberry Pi 2 B v1.1 with an ARMv7 CPU for running the node at the very end of this guide. The version of your Raspberry Pi is important since it determines for which target we need to compile.
Before we actually start compiling, we need to set up a few things. First of all, we need the substrate-node-template and install all dependencies to be able to compile it on the host system.
After the node template has compiled successfully and we are able to run the node on our host system, we can start to set up our host for cross compiling. Let’s start with a compiler that can build binaries for the ARM Cortex-A architecture. Here we need to be careful and select a version that is supported by the Operating System running on our Raspberry Pi. At the time of writing, the highest supported compiler version was 8.3 since we are running Raspbian on our Raspberry Pi. At the ARM download page a bunch of different toolchains are listed. For the Raspberry Pi we need the toolchain for an “AArch32 target with hard float (arm-linux-gnueabihf)”. After we downloaded the toolchain, we extract it from the archive.
Next, we set up our environment variables so that cargo knows which compiler and libc it should use for cross compiling to the Raspberry Pi. Here we obviously point to our just downloaded toolchain. I assume that you downloaded the toolchain to your home directory. Make sure to adjust the paths if you downloaded it to somewhere else.
You also might need to install glibc for 32-bit architectures and export the path to llvm_config (or rename it).
Now, we need to set up cargo to be able to compile to ARM. First we install the target using rustup.
The last step for preparation is to tell cargo which compiler to use for our target. For that we adjust the cargo configuration at ~/.cargo/config. Add the following lines to the end of the file. In case it doesn’t exist, you might need to create it.
Sadly, we cannot compile the template directly. Inside the Cargo.toml there are a few dependencies that have the wasmtime feature enabled. However, wasmtime can’t be compiled for armv7. Therefore, we have to remove all lines looking like features = [‘wasmtime’].
Now that we prepared everything, let’s compile! There are only two things to consider here. First, we obviously need to specify our compilation target. Second, we might want to build in release mode. The Raspberry Pi might have a Quad Core CPU, but it’s not as fast as an AMD Epic or an Intel i7.
Time to lean back and grab a drink because compiling always takes some time. If there are any issues while compiling, try a cargo clean. This resolved most of our issues while compiling.
After cargo and rustc did their magic, we finally can copy our binary over to the Raspberry Pi!
We showed that expensive hardware is not required to run a Polkadot validator by means of a Raspberry Pi. Nevertheless, validating on such a device might not be the best idea. There are reasons for all the redundancy in a datacenter. The Raspberry Pi might also struggle to validate heavy blocks in time. Therefore, it’s reasonable to ask why someone would want to run a node on such a device at all! But at least we at KILT could think of a few interesting projects where you would want to run a light client or even a full node in a constrained environment and trying out what’s possible on a Raspberry Pi is a nice first step.