#!/bin/sh # Download, verify and assemble source code for the Bitcoin reference implementation maintained by JWRD Computing. # Jacob Welsh, Nov 2021 set -e PATCHES_BASE=http://fixpoint.welshcomputing.com/v DEPS_BASE=http://fixpoint.welshcomputing.com/code/trb info() { printf '%s\n' "$1"; } err() { printf '%s\n' "$1" >&2; } cmd_exists() { command -v "$1" >/dev/null; } require_cmd() { if ! cmd_exists "$1" ; then err "Required command '$1' not found." exit 1 fi } preflight_check() { # Check for nonstandard dependencies require_cmd wget require_cmd gpg require_cmd sha512sum HAVE_KEKSUM=1 if ! cmd_exists keksum ; then err "WARNING: 'keksum' command not found. Patch output hashes will not be verified." HAVE_KEKSUM=0 fi } fail() { err "$1" err "See $LOG for detail." exit 1 } get() { # Ensure we have a file by downloading as necessary, preventing incomplete downloads. get_filename=`basename "$1"` if [ -e "$get_filename" ] ; then return 0 fi info "Fetching $get_filename ..." printf '\nFetching %s\n' "$1" >>"$LOG" if ! wget -O "$TMP/download" "$1" >>"$LOG" 2>&1 ; then rm -f "$TMP/download" fail "Failed." fi mv -- "$TMP/download" "$get_filename" } get_patches_verify() { # Fetch and verify patches and seals. mkdir -p patches ( cd patches while read subdir basename signer ; do vp="$basename.vpatch" # If downloading from a one-level tree you could remove the $subdir here. get "$PATCHES_BASE/$subdir/$vp" # And if seals are in separate subdirs, adjust here. get "$PATCHES_BASE/$subdir/$vp.$signer.sig" gpg --verify "$vp.$signer.sig" "$vp" 2>>"$LOG" || fail "Signature verification failed for $vp !" done <"$TMP/press_path" ) } get_deps() { # Fetch required depwads (non-V-ingested dependency tarballs). mkdir -p deps ( cd deps get "$DEPS_BASE/boost_1_52_0.tar.bz2" get "$DEPS_BASE/db-4.8.30.tar.gz" get "$DEPS_BASE/openssl-1.0.1g.tar.gz" ) } extract_hashes() { # Extract a listing of file path (omitting leading a/ or b/) and hash from each output header in a vpatch on stdin. awk ' /^diff/ { in_header = 1; next; } in_header && /^\+\+\+/ { in_header = 0; sub(/^[^\/]*\//, "", $2); print $2, $3; } ' } verify_hashes() { # Verify output hashes from a vpatch on stdin, with paths relative to the working directory. extract_hashes | while read path hash ; do if [ "$hash" = "false" ] ; then [ ! -e "$path" ] || fail "Patch failed to remove empty file $path !" elif [ $HAVE_KEKSUM -eq 1 ] ; then [ "`keksum -s256 -l512 <"$path"`" = "$hash" ] || fail "Hash verification failed on $path !" fi done } press() { # Apply trusted patches in the prescribed sequence into a given subdir, verifying their output file hashes, then link depwads into place and verify them against checksums in the newly pressed V-tree. info 'Pressing...' if [ -e "$1" ] ; then err "Press directory $TOP/$1 already exists! You must move or delete it to proceed." exit 1 fi mkdir "$1" ( cd "$1" while read subdir basename signer ; do vp="$basename.vpatch" printf '\nApplying %s\n' "$vp" >>"$LOG" patch -E -p1 <"../patches/$vp" >>"$LOG" 2>&1 || fail "Failed to apply $vp !" verify_hashes <"../patches/$vp" done <"$TMP/press_path" cd bitcoin/deps ln "$TOP"/deps/*.tar.* . if ! sha512sum -c Manifest.sha512 >/dev/null; then rm -f *.tar.* err "Depwad verification failed!" err "Your downloaded tar files may be corrupt. Try removing them from $TOP/deps/ to re-download." exit 1 fi ) info "Successfully pressed to $TOP/$1 !" info "To build bitcoin or keksum, enter the respective subdirectory and run 'make'." info "(For faster results try 'make -jN' where N is the max concurrent job count.)" info "For gbw-node, gbw-signer, or gscm, see the README in the respective subdir." } # Establish the top-level working directory. case "$1" in ''|-*) err "You must specify a top-level directory for the build environment. It will be created if necessary." err "Example:" err " sh $0 ~/src/bitcoin" exit 1 ;; esac mkdir -p "$1" cd "$1" TOP=`pwd` # absolute so it's usable from anywhere preflight_check # Set up temporary data tree, purging any left over from prior runs. TMP="$TOP/fetch-bitcoind.tmp" rm -rf "$TMP" mkdir "$TMP" LOG="$TMP/debug.log" export GNUPGHOME="$TMP/gpgdata" mkdir -m 700 "$GNUPGHOME" # Load patch signer keys: jfw, jfw_unchecked gpg --import 2>>"$LOG" <<. -----BEGIN PGP PUBLIC KEY BLOCK----- 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 9QMd/Rt5H3gtxri5J/zQJlzYCvkKng== =4dAK -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBF59eScBEADHOi3Vt/gfq1TB4abvn7jxx0SRxINURjYWqoGJ8K16F9MoBC18 H9N+x1PMDzaGBghaFz1ERcgbGrFsA9LdZUSzJK6JtCjaI7P+XkX0CH+6Y+wRpNKk lObYvi6zanYSd4+JmqTkvRpTJavDjFKxL2xhixiwa2cTxAZVMFngIP5iZD+KulJg WOyBnwZ0OUeA24qXMy8ovBM6NsDzGPW/6bE6GxaHY/FT2vbmIPdI9RqeI2WxYuHm OcmFhaSnPuf8fAInJJc1Y/bc8rv//BfcWoDy60sDjkKgxfrden03FVRnTPBrNDcj P72BL/3hYan9xjx3hSkrOjX/JVPgnvxKgc/3YNk7MUMyBoRij397chJup9bbcGWU 4MopCDOpB504bzA4jwDEIMQxv8iBEF0lhv3/7Wc7jZzQ7Xyfeid9UVCQVdWyOil2 QmhGSa7sOcKCjR/qeHJIqbDeSAhIQTx057eBqj1f3xbW0X/YB6COhm6APsDXQWnX NNgDi9BIOfpS7TZ+tAnHIZpf9SdWcofBsE7sIG/G5L7iDsrY4KVIqcU2bv8sp0zE RpoAd9P9Am8GsysT+TMZe/ztfQG8DaKr8+88FCxwEl+C+HTeS+aYZ/+cm4DgS5yH mWWZ5UoubwVHCCMpI7G3JBNbT1mYP4ja6JzJFthttkfJn9kOldeWRc7u2QARAQAB tEVKYWNvYiBXZWxzaCAoamZ3X3VuY2hlY2tlZCAtIGluZGljYXRlcyBjb2RlIGJy b3VnaHQgaW4gZnJvbSB0aGUgd2lsZCmJAi4EEwECABgCGwMCHgECF4AFAl59ftwF CwkIBwMCFQoACgkQfpO9iVXJds49pxAAohOxvnxDTeK+20h5x1RxMI9TG/vC27Bu Il2RP/cUlC14w8QRZ15/zqboPOECmaYIUS+sdVtkr5DnQ8U5fO2vv7UluHYLqvN3 JUkfPOvrhs0Ga/yOq/7xV0r14X2eiR6FMncEWY7XZhKLshXOu3L4+IjsF1kbOUQZ c6/UvyOHQwXuh3ksebGCE1OJF16LH3u/b4rzb5mphNbx5Wwlb2T9/BQ0Nf7xkitD C7p1dL9GKk10M2V/FMgnZI9Bj1pY8ZlPjIh8EHs1VSBzh/95jt2VjHSbGW9lG3Zj EyV8XBcJwNM80rRBsY93JbgNOsx3wWtqc3oMHVmc7/Wta/IXrJP7jGdvVJSxaOQ+ aCWY5TXhOrfTm5quh9ny3DTgdyWd3nU6xfc0PIasSUPkrxrupDilldoyTF76bj0u 8SveUkpNAtxSzpj0X6rnxIb6nC2ivFx3vkB8kRhGBiY63Pk3MmM47GJW6r0sOZAn SGfMXTrdX3hjvIH5JzqwyEromrla4dh0oJiBK6qg2PxDckSl/8GNbaaczAEhM6mz 4QLfckXvyI8OApuuPGpW0PdzYhJfXUzt5RyAJYsxldonMqsfUKCMcw7aMa8kmk8l GArFxLhimBXO7JU7DvI4gOs6ny2PM9CW/lF2ux2CJwRkgOvl5FLKaagqSlM6rZmK QeJQS3RcbPE= =JTyf -----END PGP PUBLIC KEY BLOCK----- . # Load patch sequence and signer names for future reference. cat >"$TMP/press_path" <<. bitcoin genesis jfw_unchecked bitcoin bitcoin-asciilifeform.1 jfw bitcoin rm_rf_upnp jfw_unchecked bitcoin bitcoin-asciilifeform.2-https_snipsnip jfw bitcoin bitcoin-asciilifeform.3-turdmeister-alert-snip jfw_unchecked bitcoin bitcoin-asciilifeform.4-goodbye-win32 jfw bitcoin bitcoin-v0_5_3-db_config.6 jfw_unchecked bitcoin bitcoin-v0_5_3_1-rev_bump.7 jfw bitcoin bitcoin-v0_5_3_1-static_makefile_v002.8 jfw bitcoin asciilifeform-kills-integer-retardation jfw_unchecked bitcoin asciilifeform_and_now_we_have_block_dumper_corrected jfw_unchecked bitcoin asciilifeform_dnsseed_snipsnip jfw bitcoin asciilifeform_maxint_locks_corrected jfw_unchecked bitcoin asciilifeform_orphanage_thermonuke jfw_unchecked bitcoin asciilifeform_tx-orphanage_amputation jfw_unchecked bitcoin asciilifeform_zap_hardcoded_seeds jfw bitcoin asciilifeform_zap_showmyip_crud jfw_unchecked bitcoin mod6_fix_dumpblock_params jfw_unchecked bitcoin asciilifeform_dns_thermonyukyoolar_kleansing jfw bitcoin asciilifeform_ver_now_5_4_and_irc_is_gone_and_now_must_give_ip jfw_unchecked bitcoin asciilifeform_and_now_we_have_eatblock jfw_unchecked bitcoin asciilifeform_lets_lose_testnet jfw_unchecked bitcoin asciilifeform_add_verifyall_option jfw bitcoin programmable-versionstring jfw_unchecked bitcoin malleus_mikehearnificarum jfw bitcoin mod6_der_high_low_s jfw_unchecked bitcoin mod6_privkey_tools jfw_unchecked bitcoin makefiles jfw bitcoin asciilifeform_aggressive_pushgetblocks jfw_unchecked bitcoin mod6_manifest jfw bitcoin mod6_phexdigit_fix jfw bitcoin mod6_excise_hash_truncation jfw bitcoin mod6_whogaveblox jfw_unchecked bitcoin bitcoin_rawtx_get_send jfw bitcoin bitcoin_system_compiler jfw bitcoin bitcoin_dumpblock_no_losers jfw bitcoin bitcoin_help_tuneups jfw bitcoin bitcoin_permissive_mode jfw bitcoin bitcoin_boost_prune_built_libs jfw bitcoin bitcoin_tx_fee_cleanup jfw bitcoin bitcoin_fsync_all_blocks jfw bitcoin bitcoin_checkblocks_cleanup jfw keksum keksum_subdir_genesis jfw gscm gscm_subdir_genesis jfw gscm gscm_fix_m_whitespace_package_install jfw gscm gscm_immutable_fill jfw gscm gscm_usrbin jfw gbw-node gbw-node_subdir_genesis jfw gbw-node gbw-node_usrbin jfw gbw-signer gbw-signer_subdir_genesis jfw gbw-signer gbw-signer_usrbin jfw . get_patches_verify get_deps press tree # Cleanup on success. rm -rf "$TMP"