mirror of
https://github.com/openoms/joininbox.git
synced 2026-08-13 12:33:14 +02:00
Compare commits
52 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16fc83f47d | ||
|
|
54473190c8 | ||
|
|
dfb33c8ab0 | ||
|
|
aa8d79c97d | ||
|
|
efdf660969 | ||
|
|
554a20a297 | ||
|
|
7a61e3b357 | ||
|
|
f92be4e5b3 | ||
|
|
ea675689c5 | ||
|
|
e69d6006a4 | ||
|
|
1b9eca2447 | ||
|
|
a91cdc3657 | ||
|
|
56b06fafa4 | ||
|
|
304144e881 | ||
|
|
b5bc21ad7b | ||
|
|
9594fbf20e | ||
|
|
44e095e324 | ||
|
|
601eede8b5 | ||
|
|
19ffa45e66 | ||
|
|
8afc78dcf4 | ||
|
|
41a5c9e573 | ||
|
|
b532dbeab3 | ||
|
|
7800d632a5 | ||
|
|
18d28bedf4 | ||
|
|
aaa22e375b | ||
|
|
c75ddacfc9 | ||
|
|
6b606760eb | ||
|
|
b9360c1008 | ||
|
|
622847e80e | ||
|
|
c87e06c829 | ||
|
|
efad4a01ff | ||
|
|
e2e540ccbd | ||
|
|
d961839137 | ||
|
|
0126005b90 | ||
|
|
11c2e0dacd | ||
|
|
dec26c7732 | ||
|
|
ea5187c933 | ||
|
|
a61da715ca | ||
|
|
0daac40e21 | ||
|
|
7b2166d124 | ||
|
|
8f61362f9b | ||
|
|
c240ba2885 | ||
|
|
a596e25ce0 | ||
|
|
accf274730 | ||
|
|
709ea134dc | ||
|
|
8a924cd07b | ||
|
|
0e388a9898 | ||
|
|
ec556ab64a | ||
|
|
b1e933d013 | ||
|
|
6032311eca | ||
|
|
83ab1e5b2a | ||
|
|
fd39fade35 |
63 changed files with 2362 additions and 988 deletions
15
.editorconfig
Normal file
15
.editorconfig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# EditorConfig helps maintain consistent coding styles
|
||||
# https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
17
.github/workflows/amd64-image-build.yml
vendored
17
.github/workflows/amd64-image-build.yml
vendored
|
|
@ -1,5 +1,9 @@
|
|||
name: amd64-image-build
|
||||
|
||||
concurrency:
|
||||
group: amd64-image-build-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
|
@ -26,17 +30,24 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set values
|
||||
id: set_values
|
||||
run: |
|
||||
echo "BUILD_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
|
||||
echo "BUILD_VERSION=$(git describe --always --tags)" >> $GITHUB_ENV
|
||||
if [[ "${{github.event_name}}" == "pull_request" ]]; then
|
||||
echo "::set-output name=github_user::${{github.event.pull_request.head.repo.owner.login}}"
|
||||
else
|
||||
echo "::set-output name=github_user::$(echo ${{github.repository}} | cut -d'/' -f1)"
|
||||
fi
|
||||
|
||||
- name: Hello JoininBox
|
||||
- name: Display the build name
|
||||
run: echo "Building the joininbox-amd64-debian-image-${{ env.BUILD_DATE }}-${{ env.BUILD_VERSION }}"
|
||||
|
||||
- name: Run the build script
|
||||
run: |
|
||||
echo "Running with: ${{steps.set_values.outputs.github_user}} $GITHUB_HEAD_REF"
|
||||
cd ci/amd64
|
||||
bash packer.build.amd64-debian.sh $GITHUB_ACTOR $GITHUB_HEAD_REF
|
||||
bash packer.build.amd64-debian.sh ${{steps.set_values.outputs.github_user}} $GITHUB_HEAD_REF
|
||||
|
||||
- name: Compute checksum of the raw image
|
||||
run: |
|
||||
|
|
@ -54,7 +65,7 @@ jobs:
|
|||
sha256sum joininbox-amd64-debian.qcow2.gz > joininbox-amd64-debian.qcow2.gz.sha256
|
||||
|
||||
- name: Upload the image and checksums
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: joininbox-amd64-image-${{ env.BUILD_DATE }}-${{ env.BUILD_VERSION }}
|
||||
path: |
|
||||
|
|
|
|||
65
.github/workflows/amd64-image-test.yml
vendored
Normal file
65
.github/workflows/amd64-image-test.yml
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
name: amd64-image-test
|
||||
|
||||
concurrency:
|
||||
group: amd64-image-test-${{ github.event.workflow_run.id || inputs.run_id || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["amd64-image-build"]
|
||||
types: [completed]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_id:
|
||||
description: "amd64-image-build workflow run ID to test"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
bats-image-test:
|
||||
name: Run Bats against amd64 image artifact
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 240
|
||||
if: ${{ github.event_name != 'workflow_run' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_repository.full_name == github.repository) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ github.event.workflow_run.head_repository.full_name || github.repository }}
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
|
||||
|
||||
- name: Check out bats-core
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: bats-core/bats-core
|
||||
# bats-core v1.12.0
|
||||
ref: 713504bc0224a19b3d7c7958c18dc07f64f54b44
|
||||
path: .bats-core
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download amd64 image artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
run-id: ${{ github.event.workflow_run.id || inputs.run_id }}
|
||||
pattern: joininbox-amd64-image-*
|
||||
path: artifacts
|
||||
merge-multiple: true
|
||||
|
||||
- name: Verify and decompress image
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
cd artifacts
|
||||
sha256sum -c joininbox-amd64-debian.qcow2.gz.sha256
|
||||
gzip -dk joininbox-amd64-debian.qcow2.gz
|
||||
sha256sum -c joininbox-amd64-debian.qcow2.sha256
|
||||
|
||||
- name: Run image Bats tests
|
||||
timeout-minutes: 30
|
||||
run: ci/amd64/test.amd64-image-bats.sh "${GITHUB_WORKSPACE}/artifacts/joininbox-amd64-debian.qcow2"
|
||||
17
.github/workflows/arm64-rpi-image-build.yml
vendored
17
.github/workflows/arm64-rpi-image-build.yml
vendored
|
|
@ -1,5 +1,9 @@
|
|||
name: arm64-rpi-image-build
|
||||
|
||||
concurrency:
|
||||
group: arm64-rpi-image-build-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
|
@ -28,11 +32,17 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set values
|
||||
id: set_values
|
||||
run: |
|
||||
echo "BUILD_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
|
||||
echo "BUILD_VERSION=$(git describe --always --tags)" >> $GITHUB_ENV
|
||||
if [[ "${{github.event_name}}" == "pull_request" ]]; then
|
||||
echo "::set-output name=github_user::${{github.event.pull_request.head.repo.owner.login}}"
|
||||
else
|
||||
echo "::set-output name=github_user::$(echo ${{github.repository}} | cut -d'/' -f1)"
|
||||
fi
|
||||
|
||||
- name: Hello JoininBox
|
||||
- name: Display the build name
|
||||
run: echo "Building the joininbox-arm64-rpi-image-${{ env.BUILD_DATE }}-${{ env.BUILD_VERSION }}"
|
||||
|
||||
- name: Set up QEMU
|
||||
|
|
@ -42,8 +52,9 @@ jobs:
|
|||
|
||||
- name: Run the build script
|
||||
run: |
|
||||
echo "Running with: ${{steps.set_values.outputs.github_user}} $GITHUB_HEAD_REF"
|
||||
cd ci/arm64-rpi
|
||||
bash arm64-rpi.sh $GITHUB_ACTOR $GITHUB_HEAD_REF
|
||||
bash arm64-rpi.sh ${{steps.set_values.outputs.github_user}} $GITHUB_HEAD_REF
|
||||
|
||||
- name: Compute checksum of the raw image
|
||||
run: |
|
||||
|
|
@ -61,7 +72,7 @@ jobs:
|
|||
sha256sum joininbox-arm64-rpi.img.gz > joininbox-arm64-rpi.img.gz.sha256
|
||||
|
||||
- name: Upload the image and checksums
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: joininbox-arm64-rpi-image-${{ env.BUILD_DATE }}-${{ env.BUILD_VERSION }}
|
||||
path: |
|
||||
|
|
|
|||
60
.github/workflows/packer-syntax-check.yml
vendored
Normal file
60
.github/workflows/packer-syntax-check.yml
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
name: Packer Syntax Check
|
||||
|
||||
concurrency:
|
||||
group: packer-syntax-check-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- '.github/workflows/packer-syntax-check.yml'
|
||||
- 'ci/amd64/**/*.pkr.hcl'
|
||||
- 'ci/amd64/**/*.pkrvars.hcl'
|
||||
- 'ci/amd64/packer.build.amd64-debian.sh'
|
||||
- 'ci/arm64-rpi/**/*.pkr.hcl'
|
||||
- 'ci/arm64-rpi/**/*.pkrvars.hcl'
|
||||
- 'ci/arm64-rpi/arm64-rpi.sh'
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- '.github/workflows/packer-syntax-check.yml'
|
||||
- 'ci/amd64/**/*.pkr.hcl'
|
||||
- 'ci/amd64/**/*.pkrvars.hcl'
|
||||
- 'ci/amd64/packer.build.amd64-debian.sh'
|
||||
- 'ci/arm64-rpi/**/*.pkr.hcl'
|
||||
- 'ci/arm64-rpi/**/*.pkrvars.hcl'
|
||||
- 'ci/arm64-rpi/arm64-rpi.sh'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
validate-packer-syntax:
|
||||
name: Validate Packer Syntax
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Packer
|
||||
uses: hashicorp/setup-packer@v3
|
||||
|
||||
- name: Show Packer version
|
||||
run: packer version
|
||||
|
||||
- name: Validate amd64 templates (syntax only)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
mapfile -t templates < <(find ci/amd64 ci/arm64-rpi -type f \( -name '*.pkr.hcl' -o -name '*.pkrvars.hcl' \) | sort)
|
||||
|
||||
if [ ${#templates[@]} -eq 0 ]; then
|
||||
echo "No Packer templates found under ci/amd64 or ci/arm64-rpi"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for template in "${templates[@]}"; do
|
||||
echo "Validating $template"
|
||||
packer validate -syntax-only "$template"
|
||||
done
|
||||
17
.github/workflows/spelling.yml
vendored
Normal file
17
.github/workflows/spelling.yml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
name: spelling
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
spelling:
|
||||
name: Spell Check with Typos
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Actions Repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Spell Check Repo
|
||||
uses: crate-ci/typos@master
|
||||
with:
|
||||
config: typos.toml
|
||||
19
.github/workflows/test-shellcheck.yml
vendored
Normal file
19
.github/workflows/test-shellcheck.yml
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: "Test Shellcheck"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: ["master"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
name: Run Shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
with:
|
||||
severity: error
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,5 @@
|
|||
scripts/wallets
|
||||
ci/arm64-rpi/.packer*
|
||||
ci/arm64-rpi/joininbox-arm64-rpi*
|
||||
ci/amd64/builds
|
||||
scripts/jam-remote/download
|
||||
|
|
|
|||
189
FAQ.md
189
FAQ.md
|
|
@ -10,7 +10,6 @@
|
|||
- [Log in through SSH using a hardware wallet](#log-in-through-ssh-using-a-hardware-wallet)
|
||||
- [SSH through Tor from Linux](#ssh-through-tor-from-linux)
|
||||
- [Allow Tor to connect to localhost](#allow-tor-to-connect-to-localhost)
|
||||
- [Set up Armbian on the Hardkernel Odroid HC1 / XU4](#set-up-armbian-on-the-hardkernel-odroid-hc1--xu4)
|
||||
- [Download and verify Raspbian SDcard image for a Raspberry Pi](#download-and-verify-raspbian-sdcard-image-for-a-raspberry-pi)
|
||||
- [Error when connecting to a full node remotely through Tor](#error-when-connecting-to-a-full-node-remotely-through-tor)
|
||||
- [Erase the joinmarket user and the /home/joinmarket folder](#erase-the-joinmarket-user-and-the-homejoinmarket-folder)
|
||||
|
|
@ -31,6 +30,7 @@
|
|||
- [Wallet recovery](#wallet-recovery)
|
||||
- [on JoininBox](#on-joininbox)
|
||||
- [on the remote node](#on-the-remote-node)
|
||||
- [Migrating from legacy wallet.dat to descriptor wallet](#migrating-from-legacy-walletdat-to-descriptor-wallet)
|
||||
- [USB SSD recommendation](#usb-ssd-recommendation)
|
||||
- [Pruned node notes](#pruned-node-notes)
|
||||
- [External drive](#external-drive)
|
||||
|
|
@ -172,55 +172,10 @@ Use `ssh` with `torsocks` on the desktop (needs Tor installed):
|
|||
* Restart Tor:
|
||||
`sudo systemctl restart tor`
|
||||
|
||||
## Set up Armbian on the Hardkernel Odroid HC1 / XU4
|
||||
* Download the base image (`.img.gz`), the `.sha` and `.asc` file
|
||||
https://www.armbian.com/odroid-xu4/
|
||||
* Verify: https://docs.armbian.com/User-Guide_Getting-Started/#how-to-check-download-authenticity
|
||||
```bash
|
||||
gpg --keyserver ha.pool.sks-keyservers.net --recv-key DF00FAF1C577104B50BF1D0093D6889F9F0E78D5
|
||||
# gpg: key 93D6889F9F0E78D5: public key "Igor Pecovnik # <igor@armbian. com>" imported
|
||||
# gpg: Total number processed: 1
|
||||
# gpg: imported: 1
|
||||
gpg --verify Armbian_21.02.3_Odroidxu4_buster_legacy_4.14.222.img.xz.asc
|
||||
# gpg: assuming signed data in 'Armbian_21.02.3_Odroidxu4_buster_legacy_4.14.222.img.xz'
|
||||
# gpg: Signature made Tue 09 Mar 2021 03:00:30 GMT
|
||||
# gpg: using RSA key DF00FAF1C577104B50BF1D0093D6889F9F0E78D5
|
||||
# gpg: Good signature from "Igor Pecovnik <igor@armbian.com>" [unknown]
|
||||
# gpg: aka "Igor Pecovnik (Ljubljana, Slovenia) <igor.pecovnik@gmail.com>" [unknown]
|
||||
# gpg: WARNING: This key is not certified with a trusted signature!
|
||||
# gpg: There is no indication that the signature belongs to the owner.
|
||||
# Primary key fingerprint: DF00 FAF1 C577 104B 50BF 1D00 93D6 889F 9F0E 78D5
|
||||
shasum -c Armbian_21.02.3_Odroidxu4_buster_legacy_4.14.222.img.xz.sha
|
||||
# Armbian_21.02.3_Odroidxu4_buster_legacy_4.14.222.img.xz: OK
|
||||
```
|
||||
* Preparation
|
||||
Make sure you have a good & reliable SD card and a proper power supply. Archives can be uncompressed with 7-Zip on Windows, Keka on OS X and 7z on Linux (apt-get install p7zip-full). RAW images can be written with Etcher (all OS).
|
||||
* Boot
|
||||
Insert the SD card into the slot, connect a cable to your network if possible or a display and power your board. (First) boot (with DHCP) takes up to 35 seconds with a class 10 SD Card.
|
||||
* Login
|
||||
Log in as: `root` Password: `1234`. Then you are prompted to change this password (US-Keyboard setting). When done, you are asked to create a normal user-account for your everyday tasks.
|
||||
* Change the password.
|
||||
* Create a new user called `joinmarket` and set the password (the password will be changed to `joininbox`).
|
||||
Keep pressing [ENTER] to use the default user information.
|
||||
* Continue to [install JoininBox](README.md#install-joininbox)
|
||||
|
||||
## Download and verify Raspbian SDcard image for a Raspberry Pi
|
||||
To be able to open the JoinMarket-QT GUI on the dekstop from the RPI
|
||||
need to use the Raspberry Pi OS (32-bit) with desktop image
|
||||
* Download image:
|
||||
https://downloads.raspberrypi.org/raspios_armhf/images/raspios_armhf-2020-05-28/2020-05-27-raspios-buster-armhf.zip
|
||||
* Download signature:
|
||||
https://downloads.raspberrypi.org/raspios_armhf/images/raspios_armhf-2020-05-28/2020-05-27-raspios-buster-armhf.zip.sig
|
||||
* Import PGP pubkey:
|
||||
`curl https://www.raspberrypi.org/raspberrypi_downloads.gpg.key | gpg --import`
|
||||
* Verify the image:
|
||||
`gpg --verify 2020-05-27-raspios-buster-armhf.zip.sig`
|
||||
* Flash the image to an SDcard, can use the [Raspberry Pi Imager](https://www.raspberrypi.org/downloads/)
|
||||
* put a file called simply: `ssh` to the root of the sdcard.
|
||||
Read more on [how to gain ssh access here](https://www.raspberrypi.org/documentation/remote-access/ssh/).
|
||||
* boot up the RPi and log in with ssh to:
|
||||
`pi@LAN_IP_ADDRESS`
|
||||
The default password is: `raspberry`
|
||||
* Download [Raspberry Pi Imager](https://www.raspberrypi.com/software/)
|
||||
* enable the ssh login in the
|
||||
* Flash the image to a min 32GB Endurance type SDcard
|
||||
* Continue to [install JoininBox](README.md#install-joininbox)
|
||||
|
||||
## Error when connecting to a full node remotely through Tor
|
||||
|
|
@ -241,7 +196,7 @@ The default password is: `raspberry`
|
|||
server=1
|
||||
daemon=1
|
||||
disablewallet=0
|
||||
main.wallet=wallet.dat
|
||||
main.wallet=watch-only-descriptor-wallet
|
||||
|
||||
# Connection settings
|
||||
rpcuser=REDACTED
|
||||
|
|
@ -474,7 +429,7 @@ JoinMarket docs:
|
|||
* https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/USAGE.md#recover
|
||||
|
||||
### on JoininBox
|
||||
* Connect the remote bitcoind with `CONFIG` -> `CONNECT` menu so it checks if the connection is successful. It will also set the remote watch-only wallet in bitcoind to "joininbox" so will need to rescan that after recovering an old wallet with previously used addresses.
|
||||
* Connect the remote bitcoind with `CONFIG` -> `CONNECT` menu so it checks if the connection is successful. It will also set the remote watch-only-descriptor-wallet in bitcoind to "joininbox" so will need to rescan that after recovering an old wallet with previously used addresses.
|
||||
|
||||
* When using the CLI and connecting to the remote node over Tor, you will need to use the script with the torsocks prefix like:
|
||||
`torsocks python3 wallet-tool.py --recoversync -g 20 ~/.joinmarket/wallets/wallet.jmdat`
|
||||
|
|
@ -483,18 +438,77 @@ JoinMarket docs:
|
|||
* Use the menu option `WALLET` -> `RESCAN` or follow manually
|
||||
* the wallet defined as
|
||||
`rpc_wallet =`
|
||||
in the joinmarket.cfg is the wallet which is used as watch only in the remote bitcoind.
|
||||
in the joinmarket.cfg is the wallet which is used as a watch-only-descriptor-wallet in the remote bitcoind.
|
||||
You need to run rescanblockchain on that wallet in bitcoind after importing the joinmarket wallet.
|
||||
* The wallet is set in the joinmarket.cfg (by default called `joininbox` should show up when you run:
|
||||
`bitcoin-cli listwallets`
|
||||
|
||||
* To rescan on the node run (https://developer.bitcoin.org/reference/rpc/rescanblockchain.html?highlight=rescanblockchain):
|
||||
`bitcoin-cli -rpcwallet=joininbox rescanblockchain 477120`
|
||||
Rescanning fom the first SegWit block is sufficient for the default SegWit wallets.
|
||||
Rescanning from the first SegWit block is sufficient for the default SegWit wallets.
|
||||
|
||||
* Monitor progress (on a RaspiBlitz):
|
||||
`sudo tail -fn 100 /mnt/hdd/bitcoin/debug.log`
|
||||
`sudo tail -fn 100 /mnt/hdd/app-storage/bitcoin/debug.log`
|
||||
Once the rescan is finished you balances should appear in the `INFO` menu (`wallet-tool.py`)
|
||||
|
||||
## Migrating from legacy wallet.dat to descriptor wallet
|
||||
|
||||
Starting with the 0.9.0 version, JoininBox uses Bitcoin Core's descriptor wallets (`watch-only-descriptor-wallet`) instead of the legacy `wallet.dat`. This change provides better compatibility with modern Bitcoin Core versions (v26+) and aligns with Bitcoin Core's default wallet format.
|
||||
|
||||
### Why this change?
|
||||
|
||||
Bitcoin Core has deprecated BDB (Berkeley DB) wallets in favor of descriptor wallets. The new descriptor wallets:
|
||||
- Are the default in Bitcoin Core v26+
|
||||
- Don't require the `deprecatedrpc=create_bdb` configuration
|
||||
- Have better performance and features
|
||||
- Are actively maintained and improved
|
||||
|
||||
### How automatic migration works
|
||||
|
||||
When `rpc_wallet_file` is still set to `wallet.dat`, JoininBox queries the connected Bitcoin Core node using RPC before changing the configuration:
|
||||
|
||||
- Bitcoin Core v30.0 and newer: JoininBox atomically changes `rpc_wallet_file` to `watch-only-descriptor-wallet`, creates or loads that descriptor wallet, and displays the migration notice when the old `wallet.dat` is present.
|
||||
- Bitcoin Core v29.x and earlier: JoininBox keeps using `wallet.dat` and does not start automatic migration.
|
||||
- Version unavailable: JoininBox leaves `wallet.dat` configured rather than migrating without confirming compatibility.
|
||||
|
||||
The migration does not rename, modify, or delete the old `wallet.dat`. It changes which Bitcoin Core wallet JoinMarket uses for watch-only address imports and transaction history.
|
||||
|
||||
### Migration steps for existing users
|
||||
|
||||
If you're upgrading from a previous version of JoininBox that used `wallet.dat`, follow these steps:
|
||||
|
||||
1. **The migration notice will appear automatically on Bitcoin Core v30.0 and newer**
|
||||
When you first use any wallet-related function after updating, JoininBox checks the connected Bitcoin Core version. On v30.0 and newer it switches the configured RPC wallet to `watch-only-descriptor-wallet`, detects the old `wallet.dat`, and displays a migration notice. Bitcoin Core v29.x and earlier continue using `wallet.dat` without starting the automatic migration.
|
||||
|
||||
2. **Open each JoinMarket wallet**
|
||||
Go to `WALLET` -> `DISPLAY` and open each of your JoinMarket wallets (`.jmdat` files) at least once. This imports the addresses into the new `watch-only-descriptor-wallet` in Bitcoin Core.
|
||||
|
||||
3. **Run a blockchain rescan**
|
||||
After opening all your wallets, go to `WALLET` -> `RESCAN` and enter a blockheight:
|
||||
- Use `481824` (first SegWit block) for wallets created after August 2017
|
||||
- Can use a later blockheight if you know when your wallet had its first deposit
|
||||
|
||||
4. **Wait for the rescan to complete**
|
||||
The rescan can take several hours depending on the blockheight and your hardware. Monitor progress with:
|
||||
```bash
|
||||
# On standalone JoininBox:
|
||||
sudo tail -f /home/bitcoin/.bitcoin/debug.log
|
||||
|
||||
# On RaspiBlitz:
|
||||
sudo tail -f /mnt/hdd/bitcoin/debug.log
|
||||
```
|
||||
|
||||
5. **Verify your balances**
|
||||
Once the rescan completes, check your wallet balances with `WALLET` -> `DISPLAY`.
|
||||
|
||||
### Notes
|
||||
|
||||
- The old `wallet.dat` is not deleted and remains in Bitcoin Core
|
||||
- Automatic migration only runs when the connected Bitcoin Core version is v30.0 or newer
|
||||
- You only need to perform this migration once
|
||||
- The migration notice will not appear again after you acknowledge it
|
||||
- If you have issues, you can reset the migration flag by removing `walletMigrationDone=true` from `/home/joinmarket/joinin.conf`
|
||||
|
||||
## USB SSD recommendation
|
||||
**JoininBox operates on the minimum viable hardware under the assumption that the seed (and passphrase) of the wallets used is safely backed up and can be recovered fully**
|
||||
* The above warning is especially true for SDcard as they fail often, use a good quality one.
|
||||
|
|
@ -565,35 +579,16 @@ Alternatively to a pruned node there could be a larger >400 GB storage connected
|
|||
# -rw------- 1 bitcoin bitcoin 1521305 Mar 21 10:38 peers.dat
|
||||
# -rw-r--r-- 1 bitcoin bitcoin 7 Mar 21 10:08 settings.json
|
||||
# drwx------ 34 bitcoin bitcoin 4096 Dec 7 23:39 specter
|
||||
# drwx------ 2 bitcoin bitcoin 4096 Mar 21 10:38 wallet.dat
|
||||
# drwx------ 2 bitcoin bitcoin 4096 Mar 21 10:38 watch-only-descriptor-wallet
|
||||
installMainnet
|
||||
# Failed to stop bitcoind.service: Unit bitcoind.service not loaded.
|
||||
#
|
||||
# [Unit]
|
||||
# Description=Bitcoin daemon on mainnet
|
||||
# [Service]
|
||||
# User=bitcoin
|
||||
# Group=bitcoin
|
||||
# Type=forking
|
||||
# PIDFile=/home/bitcoin/bitcoin/bitcoind.pid
|
||||
# ExecStart=/home/bitcoin/bitcoin/bitcoind -daemon -pid=/home/bitcoin/bitcoin/bitcoind.pid
|
||||
# Restart=always
|
||||
# TimeoutSec=120
|
||||
# RestartSec=30
|
||||
# StandardOutput=null
|
||||
# StandardError=journal
|
||||
#
|
||||
# [Install]
|
||||
# WantedBy=multi-user.target
|
||||
#
|
||||
# Created symlink /etc/systemd/system/multi-user.target.wants/bitcoind.service → /etc/systemd/system/bitcoind.service.
|
||||
...
|
||||
# # OK - the bitcoind.service is now enabled
|
||||
#
|
||||
# # Installed Bitcoin Core version v0.21.0
|
||||
#
|
||||
# # Monitor the bitcoind with: sudo tail -f /home/bitcoin/.bitcoin/mainnet/debug.log
|
||||
#
|
||||
# # Create wallet.dat ...
|
||||
# # Create watch-only-descriptor-wallet ...
|
||||
# error code: -28
|
||||
# error message:
|
||||
# Loading block index...
|
||||
|
|
@ -604,48 +599,6 @@ Alternatively to a pruned node there could be a larger >400 GB storage connected
|
|||
## IRC server settings
|
||||
* See the most up to date configuration in:
|
||||
https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/jmclient/jmclient/configure.py
|
||||
* The latest setting with Tor enabled:
|
||||
```
|
||||
[MESSAGING:server1]
|
||||
#host = irc.darkscience.net
|
||||
channel = joinmarket-pit
|
||||
port = 6697
|
||||
usessl = true
|
||||
#socks5 = false
|
||||
socks5_host = localhost
|
||||
socks5_port = 9050
|
||||
#for tor
|
||||
host = darkirc6tqgpnwd3blln3yfv5ckl47eg7llfxkmtovrv7c7iwohhb6ad.onion
|
||||
socks5 = true
|
||||
|
||||
[MESSAGING:server2]
|
||||
#host = irc.hackint.org
|
||||
channel = joinmarket-pit
|
||||
#port = 6697
|
||||
#usessl = true
|
||||
#socks5 = false
|
||||
socks5_host = localhost
|
||||
socks5_port = 9050
|
||||
#for tor
|
||||
host = ncwkrwxpq2ikcngxq3dy2xctuheniggtqeibvgofixpzvrwpa77tozqd.onion
|
||||
port = 6667
|
||||
usessl = false
|
||||
socks5 = true
|
||||
|
||||
[MESSAGING:server3]
|
||||
#host = agora.anarplex.net
|
||||
channel = joinmarket-pit
|
||||
#port = 14716
|
||||
#usessl = true
|
||||
#socks5 = false
|
||||
socks5_host = localhost
|
||||
socks5_port = 9050
|
||||
#for tor
|
||||
host = vxecvd6lc4giwtasjhgbrr3eop6pzq6i5rveracktioneunalgqlwfad.onion
|
||||
port = 6667
|
||||
usessl = false
|
||||
socks5 = true
|
||||
```
|
||||
|
||||
## Install JoinMarket without the QT GUI and dependencies
|
||||
* Run the build script with the options `BRANCH` `GITHUBUSER` `without-qt`:
|
||||
|
|
|
|||
9
Makefile
9
Makefile
|
|
@ -35,3 +35,12 @@ arm64-rpi-image:
|
|||
# Compute checksum of the compressed image
|
||||
cd ci/arm64-rpi && \
|
||||
sha256sum joininbox-arm64-rpi.img.gz > joininbox-arm64-rpi.img.gz.sha256
|
||||
|
||||
release-tag:
|
||||
@if [ -z "$(TAG)" ]; then \
|
||||
echo "Error: TAG parameter is required. Usage: make release-tag TAG=v0.7.4"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "Creating signed tag $(TAG) and pushing to origin..."
|
||||
git tag -s $(TAG) -m "$(TAG)" && git push origin $(TAG)
|
||||
@echo "Successfully created and pushed signed tag $(TAG)"
|
||||
|
|
|
|||
33
README.md
33
README.md
|
|
@ -22,6 +22,9 @@ A minimalistic, security focused linux environment for JoinMarket with a termina
|
|||
|
||||
- [Features](#features)
|
||||
- [Required Hardware](#required-hardware)
|
||||
- [A computer running a Debian / Ubuntu Linux flavour.](#a-computer-running-a-debian--ubuntu-linux-flavour)
|
||||
- [RaspberryPi 5 or 4](#raspberrypi-5-or-4)
|
||||
- [VPS eg: host4coins.net](#vps-eg-host4coinsnet)
|
||||
- [Set up using an SDcard image](#set-up-using-an-sdcard-image)
|
||||
- [Set up JoininBox on Linux](#set-up-joininbox-on-linux)
|
||||
- [Tested environments](#tested-environments)
|
||||
|
|
@ -29,7 +32,6 @@ A minimalistic, security focused linux environment for JoinMarket with a termina
|
|||
- [More info](#more-info)
|
||||
- [About JoinMarket](#about-joinmarket)
|
||||
- [Forums](#forums)
|
||||
- [Donations](#donations)
|
||||
|
||||
## Features
|
||||
|
||||
|
|
@ -40,20 +42,26 @@ A minimalistic, security focused linux environment for JoinMarket with a termina
|
|||
* Connect remotely to a Bitcoin Core node
|
||||
* RaspiBlitz over [LAN or Tor](prepare_remote_node.md#raspiblitz)
|
||||
* RoninDojo over [LAN or Tor](prepare_remote_node.md#ronindojo)
|
||||
* Start a pruned node from https://prunednode.today/
|
||||
* JoininBox is part the RaspiBlitz SERVICES
|
||||
* Start a pruned node from https://pruned.host4coins.net/blocks
|
||||
* JoininBox is part of the RaspiBlitz SERVICES
|
||||
|
||||
**The addresses, transactions and balances of JoinMarket can be seen in the watch-only wallet of the connected node.**
|
||||
**The addresses, transactions and balances of JoinMarket can be seen in the watch-only-descriptor-wallet of the connected node.**
|
||||
* use your own or a trusted node
|
||||
* to protect privacy in case of physical access use disk encryption
|
||||
|
||||
## Required Hardware
|
||||
* RaspberryPi 4 ([alternatively any other computer running a Debian Linux flavour](#tested-environments))
|
||||
### A computer running a Debian / Ubuntu Linux flavour.
|
||||
* See the [tested-environments](#tested-environments).
|
||||
### RaspberryPi 5 or 4
|
||||
* Power supply (5V 3A and above recommended)
|
||||
* Heatsink case
|
||||
* 16GB SDcard (minimum) - 32GB to use a pruned node
|
||||
* 32 GB Endurance type SDcard
|
||||
* [(USB SSD to run a pruned bitcoin node locally)](FAQ.md#usb-ssd-recommendation)
|
||||
* [other tested hardware ](#tested-environments)
|
||||
### VPS eg: [host4coins.net](https://host4coins.net/)
|
||||
Recommended minimum:
|
||||
* 1 GB RAM
|
||||
* 1 vCPU
|
||||
* 32 GB SSD
|
||||
|
||||
**JoininBox operates on the minimum viable hardware under the assumption that the seed (and passphrase) of the wallets used is safely backed up and can be used to recover the funds!**
|
||||
|
||||
|
|
@ -87,7 +95,7 @@ A minimalistic, security focused linux environment for JoinMarket with a termina
|
|||
* next will be presented with the CONFIG menu to
|
||||
* Connect to a remote bitcoin node on mainnet
|
||||
* Try JoinMarket on signet
|
||||
* Start a pruned node from [prunednode.today](https://prunednode.today)
|
||||
* Start a pruned node from [pruned.host4coins.net/blocks](https://pruned.host4coins.net/blocks)
|
||||
* Edit the joinmarket.cfg manually
|
||||
* Update JoininBox or JoinMarket
|
||||
|
||||
|
|
@ -105,7 +113,7 @@ A minimalistic, security focused linux environment for JoinMarket with a termina
|
|||
* Latest
|
||||
* Debian Bullseye X86_64 desktop ([images and logs available in GitHub actions](https://github.com/openoms/joininbox/actions?query=workflow%3Aamd64-image-build++branch%3Amaster+is%3Asuccess))
|
||||
* Raspberry Pi 4 running 64bit Debian Bullseye ([images and logs available in GitHub actions](https://github.com/openoms/joininbox/actions?query=workflow%3Aarm64-rpi-image-build++branch%3Amaster+is%3Asuccess++))
|
||||
* Ubuntu 22.04 X86_64 desktop (virtual machine)
|
||||
* Ubuntu 22.04 Jammy X86_64 desktop (virtual machine)
|
||||
* Previous versions tested
|
||||
* [Raspberry Pi 4 running 64bit Debian Buster](FAQ.md#build-the-sdcard-image)
|
||||
* [Hardkernel Odroid XU4/HC1 running 32bit Armbian Buster](FAQ.md#set-up-armbian-on-the-hardkernel-odroid-xu4)
|
||||
|
|
@ -114,7 +122,7 @@ A minimalistic, security focused linux environment for JoinMarket with a termina
|
|||
|
||||
### Install JoininBox
|
||||
* Start as the `root` user or change with:
|
||||
`$ sudo - su`
|
||||
`$ sudo su -`
|
||||
|
||||
* Run the [build script](https://github.com/openoms/joininbox/blob/master/build_joininbox.sh):
|
||||
```bash
|
||||
|
|
@ -153,8 +161,3 @@ the default password is: `joininbox` - will be prompted to change it on the firs
|
|||
* IRC: #joinmarket on [libera.chat](https://libera.chat/) or [hackint.org](https://hackint.org/)
|
||||
* Reddit: <https://www.reddit.com/r/joinmarket/>
|
||||
* Keybase: <https://keybase.io/team/raspiblitz#joinmarket>
|
||||
|
||||
## Donations
|
||||
* For JoinMarket (general): https://bitcoinprivacy.me/joinmarket-donations
|
||||
* To waxwing for JoinMarket: <https://joinmarket.me/donations/>
|
||||
* To openoms for JoininBox (LN + payjoin enabled - open in the [Tor Browser](https://www.torproject.org/)): <http://7tpv3ynajkv6cdocmzitcd4z3xrstp3ic6xtv5om3dc2ned3fffll5qd.onion/apps/4FePMm7m818oppkTYNZRwbDnL6HP/pos>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
# https://github.com/openoms/joininbox#tested-environments-for-joininbox
|
||||
# login with SSH or boot directly
|
||||
# run this script as root or with sudo
|
||||
# can specify donwloading from a branch or forked repo:
|
||||
# can specify downloading from a branch or forked repo:
|
||||
# bash build_joininbox.sh [branch] [github user]
|
||||
########################################################################
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ echo "
|
|||
# https://github.com/${githubUser}/joininbox/tree/${wantedBranch}
|
||||
|
||||
# Press ENTER to confirm or CTRL+C to exit"
|
||||
read key
|
||||
read
|
||||
|
||||
echo
|
||||
echo "###################################"
|
||||
|
|
@ -78,7 +78,7 @@ if [ $(cat /etc/os-release 2>/dev/null | grep -c 'Debian') -gt 0 ]; then
|
|||
elif [ $(cat /etc/os-release 2>/dev/null | grep -c 'Ubuntu') -gt 0 ]; then
|
||||
baseimage="ubuntu"
|
||||
else
|
||||
echo "\n!!! FAIL: Base Image cannot be detected or is not supported."
|
||||
echo "\n# FAIL: Base Image cannot be detected or is not supported."
|
||||
cat /etc/os-release 2>/dev/null
|
||||
uname -a
|
||||
exit 1
|
||||
|
|
@ -90,7 +90,28 @@ echo "# Preparing the base image"
|
|||
echo "############################"
|
||||
echo
|
||||
|
||||
echo "# Prepare ${baseImage} "
|
||||
echo "# Prevent sleep" # on all platforms https://wiki.debian.org/Suspend
|
||||
systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
|
||||
mkdir /etc/systemd/sleep.conf.d
|
||||
echo "[Sleep]
|
||||
AllowSuspend=no
|
||||
AllowHibernation=no
|
||||
AllowSuspendThenHibernate=no
|
||||
AllowHybridSleep=no" | tee /etc/systemd/sleep.conf.d/nosuspend.conf
|
||||
mkdir /etc/systemd/logind.conf.d
|
||||
echo "[Login]
|
||||
HandleLidSwitch=ignore
|
||||
HandleLidSwitchDocked=ignore" | tee /etc/systemd/logind.conf.d/nosuspend.conf
|
||||
|
||||
# check if /etc/hosts already has debian entry
|
||||
# prevent "unable to resolve host debian" error
|
||||
isDebianInHosts=$(grep -c "debian" /etc/hosts)
|
||||
if [ ${isDebianInHosts} -eq 0 ]; then
|
||||
echo "# Adding debian to /etc/hosts"
|
||||
echo "127.0.1.1 debian" | tee -a /etc/hosts > /dev/null
|
||||
systemctl restart networking
|
||||
fi
|
||||
|
||||
# special prepare on RPi
|
||||
if [ "${baseimage}" = "raspios" ] || [ "${baseimage}" = "debian_rpi64" ] ||
|
||||
[ "${baseimage}" = "armbian" ]; then
|
||||
|
|
@ -139,17 +160,6 @@ if [ "${baseimage}" = "raspios" ] || [ "${baseimage}" = "debian_rpi64" ]; then
|
|||
echo "$max_usb_current already in $configFile"
|
||||
fi
|
||||
|
||||
# run fsck on sd root partition on every startup to prevent "maintenance login" screen
|
||||
# see: https://github.com/rootzoll/raspiblitz/issues/782#issuecomment-564981630
|
||||
# see https://github.com/rootzoll/raspiblitz/issues/1053#issuecomment-600878695
|
||||
# use command to check last fsck check: sudo tune2fs -l /dev/mmcblk0p2
|
||||
if [ "${tweak_boot_drive}" == "true" ]; then
|
||||
echo "* running tune2fs"
|
||||
tune2fs -c 1 /dev/mmcblk0p2
|
||||
else
|
||||
echo "* skipping tweak_boot_drive"
|
||||
fi
|
||||
|
||||
# edit kernel parameters
|
||||
kernelOptionsFile=/boot/cmdline.txt
|
||||
fsOption1="fsck.mode=force"
|
||||
|
|
@ -266,70 +276,46 @@ echo "##########"
|
|||
echo
|
||||
# apt dependencies for python
|
||||
apt-get install -y python3 virtualenv python3-venv python3-dev python3-wheel python3-jinja2 python3-pip
|
||||
if [ "${cpu}" = "armv7l" ] || [ "${cpu}" = "armv6l" ]; then
|
||||
if [ ! -f "/usr/bin/python3.7" ]; then
|
||||
# install python37
|
||||
pythonVersion="3.7.9"
|
||||
majorPythonVersion=$(echo "$pythonVersion" | awk -F. '{print $1"."$2}')
|
||||
# dependencies
|
||||
apt-get install software-properties-common build-essential libnss3-dev zlib1g-dev libgdbm-dev libncurses5-dev libssl-dev libffi-dev libreadline-dev libsqlite3-dev libbz2-dev -y
|
||||
# download
|
||||
wget --progress=bar:force https://www.python.org/ftp/python/${pythonVersion}/Python-${pythonVersion}.tgz
|
||||
# optional signature for verification
|
||||
wget --progress=bar:force https://www.python.org/ftp/python/${pythonVersion}/Python-${pythonVersion}.tgz.asc
|
||||
# get PGP pubkey of Ned Deily (Python release signing key) <nad@python.org>
|
||||
gpg --recv-key 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
|
||||
# check for: Good signature from "Pablo Galindo Salgado <pablogsal@gmail.com>"
|
||||
gpg --verify Python-${pythonVersion}.tgz.asc || exit 1
|
||||
# unzip
|
||||
tar xvf Python-${pythonVersion}.tgz
|
||||
cd Python-${pythonVersion} || exit 1
|
||||
# configure
|
||||
./configure --enable-optimizations
|
||||
# install
|
||||
make altinstall
|
||||
# move the python binary to the expected directory
|
||||
mv "$(which python${majorPythonVersion})" /usr/bin/
|
||||
# check
|
||||
ls -la /usr/bin/python${majorPythonVersion} || exit 1
|
||||
# clean
|
||||
cd ..
|
||||
rm Python-${pythonVersion}.tgz
|
||||
rm -rf Python-${pythonVersion}
|
||||
fi
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.7 1
|
||||
echo "# python calls python3.7"
|
||||
|
||||
if [ -f "/usr/bin/python3.13" ]; then
|
||||
# use python 3.13 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.13 1
|
||||
echo "# python calls python3.13"
|
||||
elif [ -f "/usr/bin/python3.12" ]; then
|
||||
# use python 3.12 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1
|
||||
echo "# python calls python3.12"
|
||||
elif [ -f "/usr/bin/python3.11" ]; then
|
||||
# use python 3.11 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1
|
||||
echo "# python calls python3.11"
|
||||
elif [ -f "/usr/bin/python3.10" ]; then
|
||||
# use python 3.10 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1
|
||||
echo "# python calls python3.10"
|
||||
elif [ -f "/usr/bin/python3.9" ]; then
|
||||
# use python 3.9 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1
|
||||
echo "# python calls python3.9"
|
||||
elif [ -f "/usr/bin/python3.8" ]; then
|
||||
# use python 3.8 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
|
||||
echo "# python calls python3.8"
|
||||
else
|
||||
if [ -f "/usr/bin/python3.7" ]; then
|
||||
# make sure /usr/bin/python exists (and calls Python3.7)
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.7 1
|
||||
echo "# python calls python3.7"
|
||||
elif [ -f "/usr/bin/python3.8" ]; then
|
||||
# use python 3.8 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
|
||||
echo "# python calls python3.8"
|
||||
elif [ -f "/usr/bin/python3.9" ]; then
|
||||
# use python 3.9 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1
|
||||
echo "# python calls python3.9"
|
||||
elif [ -f "/usr/bin/python3.10" ]; then
|
||||
# use python 3.10 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1
|
||||
echo "# python calls python3.10"
|
||||
elif [ -f "/usr/bin/python3.11" ]; then
|
||||
# use python 3.11 if available
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1
|
||||
echo "# python calls python3.11"
|
||||
else
|
||||
echo "!!! FAIL !!!"
|
||||
echo "There is no tested version of python present"
|
||||
exit 1
|
||||
fi
|
||||
echo "# FAIL- there is no tested version of python present"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# make sure /usr/bin/pip exists (and calls pip3)
|
||||
update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
|
||||
|
||||
# don't protect system packages from pip install
|
||||
# tracking issue: https://github.com/raspiblitz/raspiblitz/issues/4170
|
||||
for PYTHONDIR in /usr/lib/python3.*; do
|
||||
if [ -f "$PYTHONDIR/EXTERNALLY-MANAGED" ]; then
|
||||
rm "$PYTHONDIR/EXTERNALLY-MANAGED"
|
||||
fi
|
||||
done
|
||||
|
||||
# setuptools needed for Nyx
|
||||
pip install setuptools
|
||||
|
||||
|
|
@ -360,6 +346,8 @@ apt-get install -y dialog
|
|||
apt-get install -y qrencode
|
||||
# unzip for the pruned node snapshot
|
||||
apt-get install -y unzip
|
||||
# JoinMarket dependency https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/5bfa08c6f558458c9a93e8095ce9dc1b62412838/install.sh#L76C10-L76C21
|
||||
apt-get install -y libltdl-dev
|
||||
apt-get clean
|
||||
apt-get -y autoremove
|
||||
|
||||
|
|
@ -369,7 +357,9 @@ echo "# JoininBox"
|
|||
echo "#############"
|
||||
echo
|
||||
echo "# add the 'joinmarket' user"
|
||||
adduser --disabled-password --gecos "" joinmarket
|
||||
adduser --system --group --shell /bin/bash --home /home/joinmarket joinmarket
|
||||
echo "Copy the skeleton files for login"
|
||||
sudo -u joinmarket cp -r /etc/skel/. /home/joinmarket/
|
||||
|
||||
echo "# clone the joininbox repo and copy the scripts"
|
||||
cd /home/joinmarket || exit 1
|
||||
|
|
@ -399,21 +389,21 @@ if echo "${lastCommit}" | grep 13C688DB5B9C745DE4D2E4545BFB77609B081B65; then
|
|||
PGPsigner="openoms"
|
||||
PGPpubkeyLink="https://github.com/openoms.gpg"
|
||||
PGPpubkeyFingerprint="13C688DB5B9C745DE4D2E4545BFB77609B081B65"
|
||||
elif echo "${lastCommit}" | grep 4AEE18F83AFDEB23; then
|
||||
elif echo "${lastCommit}" | grep B5690EEEBB952194; then
|
||||
echo "# The last commit was made on GitHub and is signed with the GitHub PGP key."
|
||||
PGPsigner="web-flow"
|
||||
PGPpubkeyLink="https://github.com/${PGPsigner}.gpg"
|
||||
PGPpubkeyFingerprint="4AEE18F83AFDEB23"
|
||||
PGPpubkeyFingerprint="B5690EEEBB952194"
|
||||
else
|
||||
echo "# No known PGP key found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command="sudo -u joinmarket bash /home/joinmarket/joininbox/scripts/verify.git.sh \
|
||||
${PGPsigner} ${PGPpubkeyLink} ${PGPpubkeyFingerprint} ${tag}"
|
||||
command="bash /home/joinmarket/joininbox/scripts/verify.git.sh \
|
||||
${PGPsigner} ${PGPpubkeyLink} ${PGPpubkeyFingerprint}"
|
||||
echo "running: ${command}"
|
||||
chmod 777 /dev/shm
|
||||
${command} || exit 1
|
||||
sudo -u joinmarket ${command} || exit 1
|
||||
|
||||
runuser joinmarket -c "cp /home/joinmarket/joininbox/scripts/* /home/joinmarket/"
|
||||
runuser joinmarket -c "cp /home/joinmarket/joininbox/scripts/.* /home/joinmarket/ 2>/dev/null"
|
||||
|
|
@ -463,7 +453,7 @@ if [ "$torTest" != "Congratulations. This browser is configured to use Tor." ];
|
|||
echo "torKeyAvailable=${torKeyAvailable}"
|
||||
if [ ${torKeyAvailable} -eq 0 ]; then
|
||||
# https://support.torproject.org/apt/tor-deb-repo/
|
||||
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
|
||||
wget --prefer-family=ipv4 -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
|
||||
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | apt-key add -
|
||||
echo "OK"
|
||||
else
|
||||
|
|
@ -492,13 +482,13 @@ deb-src [arch=${arch}] https://deb.torproject.org/torproject.org ${distro} main"
|
|||
apt-get install -y build-essential fakeroot devscripts
|
||||
apt-get build-dep -y tor deb.torproject.org-keyring
|
||||
mkdir ~/debian-packages
|
||||
cd ~/debian-packages
|
||||
cd ~/debian-packages || exit 1
|
||||
apt-get source tor
|
||||
cd tor-* || exit 1
|
||||
debuild -rfakeroot -uc -us
|
||||
cd .. || exit 1
|
||||
dpkg -i tor_*.deb
|
||||
# setup Tor in the backgound
|
||||
# setup Tor in the background
|
||||
# TODO - test if remains in the background after the Tor service is started
|
||||
tor &
|
||||
else
|
||||
|
|
@ -540,6 +530,7 @@ echo
|
|||
apt-get install -y fail2ban ufw
|
||||
# autostart fail2ban
|
||||
systemctl enable fail2ban
|
||||
touch /var/log/auth.log
|
||||
|
||||
# set up the firewall
|
||||
ufw default deny incoming
|
||||
|
|
@ -592,7 +583,6 @@ echo "#############"
|
|||
echo "
|
||||
if [ -f \"/home/joinmarket/joinmarket-clientserver/jmvenv/bin/activate\" ]; then
|
||||
. /home/joinmarket/joinmarket-clientserver/jmvenv/bin/activate
|
||||
/home/joinmarket/joinmarket-clientserver/jmvenv/bin/python -c \"import PySide2\"
|
||||
cd /home/joinmarket/joinmarket-clientserver/scripts/
|
||||
fi
|
||||
# shortcut commands
|
||||
|
|
@ -608,23 +598,29 @@ echo "#########################"
|
|||
echo "# Download Bitcoin Core"
|
||||
echo "#########################"
|
||||
echo
|
||||
sudo -u joinmarket /home/joinmarket/install.bitcoincore.sh downloadCoreOnly || exit 1
|
||||
sudo -u joinmarket bash /home/joinmarket/install.bitcoincore.sh downloadCoreOnly || exit 1
|
||||
|
||||
echo
|
||||
echo "######################"
|
||||
echo "# Install JoinMarket"
|
||||
echo "######################"
|
||||
|
||||
qtgui=true
|
||||
|
||||
if [ "${cpu}" = x86_64 ]; then
|
||||
qtgui=true
|
||||
else
|
||||
# no qtgui on arm
|
||||
qtgui=false
|
||||
fi
|
||||
checkEntry=$(runuser joinmarket -c "cat /home/joinmarket/joinin.conf | grep -c qtgui")
|
||||
if [ ${checkEntry} -eq 0 ]; then
|
||||
echo "qtgui=true" | tee -a /home/joinmarket/joinin.conf
|
||||
echo "qtgui=$qtgui" | tee -a /home/joinmarket/joinin.conf
|
||||
fi
|
||||
if [ "$4" = "without-qt" ]; then
|
||||
qtgui="false"
|
||||
sed -i "s/^qtgui=.*/qtgui=false/g" /home/joinmarket/joinin.conf
|
||||
fi
|
||||
sudo -u joinmarket /home/joinmarket/install.joinmarket.sh -i install -q $qtgui || exit 1
|
||||
sudo -u joinmarket bash /home/joinmarket/install.joinmarket.sh -i install -q $qtgui || exit 1
|
||||
|
||||
echo "###################"
|
||||
echo "# bootstrap.service"
|
||||
|
|
|
|||
120
ci/amd64/debian/build.amd64-debian.pkr.hcl
Normal file
120
ci/amd64/debian/build.amd64-debian.pkr.hcl
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# images, checksums and signatures are at:
|
||||
# https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/
|
||||
# NOTE: This template is intended to be invoked via the wrapper script:
|
||||
# ci/amd64/packer.build.amd64-debian.sh
|
||||
# The wrapper resolves and injects the latest point-release ISO name and matching checksum
|
||||
# at runtime. Defaults below are placeholders and are not guaranteed to work if you run
|
||||
# `packer build` directly.
|
||||
variable "iso_name" { default = "debian-13-amd64-netinst.iso" }
|
||||
variable "iso_checksum" { default = "file:https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA256SUMS" }
|
||||
|
||||
variable "github_user" { default = "openoms" }
|
||||
variable "branch" { default = "master" }
|
||||
|
||||
variable "boot" { default = "uefi" }
|
||||
variable "preseed_file" { default = "preseed.cfg" }
|
||||
variable "hostname" { default = "joininbox-amd64" }
|
||||
|
||||
variable "image_size" { default = "30000" }
|
||||
variable "image_type" { default = "qcow2" }
|
||||
|
||||
variable "memory" { default = "2048" }
|
||||
variable "cpus" { default = "2" }
|
||||
|
||||
locals {
|
||||
name_template = "joininbox-amd64-debian"
|
||||
image_extension = var.image_type == "raw" ? "img" : var.image_type
|
||||
bios_file = var.boot == "uefi" ? "OVMF.fd" : "bios-256k.bin"
|
||||
boot_command = var.boot == "uefi" ? [
|
||||
"<wait><wait><wait>c<wait><wait><wait>",
|
||||
"linux /install.amd/vmlinuz ",
|
||||
"auto=true ",
|
||||
"url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/${var.preseed_file} ",
|
||||
"hostname=${var.hostname} ",
|
||||
"domain=${var.hostname}.local ",
|
||||
"interface=auto ",
|
||||
"vga=788 noprompt quiet --<enter>",
|
||||
"initrd /install.amd/initrd.gz<enter>",
|
||||
"boot<enter>"
|
||||
] : [
|
||||
"<esc><wait>install <wait>",
|
||||
"<wait><wait><wait><wait><wait><wait><wait><wait><wait><wait><wait><wait><wait><wait><wait><wait> preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/${var.preseed_file} <wait>",
|
||||
"debian-installer=en_US.UTF-8 <wait>",
|
||||
"auto <wait>",
|
||||
"locale=en_US.UTF-8 <wait>",
|
||||
"kbd-chooser/method=us <wait>",
|
||||
"keyboard-configuration/xkb-keymap=us <wait>",
|
||||
"netcfg/get_hostname=${var.hostname} <wait>",
|
||||
"netcfg/get_domain=${var.hostname}.local <wait>",
|
||||
"fb=false <wait>",
|
||||
"debconf/frontend=noninteractive <wait>",
|
||||
"console-setup/ask_detect=false <wait>",
|
||||
"console-keymaps-at/keymap=us <wait>",
|
||||
"grub-installer/bootdev=default <wait>",
|
||||
"<enter><wait>"
|
||||
]
|
||||
}
|
||||
|
||||
source "qemu" "debian" {
|
||||
boot_command = local.boot_command
|
||||
boot_wait = "5s"
|
||||
cpus = var.cpus
|
||||
disk_size = var.image_size
|
||||
http_directory = "./http"
|
||||
iso_checksum = var.iso_checksum
|
||||
iso_url = "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/${var.iso_name}"
|
||||
memory = var.memory
|
||||
output_directory = "../builds/${local.name_template}-qemu"
|
||||
shutdown_command = "echo 'joininbox' | sudo /sbin/shutdown -hP now"
|
||||
ssh_password = "joininbox"
|
||||
ssh_port = 22
|
||||
ssh_timeout = "10000s"
|
||||
ssh_username = "joinmarket"
|
||||
format = var.image_type
|
||||
vm_name = "${local.name_template}.${local.image_extension}"
|
||||
headless = false
|
||||
vnc_bind_address = "127.0.0.1"
|
||||
vnc_port_max = 5900
|
||||
vnc_port_min = 5900
|
||||
qemuargs = [
|
||||
["-m", var.memory],
|
||||
["-bios", local.bios_file],
|
||||
["-display", "none"]
|
||||
]
|
||||
}
|
||||
|
||||
build {
|
||||
description = "JoininBox amd64 Debian image build"
|
||||
sources = ["source.qemu.debian"]
|
||||
|
||||
provisioner "shell" {
|
||||
environment_vars = [
|
||||
"HOME_DIR=/home/joinmarket",
|
||||
"github_user=${var.github_user}",
|
||||
"branch=${var.branch}"
|
||||
]
|
||||
|
||||
execute_command = "echo 'joininbox' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'"
|
||||
expect_disconnect = true
|
||||
scripts = [
|
||||
"./scripts/update.sh",
|
||||
"./../_common/sshd.sh",
|
||||
"./scripts/networking.sh",
|
||||
"./scripts/sudoers.sh",
|
||||
"./scripts/systemd.sh",
|
||||
"./scripts/joininbox.sh",
|
||||
"./scripts/cleanup.sh"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
packer {
|
||||
required_version = ">= 1.7.0, < 2.0.0"
|
||||
|
||||
required_plugins {
|
||||
qemu = {
|
||||
source = "github.com/hashicorp/qemu"
|
||||
version = ">= 1.0.0, < 2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
choose-mirror-bin mirror/http/proxy string
|
||||
d-i apt-setup/use_mirror boolean true
|
||||
d-i base-installer/kernel/override-image string linux-server
|
||||
d-i clock-setup/utc boolean true
|
||||
d-i clock-setup/utc-auto boolean true
|
||||
d-i finish-install/reboot_in_progress note
|
||||
d-i grub-installer/only_debian boolean true
|
||||
d-i grub-installer/with_other_os boolean true
|
||||
d-i keymap select us
|
||||
d-i mirror/country string manual
|
||||
d-i mirror/http/directory string /debian
|
||||
d-i mirror/http/hostname string httpredir.debian.org
|
||||
d-i mirror/http/proxy string
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
d-i partman/confirm_write_new_label boolean true
|
||||
d-i passwd/root-login boolean false
|
||||
d-i passwd/root-password-again password joininbox
|
||||
d-i passwd/root-password password joininbox
|
||||
d-i passwd/user-fullname string joinmarket
|
||||
d-i passwd/user-uid string 1000
|
||||
d-i passwd/user-password password joininbox
|
||||
d-i passwd/user-password-again password joininbox
|
||||
d-i passwd/username string joinmarket
|
||||
d-i pkgsel/include string sudo bzip2 acpid cryptsetup zlib1g-dev wget curl dkms fuse make nfs-common net-tools cifs-utils rsync
|
||||
d-i pkgsel/install-language-support boolean false
|
||||
d-i pkgsel/update-policy select none
|
||||
d-i pkgsel/upgrade select full-upgrade
|
||||
# Prevent packaged version of VirtualBox Guest Additions being installed:
|
||||
d-i preseed/early_command string sed -i \
|
||||
'/in-target/idiscover(){/sbin/discover|grep -v VirtualBox;}' \
|
||||
/usr/lib/pre-pkgsel.d/20install-hwpackages
|
||||
d-i time/zone string UTC
|
||||
d-i user-setup/allow-password-weak boolean true
|
||||
d-i user-setup/encrypt-home boolean false
|
||||
d-i preseed/late_command string sed -i '/^deb cdrom:/s/^/#/' /target/etc/apt/sources.list
|
||||
apt-cdrom-setup apt-setup/cdrom/set-first boolean false
|
||||
apt-mirror-setup apt-setup/use_mirror boolean true
|
||||
popularity-contest popularity-contest/participate boolean false
|
||||
tasksel tasksel/first multiselect standard, ssh-server
|
||||
72
ci/amd64/debian/http/preseed.cfg
Normal file
72
ci/amd64/debian/http/preseed.cfg
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# https://github.com/chef/bento/blob/main/packer_templates/http/debian/preseed.cfg
|
||||
# https://www.debian.org/releases/stable/example-preseed.txt
|
||||
# https://github.com/tylert/packer-build/blob/master/source/debian/12_bookworm/base-uefi.preseed
|
||||
# variables: https://github.com/tylert/packer-build/blob/master/source/debian/12_bookworm/base-uefi.pkr.hcl
|
||||
|
||||
# Locale Setup
|
||||
d-i debian-installer/language string en
|
||||
d-i debian-installer/country string US
|
||||
d-i debian-installer/locale string en_US.UTF-8
|
||||
# d-i localechooser/supported-locales multiselect en_CA.UTF-8 fr_CA.UTF-8 zh_CN.UTF-8
|
||||
# d-i pkgsel/install-language-support boolean true
|
||||
|
||||
# Keyboard Setup
|
||||
d-i keyboard-configuration/xkb-keymap select us
|
||||
|
||||
# Clock Setup
|
||||
# d-i time/zone string Canada/Eastern
|
||||
d-i time/zone string UTC
|
||||
d-i clock-setup/utc boolean true
|
||||
# set above to false if making a bootable USB to run on same system as Windows
|
||||
|
||||
# Network Setup
|
||||
d-i netcfg/get_hostname string joininbox-amd64
|
||||
d-i netcfg/get_domain string
|
||||
# https://bugs.launchpad.net/ubuntu/+source/netcfg/+bug/713385
|
||||
d-i netcfg/choose_interface select auto
|
||||
# make sure you also add "interface=auto" to your boot command too
|
||||
# https://bugs.launchpad.net/ubuntu/+source/netcfg/+bug/713385
|
||||
|
||||
# User Setup
|
||||
d-i passwd/root-login boolean false
|
||||
d-i passwd/root-password-again password joininbox
|
||||
d-i passwd/root-password password joininbox
|
||||
d-i passwd/user-fullname string joinmarket
|
||||
d-i passwd/user-uid string 1000
|
||||
d-i passwd/user-password password joininbox
|
||||
d-i passwd/user-password-again password joininbox
|
||||
d-i passwd/username string joinmarket
|
||||
|
||||
# Package Setup
|
||||
d-i hw-detect/load_firmware boolean false
|
||||
d-i hw-detect/load_media boolean false
|
||||
apt-cdrom-setup apt-setup/cdrom/set-first boolean false
|
||||
d-i mirror/country string manual
|
||||
d-i mirror/http/hostname string httpredir.debian.org
|
||||
d-i mirror/http/directory string /debian
|
||||
d-i mirror/http/proxy string
|
||||
d-i apt-setup/contrib boolean true
|
||||
d-i apt-setup/non-free boolean true
|
||||
|
||||
tasksel tasksel/first multiselect ssh-server, standard
|
||||
d-i pkgsel/include string sudo bzip2 acpid cryptsetup zlib1g-dev wget curl dkms fuse make nfs-common net-tools cifs-utils rsync
|
||||
d-i pkgsel/install-language-support boolean false
|
||||
d-i pkgsel/update-policy select none
|
||||
d-i pkgsel/upgrade select full-upgrade
|
||||
|
||||
popularity-contest popularity-contest/participate boolean false
|
||||
|
||||
# Drive setup
|
||||
d-i partman-auto-lvm/guided_size string max
|
||||
d-i partman-auto/choose_recipe select atomic
|
||||
d-i partman-auto/method string lvm
|
||||
d-i partman-lvm/confirm boolean true
|
||||
d-i partman-lvm/confirm_nooverwrite boolean true
|
||||
d-i partman-lvm/device_remove_lvm boolean true
|
||||
d-i partman/choose_partition select finish
|
||||
d-i partman/confirm boolean true
|
||||
d-i partman/confirm_nooverwrite boolean true
|
||||
d-i partman/confirm_write_new_label boolean true
|
||||
|
||||
# Final Setup
|
||||
d-i finish-install/reboot_in_progress note
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
{
|
||||
"variables": {
|
||||
"box_basename": "debian",
|
||||
"build_directory": "../builds",
|
||||
"build_timestamp": "{{isotime \"20060102150405\"}}",
|
||||
"cpus": "2",
|
||||
"disk_size": "30000",
|
||||
"git_revision": "__unknown_git_revision__",
|
||||
"guest_additions_url": "",
|
||||
"headless": "false",
|
||||
"http_directory": "{{template_dir}}/http",
|
||||
"http_proxy": "{{env `http_proxy`}}",
|
||||
"https_proxy": "{{env `https_proxy`}}",
|
||||
"iso_checksum": "e482910626b30f9a7de9b0cc142c3d4a079fbfa96110083be1d0b473671ce08d",
|
||||
"iso_name": "debian-11.6.0-amd64-netinst.iso",
|
||||
"memory": "2048",
|
||||
"mirror": "http://cdimage.debian.org/cdimage/release",
|
||||
"mirror_directory": "current/amd64/iso-cd",
|
||||
"name": "debian",
|
||||
"no_proxy": "{{env `no_proxy`}}",
|
||||
"preseed_path": "debian-9/preseed.cfg",
|
||||
"qemu_display": "none",
|
||||
"qemu_bios": "bios-256k.bin",
|
||||
"template": "joininbox-amd64-debian",
|
||||
"boot_command": "<esc><wait>install <wait> preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/{{user `preseed_path`}} <wait>debian-installer=en_US.UTF-8 <wait>auto <wait>locale=en_US.UTF-8 <wait>kbd-chooser/method=us <wait>keyboard-configuration/xkb-keymap=us <wait>netcfg/get_hostname={{ .Name }} <wait>netcfg/get_domain=vagrantup.com <wait>fb=false <wait>debconf/frontend=noninteractive <wait>console-setup/ask_detect=false <wait>console-keymaps-at/keymap=us <wait>grub-installer/bootdev=default <wait><enter><wait>",
|
||||
"version": "TIMESTAMP"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"boot_command": "{{user `boot_command`}}",
|
||||
"boot_wait": "5s",
|
||||
"cpus": "{{ user `cpus` }}",
|
||||
"disk_size": "{{user `disk_size`}}",
|
||||
"headless": "{{ user `headless` }}",
|
||||
"http_directory": "{{user `http_directory`}}",
|
||||
"iso_checksum": "{{user `iso_checksum`}}",
|
||||
"iso_url": "{{user `mirror`}}/{{user `mirror_directory`}}/{{user `iso_name`}}",
|
||||
"memory": "{{ user `memory` }}",
|
||||
"output_directory": "{{ user `build_directory` }}/{{user `template`}}-qemu",
|
||||
"shutdown_command": "echo 'joininbox' | sudo /sbin/shutdown -hP now",
|
||||
"ssh_password": "joininbox",
|
||||
"ssh_port": 22,
|
||||
"ssh_timeout": "10000s",
|
||||
"ssh_username": "joinmarket",
|
||||
"type": "qemu",
|
||||
"format": "qcow2",
|
||||
"vm_name": "{{ user `template` }}.qcow2",
|
||||
"qemuargs": [
|
||||
[ "-m", "{{ user `memory` }}" ],
|
||||
[ "-bios", "{{ user `qemu_bios` }}" ],
|
||||
[ "-display", "{{ user `qemu_display` }}" ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"boot_command": "{{user `boot_command`}}",
|
||||
"boot_wait": "5s",
|
||||
"cpus": "{{ user `cpus` }}",
|
||||
"disk_size": "{{user `disk_size`}}",
|
||||
"guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso",
|
||||
"guest_additions_url": "{{ user `guest_additions_url` }}",
|
||||
"guest_os_type": "Debian_64",
|
||||
"hard_drive_interface": "sata",
|
||||
"headless": "{{ user `headless` }}",
|
||||
"http_directory": "{{user `http_directory`}}",
|
||||
"iso_checksum": "{{user `iso_checksum`}}",
|
||||
"iso_url": "{{user `mirror`}}/{{user `mirror_directory`}}/{{user `iso_name`}}",
|
||||
"memory": "{{ user `memory` }}",
|
||||
"output_directory": "{{ user `build_directory` }}/packer-{{user `template`}}-virtualbox",
|
||||
"shutdown_command": "echo 'joininbox' | sudo -S /sbin/shutdown -hP now",
|
||||
"ssh_password": "joininbox",
|
||||
"ssh_port": 22,
|
||||
"ssh_timeout": "10000s",
|
||||
"ssh_username": "joinmarket",
|
||||
"type": "virtualbox-iso",
|
||||
"virtualbox_version_file": ".vbox_version",
|
||||
"vm_name": "{{ user `template` }}"
|
||||
},
|
||||
{
|
||||
"boot_command": "{{user `boot_command`}}",
|
||||
"boot_wait": "5s",
|
||||
"cpus": "{{ user `cpus` }}",
|
||||
"disk_size": "{{user `disk_size`}}",
|
||||
"guest_os_type": "debian8-64",
|
||||
"headless": "{{ user `headless` }}",
|
||||
"http_directory": "{{user `http_directory`}}",
|
||||
"iso_checksum": "{{user `iso_checksum`}}",
|
||||
"iso_url": "{{user `mirror`}}/{{user `mirror_directory`}}/{{user `iso_name`}}",
|
||||
"memory": "{{ user `memory` }}",
|
||||
"output_directory": "{{ user `build_directory` }}/packer-{{user `template`}}-vmware",
|
||||
"shutdown_command": "echo 'joininbox' | sudo -S /sbin/shutdown -hP now",
|
||||
"ssh_password": "joininbox",
|
||||
"ssh_port": 22,
|
||||
"ssh_timeout": "10000s",
|
||||
"ssh_username": "joinmarket",
|
||||
"tools_upload_flavor": "linux",
|
||||
"type": "vmware-iso",
|
||||
"vm_name": "{{ user `template` }}",
|
||||
"vmx_data": {
|
||||
"cpuid.coresPerSocket": "1",
|
||||
"ethernet0.pciSlotNumber": "32"
|
||||
},
|
||||
"vmx_remove_ethernet_interfaces": true
|
||||
},
|
||||
{
|
||||
"boot_command": "{{user `boot_command`}}",
|
||||
"boot_wait": "5s",
|
||||
"cpus": "{{ user `cpus` }}",
|
||||
"disk_size": "{{user `disk_size`}}",
|
||||
"guest_os_type": "debian",
|
||||
"http_directory": "{{user `http_directory`}}",
|
||||
"iso_checksum": "{{user `iso_checksum`}}",
|
||||
"iso_url": "{{user `mirror`}}/{{user `mirror_directory`}}/{{user `iso_name`}}",
|
||||
"memory": "{{ user `memory` }}",
|
||||
"output_directory": "{{ user `build_directory` }}/packer-{{user `template`}}-parallels",
|
||||
"parallels_tools_flavor": "lin",
|
||||
"prlctl_version_file": ".prlctl_version",
|
||||
"shutdown_command": "echo 'joininbox' | sudo -S /sbin/shutdown -hP now",
|
||||
"ssh_password": "joininbox",
|
||||
"ssh_port": 22,
|
||||
"ssh_timeout": "10000s",
|
||||
"ssh_username": "joinmarket",
|
||||
"type": "parallels-iso",
|
||||
"vm_name": "{{ user `template` }}"
|
||||
}
|
||||
],
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell",
|
||||
"environment_vars": [
|
||||
"HOME_DIR=/home/joinmarket",
|
||||
"http_proxy={{user `http_proxy`}}",
|
||||
"https_proxy={{user `https_proxy`}}",
|
||||
"no_proxy={{user `no_proxy`}}",
|
||||
"github_user={{user `github_user`}}",
|
||||
"branch={{user `branch`}}"
|
||||
],
|
||||
"execute_command": "echo 'joininbox' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'",
|
||||
"expect_disconnect": true,
|
||||
"scripts": [
|
||||
"{{template_dir}}/scripts/update.sh",
|
||||
"{{template_dir}}/../_common/sshd.sh",
|
||||
"{{template_dir}}/scripts/networking.sh",
|
||||
"{{template_dir}}/scripts/sudoers.sh",
|
||||
"{{template_dir}}/scripts/systemd.sh",
|
||||
"{{template_dir}}/scripts/joininbox.sh",
|
||||
"{{template_dir}}/scripts/cleanup.sh"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -7,3 +7,6 @@ update-grub;
|
|||
|
||||
# Adding a 2 sec delay to the interface up, to make the dhclient happy
|
||||
echo "pre-up sleep 2" >> /etc/network/interfaces
|
||||
|
||||
echo "$(hostname -I | awk '{print $1}') $(hostname)" >>/etc/hosts
|
||||
echo "127.0.1.1 $(hostname)" >>/etc/hosts
|
||||
|
|
|
|||
|
|
@ -1,31 +1,135 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# Install packer
|
||||
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
|
||||
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
|
||||
sudo apt-get update
|
||||
echo -e "\nInstalling packer..."
|
||||
sudo apt-get install -y packer
|
||||
|
||||
# Install qemu
|
||||
echo -e "\nInstalling qemu..."
|
||||
sudo apt-get install -y qemu-system
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
github_user=$1
|
||||
# install packer
|
||||
if ! packer version 2>/dev/null; then
|
||||
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
|
||||
sudo apt-add-repository -y "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
|
||||
sudo apt-get update
|
||||
echo -e "\nInstalling packer..."
|
||||
sudo apt-get install -y packer
|
||||
else
|
||||
github_user=openoms
|
||||
echo "# Packer is installed"
|
||||
fi
|
||||
|
||||
# install qemu and UEFI firmware
|
||||
echo "# Install qemu ..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y qemu-system ovmf
|
||||
|
||||
# set vars from positional arguments (for backward compatibility with CI)
|
||||
if [ $# -gt 0 ]; then
|
||||
github_user=$1
|
||||
else
|
||||
github_user=openoms
|
||||
fi
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
branch=$2
|
||||
branch=$2
|
||||
else
|
||||
branch=master
|
||||
branch=master
|
||||
fi
|
||||
|
||||
# Resolve latest Debian 13 amd64 netinst ISO from SHA256SUMS.
|
||||
# This avoids 404s and checksum mismatches when Debian point releases rotate.
|
||||
debian_major=${DEBIAN_MAJOR:-13}
|
||||
debian_iso_dir="https://cdimage.debian.org/debian-cd/current/amd64/iso-cd"
|
||||
debian_sums_url="${debian_iso_dir}/SHA256SUMS"
|
||||
debian_sums_sig_url="${debian_iso_dir}/SHA256SUMS.sign"
|
||||
debian_cd_key_urls=(
|
||||
"https://www.debian.org/CD/key-DA87E80D6294BE9B.txt"
|
||||
"https://www.debian.org/CD/key-988021A964E6EA7D.txt"
|
||||
)
|
||||
debian_cd_expected_fprs=(
|
||||
"DF9B9C49EAA9298432589D76DA87E80D6294BE9B"
|
||||
"10460DAD76165AD81FBC0CE9988021A964E6EA7D"
|
||||
)
|
||||
|
||||
if ! command -v gpgv >/dev/null 2>&1; then
|
||||
echo "# Installing gpgv"
|
||||
sudo apt-get install -y gpgv
|
||||
fi
|
||||
|
||||
if ! command -v gpgv >/dev/null 2>&1; then
|
||||
echo "ERROR: gpgv is required for signature verification"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmp_checksums_dir=$(mktemp -d)
|
||||
trap 'rm -rf "${tmp_checksums_dir}"' EXIT
|
||||
|
||||
echo "# Downloading checksum files"
|
||||
curl -fsSL "${debian_sums_url}" -o "${tmp_checksums_dir}/SHA256SUMS"
|
||||
curl -fsSL "${debian_sums_sig_url}" -o "${tmp_checksums_dir}/SHA256SUMS.sign"
|
||||
|
||||
echo "# Verifying SHA256SUMS signature (PGP)"
|
||||
cd_keyring="${tmp_checksums_dir}/debian-cd-signing-keys.gpg"
|
||||
tmp_gnupg_home="${tmp_checksums_dir}/gnupg-home"
|
||||
mkdir -p "${tmp_gnupg_home}"
|
||||
chmod 700 "${tmp_gnupg_home}"
|
||||
|
||||
for i in "${!debian_cd_key_urls[@]}"; do
|
||||
key_url="${debian_cd_key_urls[$i]}"
|
||||
expected_fpr="${debian_cd_expected_fprs[$i]}"
|
||||
key_file="${tmp_checksums_dir}/cd-key-${i}.asc"
|
||||
curl -fsSL "${key_url}" -o "${key_file}"
|
||||
actual_fpr=$(gpg --homedir "${tmp_gnupg_home}" --show-keys --with-colons "${key_file}" 2>/dev/null | awk -F: '/^fpr:/ {print $10; exit}')
|
||||
if [ -z "${actual_fpr}" ] || [ "${actual_fpr}" != "${expected_fpr}" ]; then
|
||||
echo "# SHA256SUMS signature: FAIL"
|
||||
echo "ERROR: Unexpected fingerprint for ${key_url}"
|
||||
exit 1
|
||||
fi
|
||||
gpg --homedir "${tmp_gnupg_home}" --no-default-keyring --keyring "${cd_keyring}" --import "${key_file}" >/dev/null 2>&1
|
||||
done
|
||||
|
||||
if gpgv --keyring "${cd_keyring}" "${tmp_checksums_dir}/SHA256SUMS.sign" "${tmp_checksums_dir}/SHA256SUMS" >/dev/null 2>&1; then
|
||||
echo "# SHA256SUMS signature: PASS"
|
||||
else
|
||||
echo "# SHA256SUMS signature: FAIL"
|
||||
echo "ERROR: PGP signature verification failed for ${debian_sums_url}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Resolving latest Debian ${debian_major} amd64 netinst ISO from ${debian_sums_url}"
|
||||
latest_iso_line=$(awk -v major="${debian_major}" '$2 ~ ("^\\*?\\.?/?debian-" major "\\.[0-9]+\\.[0-9]+-amd64-netinst\\.iso$") {print $1 " " $2}' "${tmp_checksums_dir}/SHA256SUMS" | \
|
||||
sort -k2 -V | tail -1)
|
||||
|
||||
if [ -z "${latest_iso_line}" ]; then
|
||||
echo "ERROR: Could not resolve latest Debian ${debian_major} amd64 netinst ISO from ${debian_sums_url}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
latest_iso_checksum=$(echo "${latest_iso_line}" | awk '{print $1}')
|
||||
latest_iso_name=$(echo "${latest_iso_line}" | awk '{print $2}' | sed 's#^\*##; s#^\./##; s#^/##')
|
||||
|
||||
if [ -z "${latest_iso_name}" ] || [ -z "${latest_iso_checksum}" ]; then
|
||||
echo "ERROR: Failed parsing ISO name/checksum from: ${latest_iso_line}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
resolved_checksum=$(awk -v iso="${latest_iso_name}" '($2 == iso || $2 == "*" iso || $2 == "./" iso || $2 == "/" iso) {print $1; exit}' "${tmp_checksums_dir}/SHA256SUMS")
|
||||
if [ -z "${resolved_checksum}" ]; then
|
||||
echo "ERROR: Could not find checksum entry for ${latest_iso_name} in ${debian_sums_url}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Debian ISO selection"
|
||||
echo "# ISO filename : ${latest_iso_name}"
|
||||
echo "# SHA256 (selected) : ${latest_iso_checksum}"
|
||||
echo "# SHA256 (resolved) : ${resolved_checksum}"
|
||||
if [ "${latest_iso_checksum}" = "${resolved_checksum}" ]; then
|
||||
echo "# Checksum verify : PASS"
|
||||
else
|
||||
echo "# Checksum verify : FAIL"
|
||||
echo "ERROR: Checksum mismatch for ${latest_iso_name}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
vars="-var github_user=${github_user} -var branch=${branch} -var iso_name=${latest_iso_name} -var iso_checksum=${latest_iso_checksum}"
|
||||
|
||||
# Build the image
|
||||
echo -e "\nBuilding image..."
|
||||
echo "# Build the image with: github_user=${github_user} branch=${branch}"
|
||||
cd debian
|
||||
PACKER_LOG=1 packer build \
|
||||
-var github_user=${github_user} -var branch=${branch} \
|
||||
-only=qemu joininbox-amd64-debian.json
|
||||
packer init -upgrade .
|
||||
PACKER_LOG=1 packer build ${vars} -only=qemu.debian build.amd64-debian.pkr.hcl || exit 1
|
||||
|
|
|
|||
138
ci/amd64/test.amd64-image-bats.sh
Executable file
138
ci/amd64/test.amd64-image-bats.sh
Executable file
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
image="${1:-${GITHUB_WORKSPACE:-$(pwd)}/ci/amd64/builds/joininbox-amd64-debian-qemu/joininbox-amd64-debian.qcow2}"
|
||||
ssh_port="${SSH_PORT:-2222}"
|
||||
ssh_password="${SSH_PASSWORD:-joininbox}"
|
||||
qemu_pid_file="${RUNNER_TEMP:-/tmp}/joininbox-qemu.pid"
|
||||
bats_core_dir="${BATS_CORE_DIR:-${GITHUB_WORKSPACE:-$(pwd)}/.bats-core}"
|
||||
|
||||
if [ ! -f "${image}" ]; then
|
||||
echo "Missing image: ${image}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x "${bats_core_dir}/bin/bats" ]; then
|
||||
echo "Missing bats-core checkout: ${bats_core_dir}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ovmf qemu-system-x86 sshpass
|
||||
|
||||
ssh_opts=(
|
||||
-o StrictHostKeyChecking=no
|
||||
-o UserKnownHostsFile=/dev/null
|
||||
-o ConnectTimeout=5
|
||||
-p "${ssh_port}"
|
||||
)
|
||||
|
||||
ovmf_code="${OVMF_CODE:-${OVMF_BIOS:-}}"
|
||||
ovmf_vars_template="${OVMF_VARS:-}"
|
||||
ovmf_vars="${RUNNER_TEMP:-/tmp}/joininbox-ovmf-vars.fd"
|
||||
qemu_firmware_args=()
|
||||
|
||||
if [ -z "${ovmf_code}" ]; then
|
||||
for candidate in \
|
||||
/usr/share/OVMF/OVMF_CODE_4M.fd \
|
||||
/usr/share/OVMF/OVMF_CODE_4M.secboot.fd \
|
||||
/usr/share/OVMF/OVMF_CODE_4M.ms.fd \
|
||||
/usr/share/OVMF/OVMF_CODE.fd \
|
||||
/usr/share/OVMF/OVMF.fd \
|
||||
/usr/share/ovmf/OVMF_CODE_4M.fd \
|
||||
/usr/share/ovmf/OVMF_CODE_4M.secboot.fd \
|
||||
/usr/share/ovmf/OVMF_CODE_4M.ms.fd \
|
||||
/usr/share/ovmf/OVMF_CODE.fd \
|
||||
/usr/share/ovmf/OVMF.fd \
|
||||
OVMF.fd; do
|
||||
if [ -f "${candidate}" ]; then
|
||||
ovmf_code="${candidate}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "${ovmf_code}" ] || [ ! -f "${ovmf_code}" ]; then
|
||||
echo "No OVMF firmware found. Set OVMF_CODE or OVMF_BIOS to the firmware path." >&2
|
||||
find /usr/share/OVMF /usr/share/ovmf -maxdepth 1 -type f -name '*.fd' -print 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${ovmf_code##*/}" in
|
||||
*CODE*)
|
||||
if [ -z "${ovmf_vars_template}" ]; then
|
||||
for candidate in \
|
||||
"${ovmf_code/CODE/VARS}" \
|
||||
/usr/share/OVMF/OVMF_VARS_4M.fd \
|
||||
/usr/share/OVMF/OVMF_VARS.fd \
|
||||
/usr/share/ovmf/OVMF_VARS_4M.fd \
|
||||
/usr/share/ovmf/OVMF_VARS.fd; do
|
||||
if [ -f "${candidate}" ]; then
|
||||
ovmf_vars_template="${candidate}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "${ovmf_vars_template}" ] || [ ! -f "${ovmf_vars_template}" ]; then
|
||||
echo "No OVMF VARS template found for ${ovmf_code}. Set OVMF_VARS to the template path." >&2
|
||||
find /usr/share/OVMF /usr/share/ovmf -maxdepth 1 -type f -name '*.fd' -print 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "${ovmf_vars_template}" "${ovmf_vars}"
|
||||
qemu_firmware_args=(
|
||||
-drive "if=pflash,format=raw,readonly=on,file=${ovmf_code}"
|
||||
-drive "if=pflash,format=raw,file=${ovmf_vars}"
|
||||
)
|
||||
;;
|
||||
*)
|
||||
qemu_firmware_args=(-bios "${ovmf_code}")
|
||||
;;
|
||||
esac
|
||||
|
||||
cleanup() {
|
||||
if [ -f "${qemu_pid_file}" ]; then
|
||||
qemu_pid="$(cat "${qemu_pid_file}")"
|
||||
if kill -0 "${qemu_pid}" 2>/dev/null; then
|
||||
kill "${qemu_pid}" 2>/dev/null || true
|
||||
timeout 30s tail --pid="${qemu_pid}" -f /dev/null 2>/dev/null ||
|
||||
kill -9 "${qemu_pid}" 2>/dev/null ||
|
||||
true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
rm -f "${qemu_pid_file}"
|
||||
|
||||
qemu-system-x86_64 \
|
||||
-m 2048 \
|
||||
-smp 2 \
|
||||
"${qemu_firmware_args[@]}" \
|
||||
-drive "file=${image},format=qcow2" \
|
||||
-netdev "user,id=net0,hostfwd=tcp:127.0.0.1:${ssh_port}-:22" \
|
||||
-device e1000,netdev=net0 \
|
||||
-display none \
|
||||
-snapshot \
|
||||
-pidfile "${qemu_pid_file}" \
|
||||
-daemonize
|
||||
|
||||
echo "Waiting for SSH in the booted image"
|
||||
for attempt in {1..120}; do
|
||||
if sshpass -p "${ssh_password}" ssh "${ssh_opts[@]}" joinmarket@127.0.0.1 "true" 2>/dev/null; then
|
||||
break
|
||||
fi
|
||||
if [ "${attempt}" -eq 120 ]; then
|
||||
echo "Timed out waiting for SSH" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
tar -C "${bats_core_dir}" -cf - . |
|
||||
sshpass -p "${ssh_password}" ssh "${ssh_opts[@]}" joinmarket@127.0.0.1 \
|
||||
"mkdir -p /tmp/bats-core && tar -C /tmp/bats-core -xf -"
|
||||
|
||||
sshpass -p "${ssh_password}" ssh "${ssh_opts[@]}" joinmarket@127.0.0.1 \
|
||||
"PATH=/tmp/bats-core/bin:\$PATH /home/joinmarket/joininbox/test/run-bats-local.sh"
|
||||
|
|
@ -3,10 +3,10 @@ variable "branch" {}
|
|||
|
||||
source "arm" "joininbox-arm64-rpi" {
|
||||
file_checksum_type = "sha256"
|
||||
file_checksum = "b77cf8a9d46ce1be16a7a478c243b2197be5c217482db2bfee10fc94764c3805"
|
||||
file_checksum = "62d025b9bc7ca0e1facfec74ae56ac13978b6745c58177f081d39fbb8041ed45"
|
||||
file_target_extension = "xz"
|
||||
file_unarchive_cmd = ["xz", "--decompress", "$ARCHIVE_PATH"]
|
||||
file_urls = ["https://raspi.debian.net/tested/20230101_raspi_4_bookworm.img.xz"]
|
||||
file_urls = ["https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2025-05-13/2025-05-13-raspios-bookworm-arm64-lite.img.xz"]
|
||||
image_build_method = "resize"
|
||||
image_chroot_env = ["PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin"]
|
||||
image_partitions {
|
||||
|
|
@ -39,7 +39,8 @@ build {
|
|||
inline = [
|
||||
"echo 'nameserver 1.1.1.1' >/etc/resolv.conf",
|
||||
"echo 'nameserver 8.8.8.8' >>/etc/resolv.conf",
|
||||
"echo $(hostname -I | awk '{print $1}') $(hostname) >>/etc/hosts",
|
||||
"echo $(hostname -I | awk '{print $1}') $(hostname) >>/etc/hosts",
|
||||
"echo 127.0.1.1 $(hostname) >>/etc/hosts",
|
||||
"echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections",
|
||||
"apt-get update",
|
||||
"apt-get install -y sudo wget",
|
||||
|
|
|
|||
BIN
images/menu.png
BIN
images/menu.png
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 61 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 37 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 43 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
<!-- omit in toc -->
|
||||
# Prepare a bitcoin node to accept a remote RPC connection
|
||||
|
||||
If you have arrived here from runing JoininBox locally on the RaspiBlitz can skip these steps (CTRL+C to exit the connection settings). The connection to the local bitcoin node is set up automatically.
|
||||
If you have arrived here from running JoininBox locally on the RaspiBlitz can skip these steps (CTRL+C to exit the connection settings). The connection to the local bitcoin node is set up automatically.
|
||||
|
||||
JoinMarket (running in JoininBox) needs to connect to Bitcoin Core via RPC.
|
||||
A pruned node with the **bitcoind wallet enabled** will do and txindex is not required.
|
||||
|
|
@ -9,13 +9,13 @@ A pruned node with the **bitcoind wallet enabled** will do and txindex is not re
|
|||
- [Enable the bitcoind wallet](#enable-the-bitcoind-wallet)
|
||||
- [LAN connection](#lan-connection)
|
||||
- [Tor connection](#tor-connection)
|
||||
- [CONFIG -> CONNECT in JoininBox](#config---connect-in-joininbox)
|
||||
- [CONFIG -\> CONNECT in JoininBox](#config---connect-in-joininbox)
|
||||
- [RoninDojo](#ronindojo)
|
||||
- [Enable the bitcoind wallet](#enable-the-bitcoind-wallet-1)
|
||||
- [LAN connection](#lan-connection-1)
|
||||
- [Tor connection](#tor-connection-1)
|
||||
- [Recompile the Docker containers (takes time)](#recompile-the-docker-containers-takes-time)
|
||||
- [CONFIG -> CONNECT in JoininBox](#config---connect-in-joininbox-1)
|
||||
- [CONFIG -\> CONNECT in JoininBox](#config---connect-in-joininbox-1)
|
||||
- [Resources](#resources)
|
||||
## RaspiBlitz
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ Since the RaspiBlitz v1.6 run this script:
|
|||
To set up manually:
|
||||
|
||||
* Edit the bitcoin.conf:
|
||||
`$ sudo nano /mnt/hdd/bitcoin/bitcoin.conf`
|
||||
`$ sudo nano /mnt/hdd/app-data/bitcoin/bitcoin.conf`
|
||||
|
||||
* Change the disablewallet option to 0:
|
||||
```
|
||||
|
|
@ -40,15 +40,15 @@ In the terminal of the node - allow remote RPC connections to Bitcoin Core
|
|||
This can be skipped if you [connect through Tor](#tor-connection)
|
||||
|
||||
1) Edit the bitcoin.conf
|
||||
`$ sudo nano /mnt/hdd/bitcoin/bitcoin.conf`
|
||||
`$ sudo nano /mnt/hdd/app-data/bitcoin/bitcoin.conf`
|
||||
|
||||
Add the values:
|
||||
* `rpcallowip=JOININBOX_IP` or `RANGE`
|
||||
* either specify the LAN IP of the computer (here JoininBox)
|
||||
* or use a range like: `192.168.1.0/24` - edit to your local subnet - the first 3 numbes of the LAN IP address, the example used here is: 192.168.1.x
|
||||
* or use a range like: `192.168.1.0/24` - edit to your local subnet - the first 3 numbers of the LAN IP address, the example used here is: 192.168.1.x
|
||||
* `rpcbind=LAN_IP_OF_THE_NODE`
|
||||
* use the local IP of the bitcoin node in the example: `192.168.1.4`
|
||||
* can keep the other `rpcallowip` and `rpcbind` entires especially for the localhost: `127.0.0.1`
|
||||
* can keep the other `rpcallowip` and `rpcbind` entries especially for the localhost: `127.0.0.1`
|
||||
|
||||
Example:
|
||||
```bash
|
||||
|
|
@ -109,8 +109,8 @@ Fill in the `Tor_Hidden_Service.onion` to the `rpc_host` in the `joinmarket.cfg`
|
|||
|
||||
### CONFIG -> CONNECT in JoininBox
|
||||
* Username: `raspibolt `
|
||||
* Password: `passwordB` or `sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-`
|
||||
* Host: `LAN_IP_OF_THE_NODE` or `sudo cat /mnt/hdd/tor/bitcoinrpc/hostname`
|
||||
* Password: `passwordB` or `sudo cat /mnt/hdd/bitcoin/app-data/bitcoin.conf | grep rpcpassword | cut -c 13-`
|
||||
* Host: `LAN_IP_OF_THE_NODE` or `sudo cat /mnt/hdd/app-data/tor/bitcoinrpc/hostname`
|
||||
* Port: `8332`
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ RaspiBlitz integration:
|
|||
- pair the parallel 2nd node to Sphinx, BoS, ThunderHub, BTCPay - see: https://github.com/rootzoll/raspiblitz/issues/2073
|
||||
|
||||
Standalone:
|
||||
- ElectRS install scritpt to be used with a local disk (requires a non-pruned node) - [FAQ](https://github.com/openoms/joininbox/blob/master/FAQ.md#external-drive)
|
||||
- ElectRS install script to be used with a local disk (requires a non-pruned node) - [FAQ](https://github.com/openoms/joininbox/blob/master/FAQ.md#external-drive)
|
||||
|
||||
```
|
||||
369c883 payjoin: extend dialog window to content
|
||||
|
|
@ -263,7 +263,7 @@ b047395 (menu-improvements) getRPC values in the customRPC function
|
|||
0e08c25 add XPUBS option to the WALLET menu
|
||||
840094f specter: update to 1.2.2
|
||||
1f60cfc add bitcoind LOGS to TOOLS
|
||||
bf4672d specter insall fixes
|
||||
bf4672d specter install fixes
|
||||
16236e9 add SPECTER menu with UPDATE option
|
||||
fa71818 add PRUNED node and LOCAL option
|
||||
c3336cd implement checkRPC to create and load core wallet
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ dialog_color = (CYAN,BLACK,OFF)
|
|||
title_color = (CYAN,BLACK,ON)
|
||||
|
||||
# Dialog box border color
|
||||
border_color = (BLACK,BLACK,ON)
|
||||
border_color = (CYAN,BLACK,ON)
|
||||
|
||||
# Active button color
|
||||
button_active_color = (BLACK,CYAN,ON)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
# source aliases from /home/joinmarket/_aliases.sh
|
||||
if [ -f /home/joinmarket/_aliases.sh ];then
|
||||
if [ -f /home/joinmarket/_aliases.sh ]; then
|
||||
source /home/joinmarket/_aliases.sh
|
||||
fi
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ function menu() {
|
|||
}
|
||||
|
||||
# command: newnym
|
||||
function newnym(){
|
||||
function newnym() {
|
||||
if [ "$(cat /home/joinmarket/joinin.conf 2>/dev/null | grep -c "runBehindTor=on")" -eq 1 ]; then
|
||||
echo "# Changing Tor circuits..."
|
||||
echo "# Savind old ID..."
|
||||
|
|
@ -26,11 +26,11 @@ function newnym(){
|
|||
newID=$(curl --connect-timeout 15 --socks5-hostname 127.0.0.1:9050 ifconfig.me 2>/dev/null)
|
||||
echo
|
||||
if [ ${oldID} = ${newID} ]; then
|
||||
echo "# !!! FAIL: Identity did not change. Read error message above."
|
||||
echo "# FAIL: Identity did not change. Read error message above."
|
||||
echo "# Exiting for precaution."
|
||||
exit 0
|
||||
else
|
||||
echo "# !!! SUCCESS"
|
||||
echo "# SUCCESS"
|
||||
echo "# Old id: " ${oldID}
|
||||
echo "# New id: " ${newID}
|
||||
fi
|
||||
|
|
@ -41,7 +41,7 @@ function newnym(){
|
|||
|
||||
# command: torthistx
|
||||
function torthistx() {
|
||||
if [ "$(cat /home/joinmarket/joinin.conf 2>/dev/null | grep -c "runBehindTor=on")" -eq 1 ];then
|
||||
if [ "$(cat /home/joinmarket/joinin.conf 2>/dev/null | grep -c "runBehindTor=on")" -eq 1 ]; then
|
||||
echo
|
||||
if [ "$(cat /home/joinmarket/joinin.conf 2>/dev/null | grep -c "network=signet")" -eq 1 ]; then
|
||||
newnym
|
||||
|
|
@ -64,7 +64,7 @@ function torthistx() {
|
|||
# command: stats
|
||||
# shows the uptime and the fees earned as a Maker
|
||||
function stats() {
|
||||
/home/joinmarket/info.stats.sh
|
||||
/home/joinmarket/info.stats.sh showAllEarned
|
||||
}
|
||||
|
||||
# command: qtgui
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ joininConfPath="/home/joinmarket/joinin.conf"
|
|||
function downloadBitcoinCore() {
|
||||
# set version
|
||||
# https://bitcoincore.org/en/download/
|
||||
bitcoinVersion="22.0"
|
||||
bitcoinVersion="29.2"
|
||||
|
||||
# https://github.com/laanwj
|
||||
PGPname="Wladimir J. van der Laan"
|
||||
PGPpubkey="74810B012346C9A6"
|
||||
if bitcoin-cli --version | grep $bitcoinVersion >/dev/null; then
|
||||
echo "# Bitcoin Core $bitcoinVersion is already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "# *** PREPARING BITCOIN ***"
|
||||
|
|
@ -21,41 +22,25 @@ function downloadBitcoinCore() {
|
|||
sudo -u joinmarket mkdir /home/joinmarket/download 2>/dev/null
|
||||
cd /home/joinmarket/download || exit 1
|
||||
|
||||
# receive signer key
|
||||
if ! gpg -k | grep "${PGPpubkey}"; then
|
||||
if ! gpg --keyserver hkp://keyserver.ubuntu.com --recv-key "${PGPpubkey}"; then
|
||||
echo "# !!! FAIL !!! Couldn't download ${PGPname}'s PGP pubkey"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "# Receive signer keys"
|
||||
curl -s "https://api.github.com/repos/bitcoin-core/guix.sigs/contents/builder-keys" |
|
||||
jq -r '.[].download_url' | while read url; do curl -s "$url" | gpg --import; done
|
||||
|
||||
# download signed binary sha256 hash sum file
|
||||
if [ ! -f SHA256SUMS ]; then
|
||||
sudo -u joinmarket wget --progress=bar:force https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS
|
||||
fi
|
||||
# download signed binary sha256 hash sum file and check
|
||||
if [ ! -f SHA256SUMS.asc ]; then
|
||||
sudo -u joinmarket wget --progress=bar:force https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS.asc
|
||||
fi
|
||||
verifyResult=$(gpg --verify SHA256SUMS.asc 2>&1)
|
||||
goodSignature=$(echo ${verifyResult} | grep 'Good signature' -c)
|
||||
echo "goodSignature(${goodSignature})"
|
||||
correctKey=$(echo ${verifyResult} | tr -d " \t\n\r" | grep "${PGPpubkey}" -c)
|
||||
echo "correctKey(${correctKey})"
|
||||
if [ ${correctKey} -lt 1 ] || [ ${goodSignature} -lt 1 ]; then
|
||||
echo
|
||||
echo "# !!! BUILD FAILED --> the PGP verification failed / signature(${goodSignature}) verify(${correctKey})"
|
||||
echo "# Removing the conflicting files"
|
||||
echo "# This is normal after an update - try to choose the option / run the script again."
|
||||
sudo rm -f SHA256SUMS
|
||||
sudo rm -f SHA256SUMS.asc
|
||||
exit 1
|
||||
else
|
||||
sudo -u joinmarket wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS
|
||||
# download the signed binary sha256 hash sum file and check
|
||||
sudo -u joinmarket wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS.asc https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS.asc
|
||||
|
||||
if gpg --verify SHA256SUMS.asc; then
|
||||
echo
|
||||
echo "****************************************"
|
||||
echo "OK --> BITCOIN MANIFEST IS CORRECT"
|
||||
echo "****************************************"
|
||||
echo
|
||||
else
|
||||
echo
|
||||
echo "# BUILD FAILED --> the PGP verification failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# detect CPU architecture & fitting download link
|
||||
|
|
@ -75,10 +60,10 @@ function downloadBitcoinCore() {
|
|||
# download resources
|
||||
binaryName="bitcoin-${bitcoinVersion}-${bitcoinOSversion}.tar.gz"
|
||||
if [ ! -f "./${binaryName}" ]; then
|
||||
sudo -u joinmarket wget --progress=bar:force https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/${binaryName}
|
||||
sudo -u joinmarket wget --prefer-family=ipv4 --progress=bar:force https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/${binaryName}
|
||||
fi
|
||||
if [ ! -f "./${binaryName}" ]; then
|
||||
echo "!!! FAIL !!! Could not download the BITCOIN BINARY"
|
||||
echo "# FAIL - Could not download the BITCOIN BINARY"
|
||||
exit 1
|
||||
else
|
||||
# check binary checksum test
|
||||
|
|
@ -89,7 +74,7 @@ function downloadBitcoinCore() {
|
|||
echo "Valid SHA256 checksum should be: ${bitcoinSHA256}"
|
||||
echo "Downloaded binary SHA256 checksum: ${binaryChecksum}"
|
||||
if [ "${binaryChecksum}" != "${bitcoinSHA256}" ]; then
|
||||
echo "!!! FAIL !!! Downloaded BITCOIN BINARY not matching SHA256 checksum: ${bitcoinSHA256}"
|
||||
echo "# FAIL - Downloaded BITCOIN BINARY does not match SHA256 checksum: ${bitcoinSHA256}"
|
||||
rm -v ./${binaryName}
|
||||
exit 1
|
||||
else
|
||||
|
|
@ -98,8 +83,6 @@ function downloadBitcoinCore() {
|
|||
echo "OK --> VERIFIED BITCOIN CORE BINARY CHECKSUM"
|
||||
echo "********************************************"
|
||||
echo
|
||||
sleep 10
|
||||
echo
|
||||
fi
|
||||
echo
|
||||
echo "# Extracting to /home/joinmarket/download/bitcoin-${bitcoinVersion}"
|
||||
|
|
@ -117,22 +100,22 @@ function installBitcoinCore() {
|
|||
cd /home/joinmarket/download/bitcoin-${bitcoinVersion}/bin/ || exit 1
|
||||
sudo install -m 0755 -o root -g root -t /home/joinmarket/bitcoin ./*
|
||||
|
||||
if [ "$(grep -c "/home/joinmarket/bitcoin" < /home/joinmarket/.profile)" -eq 0 ];then
|
||||
if [ "$(grep -c "/home/joinmarket/bitcoin" </home/joinmarket/.profile)" -eq 0 ]; then
|
||||
echo "# Add /home/joinmarket/bitcoin to the local PATH"
|
||||
echo "PATH=/home/joinmarket/bitcoin:$PATH" | sudo tee -a /home/joinmarket/.profile
|
||||
fi
|
||||
installed=$(/home/joinmarket/bitcoin/bitcoind --version | grep -c "Bitcoin Core version")
|
||||
if [ ${installed} -lt 1 ]; then
|
||||
echo
|
||||
echo "!!! BUILD FAILED --> Was not able to install Bitcoin Core"
|
||||
echo "# BUILD FAILED --> Was not able to install Bitcoin Core"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# bitcoin.conf
|
||||
if [ ! -f /home/joinmarket/.bitcoin/bitcoin.conf ]; then
|
||||
mkdir -p /home/joinmarket/.bitcoin
|
||||
randomRPCpass=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8)
|
||||
cat > /home/joinmarket/.bitcoin/bitcoin.conf <<EOF
|
||||
randomRPCpass=$(tr </dev/urandom -dc _A-Z-a-z-0-9 | head -c8)
|
||||
cat >/home/joinmarket/.bitcoin/bitcoin.conf <<EOF
|
||||
# bitcoind configuration for signet
|
||||
|
||||
# Connection settings
|
||||
|
|
@ -172,25 +155,44 @@ function installSignet() {
|
|||
Description=Bitcoin daemon on signet
|
||||
|
||||
[Service]
|
||||
Environment='MALLOC_ARENA_MAX=1'
|
||||
PIDFile=/home/joinmarket/bitcoin/bitcoind.pid
|
||||
ExecStart=/home/joinmarket/bitcoin/bitcoind -signet -daemon \\
|
||||
-datadir=/home/joinmarket/.bitcoin \\
|
||||
-conf=/home/joinmarket/.bitcoin/bitcoin.conf \\
|
||||
-pid=/home/joinmarket/bitcoin/bitcoind.pid
|
||||
PermissionsStartOnly=true
|
||||
|
||||
# Process management
|
||||
####################
|
||||
Type=forking
|
||||
Restart=on-failure
|
||||
TimeoutStartSec=infinity
|
||||
TimeoutStopSec=600
|
||||
|
||||
# Directory creation and permissions
|
||||
####################################
|
||||
# Run as joinmarket:joinmarket
|
||||
User=joinmarket
|
||||
Group=joinmarket
|
||||
Type=forking
|
||||
PIDFile=/home/joinmarket/bitcoin/bitcoind.pid
|
||||
ExecStart=/home/joinmarket/bitcoin/bitcoind -signet -daemon \
|
||||
-datadir=/home/joinmarket/.bitcoin \
|
||||
-conf=/home/joinmarket/.bitcoin/bitcoin.conf \
|
||||
-pid=/home/joinmarket/bitcoin/bitcoind.pid
|
||||
Restart=always
|
||||
TimeoutSec=120
|
||||
RestartSec=30
|
||||
|
||||
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
|
||||
|
|
@ -204,8 +206,8 @@ signet.addnode=s7fcvn5rblem7tiquhhr7acjdhu7wsawcph7ck44uxyd6sismumemcyd.onion:38
|
|||
signet.addnode=6megrst422lxzsqvshkqkg6z2zhunywhyrhy3ltezaeyfspfyjdzr3qd.onion:38333
|
||||
signet.addnode=jahtu4veqnvjldtbyxjiibdrltqiiighauai7hmvknwxhptsb4xat4qd.onion:38333
|
||||
signet.addnode=f4kwoin7kk5a5kqpni7yqe25z66ckqu6bv37sqeluon24yne5rodzkqd.onion:38333
|
||||
signet.addnode=nsgyo7begau4yecc46ljfecaykyzszcseapxmtu6adrfagfrrzrlngyd.onion:38333"|\
|
||||
sudo tee -a /home/joinmarket/.bitcoin/bitcoin.conf
|
||||
signet.addnode=nsgyo7begau4yecc46ljfecaykyzszcseapxmtu6adrfagfrrzrlngyd.onion:38333" |
|
||||
sudo tee -a /home/joinmarket/.bitcoin/bitcoin.conf
|
||||
fi
|
||||
|
||||
# add to path
|
||||
|
|
@ -245,8 +247,8 @@ setJMconfigToSignet() {
|
|||
sed -i "s/^rpc_password =.*/rpc_password = $RPCPWSIGNET/g" $JMcfgPath
|
||||
echo "# rpc_password = $RPCPWSIGNET"
|
||||
# rpc_wallet_file
|
||||
sed -i "s/^rpc_wallet_file =.*/rpc_wallet_file = wallet.dat/g" $JMcfgPath
|
||||
echo "# using the bitcoind wallet: wallet.dat"
|
||||
sed -i "s/^rpc_wallet_file =.*/rpc_wallet_file = watch-only-descriptor-wallet/g" $JMcfgPath
|
||||
echo "# using the bitcoind watch-only-descriptor-wallet"
|
||||
# rpc_host
|
||||
sed -i "s/^rpc_host =.*/rpc_host = 127.0.0.1/g" $JMcfgPath
|
||||
echo "# rpc_host = 127.0.0.1"
|
||||
|
|
@ -263,14 +265,14 @@ setJMconfigToSignet() {
|
|||
echo "# Set signet directory nodes"
|
||||
# comment mainnet
|
||||
sed -i \
|
||||
"s/^directory_nodes = 3kxw6lf5vf6y26emzwgibzhrzhmhqiw6ekrek3nqfjjmhwznb2moonad.onion:5222,jmdirjmioywe2s5jad7ts6kgcqg66rj6wujj6q77n6wbdrgocqwexzid.onion:5222,bqlpq6ak24mwvuixixitift4yu42nxchlilrcqwk2ugn45tdclg42qid.onion:5222/\
|
||||
"s/^directory_nodes = 3kxw6lf5vf6y26emzwgibzhrzhmhqiw6ekrek3nqfjjmhwznb2moonad.onion:5222,jmdirjmioywe2s5jad7ts6kgcqg66rj6wujj6q77n6wbdrgocqwexzid.onion:5222,bqlpq6ak24mwvuixixitift4yu42nxchlilrcqwk2ugn45tdclg42qid.onion:5222/\
|
||||
#directory_nodes = 3kxw6lf5vf6y26emzwgibzhrzhmhqiw6ekrek3nqfjjmhwznb2moonad.onion:5222,jmdirjmioywe2s5jad7ts6kgcqg66rj6wujj6q77n6wbdrgocqwexzid.onion:5222,bqlpq6ak24mwvuixixitift4yu42nxchlilrcqwk2ugn45tdclg42qid.onion:5222/g" \
|
||||
$JMcfgPath
|
||||
$JMcfgPath
|
||||
# uncomment signet
|
||||
sed -i \
|
||||
"s/^# directory_nodes = rr6f6qtleiiwic45bby4zwmiwjrj3jsbmcvutwpqxjziaydjydkk5iad.onion:5222,k74oyetjqgcamsyhlym2vgbjtvhcrbxr4iowd4nv4zk5sehw4v665jad.onion:5222,y2ruswmdbsfl4hhwwiqz4m3sx6si5fr6l3pf62d4pms2b53wmagq3eqd.onion:5222/\
|
||||
"s/^# directory_nodes = rr6f6qtleiiwic45bby4zwmiwjrj3jsbmcvutwpqxjziaydjydkk5iad.onion:5222,k74oyetjqgcamsyhlym2vgbjtvhcrbxr4iowd4nv4zk5sehw4v665jad.onion:5222,y2ruswmdbsfl4hhwwiqz4m3sx6si5fr6l3pf62d4pms2b53wmagq3eqd.onion:5222/\
|
||||
directory_nodes = rr6f6qtleiiwic45bby4zwmiwjrj3jsbmcvutwpqxjziaydjydkk5iad.onion:5222,k74oyetjqgcamsyhlym2vgbjtvhcrbxr4iowd4nv4zk5sehw4v665jad.onion:5222,y2ruswmdbsfl4hhwwiqz4m3sx6si5fr6l3pf62d4pms2b53wmagq3eqd.onion:5222/g" \
|
||||
$JMcfgPath
|
||||
$JMcfgPath
|
||||
|
||||
# set joinin.conf value
|
||||
/home/joinmarket/set.value.sh set network signet ${joininConfPath}
|
||||
|
|
@ -290,13 +292,13 @@ function showBitcoinLogs() {
|
|||
elif [ "${network}" = "signet" ]; then
|
||||
bitcoinUser="joinmarket"
|
||||
fi
|
||||
if [ "${network}" = mainnet ];then
|
||||
if [ "${network}" = mainnet ]; then
|
||||
logFilePath="/home/${bitcoinUser}/.bitcoin/debug.log"
|
||||
elif [ "${network}" = signet ];then
|
||||
elif [ "${network}" = signet ]; then
|
||||
logFilePath="/home/${bitcoinUser}/.bitcoin/signet/debug.log"
|
||||
fi
|
||||
dialog \
|
||||
--title "Monitoring the ${network} logs" \
|
||||
--title "Monitoring the ${network} logs" \
|
||||
--msgbox "
|
||||
Will tail the bitcoin ${network} logfile from:
|
||||
|
||||
|
|
@ -309,30 +311,89 @@ Press CTRL+C to exit and type 'menu' for the GUI." 10 54
|
|||
# getRPC - reads the RPC settings from the joinmarket.cfg
|
||||
function getRPC {
|
||||
echo "# Reading the bitcoind RPC settings from the joinmarket.cfg"
|
||||
rpc_user="$(awk '/^rpc_user / {print $3}' < $JMcfgPath)"
|
||||
rpc_pass="$(awk '/^rpc_password / {print $3}' < $JMcfgPath)"
|
||||
rpc_host="$(awk '/^rpc_host / {print $3}' < $JMcfgPath)"
|
||||
rpc_port="$(awk '/^rpc_port / {print $3}' < $JMcfgPath)"
|
||||
rpc_wallet="$(awk '/^rpc_wallet_file / {print $3}' < $JMcfgPath)"
|
||||
rpc_user="$(awk '/^rpc_user / {print $3}' <$JMcfgPath)"
|
||||
rpc_pass="$(awk '/^rpc_password / {print $3}' <$JMcfgPath)"
|
||||
rpc_host="$(awk '/^rpc_host / {print $3}' <$JMcfgPath)"
|
||||
rpc_port="$(awk '/^rpc_port / {print $3}' <$JMcfgPath)"
|
||||
rpc_wallet="$(awk '/^rpc_wallet_file / {print $3}' <$JMcfgPath)"
|
||||
if [ ${#1} -gt 0 ] && [ $1 = print ]; then
|
||||
echo "$rpc_user $rpc_pass $rpc_host $rpc_port $rpc_wallet"
|
||||
fi
|
||||
}
|
||||
|
||||
# getConnectedBitcoinCoreVersion - read the numeric version over node RPC
|
||||
function getConnectedBitcoinCoreVersion {
|
||||
local tor=""
|
||||
if [ "$(echo "$rpc_host" | grep -c .onion)" -gt 0 ]; then
|
||||
tor="torsocks"
|
||||
fi
|
||||
$tor curl -sS --data-binary \
|
||||
'{"jsonrpc": "1.0", "id":"get_bitcoin_core_version", "method": "getnetworkinfo", "params": []}' \
|
||||
"http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/" 2>/dev/null |
|
||||
jq -r '.result.version // empty' 2>/dev/null
|
||||
}
|
||||
|
||||
# migrateLegacyRPCWalletConfig - switch the persisted JoinMarket RPC wallet
|
||||
# from the legacy wallet.dat name to the descriptor wallet used by JoininBox
|
||||
# when the connected Bitcoin Core version is v30.0 or newer
|
||||
function migrateLegacyRPCWalletConfig {
|
||||
if [ "$rpc_wallet" != "wallet.dat" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local bitcoinCoreVersion
|
||||
bitcoinCoreVersion=$(getConnectedBitcoinCoreVersion)
|
||||
if ! [[ "$bitcoinCoreVersion" =~ ^[0-9]+$ ]]; then
|
||||
echo "# Could not determine the connected Bitcoin Core version; keeping wallet.dat"
|
||||
return 0
|
||||
fi
|
||||
# Bitcoin Core's numeric version is 290200 for v29.2 and 300000 for v30.0.
|
||||
if [ "$bitcoinCoreVersion" -lt 300000 ]; then
|
||||
echo "# Connected Bitcoin Core is v29.x or earlier; keeping wallet.dat"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "# Migrating the configured Bitcoin Core wallet from wallet.dat to watch-only-descriptor-wallet"
|
||||
local migrationConfigOutput
|
||||
if ! migrationConfigOutput=$(mktemp "${JMcfgPath}.XXXXXX"); then
|
||||
echo "# Failed to create a temporary descriptor wallet configuration" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! sed \
|
||||
"s/^rpc_wallet_file =.*/rpc_wallet_file = watch-only-descriptor-wallet/g" \
|
||||
"$JMcfgPath" >"$migrationConfigOutput"; then
|
||||
rm -f "$migrationConfigOutput"
|
||||
echo "# Failed to prepare the descriptor wallet configuration" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! mv "$migrationConfigOutput" "$JMcfgPath"; then
|
||||
rm -f "$migrationConfigOutput"
|
||||
echo "# Failed to update the descriptor wallet configuration" >&2
|
||||
return 1
|
||||
fi
|
||||
getRPC
|
||||
if [ "$rpc_wallet" != "watch-only-descriptor-wallet" ]; then
|
||||
echo "# Failed to select the descriptor wallet configuration" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# checkRPCwallet <wallet>
|
||||
function checkRPCwallet {
|
||||
getRPC
|
||||
if [ $# -eq 0 ];then
|
||||
migrateLegacyRPCWalletConfig || return 1
|
||||
if [ $# -eq 0 ]; then
|
||||
rpc_wallet=$rpc_wallet
|
||||
else
|
||||
rpc_wallet=$1
|
||||
fi
|
||||
|
||||
echo "# Making sure the set $rpc_wallet wallet is present in bitcoind"
|
||||
trap 'rm -f "$connectionOutput"' EXIT
|
||||
connectionOutput=$(mktemp -p /dev/shm/)
|
||||
walletFound=$(customRPC "# Check wallet" "listwallets" 2>$connectionOutput | grep -c "$rpc_wallet")
|
||||
if [ $walletFound -eq 0 ]; then
|
||||
echo "# Setting a watch only wallet for the remote Bitcoin Core named $rpc_wallet"
|
||||
echo "# Setting a watch-only-descriptor-wallet in Bitcoin Core named $rpc_wallet"
|
||||
tor=""
|
||||
if [ $(echo $rpc_host | grep -c .onion) -gt 0 ]; then
|
||||
tor="torsocks"
|
||||
|
|
@ -341,8 +402,8 @@ function checkRPCwallet {
|
|||
fi
|
||||
#TODO rewrite customRPC to support multiple params
|
||||
$tor curl -sS --data-binary \
|
||||
'{"jsonrpc": "1.0", "id":"# Create the bitcoind wallet", "method": "createwallet", "params": {"wallet_name":"'"$rpc_wallet"'","descriptors":false}}' \
|
||||
http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/wallet/$rpc_wallet | jq .
|
||||
'{"jsonrpc": "1.0", "id":"# Create the bitcoind wallet", "method": "createwallet", "params": {"wallet_name":"'"$rpc_wallet"'","descriptors":true,"disable_private_keys":true}}' \
|
||||
http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/ | jq .
|
||||
echo
|
||||
walletFound=$(customRPC "# Check wallet" "listwallets" 2>$connectionOutput | grep -c "$rpc_wallet")
|
||||
if [ $walletFound -eq 0 ]; then
|
||||
|
|
@ -354,29 +415,98 @@ function checkRPCwallet {
|
|||
echo
|
||||
fi
|
||||
echo "# The wallet: $rpc_wallet is present and loaded in the connected bitcoind"
|
||||
|
||||
# Check for wallet migration from legacy wallet.dat
|
||||
checkWalletMigration
|
||||
}
|
||||
|
||||
# checkWalletMigration - detects legacy wallet.dat and guides user through migration
|
||||
# This function checks if:
|
||||
# 1. The old wallet.dat exists in Bitcoin Core
|
||||
# 2. The new watch-only-descriptor-wallet is being used
|
||||
# 3. Migration has not been completed yet
|
||||
# If migration is needed, it prompts the user to rescan after opening their JM wallets
|
||||
function checkWalletMigration {
|
||||
# Skip if migration was already completed
|
||||
if grep -q "walletMigrationDone=true" "${joininConfPath}" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Skip if we're not using the new descriptor wallet
|
||||
if [ "$rpc_wallet" != "watch-only-descriptor-wallet" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# RPC settings are already available from parent checkRPCwallet function
|
||||
tor=""
|
||||
if [ "$(echo "$rpc_host" | grep -c .onion)" -gt 0 ]; then
|
||||
tor="torsocks"
|
||||
fi
|
||||
|
||||
# Check if old wallet.dat exists in bitcoind (try to load it to see if it exists)
|
||||
# First check listwalletdir for wallet.dat
|
||||
oldWalletExists=$($tor curl -sS --data-binary \
|
||||
'{"jsonrpc": "1.0", "id":"check_old_wallet", "method": "listwalletdir", "params": []}' \
|
||||
"http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/" 2>/dev/null | jq -r '.result.wallets[].name' 2>/dev/null | grep -c "^wallet.dat$")
|
||||
|
||||
if [ "$oldWalletExists" -gt 0 ]; then
|
||||
echo
|
||||
echo "########################################################################"
|
||||
echo "# WALLET MIGRATION NOTICE"
|
||||
echo "########################################################################"
|
||||
echo
|
||||
echo "# A legacy wallet.dat was detected in Bitcoin Core."
|
||||
echo "# JoininBox now uses descriptor wallets (watch-only-descriptor-wallet)"
|
||||
echo "# for better compatibility with modern Bitcoin Core versions."
|
||||
echo
|
||||
echo "# To complete the migration and see your transaction history:"
|
||||
echo
|
||||
echo "# 1. Open each of your JoinMarket wallets once using:"
|
||||
echo "# WALLET -> DISPLAY"
|
||||
echo "# This imports the addresses into the new descriptor wallet."
|
||||
echo
|
||||
echo "# 2. After opening all wallets, run a blockchain rescan:"
|
||||
echo "# WALLET -> RESCAN"
|
||||
echo "# Use blockheight 481824 (first SegWit block) or later if you know when your wallet had its first deposit."
|
||||
echo
|
||||
echo "# The rescan may take several hours depending on wallet age."
|
||||
echo "# You can monitor progress in the Bitcoin Core debug.log"
|
||||
echo
|
||||
echo "########################################################################"
|
||||
echo
|
||||
echo "# Press ENTER to continue..."
|
||||
read -r
|
||||
|
||||
# Mark migration notice as shown (user can still run rescan manually)
|
||||
if ! grep -q "walletMigrationDone=" "${joininConfPath}" 2>/dev/null; then
|
||||
echo "walletMigrationDone=true" >>"${joininConfPath}"
|
||||
else
|
||||
sed -i "s/^walletMigrationDone=.*/walletMigrationDone=true/g" "${joininConfPath}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# customRPC - sends a custom RPC command
|
||||
# $1=id $2=method $3=string params $4=print
|
||||
function customRPC {
|
||||
getRPC
|
||||
if [ ${#4} -eq 0 ];then
|
||||
if [ ${#4} -eq 0 ]; then
|
||||
print="no"
|
||||
else
|
||||
print=$4
|
||||
fi
|
||||
if [ $print = print ];then
|
||||
echo print
|
||||
fi
|
||||
if [ $print = print ]; then
|
||||
echo print
|
||||
fi
|
||||
tor=""
|
||||
if [ $(echo $rpc_host | grep -c .onion) -gt 0 ]; then
|
||||
tor="torsocks"
|
||||
echo "# Connecting over Tor..."
|
||||
echo
|
||||
fi
|
||||
is_int () { test "$@" -eq "$@" 2> /dev/null; }
|
||||
if is_int "$3" ||[ ${#3} -eq 0 ]; then
|
||||
if [ $print = print ];then
|
||||
is_int() { test "$@" -eq "$@" 2>/dev/null; }
|
||||
if is_int "$3" || [ ${#3} -eq 0 ]; then
|
||||
if [ $print = print ]; then
|
||||
echo "# Using the RPC command:"
|
||||
echo "$tor curl -sS --data-binary\
|
||||
'{\"jsonrpc\": \"1.0\", \"id\":\"$1\", \"method\": \"$2\", \"params\": [$3] }'\
|
||||
|
|
@ -384,10 +514,10 @@ fi
|
|||
echo
|
||||
fi
|
||||
$tor curl -sS --data-binary \
|
||||
'{"jsonrpc": "1.0", "id":"'"$1"'", "method": "'"$2"'", "params": ['"$3"'] }' \
|
||||
http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/wallet/$rpc_wallet | jq .
|
||||
'{"jsonrpc": "1.0", "id":"'"$1"'", "method": "'"$2"'", "params": ['"$3"'] }' \
|
||||
http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/wallet/$rpc_wallet | jq .
|
||||
else
|
||||
if [ $print = print ];then
|
||||
if [ $print = print ]; then
|
||||
echo "# Using the RPC command:"
|
||||
echo "$tor curl -sS --data-binary\
|
||||
'{\"jsonrpc\": \"1.0\", \"id\":\"$1\", \"method\": \"$2\", \"params\": [\"$3\"] }'\
|
||||
|
|
@ -395,8 +525,8 @@ fi
|
|||
echo
|
||||
fi
|
||||
$tor curl -sS --data-binary \
|
||||
'{"jsonrpc": "1.0", "id":"'"$1"'", "method": "'"$2"'", "params": ["'"$3"'"] }' \
|
||||
http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/wallet/$rpc_wallet | jq .
|
||||
'{"jsonrpc": "1.0", "id":"'"$1"'", "method": "'"$2"'", "params": ["'"$3"'"] }' \
|
||||
http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/wallet/$rpc_wallet | jq .
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -408,28 +538,34 @@ function connectLocalNode() {
|
|||
fi
|
||||
echo "# Setting connection to the local Bitcoin node on ${network}"
|
||||
rpc_host="127.0.0.1"
|
||||
if [ "${network}" = mainnet ];then
|
||||
if [ "${network}" = mainnet ]; then
|
||||
rpc_port="8332"
|
||||
elif [ "${network}" = signet ];then
|
||||
elif [ "${network}" = signet ]; then
|
||||
rpc_port="38332"
|
||||
elif [ "${network}" = testnet ];then
|
||||
elif [ "${network}" = testnet ]; then
|
||||
rpc_port="18332"
|
||||
fi
|
||||
rpc_wallet="wallet.dat"
|
||||
if [ $runningEnv = raspiblitz ];then
|
||||
rpc_user=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
rpc_pass=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf|grep rpcpassword|cut -c 13-)
|
||||
elif [ $runningEnv = mynode ];then
|
||||
rpc_wallet="watch-only-descriptor-wallet"
|
||||
if [ $runningEnv = raspiblitz ]; then
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ]; then
|
||||
rpc_user=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
rpc_pass=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
else
|
||||
rpc_user=$(sudo cat /mnt/hdd/app-data/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
rpc_pass=$(sudo cat /mnt/hdd/app-data/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
fi
|
||||
|
||||
elif [ $runningEnv = mynode ]; then
|
||||
rpc_user=mynode
|
||||
rpc_pass=$(sudo cat /mnt/hdd/mynode/settings/.btcrpcpw)
|
||||
elif [ $runningEnv = standalone ];then
|
||||
rpc_user=$(sudo cat /home/bitcoin/.bitcoin/bitcoin.conf|grep rpcuser|cut -c 9-)
|
||||
rpc_pass=$(sudo cat /home/bitcoin/.bitcoin/bitcoin.conf|grep rpcpassword|cut -c 13-)
|
||||
elif [ $runningEnv = standalone ]; then
|
||||
rpc_user=$(sudo cat /home/bitcoin/.bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
rpc_pass=$(sudo cat /home/bitcoin/.bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
fi
|
||||
# set.bitcoinrpc.py
|
||||
python /home/joinmarket/set.bitcoinrpc.py --network=${network} \
|
||||
--rpc_user="$rpc_user" --rpc_pass="$rpc_pass" --rpc_host=$rpc_host \
|
||||
--rpc_port=$rpc_port --rpc_wallet=$rpc_wallet
|
||||
--rpc_user="$rpc_user" --rpc_pass="$rpc_pass" --rpc_host=$rpc_host \
|
||||
--rpc_port=$rpc_port --rpc_wallet=$rpc_wallet
|
||||
|
||||
# set joinin.conf value
|
||||
/home/joinmarket/set.value.sh set network ${network} ${joininConfPath}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ function menu_MAKER() {
|
|||
sleep 3
|
||||
dialog \
|
||||
--title "Monitoring the Yield Generator - press CTRL+C to exit" \
|
||||
--prgbox "sudo journalctl -fn20 -u yg-privacyenhanced" 30 200
|
||||
--prgbox "sudo journalctl -fn100 -u yg-privacyenhanced" -1 -1
|
||||
echo "# returning to the menu..."
|
||||
sleep 1
|
||||
/home/joinmarket/menu.yg.sh
|
||||
|
|
@ -66,7 +66,7 @@ It is best to reset the joinmarket.cfg after every install.
|
|||
|
||||
Do you want to reset the joinmarket.cfg to the defaults now?
|
||||
" 12 65
|
||||
# make decison
|
||||
# make decision
|
||||
pressed=$?
|
||||
case $pressed in
|
||||
0)
|
||||
|
|
@ -87,7 +87,7 @@ dialog --backtitle "Connect to the local Bitcoin Core" \
|
|||
--title "Connect to the local Bitcoin Core" \
|
||||
--yesno "
|
||||
Do you want to connect to the local Bitcoin Core on mainnet now?" 7 55
|
||||
# make decison
|
||||
# make decision
|
||||
pressed=$?
|
||||
case $pressed in
|
||||
0)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,21 @@ currentJBcommit=$(cd /home/joinmarket/joininbox; git describe --tags)
|
|||
currentJBtag=$(cd /home/joinmarket/joininbox; git tag | sort -V | tail -1)
|
||||
currentJMversion=$(cd /home/joinmarket/joinmarket-clientserver 2>/dev/null; \
|
||||
git describe --tags 2>/dev/null)
|
||||
currentBTCversion=$(bitcoind --version | grep version)
|
||||
|
||||
# paths
|
||||
walletPath="/home/joinmarket/.joinmarket/wallets/"
|
||||
JMcfgPath="/home/joinmarket/.joinmarket/joinmarket.cfg"
|
||||
joininConfPath="/home/joinmarket/joinin.conf"
|
||||
|
||||
## dialog fixes
|
||||
# fallback for unknown terminal types (e.g., xterm-ghostty)
|
||||
if ! infocmp "$TERM" &>/dev/null; then
|
||||
export TERM=xterm-256color
|
||||
fi
|
||||
# fix dialog box drawing characters
|
||||
export NCURSES_NO_UTF8_ACS=1
|
||||
|
||||
# functions
|
||||
source /home/joinmarket/_functions.menu.sh
|
||||
source /home/joinmarket/_functions.bitcoincore.sh
|
||||
|
|
@ -22,7 +31,6 @@ fi
|
|||
|
||||
function activateJMvenv() {
|
||||
. /home/joinmarket/joinmarket-clientserver/jmvenv/bin/activate || exit 1
|
||||
/home/joinmarket/joinmarket-clientserver/jmvenv/bin/python -c "import PySide2"
|
||||
}
|
||||
|
||||
function openMenuIfCancelled() {
|
||||
|
|
@ -66,7 +74,7 @@ function passwordToFile() {
|
|||
--title "Enter password" \
|
||||
--insecure \
|
||||
--passwordbox "Type or paste the wallet decryption password" 8 52 2> "$data"
|
||||
# make decison
|
||||
# make decision
|
||||
pressed=$?
|
||||
case $pressed in
|
||||
0)
|
||||
|
|
@ -162,16 +170,16 @@ function stopYG() {
|
|||
|
||||
function YGnickname() {
|
||||
# Retrieves nickname from the latest NickServ message in the newest logfile
|
||||
if ls -td /home/joinmarket/.joinmarket/logs/* 1>&2>/dev/null ; then
|
||||
newest_log=$(ls -td /home/joinmarket/.joinmarket/logs/* | grep J5 | head -n 1)
|
||||
name=$(grep NickServ $newest_log | tail -1 | awk '{print $9}')
|
||||
if [ ${#name} -eq 0 ];then
|
||||
newest_log=$(ls -td /home/joinmarket/.joinmarket/logs/*J5* 2>/dev/null | head -n 1)
|
||||
if [ -n "$newest_log" ] && [ -f "$newest_log" ]; then
|
||||
name=$(grep NickServ "$newest_log" 2>/dev/null | tail -1 | awk '{print $9}')
|
||||
if [ ${#name} -eq 0 ]; then
|
||||
name="no_Nick_see_LOGS"
|
||||
fi
|
||||
else
|
||||
name="waiting__to__run"
|
||||
fi
|
||||
echo $name
|
||||
echo "$name"
|
||||
}
|
||||
|
||||
# copyJoininboxScripts
|
||||
|
|
@ -249,28 +257,33 @@ function generateJMconfig() {
|
|||
|
||||
setJMconfigToSignet
|
||||
|
||||
elif [ -f "/mnt/hdd/bitcoin/bitcoin.conf" ]; then
|
||||
elif [ $runningEnv = "raspiblitz" ]; then
|
||||
echo
|
||||
echo "## editing the joinmarket.cfg with the local bitcoin RPC settings."
|
||||
|
||||
RPCUSER=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
sed -i "s/^rpc_user =.*/rpc_user = $RPCUSER/g" $JMcfgPath
|
||||
echo "# rpc_user = $RPCUSER"
|
||||
|
||||
PASSWORD_B=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
sed -i "s/^rpc_password =.*/rpc_password = $PASSWORD_B/g" $JMcfgPath
|
||||
echo "# rpc_password = $PASSWORD_B"
|
||||
|
||||
RPCPORT=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep main.rpcport | cut -c 14-)
|
||||
if [ ${#RPCPORT} -eq 0 ];then
|
||||
if [ -f "/mnt/hdd/bitcoin/bitcoin.conf" ]; then
|
||||
RPCUSER=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
sed -i "s/^rpc_user =.*/rpc_user = $RPCUSER/g" $JMcfgPath
|
||||
echo "# rpc_user = $RPCUSER"
|
||||
PASSWORD_B=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
sed -i "s/^rpc_password =.*/rpc_password = $PASSWORD_B/g" $JMcfgPath
|
||||
echo "# rpc_password = $PASSWORD_B"
|
||||
RPCPORT=$(sudo cat /mnt/hdd/bitcoin/bitcoin.conf | grep main.rpcport | cut -c 14-)
|
||||
else
|
||||
RPCUSER=$(sudo cat /mnt/hdd/app-data/bitcoin/bitcoin.conf | grep rpcuser | cut -c 9-)
|
||||
sed -i "s/^rpc_user =.*/rpc_user = $RPCUSER/g" $JMcfgPath
|
||||
echo "# rpc_user = $RPCUSER"
|
||||
PASSWORD_B=$(sudo cat /mnt/hdd/app-data/bitcoin/bitcoin.conf | grep rpcpassword | cut -c 13-)
|
||||
sed -i "s/^rpc_password =.*/rpc_password = $PASSWORD_B/g" $JMcfgPath
|
||||
echo "# rpc_password = $PASSWORD_B"
|
||||
RPCPORT=$(sudo cat /mnt/hdd/app-data/bitcoin/bitcoin.conf | grep main.rpcport | cut -c 14-)
|
||||
fi
|
||||
if [ ${#RPCPORT} -eq 0 ]; then
|
||||
RPCPORT=8332
|
||||
fi
|
||||
sed -i "s/^rpc_port =.*/rpc_port = $RPCPORT/g" $JMcfgPath
|
||||
echo "# rpc_port = $RPCPORT"
|
||||
|
||||
sed -i "s/^rpc_wallet_file =.*/rpc_wallet_file = wallet.dat/g" $JMcfgPath
|
||||
echo "# using the bitcoind wallet: wallet.dat"
|
||||
|
||||
sed -i "s/^rpc_wallet_file =.*/rpc_wallet_file = watch-only-descriptor-wallet/g" $JMcfgPath
|
||||
echo "# using the bitcoind watch-only-descriptor-wallet"
|
||||
# set joinin.conf value
|
||||
/home/joinmarket/set.value.sh set network mainnet ${joininConfPath}
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ Instructions to COPY wallets from another computer
|
|||
You can use the wallets from another JoinMarket instance
|
||||
"
|
||||
if [ "${CHOICE}" = "LAN" ]; then
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ] ; then
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ] || [ -f "/mnt/hdd/app-data/raspiblitz.conf" ] ; then
|
||||
echo "Both computers (the RaspiBlitz and the source computer with the wallet(s))"
|
||||
else
|
||||
echo "Both computers (the JoininBox and the source computer with the wallet(s))"
|
||||
|
|
@ -62,9 +62,9 @@ elif [ "${CHOICE}" = "TOR" ]; then
|
|||
echo "torsocks scp ./*.jmdat joinmarket@${TOR_ADDRESS}:~/.joinmarket/wallets/"
|
||||
fi
|
||||
echo ""
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ] ; then
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ] || [ -f "/mnt/hdd/app-data/raspiblitz.conf" ] ; then
|
||||
echo "Use the PASSWORD_B to authorize the file transfer
|
||||
(same as the rpcpassword in the /mnt/hdd/bitcoin/bitcoin.conf)."
|
||||
(same as the rpcpassword in the bitcoin.conf)."
|
||||
else
|
||||
echo "This command will ask for the SSH PASSWORD of the JoininBox."
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ source /home/joinmarket/_functions.sh
|
|||
|
||||
# check connectedRemoteNode var in joinin.conf
|
||||
if ! grep -Eq "^connectedRemoteNode=" $joininConfPath; then
|
||||
echo "connectedRemoteNode=off" >> $joininConfPath
|
||||
echo "connectedRemoteNode=off" >>$joininConfPath
|
||||
fi
|
||||
|
||||
if [ "$1" = "signetOn" ]; then
|
||||
installBitcoinCore
|
||||
installSignet
|
||||
if [ "$connectedRemoteNode" = "on" ];then
|
||||
if [ "$connectedRemoteNode" = "on" ]; then
|
||||
backupJMconf
|
||||
fi
|
||||
generateJMconfig
|
||||
|
|
@ -24,16 +24,16 @@ if [ "$1" = "signetOn" ]; then
|
|||
bitcoinUser="joinmarket"
|
||||
cliPath="/home/joinmarket/bitcoin/"
|
||||
fi
|
||||
if [ ! -f /home/${bitcoinUser}/.bitcoin/signet/wallets/wallet.dat/wallet.dat ];then
|
||||
echo "# Create wallet.dat for signet ..."
|
||||
if [ ! -d /home/${bitcoinUser}/.bitcoin/signet/wallets/watch-only-descriptor-wallet ]; then
|
||||
echo "# Create watch-only-descriptor-wallet for signet ..."
|
||||
sleep 10
|
||||
sudo -u ${bitcoinUser} ${cliPath}/bitcoin-cli -signet -named createwallet wallet_name=wallet.dat descriptors=false
|
||||
sudo -u ${bitcoinUser} ${cliPath}/bitcoin-cli -signet -named createwallet wallet_name=watch-only-descriptor-wallet descriptors=true disable_private_keys=true
|
||||
fi
|
||||
|
||||
elif [ "$1" = "signetOff" ]; then
|
||||
removeSignetdService
|
||||
isSignet=$(grep -c "network = signet" < $JMcfgPath)
|
||||
if [ $isSignet -gt 0 ];then
|
||||
isSignet=$(grep -c "network = signet" <$JMcfgPath)
|
||||
if [ $isSignet -gt 0 ]; then
|
||||
echo "# Removing the joinmarket.cfg with signet settings"
|
||||
rm -f $JMcfgPath
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,9 +1,21 @@
|
|||
#!/bin/bash
|
||||
|
||||
testedJMversion="v0.9.9"
|
||||
PGPsigner="waxwing"
|
||||
PGPpkeys="https://raw.githubusercontent.com/JoinMarket-Org/joinmarket-clientserver/master/pubkeys/AdamGibson.asc"
|
||||
PGPcheck="2B6FC204D9BF332D062B461A141001A1AF77F20B"
|
||||
# https://github.com/JoinMarket-Org/joinmarket-clientserver/releases
|
||||
# Use tag for verification when available, otherwise use commit hash
|
||||
testedJMversion="v0.9.12"
|
||||
|
||||
# https://github.com/JoinMarket-Org/joinmarket-clientserver/commits/master/
|
||||
# Only used if testedJMversion is empty or not set
|
||||
#testedJMcommit="ce32bafbb5d716bde61830f71266410249d43dbc"
|
||||
|
||||
PGPsigner="AdamISZ"
|
||||
PGPpkeys="https://github.com/AdamISZ.gpg"
|
||||
# AdamISZ current primary code-signing key used for v0.9.12
|
||||
PGPcheck="0F1C7345D9193D1C8E3F21810C44134F93234873"
|
||||
|
||||
#PGPsigner="kristapsk"
|
||||
#PGPpkeys="https://github.com/kristapsk.gpg"
|
||||
#PGPcheck="33E472FE870C7E5D"
|
||||
|
||||
me="${0##/*}"
|
||||
|
||||
|
|
@ -11,17 +23,17 @@ nocolor="\033[0m"
|
|||
red="\033[31m"
|
||||
|
||||
## see https://github.com/rootzoll/raspiblitz/blob/v1.7/build_sdcard.sh for code comments
|
||||
usage(){
|
||||
usage() {
|
||||
printf %s"${me} [--option <argument>]
|
||||
|
||||
a script to install, update or configure JoinMarket
|
||||
the latest tested version: $testedJMversion is installed by default with the QT GUI
|
||||
the latest tested version: ${testedJMversion:-$testedJMcommit} is installed by default with the QT GUI
|
||||
|
||||
Options:
|
||||
-h, --help this help info
|
||||
-i, --install [install|config|update|testPR|commit] install options, use 'commit' for the latest master
|
||||
-v, --version [version|number-of-PR] the version to install or PR to test (default: ${testedJMversion})
|
||||
-q, --qtgui [0|1] install the QT GUI and dependencies (default: 1)
|
||||
-q, --qtgui [0|1] install the QT GUI and dependencies (default: 0)
|
||||
-u, --user [user] the linux user to install with (default: joinmarket)
|
||||
|
||||
Notes:
|
||||
|
|
@ -35,28 +47,31 @@ if [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
|||
usage
|
||||
fi
|
||||
|
||||
error_msg(){ printf %s"${red}${me}: ${1}${nocolor}\n"; exit 1; }
|
||||
assign_value(){
|
||||
error_msg() {
|
||||
printf %s"${red}${me}: ${1}${nocolor}\n"
|
||||
exit 1
|
||||
}
|
||||
assign_value() {
|
||||
case "${2}" in
|
||||
--*) value="${2#--}";;
|
||||
-*) value="${2#-}";;
|
||||
*) value="${2}"
|
||||
--*) value="${2#--}" ;;
|
||||
-*) value="${2#-}" ;;
|
||||
*) value="${2}" ;;
|
||||
esac
|
||||
case "${value}" in
|
||||
0) value="false";;
|
||||
1) value="true";;
|
||||
0) value="false" ;;
|
||||
1) value="true" ;;
|
||||
esac
|
||||
eval "${1}"="\"${value}\""
|
||||
}
|
||||
|
||||
get_arg(){
|
||||
get_arg() {
|
||||
case "${3}" in
|
||||
""|-*) error_msg "Option '${2}' requires an argument.";;
|
||||
"" | -*) error_msg "Option '${2}' requires an argument." ;;
|
||||
esac
|
||||
assign_value "${1}" "${3}"
|
||||
}
|
||||
|
||||
range_argument(){
|
||||
range_argument() {
|
||||
name="${1}"
|
||||
eval var='$'"${1}"
|
||||
shift
|
||||
|
|
@ -71,17 +86,29 @@ range_argument(){
|
|||
|
||||
while :; do
|
||||
case "${1}" in
|
||||
-*=*) opt="${1%=*}"; arg="${1#*=}"; shift_n=1;;
|
||||
-*) opt="${1}"; arg="${2}"; shift_n=2;;
|
||||
*) opt="${1}"; arg="${2}"; shift_n=1;;
|
||||
-*=*)
|
||||
opt="${1%=*}"
|
||||
arg="${1#*=}"
|
||||
shift_n=1
|
||||
;;
|
||||
-*)
|
||||
opt="${1}"
|
||||
arg="${2}"
|
||||
shift_n=2
|
||||
;;
|
||||
*)
|
||||
opt="${1}"
|
||||
arg="${2}"
|
||||
shift_n=1
|
||||
;;
|
||||
esac
|
||||
case "${opt}" in
|
||||
-i|-i=*|--install|--install=*) get_arg install "${opt}" "${arg}";;
|
||||
-v|-v=*|--version|--version=*) get_arg version "${opt}" "${arg}";;
|
||||
-q|-q=*|--qtgui|--qtgui=*) get_arg qtgui "${opt}" "${arg}";;
|
||||
-u|-u=*|--user|--user=*) get_arg user "${opt}" "${arg}";;
|
||||
"") break;;
|
||||
*) error_msg "Invalid option: ${opt}";;
|
||||
-i | -i=* | --install | --install=*) get_arg install "${opt}" "${arg}" ;;
|
||||
-v | -v=* | --version | --version=*) get_arg version "${opt}" "${arg}" ;;
|
||||
-q | -q=* | --qtgui | --qtgui=*) get_arg qtgui "${opt}" "${arg}" ;;
|
||||
-u | -u=* | --user | --user=*) get_arg user "${opt}" "${arg}" ;;
|
||||
"") break ;;
|
||||
*) error_msg "Invalid option: ${opt}" ;;
|
||||
esac
|
||||
shift "${shift_n}"
|
||||
done
|
||||
|
|
@ -89,10 +116,13 @@ done
|
|||
: "${install:=install}"
|
||||
range_argument install "install" "config" "update" "testPR" "commit"
|
||||
|
||||
: "${version:=${testedJMversion}}"
|
||||
curl -s "https://github.com/JoinMarket-Org/joinmarket-clientserver/release/tag/${version}" | grep -q "\"message\": \"Version not found\"" && error_msg "'There is no: https://github.com/JoinMarket-Org/joinmarket-clientserver/release/tag/${version}'"
|
||||
|
||||
: "${qtgui:=true}"
|
||||
# Use tag if set, otherwise use commit hash
|
||||
: "${version:=${testedJMversion:-$testedJMcommit}}"
|
||||
# Only check GitHub releases if version looks like a tag (starts with 'v')
|
||||
if [[ "${version}" == v* ]]; then
|
||||
curl -s "https://github.com/JoinMarket-Org/joinmarket-clientserver/releases/tag/${version}" | grep -q "\"message\": \"Version not found\"" && error_msg "'There is no: https://github.com/JoinMarket-Org/joinmarket-clientserver/releases/tag/${version}'"
|
||||
fi
|
||||
: "${qtgui:=false}"
|
||||
range_argument qtgui "0" "1" "false" "true"
|
||||
|
||||
: "${user:=joinmarket}"
|
||||
|
|
@ -103,14 +133,16 @@ source /home/joinmarket/joinin.conf
|
|||
# create user if not default
|
||||
if [ "${user}" != "joinmarket" ]; then
|
||||
echo "# add the '${user}' user"
|
||||
sudo adduser --disabled-password --gecos "" ${user}
|
||||
sudo adduser --system --group --shell /bin/bash --home /home/${user} ${user}
|
||||
echo "Copy the skeleton files for login"
|
||||
sudo -u ${user} cp -r /etc/skel/. /home/${user}/
|
||||
sudo adduser ${user} sudo
|
||||
# add user to Tor group
|
||||
sudo usermod -a -G debian-tor ${user}
|
||||
# configure for usage without password entry
|
||||
checkEntry=$(sudo cat /etc/sudoers | grep -c "${user} ALL=(ALL) NOPASSWD:ALL")
|
||||
if [ ${checkEntry} -eq 0 ]; then
|
||||
echo "${user} ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers
|
||||
echo "${user} ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers
|
||||
fi
|
||||
# Autostart
|
||||
checkEntry=$(sudo -u ${user} cat /home/${user}/.bashrc | grep -c "jmvenv/bin/activate")
|
||||
|
|
@ -118,7 +150,6 @@ if [ "${user}" != "joinmarket" ]; then
|
|||
echo "
|
||||
if [ -f \"/home/${user}/joinmarket-clientserver/jmvenv/bin/activate\" ]; then
|
||||
. /home/${user}/joinmarket-clientserver/jmvenv/bin/activate
|
||||
/home/${user}/joinmarket-clientserver/jmvenv/bin/python -c \"import PySide2\"
|
||||
cd /home/${user}/joinmarket-clientserver/scripts/
|
||||
fi
|
||||
" | sudo -u ${user} tee -a /home/${user}/.bashrc
|
||||
|
|
@ -130,22 +161,14 @@ checkEntry=$(sudo -u ${user} cat /home/${user}/joinin.conf | grep -c "qtgui")
|
|||
if [ ${checkEntry} -eq 0 ]; then
|
||||
echo "qtgui=true" | sudo -u ${user} tee -a /home/${user}/joinin.conf
|
||||
fi
|
||||
if [ "${qtgui}" = "false" ]; then
|
||||
sudo -u ${user} sed -i "s/^qtgui=.*/qtgui=false/g" /home/${user}/joinin.conf
|
||||
fi
|
||||
sudo -u ${user} sed -i "s/^qtgui=.*/qtgui=${qtgui}/g" /home/${user}/joinin.conf
|
||||
|
||||
# installJoinMarket [update|testPR <PRnumber>|commit]
|
||||
function installJoinMarket() {
|
||||
cpu=$(uname -m)
|
||||
cd /home/${user} || exit 1
|
||||
if [ "${qtgui}" = "true" ]; then
|
||||
# PySide2 for armf: https://packages.debian.org/buster/python3-pyside2.qtcore
|
||||
echo "# Installing ARM specific dependencies to run the QT GUI"
|
||||
sudo apt-get install -y python3-pyside2.qtcore python3-pyside2.qtgui \
|
||||
python3-pyside2.qtwidgets zlib1g-dev libjpeg-dev python3-pyqt5 libltdl-dev
|
||||
fi
|
||||
# https://github.com/JoinMarket-Org/joinmarket-clientserver/issues/668#issuecomment-717815719
|
||||
sudo apt-get install -y build-essential automake pkg-config libffi-dev python3-dev
|
||||
sudo -u ${user} pip config set global.break-system-packages true
|
||||
sudo -u ${user} pip install libtool asn1crypto cffi pycparser
|
||||
echo "# Installing JoinMarket"
|
||||
|
||||
|
|
@ -169,65 +192,39 @@ function installJoinMarket() {
|
|||
elif [ "$install" = "update" ] && [ ${#2} -gt 0 ]; then
|
||||
updateVersion="$2"
|
||||
sudo -u ${user} git reset --hard $updateVersion
|
||||
else
|
||||
sudo -u ${user} git reset --hard $testedJMversion
|
||||
|
||||
sudo -u ${user} wget -O "pgp_keys.asc" ${PGPpkeys}
|
||||
sudo -u ${user} gpg --import --import-options show-only ./pgp_keys.asc
|
||||
fingerprint=$(sudo -u ${user} gpg "pgp_keys.asc" 2>/dev/null | grep "${PGPcheck}" -c)
|
||||
if [ ${fingerprint} -lt 1 ]; then
|
||||
echo
|
||||
echo "# !!! WARNING --> the PGP fingerprint is not as expected for ${PGPsigner}"
|
||||
echo "# Should contain PGP: ${PGPcheck}"
|
||||
echo "# PRESS ENTER to TAKE THE RISK if you think all is OK"
|
||||
read key
|
||||
fi
|
||||
sudo -u ${user} gpg --import ./pgp_keys.asc
|
||||
|
||||
verifyResult=$(sudo -u ${user} git verify-tag $testedJMversion 2>&1)
|
||||
|
||||
goodSignature=$(echo ${verifyResult} | grep 'Good signature' -c)
|
||||
echo "# goodSignature(${goodSignature})"
|
||||
correctKey=$(echo ${verifyResult} | tr -d " \t\n\r" | grep "${PGPcheck}" -c)
|
||||
echo "# correctKey(${correctKey})"
|
||||
if [ ${correctKey} -lt 1 ] || [ ${goodSignature} -lt 1 ]; then
|
||||
echo
|
||||
echo "# !!! BUILD FAILED --> PGP verification not OK / signature(${goodSignature}) verify(${correctKey})"
|
||||
exit 1
|
||||
echo "# Verifying signature for version: $updateVersion"
|
||||
# Determine if it's a tag (starts with 'v') or commit hash
|
||||
if [[ "$updateVersion" == v* ]]; then
|
||||
sudo -u ${user} bash /home/joinmarket/joininbox/scripts/verify.git.sh \
|
||||
"${PGPsigner}" "${PGPpkeys}" "${PGPcheck}" "$updateVersion" || exit 1
|
||||
else
|
||||
echo
|
||||
echo "#########################################################"
|
||||
echo "# OK --> the PGP signature of the $testedJMversion tag is correct"
|
||||
echo "#########################################################"
|
||||
echo
|
||||
sudo -u ${user} bash /home/joinmarket/joininbox/scripts/verify.git.sh \
|
||||
"${PGPsigner}" "${PGPpkeys}" "${PGPcheck}" || exit 1
|
||||
fi
|
||||
else
|
||||
# Decide whether to use tag or commit
|
||||
if [ -n "${testedJMversion}" ]; then
|
||||
echo "# Installing tested version: ${testedJMversion}"
|
||||
sudo -u ${user} git reset --hard $testedJMversion
|
||||
echo "# Verifying tag signature: ${testedJMversion}"
|
||||
sudo -u ${user} bash /home/joinmarket/joininbox/scripts/verify.git.sh \
|
||||
"${PGPsigner}" "${PGPpkeys}" "${PGPcheck}" "${testedJMversion}" || exit 1
|
||||
else
|
||||
echo "# Installing tested commit: ${testedJMcommit}"
|
||||
sudo -u ${user} git reset --hard $testedJMcommit
|
||||
echo "# Verifying commit signature: ${testedJMcommit}"
|
||||
sudo -u ${user} bash /home/joinmarket/joininbox/scripts/verify.git.sh \
|
||||
"${PGPsigner}" "${PGPpkeys}" "${PGPcheck}" || exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Use specific python version, if set
|
||||
python_args=""
|
||||
if [[ ! -z "${JM_PYTHON}" ]]; then
|
||||
if [[ -n "${JM_PYTHON}" ]]; then
|
||||
python_args="--python=${JM_PYTHON}"
|
||||
fi
|
||||
# do not clear screen during installation
|
||||
sudo -u ${user} sed -i 's/clear//g' install.sh
|
||||
# do not stop at installing Debian dependencies
|
||||
sudo -u ${user} sed -i \
|
||||
"s#^ if ! sudo apt-get install \${deb_deps\[@\]}; then#\
|
||||
if ! sudo apt-get install -y \${deb_deps\[@\]}; then#g" install.sh
|
||||
|
||||
if [ ${cpu} != "x86_64" ]; then
|
||||
echo "# Make install.sh set up jmvenv with -- system-site-packages on arm"
|
||||
# and import the PySide2 armf package from the system
|
||||
sudo -u ${user} sed -i "s#^ virtualenv -p \"\${python}\" \"\${jm_source}/jmvenv\" || return 1#\
|
||||
virtualenv --system-site-packages -p \"\${python}\" \"\${jm_source}/jmvenv\" || return 1 ;\
|
||||
/home/${user}/joinmarket-clientserver/jmvenv/bin/python -c \'import PySide2\'\
|
||||
#g" install.sh
|
||||
# don't install PySide2 - using the system-site-package instead
|
||||
sudo -u ${user} sed -i "s#^PySide2.*##g" requirements/gui.txt
|
||||
# don't install PyQt5 - using the system package instead
|
||||
sudo -u ${user} sed -i "s#^PyQt5.*##g" requirements/gui.txt
|
||||
sudo -u ${user} sed -i "s#PyQt5!=5.15.0,!=5.15.1,!=5.15.2,!=6.0##g" jmqtui/setup.py
|
||||
fi
|
||||
|
||||
if [ "${qtgui}" = "false" ]; then
|
||||
GUIchoice="--without-qt"
|
||||
|
|
@ -241,8 +238,10 @@ function installJoinMarket() {
|
|||
else
|
||||
sudo -u ${user} ./install.sh "${GUIchoice}" "$python_args" || exit 1
|
||||
fi
|
||||
currentJMversion=$(cd /home/${user}/joinmarket-clientserver 2>/dev/null; \
|
||||
git describe --tags 2>/dev/null)
|
||||
currentJMversion=$(
|
||||
cd /home/${user}/joinmarket-clientserver 2>/dev/null
|
||||
git describe --tags 2>/dev/null
|
||||
)
|
||||
echo
|
||||
echo "# installed JoinMarket $currentJMversion"
|
||||
echo
|
||||
|
|
@ -256,9 +255,9 @@ if [ "$install" = "config" ]; then
|
|||
fi
|
||||
# show info
|
||||
dialog \
|
||||
--title "Configure JoinMarket" \
|
||||
--exit-label "Continue to edit the joinmarket.cfg" \
|
||||
--textbox "/home/joinmarket/info.conf.txt" 43 108
|
||||
--title "Configure JoinMarket" \
|
||||
--exit-label "Continue to edit the joinmarket.cfg" \
|
||||
--textbox "/home/joinmarket/info.conf.txt" 43 108
|
||||
# edit joinmarket.cfg
|
||||
/home/${user}/set.conf.sh $JMcfgPath
|
||||
exit 0
|
||||
|
|
@ -266,7 +265,7 @@ fi
|
|||
|
||||
if [ "$install" = "install" ]; then
|
||||
# install joinmarket
|
||||
if [ ! -f "/home/${user}/joinmarket-clientserver/jmvenv/bin/activate" ] ; then
|
||||
if [ ! -f "/home/${user}/joinmarket-clientserver/jmvenv/bin/activate" ]; then
|
||||
echo
|
||||
echo "# JoinMarket is not yet installed - proceeding now"
|
||||
echo
|
||||
|
|
@ -274,10 +273,10 @@ if [ "$install" = "install" ]; then
|
|||
errorOnInstall $?
|
||||
echo "# Check for optional dependencies: matplotlib and scipy"
|
||||
activateJMvenv
|
||||
if [ "$(pip list | grep -c matplotlib)" -eq 0 ];then
|
||||
if [ "$(pip list | grep -c matplotlib)" -eq 0 ]; then
|
||||
pip install matplotlib
|
||||
fi
|
||||
if [ "$(pip list | grep -c scipy)" -eq 0 ];then
|
||||
if [ "$(pip list | grep -c scipy)" -eq 0 ]; then
|
||||
# https://stackoverflow.com/questions/7496547/does-python-scipy-need-blas
|
||||
sudo apt-get install -y gfortran libopenblas-dev liblapack-dev
|
||||
# fix 'No space left on device' with 2GB RAM
|
||||
|
|
|
|||
|
|
@ -1,33 +1,38 @@
|
|||
# Install Jam and connect to a remote Joininbox
|
||||
|
||||
* tested on Debian Bullseye desktop - Ubuntu should also work
|
||||
* tested on Debian Bullseye and Bookworm desktop - Ubuntu should also work
|
||||
|
||||
### Download the repo
|
||||
```
|
||||
git clone github.com/openoms/joininbox
|
||||
cd joininbox
|
||||
```
|
||||
|
||||
### Install Jam locally
|
||||
* will be under the user: `jam`
|
||||
```
|
||||
cd scripts/jam-remote
|
||||
bash install.jam.sh on
|
||||
```
|
||||
|
||||
### On your Joininbox
|
||||
## Steps in your Joininbox terminal
|
||||
* (optional) update the joininbox scripts: `UPDATE` - `ADVANCED` - `JBCOMMIT`
|
||||
* start the `API` from `TOOLS`
|
||||
* (optional) start the ob-watcher from `OFFERS`
|
||||
|
||||
## Steps on your desktop
|
||||
### Download the repo
|
||||
* move to a directory where the joininbox repo will be stored
|
||||
```
|
||||
git clone https://github.com/openoms/joininbox
|
||||
cd joininbox
|
||||
```
|
||||
|
||||
### Install Jam locally
|
||||
* will be under the user: `jam`
|
||||
```
|
||||
cd scripts/jam-remote
|
||||
bash install.jam.sh on
|
||||
```
|
||||
|
||||
### Forward the API and ob-watcher ports with ssh from your Joininbox
|
||||
```
|
||||
bash ssh-portforward $JOININBOX_LAN_IP
|
||||
```
|
||||
* run the ssh-port-forward script in the `joininbox/scripts/jam-remote` folder
|
||||
```
|
||||
bash ./ssh-port-forward.sh $JOININBOX_LAN_IP
|
||||
```
|
||||
* leave this terminal open until working with Jam
|
||||
* close when done to close the ssh connection
|
||||
* Earn will continue to run on the Joininbox
|
||||
* can check it's logs in the menu - `MAKER` - `LOGS`
|
||||
|
||||
### Open Jam locally using the wallets on your remote Joininbox
|
||||
`https://localhost:7501`
|
||||
* open Jam at https://localhost:7501
|
||||
* accept the self-signed certificate served from your Joininbox
|
||||
* Use Jam - docs: https://jamdocs.org/
|
||||
* Earn will continue to run on the Joininbox even after the terminal and Jam windows are closed
|
||||
* can check the logs in the Joininbox menu - `MAKER` - `LOGS`
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ if [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
# download
|
||||
mkdir download
|
||||
cd download || exit 1
|
||||
wget -O node-$VERSION-$DISTRO.tar.xz https://nodejs.org/dist/$VERSION/node-$VERSION-$DISTRO.tar.xz
|
||||
wget --prefer-family=ipv4 -O node-$VERSION-$DISTRO.tar.xz https://nodejs.org/dist/$VERSION/node-$VERSION-$DISTRO.tar.xz
|
||||
# checksum
|
||||
wget -O SHASUMS256.txt https://nodejs.org/dist/$VERSION/SHASUMS256.txt
|
||||
wget --prefer-family=ipv4 -O SHASUMS256.txt https://nodejs.org/dist/$VERSION/SHASUMS256.txt
|
||||
if ! sha256sum -c SHASUMS256.txt --ignore-missing; then
|
||||
echo "FAIL: The checksum of node-$VERSION-$DISTRO.tar.xz is not found in the SHASUMS256.txt"
|
||||
rm -f node-$VERSION-$DISTRO.tar.xz*
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
# https://github.com/joinmarket-webui/jam
|
||||
|
||||
USERNAME=jam
|
||||
WEBUI_VERSION=0.1.5
|
||||
WEBUI_VERSION="v0.4.0"
|
||||
REPO=joinmarket-webui/jam
|
||||
HOME_DIR=/home/${USERNAME}
|
||||
APP_DIR=webui
|
||||
SOURCEDIR=$(pwd)
|
||||
|
||||
PGPsigner="dergigi"
|
||||
PGPsigner="theborakompanioni"
|
||||
PGPpubkeyLink="https://github.com/${PGPsigner}.gpg"
|
||||
PGPpubkeyFingerprint="89C4A25E69A5DE7F"
|
||||
PGPpubkeyFingerprint="E8070AF0053AAC0D"
|
||||
|
||||
# command info
|
||||
if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then
|
||||
|
|
@ -46,7 +46,7 @@ if [ "$1" = "on" ]; then
|
|||
|
||||
echo "# Creating the ${USERNAME} user"
|
||||
echo
|
||||
sudo adduser --disabled-password --gecos "" ${USERNAME}
|
||||
sudo adduser --system --group --home /home/${USERNAME} ${USERNAME}
|
||||
|
||||
# install nodeJS
|
||||
bash ${SOURCEDIR}/bonus.nodejs.sh on
|
||||
|
|
@ -57,10 +57,10 @@ if [ "$1" = "on" ]; then
|
|||
sudo -u $USERNAME git clone https://github.com/$REPO
|
||||
|
||||
cd jam || exit 1
|
||||
sudo -u $USERNAME git reset --hard v${WEBUI_VERSION}
|
||||
sudo -u $USERNAME git reset --hard ${WEBUI_VERSION}
|
||||
|
||||
sudo -u $USERNAME bash ${SOURCEDIR}/../verify.git.sh \
|
||||
"${PGPsigner}" "${PGPpubkeyLink}" "${PGPpubkeyFingerprint}" "v${WEBUI_VERSION}" || exit 1
|
||||
"${PGPsigner}" "${PGPpubkeyLink}" "${PGPpubkeyFingerprint}" "${WEBUI_VERSION}" || exit 1
|
||||
|
||||
cd $HOME_DIR || exit 1
|
||||
sudo -u $USERNAME mv jam $APP_DIR
|
||||
|
|
@ -134,10 +134,15 @@ if [ "$1" = "update" ]; then
|
|||
echo "FAIL - npm install did not run correctly, aborting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo -u $USERNAME npm run build
|
||||
echo "*** JAM UPDATED to $version ***"
|
||||
fi
|
||||
|
||||
if ! sudo -u $USERNAME npm install; then
|
||||
echo "FAIL - npm install did not run correctly, aborting"
|
||||
exit 1
|
||||
fi
|
||||
sudo -u $USERNAME npm run build
|
||||
|
||||
else
|
||||
echo "*** JAM NOT INSTALLED ***"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
USERNAME=jam
|
||||
|
||||
sudo apt install nginx
|
||||
sudo apt-get install -y nginx
|
||||
|
||||
if ! sudo ls /home/jam/nginx/tls.cert || ! sudo ls /home/jam/nginx/tls.key; then
|
||||
sudo apt-get install openssl
|
||||
sudo apt-get install -y openssl
|
||||
|
||||
subj="/C=US/ST=Utah/L=Lehi/O=Your Company, Inc./OU=IT/CN=example.com"
|
||||
sudo -u $USERNAME mkdir -p /home/jam/nginx/ \
|
||||
|
|
|
|||
|
|
@ -10,7 +10,11 @@ if [ ${#network} -eq 0 ] || [ "${network}" = "unknown" ] ;then
|
|||
elif [ "${runningEnv}" = mynode ];then
|
||||
network=mainnet
|
||||
elif [ "${runningEnv}" = raspiblitz ];then
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ]; then
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
else
|
||||
source /mnt/hdd/app-data/raspiblitz.conf
|
||||
fi
|
||||
if [ $network = bitcoin ];then
|
||||
network=${chain}net
|
||||
else
|
||||
|
|
@ -25,7 +29,7 @@ if [ "$runningEnv" = "standalone" ] && [ "$setupStep" -lt 100 ]; then
|
|||
|
||||
# BASIC MENU INFO
|
||||
HEIGHT=16
|
||||
WIDTH=64
|
||||
WIDTH=68
|
||||
CHOICE_HEIGHT=24
|
||||
TITLE="Startup options"
|
||||
MENU="
|
||||
|
|
@ -38,7 +42,7 @@ if [ "$runningEnv" = "standalone" ] && [ "$setupStep" -lt 100 ]; then
|
|||
OPTIONS+=(
|
||||
CONNECT "Connect to a remote bitcoin node on mainnet"
|
||||
SIGNET "Start on signet with a local Bitcoin Core"
|
||||
PRUNED "Start a pruned node from prunednode.today")
|
||||
PRUNED "Start a pruned node from pruned.host4coins.net/blocks")
|
||||
if [ -f /home/bitcoin/.bitcoin/bitcoin.conf ];then
|
||||
OPTIONS+=(
|
||||
LOCAL "Connect to the local Bitcoin Core on mainnet")
|
||||
|
|
@ -54,7 +58,7 @@ if [ "$runningEnv" = "standalone" ] && [ "$setupStep" -lt 100 ]; then
|
|||
else
|
||||
# BASIC MENU INFO
|
||||
HEIGHT=12
|
||||
WIDTH=64
|
||||
WIDTH=68
|
||||
CHOICE_HEIGHT=20
|
||||
TITLE="Configuration options"
|
||||
MENU=""
|
||||
|
|
@ -70,7 +74,7 @@ else
|
|||
SIGNET "Switch to signet with a local Bitcoin Core")
|
||||
if [ "${runningEnv}" = standalone ]; then
|
||||
OPTIONS+=(
|
||||
PRUNED "Start a pruned node locally from prunednode.today")
|
||||
PRUNED "Start a pruned node from pruned.host4coins.net/blocks")
|
||||
HEIGHT=$((HEIGHT+1))
|
||||
CHOICE_HEIGHT=$((CHOICE_HEIGHT+1))
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
source /home/joinmarket/joinin.conf
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ]; then
|
||||
source /mnt/hdd/raspiblitz.conf
|
||||
else
|
||||
source /mnt/hdd/app-data/raspiblitz.conf
|
||||
fi
|
||||
|
||||
# BASIC MENU INFO
|
||||
HEIGHT=8
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ function startOrderBook() {
|
|||
sleep 3
|
||||
dialog \
|
||||
--title "Monitoring the ob-watcher - press CTRL+C to exit" \
|
||||
--prgbox "sudo journalctl -fn20 -u ob-watcher" 30 200
|
||||
--prgbox "sudo journalctl -fn100 -u ob-watcher" -1 -1
|
||||
}
|
||||
|
||||
if [ "$1" = startOrderBookService ]; then
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ $(echo $(cat $wallet) | sed "s#$walletPath##g")
|
|||
mixdepth: $(cat $mixdepth)
|
||||
" 12 55
|
||||
|
||||
# make decison
|
||||
# make decision
|
||||
pressed=$?
|
||||
case $pressed in
|
||||
0)
|
||||
|
|
@ -141,7 +141,7 @@ mixdepth: $(cat "$mixdepth")
|
|||
|
||||
Miner fee: $txfeeMessage
|
||||
" 16 55
|
||||
# make decison
|
||||
# make decision
|
||||
pressed=$?
|
||||
case $pressed in
|
||||
0)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ Paste the destination address" 19 69 2> "$address"
|
|||
openMenuIfCancelled $?
|
||||
|
||||
# changeAddress
|
||||
trap 'rm -f "$changeAdress"' EXIT
|
||||
trap 'rm -f "$changeAddress"' EXIT
|
||||
changeAddress=$(mktemp -p /dev/shm/)
|
||||
if [ "$amountsats" != "0 sats" ]; then
|
||||
dialog --backtitle "Custom change address" \
|
||||
|
|
@ -185,7 +185,7 @@ $(cat "$address")
|
|||
change address (optional):
|
||||
$changeAddressMessage" 17 69
|
||||
|
||||
# make decison
|
||||
# make decision
|
||||
pressed=$?
|
||||
case $pressed in
|
||||
0)
|
||||
|
|
|
|||
|
|
@ -26,17 +26,6 @@ function listCJcandidateTXNs {
|
|||
done
|
||||
}
|
||||
|
||||
function installBoltzmann {
|
||||
if [ ! -f "/home/joinmarket/boltzmann/bvenv/bin/activate" ]; then
|
||||
cd /home/joinmarket/ || exit 1
|
||||
git clone https://code.samourai.io/oxt/boltzmann.git
|
||||
cd boltzmann || exit 1
|
||||
python3 -m venv bvenv
|
||||
source bvenv/bin/activate || exit 1
|
||||
python setup.py install
|
||||
fi
|
||||
}
|
||||
|
||||
function dialog_inputbox {
|
||||
local title=$1
|
||||
local text=$2
|
||||
|
|
@ -66,7 +55,7 @@ isLocalBitcoinCLI=$(sudo -u bitcoin bitcoin-cli -version | grep -c "Bitcoin Core
|
|||
isTxindex=$(sudo -u bitcoin cat /home/bitcoin/.bitcoin/bitcoin.conf | grep -c "txindex=1")
|
||||
|
||||
# BASIC MENU INFO
|
||||
HEIGHT=13
|
||||
HEIGHT=12
|
||||
WIDTH=61
|
||||
CHOICE_HEIGHT=7
|
||||
TITLE="Tools"
|
||||
|
|
@ -97,8 +86,6 @@ if [ "$isLocalBitcoinCLI" -gt 0 ] && [ "$isTxindex" -gt 0 ]; then
|
|||
CHOICE_HEIGHT=$((CHOICE_HEIGHT + 1))
|
||||
fi
|
||||
fi
|
||||
OPTIONS+=(
|
||||
BOLTZMANN "Analyze the entropy of a transaction")
|
||||
if [ "${runningEnv}" != mynode ]; then
|
||||
OPTIONS+=(
|
||||
PASSWORD "Change the ssh password")
|
||||
|
|
@ -186,15 +173,6 @@ CHECKTXN)
|
|||
echo "Press ENTER to return to the menu..."
|
||||
read key
|
||||
;;
|
||||
BOLTZMANN)
|
||||
dialog_inputbox "Boltzmann transaction entropy analysis" "\nUsing: https://code.samourai.io/oxt/boltzmann\n\nPaste a TXID to analyze" 11 71
|
||||
clear
|
||||
installBoltzmann
|
||||
python /home/joinmarket/start.boltzmann.py --txid=$dialog_output
|
||||
echo
|
||||
echo "Press ENTER to return to the menu..."
|
||||
read key
|
||||
;;
|
||||
CJFINDER)
|
||||
BLOCKHEIGHT=$(customRPC "" "getblockchaininfo" "" |
|
||||
grep blocks | awk '{print $2}' | cut -d, -f1)
|
||||
|
|
|
|||
|
|
@ -3,13 +3,16 @@
|
|||
source /home/joinmarket/_functions.sh
|
||||
|
||||
# BASIC MENU INFO
|
||||
HEIGHT=16
|
||||
HEIGHT=18
|
||||
WIDTH=60
|
||||
CHOICE_HEIGHT=7
|
||||
TITLE="Advanced update options"
|
||||
MENU="
|
||||
Current JoininBox version: $currentJBcommit
|
||||
Current JoinMarket version: $currentJMversion"
|
||||
Installed versions:
|
||||
JoininBox $currentJBcommit
|
||||
JoinMarket $currentJMversion
|
||||
$currentBTCversion"
|
||||
|
||||
OPTIONS=()
|
||||
BACKTITLE="JoininBox GUI"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,20 +3,34 @@
|
|||
source /home/joinmarket/_functions.sh
|
||||
|
||||
# BASIC MENU INFO
|
||||
HEIGHT=12
|
||||
WIDTH=56
|
||||
CHOICE_HEIGHT=3
|
||||
HEIGHT=15
|
||||
WIDTH=57
|
||||
CHOICE_HEIGHT=4
|
||||
TITLE="Update options"
|
||||
MENU="
|
||||
Current JoininBox version: $currentJBcommit
|
||||
Current JoinMarket version: $currentJMversion"
|
||||
Installed versions:
|
||||
JoininBox $currentJBcommit
|
||||
JoinMarket $currentJMversion
|
||||
$currentBTCversion"
|
||||
OPTIONS=()
|
||||
BACKTITLE="JoininBox GUI"
|
||||
|
||||
# Basic Options
|
||||
# Determine if using tag or commit for display
|
||||
testedVersion=$(grep 'testedJMversion=' < ~/install.joinmarket.sh | grep -v '^#' | cut -d '"' -f 2)
|
||||
if [ -z "$testedVersion" ]; then
|
||||
testedVersion=$(grep 'testedJMcommit=' < ~/install.joinmarket.sh | cut -d '"' -f 2 | cut -c 1-12)
|
||||
testedVersion="${testedVersion} (commit)"
|
||||
fi
|
||||
OPTIONS+=(
|
||||
JOININBOX "Update the JoininBox scripts and menu"
|
||||
JOINMARKET "Update/reinstall JoinMarket to $(grep testedJMversion= < ~/install.joinmarket.sh | cut -d '"' -f 2)"
|
||||
JOINMARKET "Update/reinstall JoinMarket to ${testedVersion}")
|
||||
|
||||
if [ "$runningEnv" = "standalone" ]; then
|
||||
OPTIONS+=(\
|
||||
BITCOIN "Update Bitcoin Core to a chosen version")
|
||||
fi
|
||||
OPTIONS+=(\
|
||||
ADVANCED "Advanced update options")
|
||||
|
||||
CHOICE=$(dialog --clear \
|
||||
|
|
@ -47,6 +61,14 @@ case $CHOICE in
|
|||
echo
|
||||
echo "Press ENTER to return to the menu"
|
||||
read key;;
|
||||
BITCOIN)
|
||||
/home/joinmarket/standalone/bitcoin.update.sh custom
|
||||
errorOnInstall $?
|
||||
echo
|
||||
echo "# Start bitcoind .. "
|
||||
sudo systemctl start bitcoind
|
||||
echo "# Monitoring the bitcoind logs .. "
|
||||
showBitcoinLogs;;
|
||||
ADVANCED)
|
||||
/home/joinmarket/menu.update.advanced.sh;;
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ Enter the new gap limit to be used" 16 60 2> "$gaplimit"
|
|||
echo
|
||||
/home/joinmarket/start.script.sh wallet-tool "$(cat $wallet)"|grep mixdepth|sed -n '1~2p'|awk '{print $3}'
|
||||
echo
|
||||
echo "Import the master public keys to Specter Desktop or Electrum to create watch only wallets."
|
||||
echo "Import the master public keys to Specter Desktop or Electrum to create watch-only wallets."
|
||||
echo
|
||||
echo "Press ENTER to return to the menu..."
|
||||
read key
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ case $CHOICE in
|
|||
--msgbox "
|
||||
There are no stats because the Yield Generator was never run.
|
||||
|
||||
Start with the menu option: RUN_YG" 10 50
|
||||
Start with the menu option: MAKER" 10 50
|
||||
else
|
||||
dialog --prgbox "/home/joinmarket/info.stats.sh showAllEarned" 9 55
|
||||
dialog --prgbox "/home/joinmarket/info.stats.sh showAllEarned" 9 67
|
||||
fi;;
|
||||
NICKNAME)
|
||||
name=$(YGnickname)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ ${#1} -eq 0 ]||[ $1 = "-h" ]||[ $1 = "--help" ];then
|
||||
if [ ${#1} -eq 0 ] || [ $1 = "-h" ] || [ $1 = "--help" ]; then
|
||||
echo "Enable or disable ssh access with the joinmarket user"
|
||||
echo "sudo set.ssh.sh [off|on]"
|
||||
echo
|
||||
|
|
@ -18,7 +18,7 @@ if ! grep -Eq "^joinmarketSSH=" /home/joinmarket/joinin.conf; then
|
|||
fi
|
||||
|
||||
echo
|
||||
if [ "$1" = "off" ];then
|
||||
if [ "$1" = "off" ]; then
|
||||
echo "# Disable ssh access with the joinmarket user"
|
||||
if ! grep -Eq "^DenyUsers joinmarket" /etc/ssh/sshd_config; then
|
||||
echo "DenyUsers joinmarket" | tee -a /etc/ssh/sshd_config
|
||||
|
|
@ -35,4 +35,4 @@ elif [ "$1" = "on" ]; then
|
|||
else
|
||||
echo "# Invalid option $*"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ if [ "$1" = "set" ]; then
|
|||
# check that config file exists
|
||||
raspiblitzConfExists=$(ls ${configFile} 2>/dev/null | grep -c "${configFile}")
|
||||
if [ ${raspiblitzConfExists} -eq 0 ]; then
|
||||
echo "# blitz.conf.sh $@"
|
||||
echo "# blitz.conf.sh $*"
|
||||
echo "# FAIL: missing config file: ${configFile}"
|
||||
exit 3
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
function addUserStore() {
|
||||
if [ ! -d /home/store/app-data ];then
|
||||
if [ ! -d /home/store/app-data ]; then
|
||||
echo "# Adding the user: store"
|
||||
sudo adduser --disabled-password --gecos "" 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
|
||||
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/
|
||||
|
|
@ -20,7 +22,7 @@ function moveSignetData() {
|
|||
fi
|
||||
}
|
||||
|
||||
function makeEncryptedFolder(){
|
||||
function makeEncryptedFolder() {
|
||||
# TODO
|
||||
# make encrypted file
|
||||
|
||||
|
|
@ -33,32 +35,46 @@ function makeEncryptedFolder(){
|
|||
}
|
||||
|
||||
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 12582912 ];then # 12G = 12*1024*1024k
|
||||
if [ $FREE -lt 21000000 ]; then
|
||||
echo "# The free space is only $FREE bytes!"
|
||||
echo "# Would need ~12GB free space to download and extract the snapshot."
|
||||
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 12GB is free!"
|
||||
echo "# OK, more than 21GB is free!"
|
||||
fi
|
||||
sudo -u joinmarket mkdir /home/joinmarket/download 2>/dev/null
|
||||
cd /home/joinmarket/download || exit 1
|
||||
hashFileName="latest.signed.txt"
|
||||
sudo rm $hashFileName
|
||||
wget https://prunednode.today/$hashFileName || exit 1
|
||||
downloadFileName=$(grep .zip < $hashFileName | awk '{print $2}')
|
||||
downloadLink="https://prunednode.today/$downloadFileName"
|
||||
|
||||
echo "# Import the PGP keys of Stepan Snigirev"
|
||||
curl https://stepansnigirev.com/ss-specter-release.asc | gpg --import || 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 ..."
|
||||
verifyResult=$(gpg --verify $hashFileName 2>&1)
|
||||
goodSignature=$(echo ${verifyResult} | grep -c 'Good signature')
|
||||
echo "# goodSignature (${goodSignature})"
|
||||
if [ ${goodSignature} -eq 0 ];then
|
||||
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
|
||||
|
|
@ -67,18 +83,18 @@ function downloadSnapShot() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f $downloadFileName ];then
|
||||
if [ ! -f $downloadFileName ]; then
|
||||
echo
|
||||
echo "# Downloading $downloadLink ..."
|
||||
echo
|
||||
wget $downloadLink
|
||||
wget --prefer-family=ipv4 -O $downloadFileName $downloadLink || exit 1
|
||||
fi
|
||||
|
||||
echo "# Verifying the hash (takes time) ..."
|
||||
verifyHash=$(sha256sum -c $hashFileName 2>&1)
|
||||
goodHash=$(echo ${verifyHash} | grep -c OK)
|
||||
echo "# goodHash ($goodHash)"
|
||||
if [ ${goodSignature} -lt 1 ] || [ ${goodHash} -lt 1 ]; then
|
||||
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."
|
||||
|
|
@ -87,71 +103,82 @@ function downloadSnapShot() {
|
|||
rm -f $hashFileName
|
||||
rm -f $downloadFileName
|
||||
exit 1
|
||||
else
|
||||
echo
|
||||
echo "# The PGP signature and the hash of the downloaded snapshot is correct"
|
||||
fi
|
||||
|
||||
echo "# Exracting to /home/store/app-data/.bitcoin ..."
|
||||
echo "# Extracting to /home/store/app-data/.bitcoin ..."
|
||||
FREE=$(df -k --output=avail "$PWD" | tail -n1) # df -k not df -h
|
||||
if [ $FREE -lt 7340032 ];then # 7G = 7*1024*1024k
|
||||
if [ $FREE -lt 11000000 ]; then
|
||||
echo "# The free space is only $FREE bytes!"
|
||||
echo "# Would need ~7GB free space to extract the snapshot."
|
||||
echo "# Press ENTER to continue to download regardless or CTRL+C to exit."
|
||||
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 7GB is free!"
|
||||
echo "# OK, more than 11GB is free!"
|
||||
fi
|
||||
addUserStore
|
||||
sudo mkdir -p /home/store/app-data/.bitcoin
|
||||
echo "# Make sure bitcoind is not running"
|
||||
sudo systemctl stop bitcoind
|
||||
if [ -f /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 "# Check unzip"
|
||||
sudo apt-get install -y unzip
|
||||
sudo unzip -o $downloadFileName -d /home/store/app-data/.bitcoin
|
||||
if [ -f /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
|
||||
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 --disabled-password --gecos "" 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/
|
||||
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 /home/bitcoin/bitcoin/bitcoind ];then
|
||||
installedVersion=$(/home/bitcoin/bitcoin/bitcoind --version | grep version)
|
||||
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 --disabled-password --gecos "" 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}"
|
||||
sudo -u bitcoin mkdir -p /home/bitcoin/bitcoin
|
||||
cd /home/joinmarket/download/bitcoin-${bitcoinVersion}/bin/ || exit 1
|
||||
sudo install -m 0755 -o root -g root -t /home/bitcoin/bitcoin ./*
|
||||
sudo install -m 0755 -o root -g root -t /usr/local/bin/ ./*
|
||||
fi
|
||||
if [ "$(grep -c "/home/bitcoin/bitcoin" < /etc/profile)" -eq 0 ];then
|
||||
echo "# Add /home/bitcoin/bitcoin to global PATH"
|
||||
echo "PATH=/home/bitcoin/bitcoin:$PATH" | sudo tee -a /etc/profile
|
||||
fi
|
||||
installed=$(/home/bitcoin/bitcoin/bitcoind --version | grep -c "Bitcoin Core version")
|
||||
if [ ${installed} -lt 1 ]; then
|
||||
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)"
|
||||
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 [ $(grep -c rpcpassword < /home/store/app-data/.bitcoin/bitcoin.conf) -eq 0 ];then
|
||||
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
|
||||
|
|
@ -161,14 +188,14 @@ function installBitcoinCoreStandalone() {
|
|||
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=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c20)
|
||||
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
|
||||
rpcpassword="$randomRPCpass"
|
||||
|
||||
prune=1000
|
||||
server=1
|
||||
|
|
@ -192,24 +219,45 @@ function installMainnet() {
|
|||
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
|
||||
Type=forking
|
||||
PIDFile=/home/bitcoin/bitcoin/bitcoind.pid
|
||||
ExecStart=/home/bitcoin/bitcoin/bitcoind -daemon \
|
||||
-pid=/home/bitcoin/bitcoin/bitcoind.pid
|
||||
Restart=always
|
||||
TimeoutSec=120
|
||||
RestartSec=30
|
||||
|
||||
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
|
||||
|
|
@ -219,9 +267,17 @@ WantedBy=multi-user.target
|
|||
echo "# OK - the bitcoind.service is now enabled"
|
||||
|
||||
# add aliases
|
||||
if [ $(alias | grep -c "sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli") -eq 0 ];then
|
||||
sudo bash -c "echo 'alias bitcoin-cli=\"sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli\"' >> /home/joinmarket/_aliases.sh"
|
||||
sudo bash -c "echo 'alias bitcoind=\"sudo -u bitcoin /home/bitcoin/bitcoin/bitcoind\"' >> /home/joinmarket/_aliases.sh"
|
||||
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
|
||||
|
|
@ -229,14 +285,14 @@ WantedBy=multi-user.target
|
|||
|
||||
sudo systemctl start bitcoind
|
||||
echo
|
||||
echo "# Installed $(/home/bitcoin/bitcoin/bitcoind --version | grep version)"
|
||||
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 [ ! -f /home/bitcoin/.bitcoin/mainnet/wallets/wallet.dat/wallet.dat ];then
|
||||
echo "# Create wallet.dat ..."
|
||||
if [ ! -d /home/bitcoin/.bitcoin/wallets/watch-only-descriptor-wallet ]; then
|
||||
echo "# Create watch-only-descriptor-wallet ..."
|
||||
sleep 10
|
||||
sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -named createwallet wallet_name=wallet.dat descriptors=false
|
||||
sudo -u bitcoin /usr/local/bin/bitcoin-cli -named createwallet wallet_name=watch-only-descriptor-wallet descriptors=true disable_private_keys=true
|
||||
fi
|
||||
}
|
||||
|
|
|
|||
219
scripts/standalone/bitcoin.update.sh
Normal file
219
scripts/standalone/bitcoin.update.sh
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
#!/bin/bash
|
||||
|
||||
# command info
|
||||
if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then
|
||||
echo "Interim optional Bitcoin Core updates."
|
||||
echo "bitcoin.update.sh [info|tested|reckless|custom]"
|
||||
echo "info -> get actual state and possible actions"
|
||||
echo "tested -> only do a tested update by the RaspiBlitz team"
|
||||
echo "reckless -> the update was not tested by the RaspiBlitz team"
|
||||
echo "custom <version> <skipverify> -> update to a chosen version"
|
||||
echo " the binary checksum and signatures will be checked in all cases"
|
||||
echo " except when 'skipverify' is used"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Running: bitcoin.update.sh $*"
|
||||
|
||||
# 1. parameter [info|tested|reckless]
|
||||
mode="$1"
|
||||
|
||||
# RECOMMENDED UPDATE BY RASPIBLITZ TEAM (just possible once per sd card update)
|
||||
# comment will be shown as "BEWARE Info" when option is chosen (can be multiple lines)
|
||||
bitcoinVersion="" # example: 22.0 .. keep empty if no newer version as sd card build is available
|
||||
|
||||
# GATHER DATA
|
||||
# setting download directory to the current user
|
||||
downloadDir="/home/$(whoami)/download/bitcoin.update"
|
||||
|
||||
# bitcoinOSversion
|
||||
if [ "$(uname -m | grep -c 'arm')" -gt 0 ]; then
|
||||
bitcoinOSversion="arm-linux-gnueabihf"
|
||||
elif [ "$(uname -m | grep -c 'aarch64')" -gt 0 ]; then
|
||||
bitcoinOSversion="aarch64-linux-gnu"
|
||||
elif [ "$(uname -m | grep -c 'x86_64')" -gt 0 ]; then
|
||||
bitcoinOSversion="x86_64-linux-gnu"
|
||||
fi
|
||||
|
||||
# installed version
|
||||
installedVersion=$(sudo -u bitcoin /usr/local/bin/bitcoind --version | head -n1 | cut -d" " -f4 | cut -c 2-)
|
||||
|
||||
# test if the installed version already the tested/recommended update version
|
||||
bitcoinUpdateInstalled=$(echo "${installedVersion}" | grep -c "${bitcoinVersion}")
|
||||
|
||||
# get latest release from GitHub releases
|
||||
bitcoinLatestVersion=$(curl --header "X-GitHub-Api-Version:2022-11-28" -s https://api.github.com/repos/bitcoin/bitcoin/releases | jq -r '.[].tag_name' | sort | tail -n1 | cut -c 2-)
|
||||
|
||||
# INFO
|
||||
function displayInfo() {
|
||||
echo "# basic data"
|
||||
echo "installedVersion='${installedVersion}'"
|
||||
echo "bitcoinOSversion='${bitcoinOSversion}'"
|
||||
|
||||
echo "# the tested/recommended update option"
|
||||
echo "bitcoinUpdateInstalled='${bitcoinUpdateInstalled}'"
|
||||
echo "bitcoinVersion='${bitcoinVersion}'"
|
||||
|
||||
echo "# reckless update option (latest Bitcoin Core release from GitHub)"
|
||||
echo "bitcoinLatestVersion='${bitcoinLatestVersion}'"
|
||||
}
|
||||
|
||||
if [ "${mode}" = "info" ]; then
|
||||
displayInfo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# tested
|
||||
if [ "${mode}" = "tested" ]; then
|
||||
|
||||
echo "# bitcoin.update.sh tested"
|
||||
|
||||
elif [ "${mode}" = "reckless" ]; then
|
||||
# RECKLESS
|
||||
# this mode is just for people running test and development nodes - its not recommended
|
||||
# for production nodes. In a update/recovery scenario it will not install a fixed version
|
||||
# it will always pick the latest release from the github
|
||||
echo "# bitcoin.update.sh reckless"
|
||||
bitcoinVersion=${bitcoinLatestVersion}
|
||||
pathVersion=${bitcoinVersion}
|
||||
|
||||
elif [ "${mode}" = "custom" ]; then
|
||||
if [ $# -gt 1 ]; then
|
||||
bitcoinVersion="$2"
|
||||
else
|
||||
clear
|
||||
echo
|
||||
echo "# Update Bitcoin Core to a chosen version."
|
||||
echo
|
||||
echo "# Input the version you would like to install and press ENTER."
|
||||
echo "# Examples (versions below 22.1 are not supported):"
|
||||
echo "24.0.1"
|
||||
echo "26.0"
|
||||
echo
|
||||
read bitcoinVersion
|
||||
fi
|
||||
|
||||
if [ $(echo ${bitcoinVersion} | grep -c "rc") -gt 0 ]; then
|
||||
cutVersion=$(echo ${bitcoinVersion} | awk -F"r" '{print $1}')
|
||||
rcVersion=$(echo ${bitcoinVersion} | awk -F"r" '{print $2}')
|
||||
# https://bitcoincore.org/bin/bitcoin-core-22.0/test.rc3/
|
||||
pathVersion=${cutVersion}/test.r${rcVersion}
|
||||
else
|
||||
pathVersion=${bitcoinVersion}
|
||||
fi
|
||||
|
||||
if curl --output /dev/null --silent --head --fail \
|
||||
https://bitcoincore.org/bin/bitcoin-core-${pathVersion}/SHA256SUMS.asc; then
|
||||
echo "# OK version exists at https://bitcoincore.org/bin/bitcoin-core-${pathVersion}"
|
||||
if [ "${mode}" = "custom" ] && [ "$3" = "skipverify" ]; then
|
||||
echo "# skipping signature verification"
|
||||
fi
|
||||
echo "# Press ENTER to proceed to install Bitcoin Core $bitcoinVersion or CTRL+C to abort."
|
||||
read key
|
||||
else
|
||||
echo "# FAIL $bitcoinVersion does not exist"
|
||||
echo
|
||||
echo "# Press ENTER to return to the main menu"
|
||||
read key
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# JOINED INSTALL
|
||||
if [ "${mode}" = "tested" ] || [ "${mode}" = "reckless" ] || [ "${mode}" = "custom" ]; then
|
||||
|
||||
displayInfo
|
||||
|
||||
if [ "$installedVersion" = "$bitcoinVersion" ]; then
|
||||
echo "# installedVersion = bitcoinVersion"
|
||||
echo "# exiting script"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "# clean & change into download directory"
|
||||
sudo rm -rf "${downloadDir}"
|
||||
mkdir -p "${downloadDir}"
|
||||
cd "${downloadDir}" || exit 1
|
||||
|
||||
echo "# Receive signer keys"
|
||||
curl -s "https://api.github.com/repos/bitcoin-core/guix.sigs/contents/builder-keys" |
|
||||
jq -r '.[].download_url' | while read url; do curl -s "$url" | gpg --import; done
|
||||
|
||||
# download signed binary sha256 hash sum file
|
||||
wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS
|
||||
# download the signed binary sha256 hash sum file and check
|
||||
wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS.asc https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS.asc
|
||||
|
||||
if [ "${mode}" = "custom" ] && [ "$3" = "skipverify" ]; then
|
||||
echo "# skipping signature verification"
|
||||
echo "# display the output of 'gpg --verify SHA256SUMS.asc'"
|
||||
gpg --verify SHA256SUMS.asc
|
||||
else
|
||||
if gpg --verify SHA256SUMS.asc; then
|
||||
echo
|
||||
echo "****************************************"
|
||||
echo "OK --> BITCOIN MANIFEST IS CORRECT"
|
||||
echo "****************************************"
|
||||
echo
|
||||
else
|
||||
echo
|
||||
echo "# BUILD FAILED --> the PGP verification failed"
|
||||
echo "# try again or with a different version"
|
||||
echo "# if you want to skip verifying all signatures (and just show them) use the command:"
|
||||
echo "# /home/admin/config.scripts/bonus.bitcoin.sh custom ${bitcoinVersion:-<version>} skipverify"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "# Downloading Bitcoin Core v${bitcoinVersion} for ${bitcoinOSversion} ..."
|
||||
binaryName="bitcoin-${bitcoinVersion}-${bitcoinOSversion}.tar.gz"
|
||||
wget https://bitcoincore.org/bin/bitcoin-core-${pathVersion}/${binaryName}
|
||||
if [ ! -f "./${binaryName}" ]; then
|
||||
echo "# FAIL # Downloading BITCOIN BINARY did not succeed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Checking the binary checksum ..."
|
||||
if ! sha256sum -c --ignore-missing SHA256SUMS; then
|
||||
# get the sha256 value for the corresponding platform from signed hash sum file
|
||||
bitcoinSHA256=$(grep -i "${binaryName}}" SHA256SUMS | cut -d " " -f1)
|
||||
echo "# FAIL # Downloaded BITCOIN BINARY CHECKSUM:"
|
||||
echo "$(sha256sum ${binaryName})"
|
||||
echo "NOT matching SHA256 checksum:"
|
||||
echo "${bitcoinSHA256}"
|
||||
exit 1
|
||||
else
|
||||
echo
|
||||
echo "# OK --> VERIFIED BITCOIN CORE BINARY CHECKSUM IS CORRECT"
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
|
||||
# JOINED INSTALL
|
||||
if [ "${mode}" = "tested" ] || [ "${mode}" = "reckless" ] || [ "${mode}" = "custom" ]; then
|
||||
|
||||
# install
|
||||
echo "# Stopping bitcoind ..."
|
||||
sudo systemctl stop bitcoind 2>/dev/null
|
||||
sudo systemctl stop tbitcoind 2>/dev/null
|
||||
sudo systemctl stop sbitcoind 2>/dev/null
|
||||
echo
|
||||
echo "# Installing Bitcoin Core v${bitcoinVersion}"
|
||||
tar -xvf ${binaryName}
|
||||
sudo install -m 0755 -o root -g root -t /usr/local/bin/ bitcoin-${bitcoinVersion}/bin/*
|
||||
sleep 3
|
||||
if ! sudo /usr/local/bin/bitcoind --version | grep "${bitcoinVersion}"; then
|
||||
echo
|
||||
echo "# BUILD FAILED --> Was not able to install bitcoind version(${bitcoinVersion})"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# OK Bitcoin Core ${bitcoinVersion} is installed"
|
||||
exit 0
|
||||
|
||||
else
|
||||
echo "# error='parameter not known'"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -21,3 +21,7 @@ echo "***********************************************" >> $logFile
|
|||
|
||||
# make sure SSH server is configured & running
|
||||
sudo /home/joinmarket/standalone/ssh.sh checkrepair >> ${logFile}
|
||||
|
||||
# fix ownership of possibly migrated files
|
||||
sudo chown -R bitcoin:bitcoin /home/bitcoin/
|
||||
sudo chown -R joinmarket:joinmarket /home/joinmarket/
|
||||
|
|
|
|||
296
scripts/standalone/install.i2pd.sh
Normal file
296
scripts/standalone/install.i2pd.sh
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
#!/bin/bash
|
||||
|
||||
# https://i2pd.readthedocs.io
|
||||
|
||||
if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then
|
||||
echo "I2P Daemon install script"
|
||||
echo "More info at https://i2pd.readthedocs.io"
|
||||
echo "Usage:"
|
||||
echo "install.i2pd.sh install -> Install i2pd"
|
||||
echo "install.i2pd.sh on -> Switch on i2pd"
|
||||
echo "install.i2pd.sh off -> Uninstall i2pd"
|
||||
echo "install.i2pd.sh addseednodes -> Add 21 randonly selected I2P seed nodes from: https://github.com/bitcoin/bitcoin/blob/master/contrib/seeds/nodes_main.txt"
|
||||
echo "install.i2pd.sh status -> I2P related logs from bitcoind, bitcoin-cli -netinfo 4 and webconsole access"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function confAdd {
|
||||
# get parameters
|
||||
keystr="$1"
|
||||
valuestr=$(echo "$2" | sed 's/\//\\\//g')
|
||||
configFile="$3"
|
||||
|
||||
# check if key needs to be added (prepare new entry)
|
||||
entryExists=$(grep -c "^${keystr}=" ${configFile})
|
||||
if [ ${entryExists} -eq 0 ]; then
|
||||
echo "${keystr}=" | sudo tee -a ${configFile} 1>/dev/null
|
||||
fi
|
||||
|
||||
# add an extra key=value line (needs sudo to operate when user is not root)
|
||||
echo "${keystr}=${valuestr}" | sudo tee -a ${configFile}
|
||||
}
|
||||
|
||||
function add_repo {
|
||||
# Add repo for the latest version
|
||||
# i2pd — https://repo.i2pd.xyz/.help/readme.txt
|
||||
# https://repo.i2pd.xyz/.help/add_repo
|
||||
|
||||
source /etc/os-release
|
||||
DIST=$ID
|
||||
case $ID in
|
||||
debian | ubuntu | raspbian)
|
||||
if [[ -n $DEBIAN_CODENAME ]]; then
|
||||
VERSION_CODENAME=$DEBIAN_CODENAME
|
||||
fi
|
||||
if [[ -n $UBUNTU_CODENAME ]]; then
|
||||
VERSION_CODENAME=$UBUNTU_CODENAME
|
||||
fi
|
||||
if [[ -z $VERSION_CODENAME ]]; then
|
||||
echo "Couldn't find VERSION_CODENAME in your /etc/os-release file. Did your system supported? Please report issue to me by writing to email: 'r4sas <at> i2pd.xyz'"
|
||||
exit 1
|
||||
fi
|
||||
RELEASE=$VERSION_CODENAME
|
||||
;;
|
||||
*)
|
||||
if [[ -z $ID_LIKE || "$ID_LIKE" != "debian" && "$ID_LIKE" != "ubuntu" ]]; then
|
||||
echo "Your system is not supported by this script. Currently it supports debian-like and ubuntu-like systems."
|
||||
exit 1
|
||||
else
|
||||
DIST=$ID_LIKE
|
||||
case $ID_LIKE in
|
||||
debian)
|
||||
if [[ "$ID" == "kali" ]]; then
|
||||
if [[ "$VERSION" == "2019"* || "$VERSION" == "2020"* ]]; then
|
||||
RELEASE="buster"
|
||||
elif [[ "$VERSION" == "2021"* || "$VERSION" == "2022"* ]]; then
|
||||
RELEASE="bullseye"
|
||||
fi
|
||||
else
|
||||
RELEASE=$DEBIAN_CODENAME
|
||||
fi
|
||||
;;
|
||||
ubuntu)
|
||||
RELEASE=$UBUNTU_CODENAME
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [[ -z $RELEASE ]]; then
|
||||
echo "Couldn't detect your system release. Please report issue to me by writing to email: 'r4sas <at> i2pd.xyz'"
|
||||
exit 1
|
||||
fi
|
||||
echo "Importing signing key"
|
||||
wget -q -O - https://repo.i2pd.xyz/r4sas.gpg | sudo apt-key --keyring /etc/apt/trusted.gpg.d/i2pd.gpg add -
|
||||
echo "Adding APT repository"
|
||||
echo "deb https://repo.i2pd.xyz/$DIST $RELEASE main" | sudo tee /etc/apt/sources.list.d/i2pd.list
|
||||
echo "deb-src https://repo.i2pd.xyz/$DIST $RELEASE main" | sudo tee -a /etc/apt/sources.list.d/i2pd.list
|
||||
}
|
||||
|
||||
function bitcoinI2Pstatus {
|
||||
echo "# I2P related logs from the bitcoin debug log"
|
||||
echo "sudo tail -n 200 ${bitcoinLogPath} | grep i2p"
|
||||
echo
|
||||
sudo cat ${bitcoinLogPath} | grep i2p
|
||||
echo
|
||||
echo "# Running the command:"
|
||||
echo "sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -netinfo 4"
|
||||
echo
|
||||
sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -netinfo 4
|
||||
echo
|
||||
echo "# i2pd webconsole:"
|
||||
localip=$(hostname -I | awk '{print $1}')
|
||||
echo "http://${localip}:7070"
|
||||
echo "# Username: i2pd"
|
||||
echo "# Password: your passwordB"
|
||||
echo
|
||||
}
|
||||
|
||||
echo "# Running: 'install.i2pd.sh $*'"
|
||||
source /home/joinmarket/joinin.conf
|
||||
|
||||
bitcoinConfPath="/home/bitcoin/.bitcoin/bitcoin.conf"
|
||||
bitcoinLogPath="/home/bitcoin/.bitcoin/debug.log"
|
||||
|
||||
# make sure to be present in PATH
|
||||
if ! echo "$PATH" | grep "/usr/sbin" >/dev/null; then
|
||||
export PATH=$PATH:/usr/sbin
|
||||
echo "PATH=\$PATH:/usr/sbin" | sudo tee -a /etc/profile
|
||||
fi
|
||||
|
||||
if [ "$1" = "install" ]; then
|
||||
|
||||
isInstalled=$(sudo systemctl list-unit-files | grep -c i2pd)
|
||||
if [ "${isInstalled}" != "0" ]; then
|
||||
echo "# i2pd is already installed."
|
||||
else
|
||||
echo "# Installing i2pd ..."
|
||||
|
||||
add_repo
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y i2pd
|
||||
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
||||
|
||||
isInstalled=$(sudo systemctl list-unit-files | grep -c i2pd)
|
||||
if [ "${isInstalled}" != "0" ]; then
|
||||
echo "# i2pd is installed."
|
||||
else
|
||||
/home/joinmarket/standalone/install.i2pd.sh install
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet i2pd.service; then
|
||||
echo "# i2pd.service is already active."
|
||||
else
|
||||
echo "# sudo systemctl enable i2pd"
|
||||
sudo systemctl enable i2pd
|
||||
fi
|
||||
|
||||
echo "# i2pd config"
|
||||
/home/joinmarket/set.value.sh set debug tor ${bitcoinConfPath} noquotes
|
||||
confAdd debug i2p ${bitcoinConfPath}
|
||||
/home/joinmarket/set.value.sh set i2psam 127.0.0.1:7656 ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh set i2pacceptincoming 1 ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh set onlynet onion ${bitcoinConfPath} noquotes
|
||||
confAdd onlynet i2p ${bitcoinConfPath}
|
||||
PASSWORD_B=$(sudo cat ${bitcoinConfPath} | grep rpcpassword | cut -c 13-)
|
||||
cat <<EOF | sudo tee /etc/i2pd/i2pd.conf
|
||||
# i2pd settings for the Joininbox
|
||||
# for the defaults see:
|
||||
# https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf
|
||||
# Docs:
|
||||
# https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
|
||||
loglevel = none
|
||||
[http]
|
||||
address=0.0.0.0
|
||||
strictheaders = false
|
||||
port = 7070
|
||||
auth = true
|
||||
user = i2pd
|
||||
pass = ${PASSWORD_B}
|
||||
[httpproxy]
|
||||
enabled = false
|
||||
[socksproxy]
|
||||
enabled = false
|
||||
[sam]
|
||||
enabled = true
|
||||
[bob]
|
||||
enabled = false
|
||||
[i2cp]
|
||||
enabled = false
|
||||
[i2pcontrol]
|
||||
enabled = false
|
||||
[upnp]
|
||||
enabled = false
|
||||
EOF
|
||||
|
||||
sudo ufw allow 7070 comment "i2pd-webconsole"
|
||||
|
||||
echo "# Start i2pd ..."
|
||||
sudo systemctl start i2pd
|
||||
echo "# Restart bitcoind ..."
|
||||
sudo systemctl restart bitcoind 2>/dev/null
|
||||
sleep 10
|
||||
|
||||
if i2pd --version; then
|
||||
echo "# Installed i2pd"
|
||||
else
|
||||
echo "# i2pd is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# setting value in raspiblitz.conf
|
||||
/home/joinmarket/set.value.sh set i2pd "on"
|
||||
|
||||
localip=$(hostname -I | awk '{print $1}')
|
||||
echo "# Config: /etc/i2pd/i2pd.conf"
|
||||
echo "# i2pd web console: ${localip}:7070"
|
||||
echo "# Monitor i2p in bitcoind:"
|
||||
echo "sudo tail -n 100 ${bitcoinLogPath} | grep i2p"
|
||||
echo "sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -netinfo 4"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "addseednodes" ]; then
|
||||
|
||||
if ! sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -netinfo 4 | grep i2p; then
|
||||
echo "# i2pd is not running"
|
||||
/home/joinmarket/standalone/install.i2pd.sh on
|
||||
fi
|
||||
|
||||
echo "Add 21 randomly selected I2P seed nodes from: https://github.com/bitcoin/bitcoin/blob/master/contrib/seeds/nodes_main.txt"
|
||||
echo "Monitor in a new terminal with:"
|
||||
echo "watch sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -netinfo 4"
|
||||
echo "This will take some time ..."
|
||||
|
||||
# Fetch and filter the list of seed nodes
|
||||
i2pSeedNodeList=$(curl -sS https://raw.githubusercontent.com/bitcoin/bitcoin/master/contrib/seeds/nodes_main.txt | grep .b32.i2p:0)
|
||||
|
||||
# Shuffle the list and pick the first 21 nodes
|
||||
selectedNodes=$(echo "$i2pSeedNodeList" | shuf | head -n 21)
|
||||
|
||||
# Add each selected node
|
||||
for i2pSeedNode in ${selectedNodes}; do
|
||||
echo "# Add i2p seed node: ${i2pSeedNode} by running:"
|
||||
echo "bitcoin-cli addnode $i2pSeedNode onetry"
|
||||
sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli addnode "$i2pSeedNode" "onetry"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "# Display sudo tail -n 100 ${bitcoinLogPath} | grep i2p"
|
||||
sudo tail -n 100 ${bitcoinLogPath} | grep i2p
|
||||
echo
|
||||
echo "# Display bitcoin-cli -netinfo 4"
|
||||
sudo -u bitcoin /home/bitcoin/bitcoin/bitcoin-cli -netinfo 4
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# switch off
|
||||
if [ "$1" = "0" ] || [ "$1" = "off" ]; then
|
||||
|
||||
echo "# stop & remove systemd service"
|
||||
sudo systemctl stop i2pd 2>/dev/null
|
||||
sudo systemctl disable i2pd.service
|
||||
|
||||
echo "# Uninstall with apt"
|
||||
sudo apt remove -y i2pd
|
||||
|
||||
echo "# Remove settings from bitcoind"
|
||||
/home/joinmarket/set.value.sh delete debug ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh set debug tor ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh delete i2psam ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh delete i2pacceptincoming ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh delete onlynet ${bitcoinConfPath} noquotes
|
||||
/home/joinmarket/set.value.sh set onlynet onion ${bitcoinConfPath} noquotes
|
||||
|
||||
sudo rm /etc/systemd/system/i2pd.service
|
||||
|
||||
sudo ufw delete allow 7070
|
||||
|
||||
if ! i2pd --version 2>/dev/null; then
|
||||
echo "# OK - i2pd is not installed now"
|
||||
else
|
||||
echo "# i2pd is still installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# setting value in raspiblitz.conf
|
||||
/home/joinmarket/set.value.sh set i2pd "off"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "status" ]; then
|
||||
bitcoinI2Pstatus
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "# FAIL - Unknown Parameter $1"
|
||||
exit 1
|
||||
|
|
@ -149,7 +149,7 @@ if [ "$1" = "1" ] || [ "$1" = "on" ]; then
|
|||
|
||||
addUserStore
|
||||
|
||||
sudo adduser --disabled-password --gecos "" specter
|
||||
sudo adduser --system --group --home /home/specter specter
|
||||
|
||||
# store data with the store user
|
||||
sudo mkdir -p /home/store/app-data/.specter 2>/dev/null
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
source /home/joinmarket/_functions.sh
|
||||
|
||||
# add default value to config if needed
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import configparser
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
|
||||
def main(argv):
|
||||
|
||||
description = "\nBoltzmann - https://code.samourai.io/oxt/boltzmann/\n\
|
||||
A python script computing the entropy of Bitcoin transactions and the linkability of their inputs and outputs.\n\
|
||||
For a description of the metrics and related discussions:\n\
|
||||
Bitcoin Transactions & Privacy (part 1) : https://gist.github.com/LaurentMT/e758767ca4038ac40aaf\n\
|
||||
Bitcoin Transactions & Privacy (part 2) : https://gist.github.com/LaurentMT/d361bca6dc52868573a2\n\
|
||||
Bitcoin Transactions & Privacy (part 3) : https://gist.github.com/LaurentMT/e8644d5bc903f02613c6\n\
|
||||
\n\
|
||||
WARNING: this feature is highly experimental and not optimised to be used with JoinMarket."
|
||||
os.system('clear')
|
||||
print(description)
|
||||
|
||||
txids = ''
|
||||
try:
|
||||
opts, args = getopt.getopt(argv,"t:",["txids="])
|
||||
except getopt.GetoptError:
|
||||
print('python run.boltzmann.py --txids=TXID1,TXID2')
|
||||
sys.exit(2)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ('-t', '--txids'):
|
||||
txids = arg
|
||||
config = configparser.ConfigParser(strict=False)
|
||||
|
||||
config.read('/home/joinmarket/.joinmarket/joinmarket.cfg')
|
||||
|
||||
rpc_user = config['BLOCKCHAIN']['rpc_user']
|
||||
rpc_password = config['BLOCKCHAIN']['rpc_password']
|
||||
rpc_host = config['BLOCKCHAIN']['rpc_host']
|
||||
rpc_port = config['BLOCKCHAIN']['rpc_port']
|
||||
|
||||
tor = ''
|
||||
if rpc_host.find('.onion') >= 0:
|
||||
print('# Connecting to bitcoind RPC over Tor')
|
||||
tor = 'torsocks'
|
||||
|
||||
boltzmannpath = "/home/joinmarket/boltzmann/"
|
||||
|
||||
bvenv = ". "+boltzmannpath+"bvenv/bin/activate"
|
||||
|
||||
boltzmann = tor+" python "+boltzmannpath+"boltzmann/ludwig.py -p -x 30 \
|
||||
--txids="+txids
|
||||
|
||||
run = bvenv+";"+"export BOLTZMANN_RPC_USERNAME="+rpc_user+";\
|
||||
export BOLTZMANN_RPC_PASSWORD="+rpc_password+";\
|
||||
export BOLTZMANN_RPC_HOST="+rpc_host+";\
|
||||
export BOLTZMANN_RPC_PORT="+rpc_port+";"+boltzmann+" 2>/dev/null"
|
||||
|
||||
print('# Exporting RPC connection details')
|
||||
print('# Running the command:\n'+boltzmann+'\n')
|
||||
os.system(run)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
echo "# starting JoininBox ..."
|
||||
|
||||
if [ ! -f /home/joinmarket/joinin.conf ];then
|
||||
if [ ! -f /home/joinmarket/joinin.conf ]; then
|
||||
touch /home/joinmarket/joinin.conf
|
||||
fi
|
||||
|
||||
|
|
@ -12,45 +12,44 @@ source /home/joinmarket/_functions.sh
|
|||
# FIRST RUN #
|
||||
#############
|
||||
|
||||
setupStepEntry=$(grep -c "setupStep" < $joininConfPath)
|
||||
if [ "$setupStepEntry" -eq 0 ];then
|
||||
echo "setupStep=0" >> $joininConfPath
|
||||
setupStepEntry=$(grep -c "setupStep" <$joininConfPath)
|
||||
if [ "$setupStepEntry" -eq 0 ]; then
|
||||
echo "setupStep=0" >>$joininConfPath
|
||||
fi
|
||||
|
||||
source /home/joinmarket/joinin.conf
|
||||
if [ "$setupStep" -lt 100 ];then
|
||||
if [ "$setupStep" -lt 5 ];then
|
||||
if [ "$setupStep" -lt 100 ]; then
|
||||
if [ "$setupStep" -lt 5 ]; then
|
||||
# identify running env
|
||||
runningEnvEntry=$(grep -c "runningEnv" < $joininConfPath)
|
||||
if [ "$runningEnvEntry" -eq 0 ];then
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ];then
|
||||
runningEnvEntry=$(grep -c "runningEnv" <$joininConfPath)
|
||||
if [ "$runningEnvEntry" -eq 0 ]; then
|
||||
if [ -f "/mnt/hdd/raspiblitz.conf" ] || [ -f "/mnt/hdd/app-data/raspiblitz.conf" ] ; then
|
||||
runningEnv="raspiblitz"
|
||||
elif [ -f "/usr/share/mynode/mynode_config.sh" ];then
|
||||
elif [ -f "/usr/share/mynode/mynode_config.sh" ]; then
|
||||
runningEnv="mynode"
|
||||
else
|
||||
runningEnv="standalone"
|
||||
fi
|
||||
echo "runningEnv=$runningEnv" >> $joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=1#g" $joininConfPath
|
||||
echo "runningEnv=$runningEnv" >>$joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=1#g" $joininConfPath
|
||||
fi
|
||||
echo "# running in the environment: $runningEnv"
|
||||
|
||||
# identify cpu architecture
|
||||
cpuEntry=$(grep -c "cpu" < $joininConfPath)
|
||||
if [ "$cpuEntry" -eq 0 ];then
|
||||
cpuEntry=$(grep -c "cpu" <$joininConfPath)
|
||||
if [ "$cpuEntry" -eq 0 ]; then
|
||||
cpu=$(uname -m)
|
||||
echo "cpu=$cpu" >> $joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=2#g" $joininConfPath
|
||||
echo "cpu=$cpu" >>$joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=2#g" $joininConfPath
|
||||
fi
|
||||
echo "# cpu=${cpu}"
|
||||
|
||||
# check Tor
|
||||
torEntry=$(grep -c "runBehindTor" < $joininConfPath)
|
||||
if [ "$torEntry" -eq 0 ];then
|
||||
torEntry=$(grep -c "runBehindTor" <$joininConfPath)
|
||||
if [ "$torEntry" -eq 0 ]; then
|
||||
torTest=$(curl --socks5 localhost:9050 --socks5-hostname localhost:9050 -s \
|
||||
https://check.torproject.org/ | cat | grep -m 1 Congratulations | xargs)
|
||||
if [ "$torTest" = "Congratulations. This browser is configured to use Tor." ]
|
||||
then
|
||||
https://check.torproject.org/ | cat | grep -m 1 Congratulations | xargs)
|
||||
if [ "$torTest" = "Congratulations. This browser is configured to use Tor." ]; then
|
||||
runBehindTor=on
|
||||
else
|
||||
runBehindTor=off
|
||||
|
|
@ -59,65 +58,65 @@ if [ "$setupStep" -lt 100 ];then
|
|||
echo "# Press ENTER to continue without Tor or CTRL+C to cancel and try checking again with 'menu'"
|
||||
read key
|
||||
fi
|
||||
echo "runBehindTor=$runBehindTor" >> $joininConfPath
|
||||
echo "runBehindTor=$runBehindTor" >>$joininConfPath
|
||||
echo "# runBehindTor=$runBehindTor"
|
||||
fi
|
||||
|
||||
# make sure Tor path is known
|
||||
DirEntry=$(grep -c "HiddenServiceDir" < $joininConfPath)
|
||||
if [ "$DirEntry" -eq 0 ];then
|
||||
if [ -d "/mnt/hdd/tor" ];then
|
||||
DirEntry=$(grep -c "HiddenServiceDir" <$joininConfPath)
|
||||
if [ "$DirEntry" -eq 0 ]; then
|
||||
if [ -d "/mnt/hdd/tor" ]; then
|
||||
HiddenServiceDir="/mnt/hdd/tor"
|
||||
else
|
||||
HiddenServiceDir="/var/lib/tor"
|
||||
fi
|
||||
echo "HiddenServiceDir=$HiddenServiceDir" >> $joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=3#g" $joininConfPath
|
||||
echo "HiddenServiceDir=$HiddenServiceDir" >>$joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=3#g" $joininConfPath
|
||||
fi
|
||||
|
||||
# check for dialog
|
||||
if [ "$(dialog | grep -c "ComeOn Dialog!")" -eq 0 ];then
|
||||
if [ "$(dialog | grep -c "ComeOn Dialog!")" -eq 0 ]; then
|
||||
sudo apt-get install -y dialog
|
||||
fi
|
||||
# check for qrencode
|
||||
if [ "$(qrencode -V 2>&1 | grep -c "not found")" -gt 0 ];then
|
||||
if [ "$(qrencode -V 2>&1 | grep -c "not found")" -gt 0 ]; then
|
||||
sudo apt-get install -y qrencode
|
||||
fi
|
||||
sed -i "s#setupStep=.*#setupStep=4#g" $joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=4#g" $joininConfPath
|
||||
|
||||
# check if JoinMarket is installed
|
||||
if [ "${runningEnv}" = raspiblitz ] && [ "$(lsb_release -sc)" = bullseye ]; then
|
||||
# no qtgui for raspibliz on bullseye
|
||||
/home/joinmarket/install.joinmarket.sh -i install -q 0
|
||||
else
|
||||
if [ "${cpu}" = x86_64 ]; then
|
||||
/home/joinmarket/install.joinmarket.sh -i install
|
||||
else
|
||||
# no qtgui on arm
|
||||
/home/joinmarket/install.joinmarket.sh -i install -q 0
|
||||
fi
|
||||
sed -i "s#setupStep=.*#setupStep=5#g" $joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=5#g" $joininConfPath
|
||||
fi
|
||||
# change the ssh password if standalone
|
||||
if [ "$runningEnv" = "standalone" ];then
|
||||
if [ "$runningEnv" = "standalone" ]; then
|
||||
source /home/joinmarket/joinin.conf
|
||||
if [ "$setupStep" -lt 6 ];then
|
||||
if [ "$setupStep" -lt 6 ]; then
|
||||
# set ssh passwords on the first run
|
||||
sudo /home/joinmarket/set.password.sh
|
||||
sed -i "s#setupStep=.*#setupStep=6#g" $joininConfPath
|
||||
sed -i "s#setupStep=.*#setupStep=6#g" $joininConfPath
|
||||
fi
|
||||
source /home/joinmarket/joinin.conf
|
||||
if [ "$setupStep" -lt 7 ]&&[ ${cpu} != "x86_64" ];then
|
||||
if [ "$setupStep" -lt 7 ] && [ ${cpu} != "x86_64" ]; then
|
||||
# expand SDcard partition on ARM
|
||||
sudo /home/joinmarket/standalone/expand.rootfs.sh
|
||||
fi
|
||||
fi
|
||||
generateJMconfig
|
||||
sudo sed -i "s#setupStep=.*#setupStep=10#g" $joininConfPath
|
||||
sudo sed -i "s#setupStep=.*#setupStep=10#g" $joininConfPath
|
||||
source /home/joinmarket/joinin.conf
|
||||
if [ "$setupStep" -lt 11 ];then
|
||||
if [ "$runningEnv" = "standalone" ];then
|
||||
if [ "$setupStep" -lt 11 ]; then
|
||||
if [ "$runningEnv" = "standalone" ]; then
|
||||
# open the config menu if standalone
|
||||
/home/joinmarket/menu.config.sh
|
||||
else
|
||||
# setup finished
|
||||
sudo sed -i "s#setupStep=.*#setupStep=100#g" $joininConfPath
|
||||
sudo sed -i "s#setupStep=.*#setupStep=100#g" $joininConfPath
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
@ -128,11 +127,11 @@ fi
|
|||
|
||||
# check bitcoind RPC setting
|
||||
# add default value to joinin config if needed
|
||||
if ! grep -Eq "^RPCoverTor=" $joininConfPath;then
|
||||
echo "RPCoverTor=off" >> $joininConfPath
|
||||
if ! grep -Eq "^RPCoverTor=" $joininConfPath; then
|
||||
echo "RPCoverTor=off" >>$joininConfPath
|
||||
fi
|
||||
# check if bitcoin RPC connection is over Tor
|
||||
if grep -Eq "^rpc_host = .*.onion" $JMcfgPath;then
|
||||
if grep -Eq "^rpc_host = .*.onion" $JMcfgPath; then
|
||||
echo "# RPC over Tor is on"
|
||||
sed -i "s/^RPCoverTor=.*/RPCoverTor=on/g" $joininConfPath
|
||||
else
|
||||
|
|
@ -142,14 +141,14 @@ fi
|
|||
|
||||
# check if there is only one joinmarket wallet and make default
|
||||
# add default value to joinin config if needed
|
||||
if ! grep -Eq "^defaultWallet=" $joininConfPath;then
|
||||
echo "defaultWallet=off" >> $joininConfPath
|
||||
if ! grep -Eq "^defaultWallet=" $joininConfPath; then
|
||||
echo "defaultWallet=off" >>$joininConfPath
|
||||
fi
|
||||
if [ "$(ls -p /home/joinmarket/.joinmarket/wallets/ | grep -cv /)" -gt 1 ];then
|
||||
if [ "$(ls -p /home/joinmarket/.joinmarket/wallets/ | grep -cv /)" -gt 1 ]; then
|
||||
echo "# Found more than one wallet file"
|
||||
echo "# Setting defaultWallet to off"
|
||||
sed -i "s#^defaultWallet=.*#defaultWallet=off#g" $joininConfPath
|
||||
elif [ "$(ls -p /home/joinmarket/.joinmarket/wallets/ | grep -cv /)" -eq 1 ];then
|
||||
elif [ "$(ls -p /home/joinmarket/.joinmarket/wallets/ | grep -cv /)" -eq 1 ]; then
|
||||
onlyWallet=$(ls -p /home/joinmarket/.joinmarket/wallets/ | grep -v /)
|
||||
echo "# Found only one wallet file: $onlyWallet"
|
||||
echo "# Using it as default"
|
||||
|
|
@ -157,28 +156,28 @@ elif [ "$(ls -p /home/joinmarket/.joinmarket/wallets/ | grep -cv /)" -eq 1 ];the
|
|||
fi
|
||||
|
||||
# add default value to joinin config if needed
|
||||
if ! grep -Eq "^network=" $joininConfPath;then
|
||||
echo "network=unknown" >> $joininConfPath
|
||||
if ! grep -Eq "^network=" $joininConfPath; then
|
||||
echo "network=unknown" >>$joininConfPath
|
||||
fi
|
||||
isMainnet=$(grep -c "network = mainnet" < $JMcfgPath)
|
||||
isSignet=$(grep -c "network = signet" < $JMcfgPath)
|
||||
isTestnet=$(grep -c "network = testnet" < $JMcfgPath)
|
||||
if [ $isMainnet -gt 0 ];then
|
||||
isMainnet=$(grep -c "network = mainnet" <$JMcfgPath)
|
||||
isSignet=$(grep -c "network = signet" <$JMcfgPath)
|
||||
isTestnet=$(grep -c "network = testnet" <$JMcfgPath)
|
||||
if [ $isMainnet -gt 0 ]; then
|
||||
sed -i "s#^network=.*#network=mainnet#g" $joininConfPath
|
||||
elif [ $isSignet -gt 0 ];then
|
||||
elif [ $isSignet -gt 0 ]; then
|
||||
sed -i "s#^network=.*#network=signet#g" $joininConfPath
|
||||
elif [ $isTestnet -gt 0 ];then
|
||||
elif [ $isTestnet -gt 0 ]; then
|
||||
sed -i "s#^network=.*#network=testnet#g" $joininConfPath
|
||||
else
|
||||
sed -i "s#^network=.*#network=unknown#g" $joininConfPath
|
||||
fi
|
||||
|
||||
# add default value to joinin config if needed
|
||||
if ! grep -Eq "^localip=" $joininConfPath;then
|
||||
echo "localip=unknown" >> $joininConfPath
|
||||
if ! grep -Eq "^localip=" $joininConfPath; then
|
||||
echo "localip=unknown" >>$joininConfPath
|
||||
fi
|
||||
localip=$(hostname -I | awk '{print $1}')
|
||||
sed -i "s#^localip=.*#localip=$localip#g" $joininConfPath
|
||||
|
||||
# change the onion_serving_port if LND is present (avoid collusion with LND REST port)
|
||||
# change the onion_serving_port if LND is present (avoid collision with LND REST port)
|
||||
sed -i "s#^onion_serving_port = 8080#onion_serving_port = 8090#g" $JMcfgPath
|
||||
|
|
|
|||
|
|
@ -43,6 +43,18 @@ Type=simple
|
|||
TimeoutSec=infinity
|
||||
Restart=no
|
||||
|
||||
# Memory limits (DoS / OOM protection)
|
||||
MemoryHigh=300M
|
||||
MemoryMax=512M
|
||||
MemorySwapMax=0
|
||||
|
||||
# Reduce OOM kill priority (lower = less likely to be killed)
|
||||
OOMScoreAdjust=-500
|
||||
OOMPolicy=stop
|
||||
|
||||
# CPU limit
|
||||
CPUQuota=80%
|
||||
|
||||
# Hardening measures
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ fi
|
|||
# Example for commits created on GitHub:
|
||||
# PGPsigner="web-flow"
|
||||
# PGPpubkeyLink="https://github.com/${PGPsigner}.gpg"
|
||||
# PGPpubkeyFingerprint="4AEE18F83AFDEB23"
|
||||
# PGPpubkeyFingerprint="B5690EEEBB952194"
|
||||
|
||||
# Example for commits signed with a personal PGP key:
|
||||
# PGPsigner="janoside"
|
||||
|
|
@ -30,9 +30,18 @@ PGPsigner="$1"
|
|||
PGPpubkeyLink="$2"
|
||||
PGPpubkeyFingerprint="$3"
|
||||
|
||||
wget -O /dev/shm/pgp_keys_${PGPsigner}.asc "${PGPpubkeyLink}"
|
||||
gpg --import --import-options show-only /dev/shm/pgp_keys_${PGPsigner}.asc
|
||||
fingerprint=$(gpg --show-keys /dev/shm/pgp_keys_${PGPsigner}.asc 2>/dev/null | grep "${PGPpubkeyFingerprint}" -c)
|
||||
_temp_dir="$(mktemp -d -p /dev/shm/ 2>/dev/null || mktemp -d)"
|
||||
trap 'rm -rf "$_temp_dir"' EXIT
|
||||
|
||||
keyFile="${_temp_dir}/pgp_keys_${PGPsigner}.asc"
|
||||
rawKeyFile="${keyFile}.raw"
|
||||
|
||||
wget --prefer-family=ipv4 -O "${rawKeyFile}" "${PGPpubkeyLink}"
|
||||
# GitHub can add a Note: armor header when an account key cannot be exported.
|
||||
# GPG imports the key anyway, but prints a misleading "unknown armor header".
|
||||
grep -v '^Note: ' "${rawKeyFile}" >"${keyFile}"
|
||||
gpg --quiet --import --import-options show-only "${keyFile}"
|
||||
fingerprint=$(gpg --show-keys --with-subkey-fingerprint "${keyFile}" 2>/dev/null | tr -d " \t\n\r" | grep "${PGPpubkeyFingerprint}" -c)
|
||||
if [ "${fingerprint}" -lt 1 ]; then
|
||||
echo
|
||||
echo "# WARNING --> the PGP fingerprint is not as expected for ${PGPsigner}" >&2
|
||||
|
|
@ -40,11 +49,9 @@ if [ "${fingerprint}" -lt 1 ]; then
|
|||
echo "# Exiting" >&2
|
||||
exit 7
|
||||
fi
|
||||
gpg --import /dev/shm/pgp_keys_${PGPsigner}.asc
|
||||
rm /dev/shm/pgp_keys_${PGPsigner}.asc
|
||||
gpg --quiet --import "${keyFile}"
|
||||
|
||||
trap 'rm -f "$_temp"' EXIT
|
||||
_temp="$(mktemp -p /dev/shm/)"
|
||||
_temp="${_temp_dir}/git-verify.out"
|
||||
|
||||
if [ $# -eq 3 ] || [ -z "$4" ]; then
|
||||
commitHash="$(git log --oneline | head -1 | awk '{print $1}')"
|
||||
|
|
|
|||
34
test/README.md
Normal file
34
test/README.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# JoininBox integration tests
|
||||
|
||||
Run the local Bats suite with:
|
||||
|
||||
```bash
|
||||
test/run-bats-local.sh
|
||||
```
|
||||
|
||||
The descriptor wallet tests require:
|
||||
|
||||
- `bats`
|
||||
- `bitcoind`
|
||||
- `bitcoin-cli`
|
||||
- `curl`
|
||||
- `jq`
|
||||
|
||||
The suite starts its own temporary `bitcoind -regtest` datadir and does not use
|
||||
mainnet, signet, or any existing Bitcoin Core state.
|
||||
|
||||
The `amd64-image-test` workflow downloads a previously built
|
||||
`joininbox-amd64-image-*` artifact, verifies the compressed and raw checksums,
|
||||
decompresses a runner-local qcow2 copy, boots it with QEMU in snapshot mode,
|
||||
copies a pinned `bats-core` checkout into that temporary VM session, and runs
|
||||
the same suite from the JoininBox checkout inside the image. This avoids
|
||||
depending on the guest's configured APT repositories just to install test
|
||||
tooling.
|
||||
|
||||
The test workflow has two entry points:
|
||||
|
||||
- `workflow_run`: runs after a successful `amd64-image-build` once this workflow
|
||||
exists on the repository default branch.
|
||||
- `workflow_dispatch`: reruns against a specific build artifact by providing the
|
||||
`amd64-image-build` workflow run ID, as long as the artifact is still retained
|
||||
by GitHub Actions.
|
||||
214
test/bats/descriptor-wallet.bats
Normal file
214
test/bats/descriptor-wallet.bats
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
#!/usr/bin/env bats
|
||||
|
||||
root_dir="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)"
|
||||
PATH="/home/joinmarket/bitcoin:/usr/local/bin:$PATH"
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
skip "$1 is required"
|
||||
fi
|
||||
}
|
||||
|
||||
setup() {
|
||||
require_command bitcoind
|
||||
require_command bitcoin-cli
|
||||
require_command curl
|
||||
require_command jq
|
||||
|
||||
rpc_user="joininbox"
|
||||
rpc_pass="joininbox"
|
||||
rpc_port="$((20000 + (RANDOM % 20000)))"
|
||||
p2p_port="$((40000 + (RANDOM % 20000)))"
|
||||
bitcoin_datadir="${BATS_TEST_TMPDIR}/bitcoin"
|
||||
joinmarket_cfg="${BATS_TEST_TMPDIR}/joinmarket.cfg"
|
||||
joinin_conf="${BATS_TEST_TMPDIR}/joinin.conf"
|
||||
|
||||
mkdir -p "$bitcoin_datadir"
|
||||
|
||||
bitcoind \
|
||||
-regtest \
|
||||
-datadir="$bitcoin_datadir" \
|
||||
-server \
|
||||
-daemonwait \
|
||||
-rpcuser="$rpc_user" \
|
||||
-rpcpassword="$rpc_pass" \
|
||||
-rpcport="$rpc_port" \
|
||||
-port="$p2p_port" \
|
||||
-fallbackfee=0.0001
|
||||
|
||||
cat >"$joinmarket_cfg" <<EOF
|
||||
rpc_user = $rpc_user
|
||||
rpc_password = $rpc_pass
|
||||
rpc_host = 127.0.0.1
|
||||
rpc_port = $rpc_port
|
||||
rpc_wallet_file = watch-only-descriptor-wallet
|
||||
EOF
|
||||
: >"$joinin_conf"
|
||||
}
|
||||
|
||||
teardown() {
|
||||
if [ -n "${bitcoin_datadir:-}" ] && [ -d "$bitcoin_datadir" ]; then
|
||||
bitcoin-cli \
|
||||
-regtest \
|
||||
-datadir="$bitcoin_datadir" \
|
||||
-rpcuser="$rpc_user" \
|
||||
-rpcpassword="$rpc_pass" \
|
||||
-rpcport="$rpc_port" \
|
||||
stop >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
load_joininbox_bitcoin_functions() {
|
||||
# shellcheck source=scripts/_functions.bitcoincore.sh
|
||||
# shellcheck disable=SC1091
|
||||
source "$root_dir/scripts/_functions.bitcoincore.sh"
|
||||
# shellcheck disable=SC2034
|
||||
JMcfgPath="$joinmarket_cfg"
|
||||
# shellcheck disable=SC2034
|
||||
joininConfPath="$joinin_conf"
|
||||
|
||||
mktemp() {
|
||||
if [ "${1:-}" = "-p" ] && [ "${2:-}" = "/dev/shm/" ]; then
|
||||
command mktemp "${BATS_TEST_TMPDIR}/joininbox.XXXXXX"
|
||||
else
|
||||
command mktemp "$@"
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
wallet_info() {
|
||||
bitcoin-cli \
|
||||
-regtest \
|
||||
-datadir="$bitcoin_datadir" \
|
||||
-rpcuser="$rpc_user" \
|
||||
-rpcpassword="$rpc_pass" \
|
||||
-rpcport="$rpc_port" \
|
||||
-rpcwallet=watch-only-descriptor-wallet \
|
||||
getwalletinfo
|
||||
}
|
||||
|
||||
check_wallet_migration_with_enter() {
|
||||
printf "\n" | checkWalletMigration
|
||||
}
|
||||
|
||||
check_rpc_wallet_with_enter() {
|
||||
printf "\n" | checkRPCwallet
|
||||
}
|
||||
|
||||
@test "checkRPCwallet creates the configured descriptor watch-only wallet" {
|
||||
load_joininbox_bitcoin_functions
|
||||
|
||||
run checkRPCwallet
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"The wallet: watch-only-descriptor-wallet is present and loaded"* ]]
|
||||
|
||||
run wallet_info
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(jq -r '.descriptors' <<<"$output")" = "true" ]
|
||||
[ "$(jq -r '.private_keys_enabled' <<<"$output")" = "false" ]
|
||||
run grep -q "walletMigrationDone" "$joinin_conf"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "customRPC uses the descriptor wallet RPC endpoint" {
|
||||
bitcoin-cli \
|
||||
-regtest \
|
||||
-datadir="$bitcoin_datadir" \
|
||||
-rpcuser="$rpc_user" \
|
||||
-rpcpassword="$rpc_pass" \
|
||||
-rpcport="$rpc_port" \
|
||||
-named createwallet \
|
||||
wallet_name=watch-only-descriptor-wallet \
|
||||
descriptors=true \
|
||||
disable_private_keys=true >/dev/null
|
||||
|
||||
load_joininbox_bitcoin_functions
|
||||
|
||||
run customRPC "# Wallet info" "getwalletinfo" ""
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *'"walletname": "watch-only-descriptor-wallet"'* ]]
|
||||
[[ "$output" == *'"descriptors": true'* ]]
|
||||
[[ "$output" == *'"private_keys_enabled": false'* ]]
|
||||
}
|
||||
|
||||
@test "checkRPCwallet migrates a persisted wallet.dat configuration on Bitcoin Core v30 or later" {
|
||||
bitcoin-cli \
|
||||
-regtest \
|
||||
-datadir="$bitcoin_datadir" \
|
||||
-rpcuser="$rpc_user" \
|
||||
-rpcpassword="$rpc_pass" \
|
||||
-rpcport="$rpc_port" \
|
||||
-named createwallet \
|
||||
wallet_name=wallet.dat \
|
||||
descriptors=true \
|
||||
disable_private_keys=true >/dev/null
|
||||
sed \
|
||||
"s/^rpc_wallet_file =.*/rpc_wallet_file = wallet.dat/" \
|
||||
"$joinmarket_cfg" >"${joinmarket_cfg}.legacy"
|
||||
mv "${joinmarket_cfg}.legacy" "$joinmarket_cfg"
|
||||
|
||||
load_joininbox_bitcoin_functions
|
||||
|
||||
run check_rpc_wallet_with_enter
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Migrating the configured Bitcoin Core wallet"* ]]
|
||||
[[ "$output" == *"WALLET MIGRATION NOTICE"* ]]
|
||||
grep -q "^rpc_wallet_file = watch-only-descriptor-wallet$" "$joinmarket_cfg"
|
||||
grep -q "^walletMigrationDone=true$" "$joinin_conf"
|
||||
|
||||
run wallet_info
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(jq -r '.descriptors' <<<"$output")" = "true" ]
|
||||
[ "$(jq -r '.private_keys_enabled' <<<"$output")" = "false" ]
|
||||
}
|
||||
|
||||
@test "migrateLegacyRPCWalletConfig keeps wallet.dat on Bitcoin Core v29.2" {
|
||||
sed \
|
||||
"s/^rpc_wallet_file =.*/rpc_wallet_file = wallet.dat/" \
|
||||
"$joinmarket_cfg" >"${joinmarket_cfg}.legacy"
|
||||
mv "${joinmarket_cfg}.legacy" "$joinmarket_cfg"
|
||||
|
||||
load_joininbox_bitcoin_functions
|
||||
getConnectedBitcoinCoreVersion() {
|
||||
echo 290200
|
||||
}
|
||||
getRPC >/dev/null
|
||||
|
||||
run migrateLegacyRPCWalletConfig
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"v29.x or earlier; keeping wallet.dat"* ]]
|
||||
grep -q "^rpc_wallet_file = wallet.dat$" "$joinmarket_cfg"
|
||||
}
|
||||
|
||||
@test "checkWalletMigration shows the notice once when wallet.dat exists" {
|
||||
bitcoin-cli \
|
||||
-regtest \
|
||||
-datadir="$bitcoin_datadir" \
|
||||
-rpcuser="$rpc_user" \
|
||||
-rpcpassword="$rpc_pass" \
|
||||
-rpcport="$rpc_port" \
|
||||
-named createwallet \
|
||||
wallet_name=wallet.dat \
|
||||
descriptors=true \
|
||||
disable_private_keys=true >/dev/null
|
||||
|
||||
load_joininbox_bitcoin_functions
|
||||
# shellcheck disable=SC2034
|
||||
rpc_host="127.0.0.1"
|
||||
# shellcheck disable=SC2034
|
||||
rpc_wallet="watch-only-descriptor-wallet"
|
||||
|
||||
run check_wallet_migration_with_enter
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"WALLET MIGRATION NOTICE"* ]]
|
||||
grep -q "^walletMigrationDone=true$" "$joinin_conf"
|
||||
|
||||
run checkWalletMigration
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" = "" ]
|
||||
}
|
||||
11
test/run-bats-local.sh
Executable file
11
test/run-bats-local.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
if ! command -v bats >/dev/null 2>&1; then
|
||||
echo "bats is required. Install bats-core, then rerun this script." >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
bats test/bats
|
||||
11
typos.toml
Normal file
11
typos.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
# source "$HOME/.cargo/env"
|
||||
# cargo install typos-cli
|
||||
# typos -c typos.toml
|
||||
# typos -c typos.toml -w
|
||||
|
||||
[default.extend-words]
|
||||
# don't correct these false positives
|
||||
ba = "ba"
|
||||
ned = "ned"
|
||||
fpr = "fpr"
|
||||
Loading…
Add table
Add a link
Reference in a new issue