From 753be711cef427124a5c85b94faf74a49f3b3ff5 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Sat, 2 Jun 2018 21:46:18 +0200 Subject: [PATCH] Perform accelerated initial blockchain download as a systemd service Reduces the time spent in and amount of stuff done during provisioning. Allows a future dashboard / admin page to monitor progress. Only use the expedited IBD script if there is a big disk present. --- vendor/AWS/Matreon.Template | 58 +++++++++---------- vendor/AWS/README.md | 1 + vendor/bitcoin/bitcoind.path | 2 + vendor/bitcoin/bitcoind.service | 11 +++- vendor/bitcoin/ibd-shutdown.path | 2 + vendor/bitcoin/ibd-shutdown.service | 17 ++++++ .../initial-blockchain-download.service | 41 +++++++++++++ .../initial_blockchain_download_and_prune.sh | 52 +++++++++++++++++ vendor/bitcoin/wait_for_ibd.sh | 18 ------ vendor/charge/lightning-charge.path | 2 + vendor/charge/lightning-charge.service | 3 +- vendor/lightning/lightningd.path | 2 + vendor/lightning/lightningd.service | 2 + 13 files changed, 161 insertions(+), 50 deletions(-) create mode 100644 vendor/bitcoin/bitcoind.path create mode 100644 vendor/bitcoin/ibd-shutdown.path create mode 100644 vendor/bitcoin/ibd-shutdown.service create mode 100644 vendor/bitcoin/initial-blockchain-download.service create mode 100755 vendor/bitcoin/initial_blockchain_download_and_prune.sh delete mode 100755 vendor/bitcoin/wait_for_ibd.sh create mode 100644 vendor/charge/lightning-charge.path create mode 100644 vendor/lightning/lightningd.path diff --git a/vendor/AWS/Matreon.Template b/vendor/AWS/Matreon.Template index 639b36d..6bc0711 100644 --- a/vendor/AWS/Matreon.Template +++ b/vendor/AWS/Matreon.Template @@ -241,7 +241,8 @@ Resources: 20_add_user_bitcoin: command: groupadd -r bitcoin && useradd -r -m -g bitcoin bitcoin 30_copy_systemd_files: - command: cp /usr/local/src/matreon/vendor/**/*.service /lib/systemd/system + command: cp /usr/local/src/matreon/vendor/**/*.service /lib/systemd/system + && cp /usr/local/src/matreon/vendor/**/*.path /lib/systemd/system 40_copy_bitcoind_files: command: mkdir /etc/bitcoin && cp /usr/local/src/matreon/vendor/bitcoin/bitcoin.conf /etc/bitcoin/bitcoin.conf && chmod 444 /etc/bitcoin/bitcoin.conf @@ -353,39 +354,36 @@ Resources: command: mkdir /mnt/ssd && mount -o discard /dev/nvme0n1 /mnt/ssd 04_add_ssd_bitcoin_dir: command: mkdir /mnt/ssd/bitcoin && chown -R bitcoin:bitcoin /mnt/ssd/bitcoin - 05_start_bitcoind: - command: su - bitcoin --command "bitcoind -conf=/etc/bitcoin/bitcoin.conf -datadir=/mnt/ssd/bitcoin -dbcache=20000 -prune=1 -daemon" - 06_wait_for_sync_prune_stop: - command: su - bitcoin --command "/usr/local/src/matreon/vendor/bitcoin/wait_for_ibd.sh" - 07_copy_pruned_chain: - command: - !If - - NetworkBitcoin - - su - bitcoin --command "mv /mnt/ssd/bitcoin/blocks/*.dat /home/bitcoin/.bitcoin/blocks" - && su - bitcoin --command "mv /mnt/ssd/bitcoin/blocks/index/* /home/bitcoin/.bitcoin/blocks/index" - && su - bitcoin --command "mv /mnt/ssd/bitcoin/chainstate /home/bitcoin/.bitcoin" - - su - bitcoin --command "mv /mnt/ssd/bitcoin/testnet3/blocks/*.dat /home/bitcoin/.bitcoin/testnet3/blocks" - && su - bitcoin --command "mv /mnt/ssd/bitcoin/testnet3/blocks/index/* /home/bitcoin/.bitcoin/testnet3/blocks/index" - && su - bitcoin --command "mv /mnt/ssd/bitcoin/testnet3/chainstate /home/bitcoin/.bitcoin/testnet3" + && ln -s /mnt/ssd/bitcoin /home/bitcoin/big-disk && chown -h bitcoin:bitcoin /home/bitcoin/big-disk prepare_matreon: commands: 01_install_crontab: command: crontab -u matreon /usr/local/src/matreon/vendor/AWS/crontab-matreon - 02_start_bitcoind_service_after_reboot: - command: systemctl enable bitcoind.service - 03_start_lightningd_service_after_reboot: - command: systemctl enable lightningd.service - 04_start_lightning_charge_service_after_reboot: - command: systemctl enable lightning-charge.service - 10_run_rails_service_after_reboot: - command: systemctl enable rails.service - 11_run_ngnix_after_reboot: - command: systemctl enable nginx - 90_cleanup: - command: rm -rf /tmp/* - 99_shutdown: - command: shutdown 2 + 02_prep_bitcoind_service: + command: systemctl enable bitcoind.service + && systemctl enable bitcoind.path + && systemctl start bitcoind.path + 03_start_ibd_and_prune_service: + command: systemctl enable initial-blockchain-download.service + && systemctl start initial-blockchain-download.service + && systemctl enable ibd-shutdown.service + && systemctl enable ibd-shutdown.path + && systemctl start ibd-shutdown.path + 04_prep__lightningd_service: + command: systemctl enable lightningd.service + && systemctl enable lightningd.path + && systemctl start lightningd.path + 05_prep__lightning_charge_service: + command: systemctl enable lightning-charge.service + && systemctl enable lightning-charge.path + && systemctl start lightning-charge.path + 10_run_rails_service: + command: systemctl enable rails.service + && systemctl start rails.service + 11_run_nginx_service: + command: systemctl enable nginx + && systemctl start nginx Properties: ImageId: ami-43eec3a8 @@ -413,7 +411,7 @@ Resources: /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource WebServer --region ${AWS::Region} CreationPolicy: ResourceSignal: - Timeout: PT360M + Timeout: PT60M IPAddress: Type: AWS::EC2::EIP IPAssoc: diff --git a/vendor/AWS/README.md b/vendor/AWS/README.md index fa76379..08c066c 100644 --- a/vendor/AWS/README.md +++ b/vendor/AWS/README.md @@ -33,6 +33,7 @@ First, create a new policy [here](https://console.aws.amazon.com/iam/home?region "ec2:describeAddresses", "ec2:releaseAddress", "ec2:associateAddress", + "ec2:disassociateAddress", "ec2:RunInstances", "ec2:StartInstances", "ec2:StopInstances", diff --git a/vendor/bitcoin/bitcoind.path b/vendor/bitcoin/bitcoind.path new file mode 100644 index 0000000..cda57b4 --- /dev/null +++ b/vendor/bitcoin/bitcoind.path @@ -0,0 +1,2 @@ +[Path] +PathExists=/home/bitcoin/.ibd_service_finished diff --git a/vendor/bitcoin/bitcoind.service b/vendor/bitcoin/bitcoind.service index cf4a8ed..bbd5476 100644 --- a/vendor/bitcoin/bitcoind.service +++ b/vendor/bitcoin/bitcoind.service @@ -1,6 +1,11 @@ [Unit] Description=Bitcoin daemon -After=network.target + +ConditionPathExists=/home/bitcoin/.ibd_service_finished + +# StartLimitIntervalSec=10 +# StartLimitBurst=1 +# RestartSec=60 [Service] ExecStart=/usr/local/bin/bitcoind -prune=38000 -dbcache=300 -daemon \ @@ -13,6 +18,10 @@ Type=forking PIDFile=/run/bitcoind/bitcoind.pid Restart=on-failure +StartLimitInterval=10 +StartLimitBurst=1 +RestartSec=60 + # Hardening measures #################### diff --git a/vendor/bitcoin/ibd-shutdown.path b/vendor/bitcoin/ibd-shutdown.path new file mode 100644 index 0000000..10a5f05 --- /dev/null +++ b/vendor/bitcoin/ibd-shutdown.path @@ -0,0 +1,2 @@ +[Path] +PathExists=/home/bitcoin/.ibd_service_requests_shutdown diff --git a/vendor/bitcoin/ibd-shutdown.service b/vendor/bitcoin/ibd-shutdown.service new file mode 100644 index 0000000..546639b --- /dev/null +++ b/vendor/bitcoin/ibd-shutdown.service @@ -0,0 +1,17 @@ +[Unit] +Description=Shutdown after expedited IBD to allow downgrade +After=network.target +ConditionPathExists=/home/bitcoin/.ibd_service_requests_shutdown + +[Service] +ExecStartPre=/usr/bin/rm /home/bitcoin/.ibd_service_requests_shutdown +ExecStartPre=/bin/systemctl disable ibd-shutdown.service +ExecStartPost=/usr/bin/rm /usr/lib/systemd/system/ibd-shutdown.service +ExecStartPost=/usr/bin/rm /usr/lib/systemd/system/ibd-shutdown.path +ExecStart=/sbin/shutdown + +User=root +Type=oneshot + +[Install] +WantedBy=multi-user.target diff --git a/vendor/bitcoin/initial-blockchain-download.service b/vendor/bitcoin/initial-blockchain-download.service new file mode 100644 index 0000000..98a9610 --- /dev/null +++ b/vendor/bitcoin/initial-blockchain-download.service @@ -0,0 +1,41 @@ +[Unit] +Description=Check if initial blockchain download has done and if we're on a special machine. +After=network.target +ConditionPathExists=!/home/bitcoin/.ibd_service_finished + +# Newer versions of systemd (>~ october 2017) +# StartLimitIntervalSec=10 +# StartLimitBurst=1 +# RestartSec=60 + +[Service] +ExecStart=/usr/local/src/matreon/vendor/bitcoin/initial_blockchain_download_and_prune.sh + +WorkingDirectory=/home/bitcoin +User=bitcoin +Type=simple +Restart=on-failure + +StartLimitInterval=10 +StartLimitBurst=1 +RestartSec=60 + +# 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 + +[Install] +WantedBy=multi-user.target diff --git a/vendor/bitcoin/initial_blockchain_download_and_prune.sh b/vendor/bitcoin/initial_blockchain_download_and_prune.sh new file mode 100755 index 0000000..7594e9d --- /dev/null +++ b/vendor/bitcoin/initial_blockchain_download_and_prune.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Skip if no big disk is available: +if [ ! -L /home/bitcoin/big-disk ]; then + touch /home/bitcoin/.ibd_service_finished + exit 0 +fi + +# Skip if IBD has already been done: +if [ -f /home/bitcoin/.ibd_service_finished ]; then exit 0; fi + +# /home/bitcoin/big-disk needs to be symlink pointing a big drive +export OPTS="-conf=/etc/bitcoin/bitcoin.conf -datadir=/home/bitcoin/big-disk" + +# Start bitcoind with manual pruning and a large enough dbcache. +echo "Start bitcoind as a daemon..." +bitcoind $OPTS -dbcache=20000 -prune=1 -daemon + +set -o pipefail +while sleep 60 +do + if bitcoin-cli $OPTS getblockchaininfo | jq -e '.initialblockdownload==false'; then + # Prune to slightly before (a lot on testnet) the first Lightning block: + bitcoin-cli $OPTS pruneblockchain 504500 + bitcoin-cli $OPTS stop + while sleep 10 + do # Wait for shutdown + if [ ! -f /home/bitcoin/big-disk/bitcoind.pid ] && [ ! -f /home/bitcoin/big-disk/testnet3/bitcoind.pid ]; then + break + fi + done + break + fi +done + +# Move pruned blocks to /home/bitcoin/.bitcoin +if ! cat /etc/bitcoin/bitcoin.conf | grep '^testnet=1'; then + mv /home/bitcoin/big-disk/blocks/*.dat /home/bitcoin/.bitcoin/blocks + mv /home/bitcoin/big-disk/blocks/index/* /home/bitcoin/.bitcoin/blocks/index + mv /home/bitcoin/big-disk/chainstate /home/bitcoin/.bitcoin +else + mv /home/bitcoin/big-disk/testnet3/blocks/*.dat /home/bitcoin/.bitcoin/testnet3/blocks + mv /home/bitcoin/big-disk/testnet3/blocks/index/* /home/bitcoin/.bitcoin/testnet3/blocks/index + mv /home/bitcoin/big-disk/testnet3/chainstate /home/bitcoin/.bitcoin/testnet3 +fi + +# Remove big disk symlink +rm /home/bitcoin/big-disk + +# Mark IBD as done: +touch /home/bitcoin/.ibd_service_finished +touch /home/bitcoin/.ibd_service_requests_shutdown diff --git a/vendor/bitcoin/wait_for_ibd.sh b/vendor/bitcoin/wait_for_ibd.sh deleted file mode 100755 index 5fd740f..0000000 --- a/vendor/bitcoin/wait_for_ibd.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -o pipefail -export OPTS="-conf=/etc/bitcoin/bitcoin.conf -datadir=/mnt/ssd/bitcoin" -while sleep 60 -do - if bitcoin-cli $OPTS getblockchaininfo | jq -e '.initialblockdownload==false'; then - # Prune to slightly before (a lot on testnet) the first Lightning block: - bitcoin-cli $OPTS pruneblockchain 504500 - bitcoin-cli $OPTS stop - while sleep 10 - do # Wait for shutdown - if [ ! -f /mnt/ssd/bitcoin/bitcoind.pid ] && [ ! -f /mnt/ssd/bitcoin/testnet3/bitcoind.pid ]; then - break - fi - done - break - fi -done diff --git a/vendor/charge/lightning-charge.path b/vendor/charge/lightning-charge.path new file mode 100644 index 0000000..cda57b4 --- /dev/null +++ b/vendor/charge/lightning-charge.path @@ -0,0 +1,2 @@ +[Path] +PathExists=/home/bitcoin/.ibd_service_finished diff --git a/vendor/charge/lightning-charge.service b/vendor/charge/lightning-charge.service index 7d1eaa6..95ed2f5 100644 --- a/vendor/charge/lightning-charge.service +++ b/vendor/charge/lightning-charge.service @@ -1,7 +1,8 @@ [Unit] Description=Lightning charge -Requires=lightningd.service +Wants=lightningd.service After=lightningd.service +ConditionPathExists=/home/bitcoin/.ibd_service_finished [Service] EnvironmentFile=/home/charge/.env diff --git a/vendor/lightning/lightningd.path b/vendor/lightning/lightningd.path new file mode 100644 index 0000000..cda57b4 --- /dev/null +++ b/vendor/lightning/lightningd.path @@ -0,0 +1,2 @@ +[Path] +PathExists=/home/bitcoin/.ibd_service_finished diff --git a/vendor/lightning/lightningd.service b/vendor/lightning/lightningd.service index b65251d..7594427 100644 --- a/vendor/lightning/lightningd.service +++ b/vendor/lightning/lightningd.service @@ -1,6 +1,8 @@ [Unit] Description=Lightning daemon After=bitcoind.service +Wants=bitcoind.service +ConditionPathExists=/home/bitcoin/.ibd_service_finished [Service] ExecStart=/usr/local/bin/lightningd --daemon --pid-file=/run/lightningd/lightningd.pid --rpc-file=/run/lightningd/lightning-rpc