Introduction
I still have an old Block Erupter, a small USB powered ASIC for mining Bitcoin. It hashes at a puny 333 MH/s, ~0.00000000003634% of Bitcoin’s total network hashrate of 916.36 EH/s at the time of this writing. According to ChatGPT I have a 1 in 2,751,000,000,000 chance of finding a block mining solo. Well, I’m feeling lucky so I set it up to mine as a lottery.
Installation
I opted to use CGMiner installed in a LXC container with the Block Erupter passed through to mine.
LXC Set Up
- I created a Debian 12 container with minimal specs:
pct create 107 RAID:vztmpl/debian-12-standard_*.tar.zst \
--arch amd64 \
--hostname BTC \
--cores 4 \
--memory 512 \
--swap 0 \
--unprivileged 1 \
--features nesting=1 \
--net0 name=eth0,bridge=vmbr1,firewall=1,tag=20,type=veth \
--rootfs local-zfs:2G \
--onboot 1 \
--ostype debian
- Next I needed to configure the container to use the Block Erupter. I ran
lsusb
twice on the host; first with the Block Erupter unplugged and then again plugged in. The second time showed the Block Erupter:
Bus 001 Device 005: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Then I set the LXC container’s root as owner using the Bus (001
) and Device (005
) values:
chown 100000:100000 /dev/bus/usb/001/005
Now I needed to find the major and minor device numbers for the Block Erupter:
ls -l /dev/bus/usb/001/005
Output:
crw-rw-r-- 1 100000 100000 189, 4 Jun 17 10:09 /dev/bus/usb/001/005
Finally I added the following lines to the container’s config (/etc/pve/lxc/107.conf
) now knowing the device major (189
) and minor (4
) values:
lxc.cgroup.devices.allow: c 189:4 rwm
lxc.mount.entry: /dev/bus/usb/001/005 dev/bus/usb/001/005 none bind,optional,create=file
CGMiner Set Up
Now that the container has the Block Erupter set up it was time to install CGMiner.
- First I installed Git and the required dependencies for CGMiner:
apt install git build-essential autoconf automake libtool pkg-config libcurl4-openssl-dev libudev-dev libusb-1.0-0-dev libncurses5-dev libz-dev -y
- Cloned the repo:
git clone https://github.com/ckolivas/cgminer.git
cd cgminer
- Set install flags to build for Block Erupter (
Icarus
) use and then built:
CFLAGS="-O2 -Wall -march=native -fcommon" ./autogen.sh --enable-icarus
make
Mining
-
I used BitAddress, a JavaScript client-side Bitcoin wallet generator, to generate a new Bitcoin address for mining payouts.
-
I opted to use a solo mining pool so I wouldn’t need to keep a copy of the Bitcoin blockchain stored locally. I’m using KanoPool. Once I created an account with the newly generated Bitcoin wallet address configured for payout, I was ready to start mining. I started CGMiner with the worker I set up on KanoPool configured to use KanoPool’s Seattle and Los Angeles servers as they’re geographically closest to me:
cgminer -o stratum+tcp://se.kano.is:3333 -u slowry05.worker -p x -o stratum+tcp://la.kano.is:3333 -u slowry05.worker -p x
Additional Set Up
Screen & Cron
I installed screen
in the container so I can run cgminer
as a background task that I can check on:
apt install screen -y
screen -dmS BTC cgminer -o stratum+tcp://se.kano.is:3333 -u slowry05.worker -p x -o stratum+tcp://la.kano.is:3333 -u slowry05.worker -p x
And then set that screen command as a cron
job to run after reboot.
Script to Update LXC Config
One huge drawback to this set up is after a host reboot the Block Erupter’s device values change and then the container’s root
loses ownership. To fix this I wrote a script to run after a reboot on the host to find the new values, reset ownership, and update the values in the container’s config:
#!/bin/bash
# Run lsusb and capture the output
lsusb_output=$(lsusb)
# Search for the line containing "Silicon Labs CP210x UART Bridge"
device_line=$(echo "$lsusb_output" | grep "Silicon Labs CP210x UART Bridge")
# Extract the Bus and Device numbers
bus_number=$(echo "$device_line" | awk '{print $2}')
device_number=$(echo "$device_line" | awk '{print $4}' | tr -d ':')
# Make LXC root owner of the device
chown 100000:100000 /dev/bus/usb/$bus_number/$device_number
# Run ls -l to get the device info
device_info=$(ls -l /dev/bus/usb/$bus_number/$device_number)
# Extract the "Major, Minor" and convert to "Major:Minor"
major_minor=$(echo "$device_info" | grep -o "[0-9]\+,[ ]*[0-9]\+")
formatted_major_minor=$(echo "$major_minor" | sed 's/, */:/' | tr -d ' ')
# Path to the LXC config file for container 107
lxc_config_path="/etc/pve/lxc/107.conf"
# Update the LXC configuration file
if [[ -f "$lxc_config_path" ]]; then
# Update lxc.cgroup.devices.allow line
sed -i "s|^lxc.cgroup.devices.allow: c [0-9]\+:[0-9]\+ rwm|lxc.cgroup.devices.allow: c $formatted_major_minor rwm|" "$lxc_config_path"
# Update lxc.mount.entry line
sed -i "s|^lxc.mount.entry: /dev/bus/usb/[0-9]\+/[0-9]\+ .*|lxc.mount.entry: /dev/bus/usb/$bus_number/$device_number dev/bus/usb/$bus_number/$device_number none bind,optional,create=file|" "$lxc_config_path"
else
exit 1
fi
Final Thoughts
Do I expect to actually mine a block? Hell no. This is just for fun. If I was more serious there’s newer USB ASIC devices that run circles around the now ancient Block Erupter. For ~$30 I could use this NerdMiner 75KH USB ASIC instead which is ~225x faster. It makes more sense to buy $30 of Bitcoin and hold it instead though.