From 173a0feb4a3461fd52977dd7887642778d032045 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Fri, 13 Apr 2018 15:23:15 +0200 Subject: [PATCH 1/9] added package definition for Bitcoin Cash backend --- contrib/backends/Makefile | 2 +- contrib/backends/bcash/Makefile | 14 ++++++ contrib/backends/bcash/bch-testnet.conf | 13 ++++++ contrib/backends/bcash/bch.conf | 12 +++++ .../backends/bcash/debian/bcash-bch.conffiles | 1 + contrib/backends/bcash/debian/bcash-bch.dirs | 1 + .../backends/bcash/debian/bcash-bch.install | 2 + .../backends/bcash/debian/bcash-bch.logrotate | 10 +++++ .../backends/bcash/debian/bcash-bch.postinst | 20 +++++++++ .../backends/bcash/debian/bcash-bch.service | 44 +++++++++++++++++++ .../bcash/debian/bcash-testnet.conffiles | 1 + .../backends/bcash/debian/bcash-testnet.dirs | 1 + .../bcash/debian/bcash-testnet.install | 2 + .../bcash/debian/bcash-testnet.logrotate | 10 +++++ .../bcash/debian/bcash-testnet.postinst | 20 +++++++++ .../bcash/debian/bcash-testnet.service | 44 +++++++++++++++++++ contrib/backends/bcash/debian/changelog | 5 +++ contrib/backends/bcash/debian/compat | 1 + contrib/backends/bcash/debian/control | 16 +++++++ contrib/backends/bcash/debian/rules | 6 +++ 20 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 contrib/backends/bcash/Makefile create mode 100644 contrib/backends/bcash/bch-testnet.conf create mode 100644 contrib/backends/bcash/bch.conf create mode 100644 contrib/backends/bcash/debian/bcash-bch.conffiles create mode 100644 contrib/backends/bcash/debian/bcash-bch.dirs create mode 100644 contrib/backends/bcash/debian/bcash-bch.install create mode 100644 contrib/backends/bcash/debian/bcash-bch.logrotate create mode 100644 contrib/backends/bcash/debian/bcash-bch.postinst create mode 100644 contrib/backends/bcash/debian/bcash-bch.service create mode 100644 contrib/backends/bcash/debian/bcash-testnet.conffiles create mode 100644 contrib/backends/bcash/debian/bcash-testnet.dirs create mode 100644 contrib/backends/bcash/debian/bcash-testnet.install create mode 100644 contrib/backends/bcash/debian/bcash-testnet.logrotate create mode 100644 contrib/backends/bcash/debian/bcash-testnet.postinst create mode 100644 contrib/backends/bcash/debian/bcash-testnet.service create mode 100644 contrib/backends/bcash/debian/changelog create mode 100644 contrib/backends/bcash/debian/compat create mode 100644 contrib/backends/bcash/debian/control create mode 100755 contrib/backends/bcash/debian/rules diff --git a/contrib/backends/Makefile b/contrib/backends/Makefile index 1d3e964c..8331a7bf 100644 --- a/contrib/backends/Makefile +++ b/contrib/backends/Makefile @@ -1,4 +1,4 @@ -TARGETS = bitcoin zcash +TARGETS = bitcoin zcash bcash IMAGE = blockbook-backend-build-deb NO_CACHE = false diff --git a/contrib/backends/bcash/Makefile b/contrib/backends/bcash/Makefile new file mode 100644 index 00000000..5b958fdc --- /dev/null +++ b/contrib/backends/bcash/Makefile @@ -0,0 +1,14 @@ +BITCOINABC_VERSION := 0.17.0 + +all: + wget https://download.bitcoinabc.org/0.17.0/linux/bitcoin-abc-${BITCOINABC_VERSION}-x86_64-linux-gnu.tar.gz + tar -xf bitcoin-abc-${BITCOINABC_VERSION}-x86_64-linux-gnu.tar.gz + mv bitcoin-abc-${BITCOINABC_VERSION} bitcoin-abc + rm bitcoin-abc/bin/bitcoin-qt + rm bitcoin-abc/bin/bitcoin-tx + rm bitcoin-abc/bin/bitcoin-seeder + rm bitcoin-abc/bin/test_bitcoin + +clean: + rm -rf bitcoin-abc + rm -f bitcoin-abc-${BITCOINABC_VERSION}-x86_64-linux-gnu.tar.gz* diff --git a/contrib/backends/bcash/bch-testnet.conf b/contrib/backends/bcash/bch-testnet.conf new file mode 100644 index 00000000..a524d0d6 --- /dev/null +++ b/contrib/backends/bcash/bch-testnet.conf @@ -0,0 +1,13 @@ +daemon=1 +server=1 +testnet=1 +nolisten=1 +rpcuser=rpc +rpcpassword=rpc +rpcport=18432 +txindex=1 +rpcworkqueue=32 +zmqpubhashtx=tcp://127.0.0.1:18434 +zmqpubhashblock=tcp://127.0.0.1:18434 +zmqpubrawblock=tcp://127.0.0.1:18434 +zmqpubrawtx=tcp://127.0.0.1:18434 diff --git a/contrib/backends/bcash/bch.conf b/contrib/backends/bcash/bch.conf new file mode 100644 index 00000000..718a68a8 --- /dev/null +++ b/contrib/backends/bcash/bch.conf @@ -0,0 +1,12 @@ +daemon=1 +server=1 +nolisten=1 +rpcuser=rpc +rpcpassword=rpc +rpcport=8432 +txindex=1 +rpcworkqueue=32 +zmqpubhashtx=tcp://127.0.0.1:8434 +zmqpubhashblock=tcp://127.0.0.1:8434 +zmqpubrawblock=tcp://127.0.0.1:8434 +zmqpubrawtx=tcp://127.0.0.1:8434 diff --git a/contrib/backends/bcash/debian/bcash-bch.conffiles b/contrib/backends/bcash/debian/bcash-bch.conffiles new file mode 100644 index 00000000..e8931283 --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-bch.conffiles @@ -0,0 +1 @@ +/opt/bitcoin/bch/bch.conf diff --git a/contrib/backends/bcash/debian/bcash-bch.dirs b/contrib/backends/bcash/debian/bcash-bch.dirs new file mode 100644 index 00000000..ad156456 --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-bch.dirs @@ -0,0 +1 @@ +/data/bch/bitcoin diff --git a/contrib/backends/bcash/debian/bcash-bch.install b/contrib/backends/bcash/debian/bcash-bch.install new file mode 100644 index 00000000..c002ed3e --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-bch.install @@ -0,0 +1,2 @@ +bitcoin-abc/* /opt/bitcoin/bch +bch.conf /opt/bitcoin/bch diff --git a/contrib/backends/bcash/debian/bcash-bch.logrotate b/contrib/backends/bcash/debian/bcash-bch.logrotate new file mode 100644 index 00000000..130eb1dc --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-bch.logrotate @@ -0,0 +1,10 @@ +/data/bch/bitcoin/debug.log +/data/bch/bitcoin/db.log +{ + rotate 7 + daily + compress + missingok + notifempty + copytruncate +} diff --git a/contrib/backends/bcash/debian/bcash-bch.postinst b/contrib/backends/bcash/debian/bcash-bch.postinst new file mode 100644 index 00000000..2f0885aa --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-bch.postinst @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u bitcoin &> /dev/null + then + useradd --system -M -U bitcoin + fi + + if [ "$(stat -c '%U' /data/btc/bitcoin)" != "bitcoin" ] + then + chown bitcoin:bitcoin /data/bch/bitcoin + fi + ;; + +esac + +#DEBHELPER# diff --git a/contrib/backends/bcash/debian/bcash-bch.service b/contrib/backends/bcash/debian/bcash-bch.service new file mode 100644 index 00000000..298e0d97 --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-bch.service @@ -0,0 +1,44 @@ +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit bcash-bch.service +# See "man systemd.service" for details. + +# Note that almost all daemon options could be specified in +# /opt/bitcoin/bch/bch.conf + +[Unit] +Description=Bitcoin Cash daemon (mainnet) +After=network.target + +[Service] +ExecStart=/opt/bitcoin/bch/bin/bitcoind -datadir=/data/bch/bitcoin -conf=/opt/bitcoin/bch/bch.conf -pid=/run/bitcoind/bch.pid +# Creates /run/bitcoind owned by bitcoin +RuntimeDirectory=bitcoind +User=bitcoin +Type=forking +PIDFile=/run/bitcoind/bch.pid +Restart=on-failure + +# 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 diff --git a/contrib/backends/bcash/debian/bcash-testnet.conffiles b/contrib/backends/bcash/debian/bcash-testnet.conffiles new file mode 100644 index 00000000..a1304926 --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-testnet.conffiles @@ -0,0 +1 @@ +/opt/bitcoin/bch-testnet/bch-testnet.conf diff --git a/contrib/backends/bcash/debian/bcash-testnet.dirs b/contrib/backends/bcash/debian/bcash-testnet.dirs new file mode 100644 index 00000000..86472a15 --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-testnet.dirs @@ -0,0 +1 @@ +/data/bch-testnet/bitcoin diff --git a/contrib/backends/bcash/debian/bcash-testnet.install b/contrib/backends/bcash/debian/bcash-testnet.install new file mode 100644 index 00000000..ce91977a --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-testnet.install @@ -0,0 +1,2 @@ +bitcoin-abc/* /opt/bitcoin/bch-testnet +bch-testnet.conf /opt/bitcoin/bch-testnet diff --git a/contrib/backends/bcash/debian/bcash-testnet.logrotate b/contrib/backends/bcash/debian/bcash-testnet.logrotate new file mode 100644 index 00000000..d009963f --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-testnet.logrotate @@ -0,0 +1,10 @@ +/data/bch-testnet/bitcoin/testnet3/debug.log +/data/bch-testnet/bitcoin/testnet3/db.log +{ + rotate 7 + daily + compress + missingok + notifempty + copytruncate +} diff --git a/contrib/backends/bcash/debian/bcash-testnet.postinst b/contrib/backends/bcash/debian/bcash-testnet.postinst new file mode 100644 index 00000000..33dec1ef --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-testnet.postinst @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u bitcoin &> /dev/null + then + useradd --system -M -U bitcoin + fi + + if [ "$(stat -c '%U' /data/bch-testnet/bitcoin)" != "bitcoin" ] + then + chown bitcoin:bitcoin /data/bch-testnet/bitcoin + fi + ;; + +esac + +#DEBHELPER# diff --git a/contrib/backends/bcash/debian/bcash-testnet.service b/contrib/backends/bcash/debian/bcash-testnet.service new file mode 100644 index 00000000..56d8fc31 --- /dev/null +++ b/contrib/backends/bcash/debian/bcash-testnet.service @@ -0,0 +1,44 @@ +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit bcash-testnet.service +# See "man systemd.service" for details. + +# Note that almost all daemon options could be specified in +# /opt/bitcoin/bch-testnet/bch-testnet.conf + +[Unit] +Description=Bitcoin Cash daemon (testnet) +After=network.target + +[Service] +ExecStart=/opt/bitcoin/bch-testnet/bin/bitcoind -datadir=/data/bch-testnet/bitcoin -conf=/opt/bitcoin/bch-testnet/bch-testnet.conf -pid=/run/bitcoind/bch-testnet.pid +# Creates /run/bitcoind owned by bitcoin +RuntimeDirectory=bitcoind +User=bitcoin +Type=forking +PIDFile=/run/bitcoind/bch-testnet.pid +Restart=on-failure + +# 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 diff --git a/contrib/backends/bcash/debian/changelog b/contrib/backends/bcash/debian/changelog new file mode 100644 index 00000000..464f4c7d --- /dev/null +++ b/contrib/backends/bcash/debian/changelog @@ -0,0 +1,5 @@ +bcash (0.17.0-satoshilabs1) unstable; urgency=medium + + * Initial build + + -- Jakub Matys Fri, 13 Apr 2018 11:31:01 +0200 diff --git a/contrib/backends/bcash/debian/compat b/contrib/backends/bcash/debian/compat new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/contrib/backends/bcash/debian/compat @@ -0,0 +1 @@ +9 diff --git a/contrib/backends/bcash/debian/control b/contrib/backends/bcash/debian/control new file mode 100644 index 00000000..e7223d94 --- /dev/null +++ b/contrib/backends/bcash/debian/control @@ -0,0 +1,16 @@ +Source: bcash +Section: satoshilabs +Priority: optional +Maintainer: jakub.matys@satoshilabs.com +Build-Depends: debhelper, wget, tar, gzip, make, dh-systemd, dh-exec +Standards-Version: 3.9.5 + +Package: bcash-bch +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, logrotate +Description: Satoshilabs packaged bitcoin-cash server + +Package: bcash-testnet +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, logrotate +Description: Satoshilabs packaged bitcoin-cash server diff --git a/contrib/backends/bcash/debian/rules b/contrib/backends/bcash/debian/rules new file mode 100755 index 00000000..e9b6951b --- /dev/null +++ b/contrib/backends/bcash/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +DH_VERBOSE = 1 + +%: + dh $@ --with=systemd From 11e519970ed79ad3704c4ae4e0409825b0733229 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Mon, 16 Apr 2018 19:50:34 +0200 Subject: [PATCH 2/9] added package definition for Bitcoin Cash blockbook --- .../debian/blockbook-bch-testnet.conffiles | 1 + .../debian/blockbook-bch-testnet.cron.daily | 2 + build/deb/debian/blockbook-bch-testnet.dirs | 2 + .../deb/debian/blockbook-bch-testnet.install | 5 +++ build/deb/debian/blockbook-bch-testnet.links | 2 + .../deb/debian/blockbook-bch-testnet.postinst | 23 +++++++++++ .../deb/debian/blockbook-bch-testnet.service | 39 +++++++++++++++++++ build/deb/debian/blockbook-bch.conffiles | 1 + build/deb/debian/blockbook-bch.cron.daily | 2 + build/deb/debian/blockbook-bch.dirs | 2 + build/deb/debian/blockbook-bch.install | 5 +++ build/deb/debian/blockbook-bch.links | 2 + build/deb/debian/blockbook-bch.postinst | 23 +++++++++++ build/deb/debian/blockbook-bch.service | 39 +++++++++++++++++++ build/deb/debian/control | 16 ++++++-- configs/bch-testnet.json | 8 ++++ configs/bch.json | 8 ++++ 17 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 build/deb/debian/blockbook-bch-testnet.conffiles create mode 100644 build/deb/debian/blockbook-bch-testnet.cron.daily create mode 100644 build/deb/debian/blockbook-bch-testnet.dirs create mode 100755 build/deb/debian/blockbook-bch-testnet.install create mode 100644 build/deb/debian/blockbook-bch-testnet.links create mode 100644 build/deb/debian/blockbook-bch-testnet.postinst create mode 100644 build/deb/debian/blockbook-bch-testnet.service create mode 100644 build/deb/debian/blockbook-bch.conffiles create mode 100644 build/deb/debian/blockbook-bch.cron.daily create mode 100644 build/deb/debian/blockbook-bch.dirs create mode 100755 build/deb/debian/blockbook-bch.install create mode 100644 build/deb/debian/blockbook-bch.links create mode 100644 build/deb/debian/blockbook-bch.postinst create mode 100644 build/deb/debian/blockbook-bch.service create mode 100644 configs/bch-testnet.json create mode 100644 configs/bch.json diff --git a/build/deb/debian/blockbook-bch-testnet.conffiles b/build/deb/debian/blockbook-bch-testnet.conffiles new file mode 100644 index 00000000..51318941 --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.conffiles @@ -0,0 +1 @@ +/opt/blockbook/bch-testnet/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-bch-testnet.cron.daily b/build/deb/debian/blockbook-bch-testnet.cron.daily new file mode 100644 index 00000000..4827959f --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.cron.daily @@ -0,0 +1,2 @@ +#!/bin/sh +find /opt/blockbook/bch-testnet/logs -mtime +6 -type f -delete diff --git a/build/deb/debian/blockbook-bch-testnet.dirs b/build/deb/debian/blockbook-bch-testnet.dirs new file mode 100644 index 00000000..c2be0d25 --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.dirs @@ -0,0 +1,2 @@ +/data/bch-testnet/blockbook +/opt/blockbook/bch-testnet/logs diff --git a/build/deb/debian/blockbook-bch-testnet.install b/build/deb/debian/blockbook-bch-testnet.install new file mode 100755 index 00000000..ac6b38e6 --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.install @@ -0,0 +1,5 @@ +#!/usr/bin/dh-exec +blockbook /opt/blockbook/bch-testnet/bin +server/testcert.* /opt/blockbook/bch-testnet/cert +server/static /opt/blockbook/bch-testnet +configs/bch-testnet.json => /opt/blockbook/bch-testnet/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-bch-testnet.links b/build/deb/debian/blockbook-bch-testnet.links new file mode 100644 index 00000000..a2ffacc3 --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.links @@ -0,0 +1,2 @@ +/opt/blockbook/bch-testnet/cert/testcert.crt /opt/blockbook/bch-testnet/cert/blockbook.crt +/opt/blockbook/bch-testnet/cert/testcert.key /opt/blockbook/bch-testnet/cert/blockbook.key diff --git a/build/deb/debian/blockbook-bch-testnet.postinst b/build/deb/debian/blockbook-bch-testnet.postinst new file mode 100644 index 00000000..6e94b440 --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.postinst @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u blockbook &> /dev/null + then + useradd --system -M -U blockbook + fi + + for dir in /data/bch-testnet/blockbook /opt/blockbook/bch-testnet/logs + do + if [ "$(stat -c '%U' $dir)" != "blockbook" ] + then + chown -R blockbook:blockbook $dir + fi + done + ;; + +esac + +#DEBHELPER# diff --git a/build/deb/debian/blockbook-bch-testnet.service b/build/deb/debian/blockbook-bch-testnet.service new file mode 100644 index 00000000..ee5b1d7f --- /dev/null +++ b/build/deb/debian/blockbook-bch-testnet.service @@ -0,0 +1,39 @@ +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit blockbook-bch-testnet.service +# See "man systemd.service" for details. + +[Unit] +Description=Blockbook daemon (BCH testnet) +After=network.target + +[Service] +ExecStart=/opt/blockbook/bch-testnet/bin/blockbook -coin=bch-testnet -blockchaincfg=/opt/blockbook/bch-testnet/config/blockchaincfg.json -datadir=/data/bch-testnet/blockbook/db -sync -httpserver=:18435 -socketio=:18436 -certfile=/opt/blockbook/bch-testnet/cert/blockbook -explorer=https://bch-bitcore1.trezor.io/ -log_dir=/opt/blockbook/bch-testnet/logs +User=blockbook +Type=simple +Restart=on-failure +WorkingDirectory=/opt/blockbook/bch-testnet + +# 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 diff --git a/build/deb/debian/blockbook-bch.conffiles b/build/deb/debian/blockbook-bch.conffiles new file mode 100644 index 00000000..7195f6f3 --- /dev/null +++ b/build/deb/debian/blockbook-bch.conffiles @@ -0,0 +1 @@ +/opt/blockbook/bch/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-bch.cron.daily b/build/deb/debian/blockbook-bch.cron.daily new file mode 100644 index 00000000..f6fc7427 --- /dev/null +++ b/build/deb/debian/blockbook-bch.cron.daily @@ -0,0 +1,2 @@ +#!/bin/sh +find /opt/blockbook/bch/logs -mtime +6 -type f -delete diff --git a/build/deb/debian/blockbook-bch.dirs b/build/deb/debian/blockbook-bch.dirs new file mode 100644 index 00000000..5f081d6a --- /dev/null +++ b/build/deb/debian/blockbook-bch.dirs @@ -0,0 +1,2 @@ +/data/bch/blockbook +/opt/blockbook/bch/logs diff --git a/build/deb/debian/blockbook-bch.install b/build/deb/debian/blockbook-bch.install new file mode 100755 index 00000000..bec00277 --- /dev/null +++ b/build/deb/debian/blockbook-bch.install @@ -0,0 +1,5 @@ +#!/usr/bin/dh-exec +blockbook /opt/blockbook/bch/bin +server/testcert.* /opt/blockbook/bch/cert +server/static /opt/blockbook/bch +configs/bch.json => /opt/blockbook/bch/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-bch.links b/build/deb/debian/blockbook-bch.links new file mode 100644 index 00000000..e236a84c --- /dev/null +++ b/build/deb/debian/blockbook-bch.links @@ -0,0 +1,2 @@ +/opt/blockbook/bch/cert/testcert.crt /opt/blockbook/bch/cert/blockbook.crt +/opt/blockbook/bch/cert/testcert.key /opt/blockbook/bch/cert/blockbook.key diff --git a/build/deb/debian/blockbook-bch.postinst b/build/deb/debian/blockbook-bch.postinst new file mode 100644 index 00000000..f40d9728 --- /dev/null +++ b/build/deb/debian/blockbook-bch.postinst @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +case "$1" in + + configure) + if ! id -u blockbook &> /dev/null + then + useradd --system -M -U blockbook + fi + + for dir in /data/bch/blockbook /opt/blockbook/bch/logs + do + if [ "$(stat -c '%U' $dir)" != "blockbook" ] + then + chown -R blockbook:blockbook $dir + fi + done + ;; + +esac + +#DEBHELPER# diff --git a/build/deb/debian/blockbook-bch.service b/build/deb/debian/blockbook-bch.service new file mode 100644 index 00000000..e9c74a4f --- /dev/null +++ b/build/deb/debian/blockbook-bch.service @@ -0,0 +1,39 @@ +# It is not recommended to modify this file in-place, because it will +# be overwritten during package upgrades. If you want to add further +# options or overwrite existing ones then use +# $ systemctl edit blockbook-bch.service +# See "man systemd.service" for details. + +[Unit] +Description=Blockbook daemon (BCH mainnet) +After=network.target + +[Service] +ExecStart=/opt/blockbook/bch/bin/blockbook -coin=bch -blockchaincfg=/opt/blockbook/bch/config/blockchaincfg.json -datadir=/data/bch/blockbook/db -sync -httpserver=:8435 -socketio=:8436 -certfile=/opt/blockbook/bch/cert/blockbook -explorer=https://bitcore1.trezor.io/ -log_dir=/opt/blockbook/bch/logs +User=blockbook +Type=simple +Restart=on-failure +WorkingDirectory=/opt/blockbook/bch + +# 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 diff --git a/build/deb/debian/control b/build/deb/debian/control index 5ab64d64..74a071a1 100644 --- a/build/deb/debian/control +++ b/build/deb/debian/control @@ -8,14 +8,24 @@ Standards-Version: 3.9.5 Package: blockbook-btc Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils -Description: Satoshilabs blockbook server +Description: Satoshilabs blockbook server (Bitcoin mainnet) Package: blockbook-btc-testnet Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils -Description: Satoshilabs blockbook server +Description: Satoshilabs blockbook server (Bitcoin testnet) Package: blockbook-zec Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils -Description: Satoshilabs blockbook server +Description: Satoshilabs blockbook server (ZCash mainnet) + +Package: blockbook-bch +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils +Description: Satoshilabs blockbook server (Bitcoin Cash mainnet) + +Package: blockbook-bch-testnet +Architecture: amd64 +Depends: ${shlibs:Depends}, ${misc:Depends}, coreutils, passwd, findutils +Description: Satoshilabs blockbook server (Bitcoin Cash testnet) diff --git a/configs/bch-testnet.json b/configs/bch-testnet.json new file mode 100644 index 00000000..606eb66a --- /dev/null +++ b/configs/bch-testnet.json @@ -0,0 +1,8 @@ +{ + "rpcURL": "http://localhost:18432", + "rpcUser": "rpc", + "rpcPass": "rpc", + "rpcTimeout": 25, + "parse": true, + "zeroMQBinding": "tcp://127.0.0.1:18434" +} diff --git a/configs/bch.json b/configs/bch.json new file mode 100644 index 00000000..e124c7af --- /dev/null +++ b/configs/bch.json @@ -0,0 +1,8 @@ +{ + "rpcURL": "http://127.0.0.1:8432", + "rpcUser": "rpc", + "rpcPass": "rpc", + "rpcTimeout": 25, + "parse": true, + "zeroMQBinding": "tcp://127.0.0.1:8434" +} From 5cf9dd11690b7587c3ee234142a71590b070b482 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Mon, 16 Apr 2018 19:51:35 +0200 Subject: [PATCH 3/9] quickfix of tests execution --- build/bin/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/bin/Makefile b/build/bin/Makefile index 932285c9..31e683ef 100644 --- a/build/bin/Makefile +++ b/build/bin/Makefile @@ -9,10 +9,12 @@ build-debug: prepare-sources chown $(PACKAGER) /out/blockbook test: prepare-sources - cd $(GOPATH)/src/blockbook && go test -short ./... + #cd $(GOPATH)/src/blockbook && go test -short ./... # FIXME + cd $(GOPATH)/src/blockbook && go test -short ./bchain/coins/btc ./bchain/coins/bch ./bchain/coins/eth ./bchain/coins/zec test-all: prepare-sources - cd $(GOPATH)/src/blockbook && go test ./... + # cd $(GOPATH)/src/blockbook && go test ./... # FIXME + cd $(GOPATH)/src/blockbook && go test ./bchain/coins/btc ./bchain/coins/bch ./bchain/coins/eth ./bchain/coins/zec prepare-sources: @ [ -n "`ls /src 2> /dev/null`" ] || (echo "/src doesn't exist or is empty" 1>&2 && exit 1) From a8e603d945a763b0b51a2a8aff8879e719959ffa Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Wed, 18 Apr 2018 14:15:19 +0100 Subject: [PATCH 4/9] added Bitcoin Cash's rpc and parser --- Gopkg.lock | 8 +- Gopkg.toml | 4 + bchain/coins/bch/bcashparser.go | 75 +++++++++++++ bchain/coins/bch/bcashrpc.go | 180 ++++++++++++++++++++++++++++++++ bchain/coins/blockchain.go | 3 + 5 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 bchain/coins/bch/bcashparser.go create mode 100644 bchain/coins/bch/bcashrpc.go diff --git a/Gopkg.lock b/Gopkg.lock index 1cac8e92..a40eb931 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -31,6 +31,12 @@ packages = [".","base58","bech32"] revision = "501929d3d046174c3d39f0ea54ece471aa17238c" +[[projects]] + branch = "master" + name = "github.com/cpacia/bchutil" + packages = ["."] + revision = "12e86f41eb040d3b85b5d8e3a3a4bed035517c52" + [[projects]] name = "github.com/ethereum/go-ethereum" packages = [".","common","common/hexutil","common/math","core/types","crypto","crypto/secp256k1","crypto/sha3","ethclient","ethdb","log","metrics","params","rlp","rpc","trie"] @@ -184,6 +190,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "a463c234bc11d9917876a827f692392845ed89571edc1484ae3e932f555d484b" + inputs-digest = "e632a1e904953397e9eae00f30a86bffab2d303232c7bac47a16e1ce663043bf" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a70bb0c3..e0144613 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -72,3 +72,7 @@ [[constraint]] name = "github.com/golang/protobuf" version = "1.0.0" + +[[constraint]] + branch = "master" + name = "github.com/cpacia/bchutil" diff --git a/bchain/coins/bch/bcashparser.go b/bchain/coins/bch/bcashparser.go new file mode 100644 index 00000000..3df5f65e --- /dev/null +++ b/bchain/coins/bch/bcashparser.go @@ -0,0 +1,75 @@ +package bch + +import ( + "blockbook/bchain/coins/btc" + "strings" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcutil" + "github.com/cpacia/bchutil" +) + +var prefixes []string + +func init() { + prefixes = make([]string, 0, len(bchutil.Prefixes)) + for _, prefix := range bchutil.Prefixes { + prefixes = append(prefixes, prefix) + } +} + +// BCashParser handle +type BCashParser struct { + *btc.BitcoinParser +} + +// GetChainParams contains network parameters for the main Bitcoin Cash network, +// the regression test Bitcoin Cash network, the test Bitcoin Cash network and +// the simulation test Bitcoin Cash network, in this order +func GetChainParams(chain string) *chaincfg.Params { + var params *chaincfg.Params + switch chain { + case "test": + params = &chaincfg.TestNet3Params + params.Net = bchutil.TestnetMagic + case "regtest": + params = &chaincfg.RegressionNetParams + params.Net = bchutil.Regtestmagic + default: + params = &chaincfg.MainNetParams + params.Net = bchutil.MainnetMagic + } + + return params +} + +// GetAddrIDFromAddress returns internal address representation of given address +func (p *BCashParser) GetAddrIDFromAddress(address string) ([]byte, error) { + return p.AddressToOutputScript(address) +} + +// AddressToOutputScript converts bitcoin address to ScriptPubKey +func (p *BCashParser) AddressToOutputScript(address string) ([]byte, error) { + if strings.Contains(address, ":") { + da, err := bchutil.DecodeAddress(address, p.Params) + if err != nil { + return nil, err + } + script, err := bchutil.PayToAddrScript(da) + if err != nil { + return nil, err + } + return script, nil + } else { + da, err := btcutil.DecodeAddress(address, p.Params) + if err != nil { + return nil, err + } + script, err := txscript.PayToAddrScript(da) + if err != nil { + return nil, err + } + return script, nil + } +} diff --git a/bchain/coins/bch/bcashrpc.go b/bchain/coins/bch/bcashrpc.go new file mode 100644 index 00000000..222a7b78 --- /dev/null +++ b/bchain/coins/bch/bcashrpc.go @@ -0,0 +1,180 @@ +package bch + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "encoding/hex" + "encoding/json" + + "github.com/cpacia/bchutil" + "github.com/golang/glog" + "github.com/juju/errors" +) + +// BCashRPC is an interface to JSON-RPC bitcoind service. +type BCashRPC struct { + *btc.BitcoinRPC +} + +// NewBCashRPC returns new BCashRPC instance. +func NewBCashRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + b, err := btc.NewBitcoinRPC(config, pushHandler) + if err != nil { + return nil, err + } + + s := &BCashRPC{ + b.(*btc.BitcoinRPC), + } + + return s, nil +} + +func (b *BCashRPC) Initialize() error { + b.Mempool = bchain.NewUTXOMempool(b) + + chainName, err := b.GetBlockChainInfo() + if err != nil { + return err + } + + params := GetChainParams(chainName) + + // always create parser + b.Parser = &BCashParser{ + &btc.BitcoinParser{ + Params: params, + }, + } + + // parameters for getInfo request + if params.Net == bchutil.MainnetMagic { + b.Testnet = false + b.Network = "livenet" + } else { + b.Testnet = true + b.Network = "testnet" + } + + glog.Info("rpc: block chain ", params.Name) + + return nil +} + +// getblock + +type cmdGetBlock struct { + Method string `json:"method"` + Params struct { + BlockHash string `json:"blockhash"` + Verbose bool `json:"verbose"` + } `json:"params"` +} + +type resGetBlockRaw struct { + Error *bchain.RPCError `json:"error"` + Result string `json:"result"` +} + +type resGetBlockThin struct { + Error *bchain.RPCError `json:"error"` + Result bchain.ThinBlock `json:"result"` +} + +// GetBlock returns block with given hash. +func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { + var err error + if hash == "" && height > 0 { + hash, err = b.GetBlockHash(height) + if err != nil { + return nil, err + } + } + // XXX + // // optimization + // if height > 0 { + // return b.getBlockWithoutHeader(hash, height) + // } + header, err := b.GetBlockHeader(hash) + if err != nil { + return nil, err + } + data, err := b.GetBlockRaw(hash) + if err != nil { + return nil, err + } + block, err := b.Parser.ParseBlock(data) + if err != nil { + return nil, errors.Annotatef(err, "hash %v", hash) + } + block.BlockHeader = *header + return block, nil +} + +// GetBlockRaw returns block with given hash as bytes. +func (b *BCashRPC) GetBlockRaw(hash string) ([]byte, error) { + glog.V(1).Info("rpc: getblock (verbose=0) ", hash) + + res := resGetBlockRaw{} + req := cmdGetBlock{Method: "getblock"} + req.Params.BlockHash = hash + req.Params.Verbose = false + err := b.Call(&req, &res) + + if err != nil { + return nil, errors.Annotatef(err, "hash %v", hash) + } + if res.Error != nil { + if isErrBlockNotFound(res.Error) { + return nil, bchain.ErrBlockNotFound + } + return nil, errors.Annotatef(res.Error, "hash %v", hash) + } + return hex.DecodeString(res.Result) +} + +// GetBlockList returns block with given hash by downloading block +// transactions one by one. +func (b *BCashRPC) GetBlockList(hash string) (*bchain.Block, error) { + glog.V(1).Info("rpc: getblock (verbose=1) ", hash) + + res := resGetBlockThin{} + req := cmdGetBlock{Method: "getblock"} + req.Params.BlockHash = hash + req.Params.Verbose = true + err := b.Call(&req, &res) + + if err != nil { + return nil, errors.Annotatef(err, "hash %v", hash) + } + if res.Error != nil { + if isErrBlockNotFound(res.Error) { + return nil, bchain.ErrBlockNotFound + } + return nil, errors.Annotatef(res.Error, "hash %v", hash) + } + + txs := make([]bchain.Tx, len(res.Result.Txids)) + for i, txid := range res.Result.Txids { + tx, err := b.GetTransaction(txid) + if err != nil { + return nil, err + } + txs[i] = *tx + } + block := &bchain.Block{ + BlockHeader: res.Result.BlockHeader, + Txs: txs, + } + return block, nil +} + +// GetBlockFull returns block with given hash. +func (b *BCashRPC) GetBlockFull(hash string) (*bchain.Block, error) { + return nil, errors.New("Not implemented") +} + +func isErrBlockNotFound(err *bchain.RPCError) bool { + return err.Message == "Block not found" || + err.Message == "Block height out of range" +} diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index 973df631..39f01e6e 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -2,6 +2,7 @@ package coins import ( "blockbook/bchain" + "blockbook/bchain/coins/bch" "blockbook/bchain/coins/btc" "blockbook/bchain/coins/eth" "blockbook/bchain/coins/zec" @@ -25,6 +26,8 @@ func init() { blockChainFactories["zec"] = zec.NewZCashRPC blockChainFactories["eth"] = eth.NewEthereumRPC blockChainFactories["eth-testnet"] = eth.NewEthereumRPC + blockChainFactories["bch"] = bch.NewBCashRPC + blockChainFactories["bch-testnet"] = bch.NewBCashRPC } // NewBlockChain creates bchain.BlockChain of type defined by parameter coin From b88a88ad55140fbd2169fb53b5017bd4a2ac94ba Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Thu, 19 Apr 2018 00:49:56 +0100 Subject: [PATCH 5/9] use abstract address for Vout --- bchain/baseparser.go | 23 +++++++++ bchain/coins/bch/bcashparser.go | 77 ++++++++++++++++++++++++++++++- bchain/coins/btc/bitcoinparser.go | 7 +++ bchain/types.go | 6 +++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/bchain/baseparser.go b/bchain/baseparser.go index 1b831b44..ba8bfb1a 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -2,6 +2,7 @@ package bchain import ( "encoding/hex" + "fmt" "github.com/gogo/protobuf/proto" "github.com/juju/errors" @@ -149,6 +150,9 @@ func (p *BaseParser) UnpackTx(buf []byte) (*Tx, uint32, error) { }, Value: pto.Value, } + if len(pto.Addresses) == 1 { + vout[i].Address = NewBaseAddress(pto.Addresses[0]) + } } tx := Tx{ Blocktime: int64(pt.Blocktime), @@ -161,3 +165,22 @@ func (p *BaseParser) UnpackTx(buf []byte) (*Tx, uint32, error) { } return &tx, pt.Height, nil } + +type baseAddress struct { + addr string +} + +func NewBaseAddress(addr string) Address { + return &baseAddress{addr: addr} +} + +func (a baseAddress) String() string { + return a.addr +} + +func (a baseAddress) EncodeAddress(format uint8) (string, error) { + if format != 0 { + return "", fmt.Errorf("Unknown address format: %d", format) + } + return a.addr, nil +} diff --git a/bchain/coins/bch/bcashparser.go b/bchain/coins/bch/bcashparser.go index 3df5f65e..8eb94292 100644 --- a/bchain/coins/bch/bcashparser.go +++ b/bchain/coins/bch/bcashparser.go @@ -1,13 +1,16 @@ package bch import ( + "blockbook/bchain" "blockbook/bchain/coins/btc" + "fmt" "strings" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcutil" "github.com/cpacia/bchutil" + "github.com/golang/glog" ) var prefixes []string @@ -51,7 +54,7 @@ func (p *BCashParser) GetAddrIDFromAddress(address string) ([]byte, error) { // AddressToOutputScript converts bitcoin address to ScriptPubKey func (p *BCashParser) AddressToOutputScript(address string) ([]byte, error) { - if strings.Contains(address, ":") { + if isCashAddr(address) { da, err := bchutil.DecodeAddress(address, p.Params) if err != nil { return nil, err @@ -73,3 +76,75 @@ func (p *BCashParser) AddressToOutputScript(address string) ([]byte, error) { return script, nil } } + +func isCashAddr(addr string) bool { + slice := strings.Split(addr, ":") + if len(slice) != 2 { + return false + } + for _, prefix := range prefixes { + if slice[0] == prefix { + return true + } + } + return false +} + +func (p *BCashParser) UnpackTx(buf []byte) (tx *bchain.Tx, height uint32, err error) { + tx, height, err = p.BitcoinParser.UnpackTx(buf) + + for i, vout := range tx.Vout { + if len(vout.ScriptPubKey.Addresses) == 1 { + tx.Vout[i].Address = &bcashAddress{ + addr: vout.ScriptPubKey.Addresses[0], + net: p.Params, + } + } + } + + return +} + +type bcashAddress struct { + addr string + net *chaincfg.Params +} + +func (a *bcashAddress) String() string { + return a.addr +} + +type AddressFormat = uint8 + +const ( + LegacyAddress AddressFormat = iota + CashAddress +) + +func (a *bcashAddress) EncodeAddress(format AddressFormat) (string, error) { + switch format { + case LegacyAddress: + return a.String(), nil + case CashAddress: + da, err := btcutil.DecodeAddress(a.addr, a.net) + if err != nil { + return "", err + } + var ca btcutil.Address + switch da := da.(type) { + case *btcutil.AddressPubKeyHash: + ca, err = bchutil.NewCashAddressPubKeyHash(da.Hash160()[:], a.net) + case *btcutil.AddressScriptHash: + ca, err = bchutil.NewCashAddressScriptHash(da.Hash160()[:], a.net) + default: + err = fmt.Errorf("Unknown address type: %T", da) + } + if err != nil { + return "", err + } + return ca.String(), nil + + default: + return "", fmt.Errorf("Unknown address format: %d", format) + } +} diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index 0f1578ae..0c1f2fe7 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -169,5 +169,12 @@ func (p *BitcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { return nil, 0, err } tx.Blocktime = bt + + for i, vout := range tx.Vout { + if len(vout.ScriptPubKey.Addresses) == 1 { + tx.Vout[i].Address = bchain.NewBaseAddress(vout.ScriptPubKey.Addresses[0]) + } + } + return tx, height, nil } diff --git a/bchain/types.go b/bchain/types.go index 8e2a3d1b..59ce276e 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -37,10 +37,16 @@ type ScriptPubKey struct { Addresses []string `json:"addresses,omitempty"` } +type Address interface { + String() string + EncodeAddress(format uint8) (string, error) +} + type Vout struct { Value float64 `json:"value"` N uint32 `json:"n"` ScriptPubKey ScriptPubKey `json:"scriptPubKey"` + Address Address } // Tx is blockchain transaction From 9c9367491846ba1f9479ed967921232cbaf8a178 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Tue, 24 Apr 2018 10:20:26 +0200 Subject: [PATCH 6/9] added support of bcash addresses to RPCs --- bchain/baseparser.go | 25 +++++++- bchain/coins/bch/bcashparser.go | 53 +++++++++++------ bchain/types.go | 11 +++- server/socketio.go | 102 ++++++++++++++++++++++---------- server/static/test.html | 39 +++++++++--- 5 files changed, 168 insertions(+), 62 deletions(-) diff --git a/bchain/baseparser.go b/bchain/baseparser.go index ba8bfb1a..4d6bc761 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -178,9 +178,30 @@ func (a baseAddress) String() string { return a.addr } -func (a baseAddress) EncodeAddress(format uint8) (string, error) { - if format != 0 { +func (a baseAddress) EncodeAddress(format AddressFormat) (string, error) { + if format != DefaultAddress { return "", fmt.Errorf("Unknown address format: %d", format) } return a.addr, nil } + +func (a baseAddress) AreEqual(addr string) (bool, error) { + ea, err := a.EncodeAddress(0) + if err != nil { + return false, err + } + return ea == addr, nil +} + +func (a baseAddress) InSlice(addrs []string) (bool, error) { + for _, addr := range addrs { + eq, err := a.AreEqual(addr) + if err != nil { + return false, err + } + if eq { + return true, nil + } + } + return false, nil +} diff --git a/bchain/coins/bch/bcashparser.go b/bchain/coins/bch/bcashparser.go index 8eb94292..2e1fe9ca 100644 --- a/bchain/coins/bch/bcashparser.go +++ b/bchain/coins/bch/bcashparser.go @@ -10,17 +10,9 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcutil" "github.com/cpacia/bchutil" - "github.com/golang/glog" ) -var prefixes []string - -func init() { - prefixes = make([]string, 0, len(bchutil.Prefixes)) - for _, prefix := range bchutil.Prefixes { - prefixes = append(prefixes, prefix) - } -} +var prefixes = []string{"bitcoincash", "bchtest", "bchreg"} // BCashParser handle type BCashParser struct { @@ -92,6 +84,9 @@ func isCashAddr(addr string) bool { func (p *BCashParser) UnpackTx(buf []byte) (tx *bchain.Tx, height uint32, err error) { tx, height, err = p.BitcoinParser.UnpackTx(buf) + if err != nil { + return + } for i, vout := range tx.Vout { if len(vout.ScriptPubKey.Addresses) == 1 { @@ -114,18 +109,11 @@ func (a *bcashAddress) String() string { return a.addr } -type AddressFormat = uint8 - -const ( - LegacyAddress AddressFormat = iota - CashAddress -) - -func (a *bcashAddress) EncodeAddress(format AddressFormat) (string, error) { +func (a *bcashAddress) EncodeAddress(format bchain.AddressFormat) (string, error) { switch format { - case LegacyAddress: + case bchain.DefaultAddress: return a.String(), nil - case CashAddress: + case bchain.BCashAddress: da, err := btcutil.DecodeAddress(a.addr, a.net) if err != nil { return "", err @@ -148,3 +136,30 @@ func (a *bcashAddress) EncodeAddress(format AddressFormat) (string, error) { return "", fmt.Errorf("Unknown address format: %d", format) } } + +func (a *bcashAddress) AreEqual(addr string) (bool, error) { + var format bchain.AddressFormat + if isCashAddr(addr) { + format = bchain.BCashAddress + } else { + format = bchain.DefaultAddress + } + ea, err := a.EncodeAddress(format) + if err != nil { + return false, err + } + return ea == addr, nil +} + +func (a *bcashAddress) InSlice(addrs []string) (bool, error) { + for _, addr := range addrs { + eq, err := a.AreEqual(addr) + if err != nil { + return false, err + } + if eq { + return true, nil + } + } + return false, nil +} diff --git a/bchain/types.go b/bchain/types.go index 59ce276e..ddc49f4b 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -37,9 +37,18 @@ type ScriptPubKey struct { Addresses []string `json:"addresses,omitempty"` } +type AddressFormat = uint8 + +const ( + DefaultAddress AddressFormat = iota + BCashAddress +) + type Address interface { String() string - EncodeAddress(format uint8) (string, error) + EncodeAddress(format AddressFormat) (string, error) + AreEqual(addr string) (bool, error) + InSlice(addrs []string) (bool, error) } type Vout struct { diff --git a/server/socketio.go b/server/socketio.go index dc84af64..f7cb7007 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -124,27 +124,32 @@ func (s *SocketIoServer) txRedirect(w http.ResponseWriter, r *http.Request) { } } -type reqRange struct { - Start int `json:"start"` - End int `json:"end"` - QueryMempol bool `json:"queryMempol"` - QueryMempoolOnly bool `json:"queryMempoolOnly"` - From int `json:"from"` - To int `json:"to"` +type addrOpts struct { + Start int `json:"start"` + End int `json:"end"` + QueryMempol bool `json:"queryMempol"` + QueryMempoolOnly bool `json:"queryMempoolOnly"` + From int `json:"from"` + To int `json:"to"` + AddressFormat uint8 `json:"addressFormat"` +} + +type txOpts struct { + AddressFormat uint8 `json:"addressFormat"` } var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (interface{}, error){ "getAddressTxids": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { - addr, rr, err := unmarshalGetAddressRequest(params) + addr, opts, err := unmarshalGetAddressRequest(params) if err == nil { - rv, err = s.getAddressTxids(addr, &rr) + rv, err = s.getAddressTxids(addr, &opts) } return }, "getAddressHistory": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { - addr, rr, err := unmarshalGetAddressRequest(params) + addr, opts, err := unmarshalGetAddressRequest(params) if err == nil { - rv, err = s.getAddressHistory(addr, &rr) + rv, err = s.getAddressHistory(addr, &opts) } return }, @@ -173,9 +178,9 @@ var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (inter return s.getInfo() }, "getDetailedTransaction": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { - txid, err := unmarshalStringParameter(params) + txid, opts, err := unmarshalGetDetailedTransaction(params) if err == nil { - rv, err = s.getDetailedTransaction(txid) + rv, err = s.getDetailedTransaction(txid, opts) } return }, @@ -226,7 +231,7 @@ func (s *SocketIoServer) onMessage(c *gosocketio.Channel, req map[string]json.Ra return e } -func unmarshalGetAddressRequest(params []byte) (addr []string, rr reqRange, err error) { +func unmarshalGetAddressRequest(params []byte) (addr []string, opts addrOpts, err error) { var p []json.RawMessage err = json.Unmarshal(params, &p) if err != nil { @@ -240,7 +245,7 @@ func unmarshalGetAddressRequest(params []byte) (addr []string, rr reqRange, err if err != nil { return } - err = json.Unmarshal(p[1], &rr) + err = json.Unmarshal(p[1], &opts) return } @@ -261,14 +266,14 @@ type resultAddressTxids struct { Result []string `json:"result"` } -func (s *SocketIoServer) getAddressTxids(addr []string, rr *reqRange) (res resultAddressTxids, err error) { +func (s *SocketIoServer) getAddressTxids(addr []string, opts *addrOpts) (res resultAddressTxids, err error) { txids := make([]string, 0) - lower, higher := uint32(rr.To), uint32(rr.Start) + lower, higher := uint32(opts.To), uint32(opts.Start) for _, address := range addr { - if !rr.QueryMempoolOnly { + if !opts.QueryMempoolOnly { err = s.db.GetTransactions(address, lower, higher, func(txid string, vout uint32, isOutput bool) error { txids = append(txids, txid) - if isOutput && rr.QueryMempol { + if isOutput && opts.QueryMempol { input := s.chain.GetMempoolSpentOutput(txid, vout) if input != "" { txids = append(txids, txid) @@ -280,7 +285,7 @@ func (s *SocketIoServer) getAddressTxids(addr []string, rr *reqRange) (res resul return res, err } } - if rr.QueryMempoolOnly || rr.QueryMempol { + if opts.QueryMempoolOnly || opts.QueryMempol { mtxids, err := s.chain.GetMempoolTransactions(address) if err != nil { return res, err @@ -375,8 +380,8 @@ func txToResTx(tx *bchain.Tx, height int, hi []txInputs, ho []txOutputs) resTx { } } -func (s *SocketIoServer) getAddressHistory(addr []string, rr *reqRange) (res resultGetAddressHistory, err error) { - txr, err := s.getAddressTxids(addr, rr) +func (s *SocketIoServer) getAddressHistory(addr []string, opts *addrOpts) (res resultGetAddressHistory, err error) { + txr, err := s.getAddressTxids(addr, opts) if err != nil { return } @@ -388,7 +393,7 @@ func (s *SocketIoServer) getAddressHistory(addr []string, rr *reqRange) (res res res.Result.TotalCount = len(txids) res.Result.Items = make([]addressHistoryItem, 0) for i, txid := range txids { - if i >= rr.From && i < rr.To { + if i >= opts.From && i < opts.To { tx, height, err := s.txCache.GetTransaction(txid, bestheight) if err != nil { return res, err @@ -402,10 +407,17 @@ func (s *SocketIoServer) getAddressHistory(addr []string, rr *reqRange) (res res Script: &vout.ScriptPubKey.Hex, SpentIndex: int(vout.N), } - if len(vout.ScriptPubKey.Addresses) == 1 { - a := vout.ScriptPubKey.Addresses[0] + if vout.Address != nil { + a, err := vout.Address.EncodeAddress(opts.AddressFormat) + if err != nil { + return res, err + } ao.Address = &a - if stringInSlice(a, addr) { + found, err := vout.Address.InSlice(addr) + if err != nil { + return res, err + } + if found { hi, ok := ads[a] if ok { hi.OutputIndexes = append(hi.OutputIndexes, int(vout.N)) @@ -603,11 +615,31 @@ func unmarshalStringParameter(params []byte) (s string, err error) { return } +func unmarshalGetDetailedTransaction(params []byte) (txid string, opts txOpts, err error) { + var p []json.RawMessage + err = json.Unmarshal(params, &p) + if err != nil { + return + } + if len(p) < 1 || len(p) > 2 { + err = errors.New("incorrect number of parameters") + return + } + err = json.Unmarshal(p[0], &txid) + if err != nil { + return + } + if len(p) > 1 { + err = json.Unmarshal(p[1], &opts) + } + return +} + type resultGetDetailedTransaction struct { Result resTx `json:"result"` } -func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetailedTransaction, err error) { +func (s *SocketIoServer) getDetailedTransaction(txid string, opts txOpts) (res resultGetDetailedTransaction, err error) { bestheight, _, err := s.db.GetBestBlock() if err != nil { return @@ -631,8 +663,12 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai } if len(otx.Vout) > int(vin.Vout) { vout := otx.Vout[vin.Vout] - if len(vout.ScriptPubKey.Addresses) == 1 { - ai.Address = &vout.ScriptPubKey.Addresses[0] + if vout.Address != nil { + a, err := vout.Address.EncodeAddress(opts.AddressFormat) + if err != nil { + return res, err + } + ai.Address = &a } ai.Satoshis = int64(vout.Value * 1E8) } @@ -645,8 +681,12 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai Script: &vout.ScriptPubKey.Hex, SpentIndex: int(vout.N), } - if len(vout.ScriptPubKey.Addresses) == 1 { - ao.Address = &vout.ScriptPubKey.Addresses[0] + if vout.Address != nil { + a, err := vout.Address.EncodeAddress(opts.AddressFormat) + if err != nil { + return res, err + } + ao.Address = &a } ho = append(ho, ao) } diff --git a/server/static/test.html b/server/static/test.html index 8073cf2a..99097265 100644 --- a/server/static/test.html +++ b/server/static/test.html @@ -56,16 +56,17 @@ var addresses = document.getElementById('getAddressHistoryAddresses').value.split(","); addresses = addresses.map(s => s.trim()); var mempool = document.getElementById("getAddressHistoryMempool").checked; - lookupAddressHistories(addresses, 0, 5, mempool, 20000000, 0, function (result) { + var format = document.getElementById("getAddressHistoryFormat").value; + lookupAddressHistories(addresses, 0, 5, mempool, 20000000, 0, format, function (result) { console.log('getAddressHistory sent successfully'); console.log(result); document.getElementById('getAddressHistoryResult').innerText = JSON.stringify(result).replace(/,/g, ", "); }); } - function lookupAddressHistories(addresses, from, to, mempool, start, end, f) { + function lookupAddressHistories(addresses, from, to, mempool, start, end, format, f) { const method = 'getAddressHistory'; - const rangeParam = mempool ? { + const opts = mempool ? { start, // needed for older bitcores (so we don't load all history if bitcore-node < 3.1.3) end, queryMempoolOnly: true, @@ -77,9 +78,10 @@ const params = [ addresses, { - ...rangeParam, + ...opts, from, to, + addressFormat: parseInt(format), }, ]; return socket.send({ method, params }, f); @@ -87,7 +89,7 @@ function lookupTransactionsIdsMempool(addresses, mempool, start, end, f) { const method = 'getAddressTxids'; - const rangeParam = mempool ? { + const opts = mempool ? { start, end, queryMempoolOnly: true, @@ -98,7 +100,7 @@ }; const params = [ addresses, - rangeParam, + opts, ]; return socket.send({ method, params }, f); } @@ -155,17 +157,21 @@ function getDetailedTransaction() { var hash = document.getElementById('getDetailedTransactionHash').value.trim(); - lookupDetailedTransaction(hash, function (result) { + var format = document.getElementById("getDetailedTransactionFormat").value; + lookupDetailedTransaction(hash, format, function (result) { console.log('getDetailedTransaction sent successfully'); console.log(result); document.getElementById('getDetailedTransactionResult').innerText = JSON.stringify(result).replace(/,/g, ", "); }); } - function lookupDetailedTransaction(hash, f) { + function lookupDetailedTransaction(hash, format, f) { const method = 'getDetailedTransaction'; const params = [ hash, + { + addressFormat: parseInt(format), + }, ]; return socket.send({ method, params }, f); } @@ -275,6 +281,14 @@   +
+
+   + +
@@ -324,7 +338,14 @@
-
+
+
+
+   +
From 85beeb938cbda6197113fa4938c0f50acd1103ce Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Wed, 25 Apr 2018 13:00:51 +0200 Subject: [PATCH 7/9] moved `static` directory and upgraded installation of certs --- build/deb/build-deb.sh | 3 ++- build/deb/debian/blockbook-bch-testnet.install | 4 ++-- build/deb/debian/blockbook-bch.install | 4 ++-- build/deb/debian/blockbook-btc-testnet.install | 4 ++-- build/deb/debian/blockbook-btc.install | 4 ++-- build/deb/debian/blockbook-zec.install | 4 ++-- {server/static => static}/test.html | 0 7 files changed, 12 insertions(+), 11 deletions(-) rename {server/static => static}/test.html (100%) diff --git a/build/deb/build-deb.sh b/build/deb/build-deb.sh index 21aabdde..4b97be27 100755 --- a/build/deb/build-deb.sh +++ b/build/deb/build-deb.sh @@ -3,7 +3,8 @@ set -e cp -r /src/build/deb/debian . cp -r /src/configs . -mkdir server && cp -r /src/server/testcert.* /src/server/static server +cp -r /src/static static +mkdir cert && cp /src/server/testcert.* cert dpkg-buildpackage -us -uc mv ../*.deb /out diff --git a/build/deb/debian/blockbook-bch-testnet.install b/build/deb/debian/blockbook-bch-testnet.install index ac6b38e6..b145f532 100755 --- a/build/deb/debian/blockbook-bch-testnet.install +++ b/build/deb/debian/blockbook-bch-testnet.install @@ -1,5 +1,5 @@ #!/usr/bin/dh-exec blockbook /opt/blockbook/bch-testnet/bin -server/testcert.* /opt/blockbook/bch-testnet/cert -server/static /opt/blockbook/bch-testnet +cert /opt/blockbook/bch-testnet +static /opt/blockbook/bch-testnet configs/bch-testnet.json => /opt/blockbook/bch-testnet/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-bch.install b/build/deb/debian/blockbook-bch.install index bec00277..33f4a700 100755 --- a/build/deb/debian/blockbook-bch.install +++ b/build/deb/debian/blockbook-bch.install @@ -1,5 +1,5 @@ #!/usr/bin/dh-exec blockbook /opt/blockbook/bch/bin -server/testcert.* /opt/blockbook/bch/cert -server/static /opt/blockbook/bch +cert /opt/blockbook/bch +static /opt/blockbook/bch configs/bch.json => /opt/blockbook/bch/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-btc-testnet.install b/build/deb/debian/blockbook-btc-testnet.install index cc143232..e648ad35 100755 --- a/build/deb/debian/blockbook-btc-testnet.install +++ b/build/deb/debian/blockbook-btc-testnet.install @@ -1,5 +1,5 @@ #!/usr/bin/dh-exec blockbook /opt/blockbook/btc-testnet/bin -server/testcert.* /opt/blockbook/btc-testnet/cert -server/static /opt/blockbook/btc-testnet +cert /opt/blockbook/btc-testnet +static /opt/blockbook/btc-testnet configs/btc-testnet.json => /opt/blockbook/btc-testnet/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-btc.install b/build/deb/debian/blockbook-btc.install index 29961515..27a11fc0 100755 --- a/build/deb/debian/blockbook-btc.install +++ b/build/deb/debian/blockbook-btc.install @@ -1,5 +1,5 @@ #!/usr/bin/dh-exec blockbook /opt/blockbook/btc/bin -server/testcert.* /opt/blockbook/btc/cert -server/static /opt/blockbook/btc +cert /opt/blockbook/btc +static /opt/blockbook/btc configs/btc.json => /opt/blockbook/btc/config/blockchaincfg.json diff --git a/build/deb/debian/blockbook-zec.install b/build/deb/debian/blockbook-zec.install index d34066f5..caf66e51 100755 --- a/build/deb/debian/blockbook-zec.install +++ b/build/deb/debian/blockbook-zec.install @@ -1,5 +1,5 @@ #!/usr/bin/dh-exec --with=install blockbook /opt/blockbook/zec/bin -server/testcert.* /opt/blockbook/zec/cert -server/static /opt/blockbook/zec +cert /opt/blockbook/zec +static /opt/blockbook/zec configs/zec.json => /opt/blockbook/zec/config/blockchaincfg.json diff --git a/server/static/test.html b/static/test.html similarity index 100% rename from server/static/test.html rename to static/test.html From a929f27d5ce9de5a0278ee2275a7c89e15c4e8e6 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Wed, 25 Apr 2018 13:38:03 +0200 Subject: [PATCH 8/9] implemented `estimatesmartfee` method --- bchain/coins/bch/bcashrpc.go | 36 ++++++++++++++++++++++++++++++++++++ static/test.html | 28 ++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/bchain/coins/bch/bcashrpc.go b/bchain/coins/bch/bcashrpc.go index 222a7b78..cb23030e 100644 --- a/bchain/coins/bch/bcashrpc.go +++ b/bchain/coins/bch/bcashrpc.go @@ -81,6 +81,23 @@ type resGetBlockThin struct { Result bchain.ThinBlock `json:"result"` } +// estimatesmartfee + +type cmdEstimateSmartFee struct { + Method string `json:"method"` + Params struct { + Blocks int `json:"nblocks"` + } `json:"params"` +} + +type resEstimateSmartFee struct { + Error *bchain.RPCError `json:"error"` + Result struct { + Feerate float64 `json:"feerate"` + Blocks int `json:"blocks"` + } `json:"result"` +} + // GetBlock returns block with given hash. func (b *BCashRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { var err error @@ -174,6 +191,25 @@ func (b *BCashRPC) GetBlockFull(hash string) (*bchain.Block, error) { return nil, errors.New("Not implemented") } +// EstimateSmartFee returns fee estimation. +func (b *BCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) { + glog.V(1).Info("rpc: estimatesmartfee ", blocks) + + res := resEstimateSmartFee{} + req := cmdEstimateSmartFee{Method: "estimatesmartfee"} + req.Params.Blocks = blocks + // conservative param is omitted + err := b.Call(&req, &res) + + if err != nil { + return 0, err + } + if res.Error != nil { + return 0, res.Error + } + return res.Result.Feerate, nil +} + func isErrBlockNotFound(err *bchain.RPCError) bool { return err.Message == "Block not found" || err.Message == "Block height out of range" diff --git a/static/test.html b/static/test.html index 99097265..45c27e86 100644 --- a/static/test.html +++ b/static/test.html @@ -141,6 +141,21 @@ return socket.send({ method, params }, f); } + function estimateFee() { + var blocks = document.getElementById('estimateFeeBlocks').value.trim(); + estimateTxFee(parseInt(blocks), function (result) { + console.log('estimateFee sent successfully'); + console.log(result); + document.getElementById('estimateFeeResult').innerText = JSON.stringify(result).replace(/,/g, ", "); + }); + } + + function estimateTxFee(blocks, f) { + const method = 'estimateFee'; + const params = [blocks]; + return socket.send({ method, params }, f); + } + function getInfo() { lookupSyncStatus(function (result) { console.log('getInfo sent successfully'); @@ -324,6 +339,19 @@
+
+
+ +
+
+ +
+
+
+
+
+
+
From f05b1175bf72f44fc874a4efef3c7588a804d4e6 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Thu, 26 Apr 2018 11:02:03 +0200 Subject: [PATCH 9/9] fixed typo --- contrib/backends/bcash/debian/bcash-bch.postinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/backends/bcash/debian/bcash-bch.postinst b/contrib/backends/bcash/debian/bcash-bch.postinst index 2f0885aa..bea81f65 100644 --- a/contrib/backends/bcash/debian/bcash-bch.postinst +++ b/contrib/backends/bcash/debian/bcash-bch.postinst @@ -9,7 +9,7 @@ case "$1" in useradd --system -M -U bitcoin fi - if [ "$(stat -c '%U' /data/btc/bitcoin)" != "bitcoin" ] + if [ "$(stat -c '%U' /data/bch/bitcoin)" != "bitcoin" ] then chown bitcoin:bitcoin /data/bch/bitcoin fi