mirror of
https://github.com/openoms/joininbox.git
synced 2026-08-13 12:33:14 +02:00
* chore: update wallet creation to use watch-only-descriptor-wallet * remove duplicate version check * fix: update release URL in install script and correct typo in wallet import message * ci: test amd64 image descriptor wallet migration with Bats * ci: boot amd64 image tests with OVMF pflash * fix: gate descriptor wallet migration on Bitcoin Core v30 Detect the connected Bitcoin Core version over RPC before migrating. Keep wallet.dat for v29.x or when the version cannot be determined. Add regression coverage for both migration and compatibility paths. * ci: make amd64 image tests independent of guest apt Inject a pinned bats-core checkout into the temporary VM instead of installing Bats through the guest package repositories. Remove the duplicate pull request trigger and simplify artifact lookup. * ci: harden image build run * docs(FAQ): how automatic migration works
298 lines
10 KiB
Bash
Executable file
298 lines
10 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
function addUserStore() {
|
|
if [ ! -d /home/store/app-data ]; then
|
|
echo "# Adding the user: store"
|
|
sudo adduser --system --group --home /home/store store
|
|
sudo -u store mkdir /home/store/app-data
|
|
echo "# Add the joinmarket user to the store group"
|
|
sudo usermod -aG store joinmarket
|
|
else
|
|
echo "# The folder /home/store/app-data is present already"
|
|
fi
|
|
}
|
|
|
|
function moveSignetData() {
|
|
if [ -f /etc/systemd/system/signetd.service ]; then
|
|
sudo systemctl stop signetd
|
|
sudo mv /home/joinmarket/.bitcoin /home/store/app-data/
|
|
sudo ln -s /home/store/app-data/.bitcoin /home/bitcoin/
|
|
sudo chown -R joinmarket:joinmarket /home/joinmarket/.bitcoin/
|
|
sudo systemctl start signetd
|
|
fi
|
|
}
|
|
|
|
function makeEncryptedFolder() {
|
|
# TODO
|
|
# make encrypted file
|
|
|
|
# mount to /mnt/encrypted/
|
|
|
|
# move all from app-data
|
|
sudo mv /home/store/app-data /mnt/encrypted/
|
|
# symlink
|
|
sudo ln -s /mnt/encrypted/app-data /home/store/
|
|
}
|
|
|
|
function downloadSnapShot() {
|
|
|
|
if [ $# -eq 0 ] || [ "$1" = "pruned.host4coins.net" ]; then
|
|
hashFileName="sha256sum.txt"
|
|
hashFileSigName="sha256sum.txt.asc"
|
|
downloadDomain="pruned.host4coins.net/blocks"
|
|
pgpKeyLink="https://keys.openpgp.org/vks/v1/by-fingerprint/440C15769D19E6908CC1DDB23070DE9772DB8A48"
|
|
elif [ "$1" = "prunednode.today" ]; then
|
|
hashFileName="latest.signed.txt"
|
|
downloadDomain="prunednode.today"
|
|
pgpKeyLink="https://stepansnigirev.com/ss-specter-release.asc"
|
|
fi
|
|
|
|
echo "# Check available diskspace"
|
|
FREE=$(df -k --output=avail "$PWD" | tail -n1) # df -k not df -h
|
|
if [ $FREE -lt 21000000 ]; then
|
|
echo "# The free space is only $FREE bytes!"
|
|
echo "# Would need ~21GB free space to download and extract the snapshot."
|
|
echo "# Press ENTER to continue to download regardless or CTRL+C to exit."
|
|
read key
|
|
else
|
|
echo "# OK, more than 21GB is free!"
|
|
fi
|
|
sudo -u joinmarket mkdir /home/joinmarket/download 2>/dev/null
|
|
cd /home/joinmarket/download || exit 1
|
|
|
|
sudo rm $hashFileName 2>/dev/null
|
|
echo "# Downloading $hashFileName ..."
|
|
wget --prefer-family=ipv4 -O $hashFileName https://$downloadDomain/$hashFileName || exit 1
|
|
|
|
downloadFileName=$(grep .zip <$hashFileName | awk '{print $2}')
|
|
downloadLink="https://$downloadDomain/$downloadFileName"
|
|
|
|
echo "# Import the signing key"
|
|
curl -sS "$pgpKeyLink" | gpg --import || exit 1
|
|
|
|
echo "# Verifying the signature of the hash ..."
|
|
if [ ${#hashFileSigName} -gt 0 ]; then
|
|
wget --prefer-family=ipv4 -O $hashFileSigName https://$downloadDomain/$hashFileSigName || exit 1
|
|
fi
|
|
if ! gpg --verify $hashFileSigName $hashFileName; then
|
|
echo "# Invalid signature on $hashFileName"
|
|
echo "# Press ENTER to remove the invalid file or CTRL+C to abort."
|
|
read key
|
|
echo "# Removing $hashFileName"
|
|
rm -f $hashFileName
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f $downloadFileName ]; then
|
|
echo
|
|
echo "# Downloading $downloadLink ..."
|
|
echo
|
|
wget --prefer-family=ipv4 -O $downloadFileName $downloadLink || exit 1
|
|
fi
|
|
|
|
echo "# Verifying the hash (takes time) ..."
|
|
if sha256sum -c $hashFileName --ignore-missing; then
|
|
echo
|
|
echo "# The PGP signature and the hash of the downloaded snapshot is correct"
|
|
else
|
|
echo
|
|
echo "# Download failed --> the PGP signature did not match / signature(${goodSignature})"
|
|
echo "# Press ENTER to remove the invalid files or CTRL+C to abort."
|
|
read key
|
|
echo "# Removing the downloaded files"
|
|
rm -f $hashFileName
|
|
rm -f $downloadFileName
|
|
exit 1
|
|
fi
|
|
|
|
echo "# Extracting to /home/store/app-data/.bitcoin ..."
|
|
FREE=$(df -k --output=avail "$PWD" | tail -n1) # df -k not df -h
|
|
if [ $FREE -lt 11000000 ]; then
|
|
echo "# The free space is only $FREE bytes!"
|
|
echo "# Would need ~11GB free space to extract the snapshot."
|
|
echo "# Press ENTER to continue to extract it regardless or CTRL+C to exit."
|
|
read key
|
|
else
|
|
echo "# OK, more than 11GB is free!"
|
|
fi
|
|
addUserStore
|
|
if [ ! -d /home/store/app-data/.bitcoin ]; then
|
|
sudo mkdir -p /home/store/app-data/.bitcoin
|
|
fi
|
|
echo "# Making sure user: bitcoin exists"
|
|
sudo adduser --system --group --shell /bin/bash --home /home/bitcoin bitcoin
|
|
echo "Copy the skeleton files for login"
|
|
sudo -u bitcoin cp -r /etc/skel/. /home/bitcoin/
|
|
sudo chown -R bitcoin:bitcoin /home/store/app-data/.bitcoin
|
|
echo "# Add the joinmarket user to the bitcoin group"
|
|
sudo usermod -aG bitcoin joinmarket
|
|
echo "# Make sure bitcoind is not running"
|
|
sudo systemctl stop bitcoind
|
|
if sudo -u bitcoin ls /home/bitcoin/.bitcoin/bitcoin.conf; then
|
|
echo "# Back up bitcoin.conf"
|
|
sudo -u bitcoin mv /home/bitcoin/.bitcoin/bitcoin.conf \
|
|
/home/bitcoin/.bitcoin/bitcoin.conf.backup
|
|
fi
|
|
|
|
echo "# Clean old blocks and chainstate"
|
|
sudo rm -rf /home/store/app-data/.bitcoin/blocks
|
|
sudo rm -rf /home/store/app-data/.bitcoin/chainstate
|
|
|
|
echo "# Unzip ..."
|
|
sudo apt-get install -y unzip
|
|
sudo -u bitcoin unzip -o $downloadFileName -d /home/store/app-data/.bitcoin || exit 1
|
|
echo "# OK - Decompressed successfully"
|
|
echo "# Removing the downloaded files"
|
|
rm -f $hashFileName
|
|
rm -f $downloadFileName
|
|
if sudo -u bitcoin ls /home/bitcoin/.bitcoin/bitcoin.conf.backup; then
|
|
echo "# Restore bitcoin.conf"
|
|
sudo -u bitcoin mv -f /home/bitcoin/.bitcoin/bitcoin.conf.backup \
|
|
/home/bitcoin/.bitcoin/bitcoin.conf
|
|
fi
|
|
}
|
|
|
|
function installBitcoinCoreStandalone() {
|
|
downloadBitcoinCore
|
|
|
|
if [ -f /usr/local/bin/bitcoind ]; then
|
|
installedVersion=$(/usr/local/bin/bitcoind --version | grep version)
|
|
echo "${installedVersion} is already installed"
|
|
else
|
|
echo "# Adding the user: bitcoin"
|
|
sudo adduser --system --group --shell /bin/bash --home /home/bitcoin bitcoin
|
|
echo "Copy the skeleton files for login"
|
|
sudo -u bitcoin cp -r /etc/skel/. /home/bitcoin/
|
|
echo "# Add the joinmarket user to the bitcoin group"
|
|
sudo usermod -aG bitcoin joinmarket
|
|
echo "# Installing Bitcoin Core v${bitcoinVersion}"
|
|
cd /home/joinmarket/download/bitcoin-${bitcoinVersion}/bin/ || exit 1
|
|
sudo install -m 0755 -o root -g root -t /usr/local/bin/ ./*
|
|
fi
|
|
if ! sudo -u bitcoin /usr/local/bin/bitcoind --version | grep "Bitcoin Core version"; then
|
|
echo
|
|
echo "# BUILD FAILED --> Was not able to install Bitcoin Core)"
|
|
exit 1
|
|
fi
|
|
|
|
# bitcoin.conf
|
|
if [ -f /home/store/app-data/.bitcoin/bitcoin.conf ]; then
|
|
if [ $(sudo -u bitcoin grep -c rpcpassword </home/store/app-data/.bitcoin/bitcoin.conf) -eq 0 ]; then
|
|
echo "# Removing old bitcoin.conf without rpcpassword configured"
|
|
sudo rm /home/store/app-data/.bitcoin/bitcoin.conf
|
|
fi
|
|
fi
|
|
|
|
echo "# symlink /home/store/app-data/.bitcoin to /home/bitcoin/"
|
|
sudo rm -rf /home/bitcoin/.bitcoin # not a symlink, delete
|
|
sudo mkdir -p /home/store/app-data/.bitcoin
|
|
sudo ln -s /home/store/app-data/.bitcoin /home/bitcoin/
|
|
|
|
if [ ! -f /home/bitcoin/.bitcoin/bitcoin.conf ]; then
|
|
randomRPCpass=$(tr </dev/urandom -dc _A-Z-a-z-0-9 | head -c20)
|
|
echo "
|
|
# bitcoind configuration for mainnet
|
|
|
|
# Connection settings
|
|
rpcuser=joininbox
|
|
rpcpassword="$randomRPCpass"
|
|
|
|
prune=1000
|
|
server=1
|
|
fallbackfee=0.0002
|
|
|
|
onlynet=onion
|
|
proxy=127.0.0.1:9050
|
|
" | sudo tee /home/bitcoin/.bitcoin/bitcoin.conf
|
|
else
|
|
echo "# /home/bitcoin/.bitcoin/bitcoin.conf is present"
|
|
fi
|
|
sudo chown -R bitcoin:bitcoin /home/store/app-data/.bitcoin
|
|
sudo chown -R bitcoin:bitcoin /home/bitcoin/
|
|
}
|
|
|
|
function installMainnet() {
|
|
source /home/joinmarket/_functions.bitcoincore.sh
|
|
removeSignetdService
|
|
sudo systemctl stop bitcoind
|
|
# /etc/systemd/system/bitcoind.service
|
|
echo "
|
|
[Unit]
|
|
Description=Bitcoin daemon on mainnet
|
|
|
|
[Service]
|
|
Environment='MALLOC_ARENA_MAX=1'
|
|
ExecStart=/usr/local/bin/bitcoind \\
|
|
-daemonwait \\
|
|
-conf=/home/bitcoin/.bitcoin/bitcoin.conf \\
|
|
-datadir=/home/bitcoin/.bitcoin
|
|
PermissionsStartOnly=true
|
|
|
|
# Process management
|
|
####################
|
|
Type=forking
|
|
Restart=on-failure
|
|
TimeoutStartSec=infinity
|
|
TimeoutStopSec=600
|
|
|
|
# Directory creation and permissions
|
|
####################################
|
|
# Run as bitcoin:bitcoin
|
|
User=bitcoin
|
|
Group=bitcoin
|
|
|
|
StandardOutput=null
|
|
StandardError=journal
|
|
|
|
# Hardening measures
|
|
####################
|
|
# Provide a private /tmp and /var/tmp.
|
|
PrivateTmp=true
|
|
# Mount /usr, /boot/ and /etc read-only for the process.
|
|
ProtectSystem=full
|
|
# Disallow the process and all of its children to gain
|
|
# new privileges through execve().
|
|
NoNewPrivileges=true
|
|
# Use a new /dev namespace only populated with API pseudo devices
|
|
# such as /dev/null, /dev/zero and /dev/random.
|
|
PrivateDevices=true
|
|
# Deny the creation of writable and executable memory mappings.
|
|
MemoryDenyWriteExecute=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
" | sudo tee /etc/systemd/system/bitcoind.service
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable bitcoind
|
|
echo "# OK - the bitcoind.service is now enabled"
|
|
|
|
# add aliases
|
|
if ! grep "alias bitcoin-cli" /home/joinmarket/_aliases.sh; then
|
|
sudo bash -c "echo 'alias bitcoin-cli=\"sudo -u bitcoin /usr/local/bin/bitcoin-cli\"' >> /home/joinmarket/_aliases.sh"
|
|
fi
|
|
if ! grep "alias bitcoind" /home/joinmarket/_aliases.sh; then
|
|
sudo bash -c "echo 'alias bitcoind=\"sudo -u bitcoin /usr/local/bin/bitcoind\"' >> /home/joinmarket/_aliases.sh"
|
|
fi
|
|
if ! grep "alias bitcoinlog" /home/joinmarket/_aliases.sh; then
|
|
sudo bash -c "echo 'alias bitcoinlog=\"sudo tail -f /home/bitcoin/.bitcoin/debug.log\"' >> /home/joinmarket/_aliases.sh"
|
|
fi
|
|
if ! grep "alias bitcoinconf" /home/joinmarket/_aliases.sh; then
|
|
sudo bash -c "echo 'alias bitcoinconf=\"sudo nano /home/bitcoin/.bitcoin/bitcoin.conf\"' >> /home/joinmarket/_aliases.sh"
|
|
fi
|
|
|
|
# set joinin.conf value
|
|
/home/joinmarket/set.value.sh set network mainnet ${joininConfPath}
|
|
|
|
sudo systemctl start bitcoind
|
|
echo
|
|
echo "# Installed $(sudo -u bitcoin /usr/local/bin/bitcoind --version | grep version)"
|
|
echo
|
|
echo "# Monitor the bitcoind with: sudo tail -f /home/bitcoin/.bitcoin/mainnet/debug.log"
|
|
echo
|
|
|
|
if [ ! -d /home/bitcoin/.bitcoin/wallets/watch-only-descriptor-wallet ]; then
|
|
echo "# Create watch-only-descriptor-wallet ..."
|
|
sleep 10
|
|
sudo -u bitcoin /usr/local/bin/bitcoin-cli -named createwallet wallet_name=watch-only-descriptor-wallet descriptors=true disable_private_keys=true
|
|
fi
|
|
}
|