aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README.md6
-rw-r--r--contrib/bitcoin-qt.pro2
-rw-r--r--contrib/bitcoind.bash-completion14
-rw-r--r--contrib/bitrpc/README.md8
-rw-r--r--contrib/bitrpc/bitrpc.py337
-rw-r--r--contrib/debian/bitcoin-tx.install1
-rw-r--r--contrib/debian/bitcoind.manpages1
-rw-r--r--contrib/debian/changelog54
-rw-r--r--contrib/debian/control50
-rw-r--r--contrib/debian/copyright146
-rw-r--r--contrib/debian/examples/bitcoin.conf29
-rw-r--r--contrib/debian/manpages/bitcoin-cli.121
-rw-r--r--contrib/debian/manpages/bitcoin-qt.1198
-rw-r--r--contrib/debian/manpages/bitcoin.conf.576
-rw-r--r--contrib/debian/manpages/bitcoind.1191
-rw-r--r--contrib/debian/watch2
-rw-r--r--contrib/devtools/README.md63
-rwxr-xr-xcontrib/devtools/clang-format.py62
-rwxr-xr-xcontrib/devtools/fix-copyright-headers.py4
-rwxr-xr-xcontrib/devtools/git-subtree-check.sh74
-rwxr-xr-xcontrib/devtools/github-merge.sh18
-rwxr-xr-xcontrib/devtools/optimize-pngs.py75
-rwxr-xr-xcontrib/devtools/security-check.py181
-rwxr-xr-xcontrib/devtools/symbol-check.py49
-rwxr-xr-xcontrib/devtools/test-security-check.py60
-rwxr-xr-xcontrib/devtools/update-translations.py15
-rw-r--r--contrib/gitian-descriptors/README.md16
-rw-r--r--contrib/gitian-descriptors/boost-linux.yml55
-rw-r--r--contrib/gitian-descriptors/boost-win.yml86
-rw-r--r--contrib/gitian-descriptors/deps-linux.yml98
-rw-r--r--contrib/gitian-descriptors/deps-win.yml128
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml151
-rw-r--r--contrib/gitian-descriptors/gitian-osx-bitcoin.yml61
-rw-r--r--contrib/gitian-descriptors/gitian-osx-depends.yml159
-rw-r--r--contrib/gitian-descriptors/gitian-osx-native.yml178
-rw-r--r--contrib/gitian-descriptors/gitian-osx-qt.yml186
-rw-r--r--contrib/gitian-descriptors/gitian-osx-signer.yml38
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml134
-rw-r--r--contrib/gitian-descriptors/gitian-win-signer.yml39
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml207
-rw-r--r--contrib/gitian-descriptors/protobuf-win.yml65
-rw-r--r--contrib/gitian-descriptors/qt-linux.yml264
-rw-r--r--contrib/gitian-descriptors/qt-win.yml92
-rw-r--r--contrib/gitian-downloader/bluematt-key.pgpbin4113 -> 10324 bytes
-rw-r--r--contrib/gitian-downloader/btcdrak-key.pgp142
-rw-r--r--contrib/gitian-downloader/cdecker-key.pgpbin0 -> 2230 bytes
-rw-r--r--contrib/gitian-downloader/centaur1-key.pgp30
-rw-r--r--contrib/gitian-downloader/erkmos.pgpbin0 -> 10205 bytes
-rw-r--r--contrib/gitian-downloader/fanquake-key.pgp63
-rw-r--r--contrib/gitian-downloader/jonasschnelli-key.pgp110
-rw-r--r--contrib/gitian-downloader/linux-download-config42
-rw-r--r--contrib/gitian-downloader/luke-jr-key.pgpbin7322 -> 6518 bytes
-rw-r--r--contrib/gitian-downloader/petertodd-key.pgp1901
-rw-r--r--contrib/gitian-downloader/prab-key.pgp81
-rw-r--r--contrib/gitian-downloader/sipa-key.pgpbin109468 -> 137597 bytes
-rw-r--r--contrib/gitian-downloader/win32-download-config42
-rw-r--r--contrib/init/README.md12
-rw-r--r--contrib/init/bitcoind.conf65
-rw-r--r--contrib/init/bitcoind.init67
-rw-r--r--contrib/init/bitcoind.openrc92
-rw-r--r--contrib/init/bitcoind.openrcconf33
-rw-r--r--contrib/init/bitcoind.service (renamed from contrib/systemd/bitcoind.service)11
-rw-r--r--contrib/init/org.bitcoin.bitcoind.plist15
-rw-r--r--contrib/linearize/README.md11
-rw-r--r--contrib/linearize/example-linearize.cfg12
-rwxr-xr-xcontrib/linearize/linearize-data.py283
-rwxr-xr-xcontrib/linearize/linearize-hashes.py73
-rw-r--r--contrib/macdeploy/Base.lproj/InfoPlist.strings1
-rw-r--r--contrib/macdeploy/DS_Storebin15364 -> 10244 bytes
-rw-r--r--contrib/macdeploy/README.md2
-rw-r--r--contrib/macdeploy/background.pngbin12073 -> 48690 bytes
-rw-r--r--contrib/macdeploy/background.psdbin163518 -> 982442 bytes
-rw-r--r--contrib/macdeploy/background.tiffbin0 -> 202136 bytes
-rw-r--r--contrib/macdeploy/background@2x.pngbin0 -> 138890 bytes
-rwxr-xr-xcontrib/macdeploy/detached-sig-apply.sh52
-rwxr-xr-xcontrib/macdeploy/detached-sig-create.sh47
-rw-r--r--contrib/macdeploy/fancy.plist2
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus77
-rw-r--r--contrib/seeds/README.md11
-rwxr-xr-xcontrib/seeds/generate-seeds.py138
-rwxr-xr-xcontrib/seeds/makeseeds.py167
-rw-r--r--contrib/seeds/nodes_main.txt879
-rw-r--r--contrib/seeds/nodes_test.txt11
-rw-r--r--contrib/test-patches/README.md7
-rw-r--r--contrib/test-patches/temp-revert-2.patch20
-rw-r--r--contrib/verify-commits/allow-revsig-commits2
-rwxr-xr-xcontrib/verify-commits/gpg.sh33
-rwxr-xr-xcontrib/verify-commits/pre-push-hook.sh16
-rw-r--r--contrib/verify-commits/trusted-git-root1
-rw-r--r--contrib/verify-commits/trusted-keys7
-rwxr-xr-xcontrib/verify-commits/verify-commits.sh63
-rwxr-xr-xcontrib/verifysfbinaries/verify.sh14
-rwxr-xr-xcontrib/zmq/zmq_sub.py37
93 files changed, 5590 insertions, 2776 deletions
diff --git a/contrib/README.md b/contrib/README.md
index dae975e9ef..125594312b 100644
--- a/contrib/README.md
+++ b/contrib/README.md
@@ -1,9 +1,6 @@
Wallet Tools
---------------------
-### [BitRPC](/contrib/bitrpc) ###
-Allows for sending of all standard Bitcoin commands via RPC rather than as command line args.
-
### [SpendFrom](/contrib/spendfrom) ###
Use the raw transactions API to send coins received on a particular
@@ -16,6 +13,9 @@ Repository Tools
Specific tools for developers working on this repository.
Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG.
+### [Verify-Commits](/contrib/verify-commits) ###
+Tool to verify that every merge commit was signed by a developer using the above `github-merge.sh` script.
+
### [Linearize](/contrib/linearize) ###
Construct a linear, no-fork, best version of the blockchain.
diff --git a/contrib/bitcoin-qt.pro b/contrib/bitcoin-qt.pro
index 3a72d10f47..b8133bf789 100644
--- a/contrib/bitcoin-qt.pro
+++ b/contrib/bitcoin-qt.pro
@@ -11,7 +11,7 @@ FORMS += \
../src/qt/forms/overviewpage.ui \
../src/qt/forms/receivecoinsdialog.ui \
../src/qt/forms/receiverequestdialog.ui \
- ../src/qt/forms/rpcconsole.ui \
+ ../src/qt/forms/debugwindow.ui \
../src/qt/forms/sendcoinsdialog.ui \
../src/qt/forms/sendcoinsentry.ui \
../src/qt/forms/signverifymessagedialog.ui \
diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion
index 03ef173c09..1338d2f2b5 100644
--- a/contrib/bitcoind.bash-completion
+++ b/contrib/bitcoind.bash-completion
@@ -1,6 +1,6 @@
# bash programmable completion for bitcoind(1) and bitcoin-cli(1)
# Copyright (c) 2012,2014 Christian von Roques <roques@mti.ag>
-# Distributed under the MIT/X11 software license, see the accompanying
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
have bitcoind && {
@@ -39,6 +39,10 @@ _bitcoind() {
if ((cword > 4)); then
case ${words[cword-4]} in
+ listtransactions)
+ COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
+ return 0
+ ;;
signrawtransaction)
COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) )
return 0
@@ -52,7 +56,7 @@ _bitcoind() {
_bitcoin_accounts
return 0
;;
- gettxout|importprivkey)
+ getbalance|gettxout|importaddress|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock)
COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
return 0
;;
@@ -65,7 +69,7 @@ _bitcoind() {
COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) )
return 0
;;
- getblock|getrawtransaction|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction)
+ getblock|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction)
COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
return 0
;;
@@ -92,7 +96,7 @@ _bitcoind() {
esac
case "$cur" in
- -conf=*|-pid=*|-loadblock=*|-wallet=*|-rpcsslcertificatechainfile=*|-rpcsslprivatekeyfile=*)
+ -conf=*|-pid=*|-loadblock=*|-wallet=*)
cur="${cur#*=}"
_filedir
return 0
@@ -115,7 +119,7 @@ _bitcoind() {
# only parse help if senseful
if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then
- commands=$(_bitcoin_rpc help 2>/dev/null | awk '{ print $1; }')
+ commands=$(_bitcoin_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }')
fi
COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) )
diff --git a/contrib/bitrpc/README.md b/contrib/bitrpc/README.md
deleted file mode 100644
index f5ef2f0405..0000000000
--- a/contrib/bitrpc/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-### BitRPC
-Allows for sending of all standard Bitcoin commands via RPC rather than as command line args.
-
-### Looking for Wallet Tools?
-BitRPC.py is able to do the exact same thing as `walletchangepass.py` and `walletunlock.py`. Their respective commands in BitRPC.py are:
-
- bitrpc.py walletpassphrasechange
- bitrpc.py walletpassphrase \ No newline at end of file
diff --git a/contrib/bitrpc/bitrpc.py b/contrib/bitrpc/bitrpc.py
deleted file mode 100644
index 02577b1b6a..0000000000
--- a/contrib/bitrpc/bitrpc.py
+++ /dev/null
@@ -1,337 +0,0 @@
-from jsonrpc import ServiceProxy
-import sys
-import string
-import getpass
-
-# ===== BEGIN USER SETTINGS =====
-# if you do not set these you will be prompted for a password for every command
-rpcuser = ""
-rpcpass = ""
-# ====== END USER SETTINGS ======
-
-
-if rpcpass == "":
- access = ServiceProxy("http://127.0.0.1:8332")
-else:
- access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8332")
-cmd = sys.argv[1].lower()
-
-if cmd == "backupwallet":
- try:
- path = raw_input("Enter destination path/filename: ")
- print access.backupwallet(path)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "encryptwallet":
- try:
- pwd = getpass.getpass(prompt="Enter passphrase: ")
- pwd2 = getpass.getpass(prompt="Repeat passphrase: ")
- if pwd == pwd2:
- access.encryptwallet(pwd)
- print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n"
- else:
- print "\n---Passphrases do not match---\n"
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getaccount":
- try:
- addr = raw_input("Enter a Bitcoin address: ")
- print access.getaccount(addr)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getaccountaddress":
- try:
- acct = raw_input("Enter an account name: ")
- print access.getaccountaddress(acct)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getaddressesbyaccount":
- try:
- acct = raw_input("Enter an account name: ")
- print access.getaddressesbyaccount(acct)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getbalance":
- try:
- acct = raw_input("Enter an account (optional): ")
- mc = raw_input("Minimum confirmations (optional): ")
- try:
- print access.getbalance(acct, mc)
- except:
- print access.getbalance()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getblockbycount":
- try:
- height = raw_input("Height: ")
- print access.getblockbycount(height)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getblockcount":
- try:
- print access.getblockcount()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getblocknumber":
- try:
- print access.getblocknumber()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getconnectioncount":
- try:
- print access.getconnectioncount()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getdifficulty":
- try:
- print access.getdifficulty()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getgenerate":
- try:
- print access.getgenerate()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "gethashespersec":
- try:
- print access.gethashespersec()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getinfo":
- try:
- print access.getinfo()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getnewaddress":
- try:
- acct = raw_input("Enter an account name: ")
- try:
- print access.getnewaddress(acct)
- except:
- print access.getnewaddress()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getreceivedbyaccount":
- try:
- acct = raw_input("Enter an account (optional): ")
- mc = raw_input("Minimum confirmations (optional): ")
- try:
- print access.getreceivedbyaccount(acct, mc)
- except:
- print access.getreceivedbyaccount()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getreceivedbyaddress":
- try:
- addr = raw_input("Enter a Bitcoin address (optional): ")
- mc = raw_input("Minimum confirmations (optional): ")
- try:
- print access.getreceivedbyaddress(addr, mc)
- except:
- print access.getreceivedbyaddress()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "gettransaction":
- try:
- txid = raw_input("Enter a transaction ID: ")
- print access.gettransaction(txid)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "getwork":
- try:
- data = raw_input("Data (optional): ")
- try:
- print access.gettransaction(data)
- except:
- print access.gettransaction()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "help":
- try:
- cmd = raw_input("Command (optional): ")
- try:
- print access.help(cmd)
- except:
- print access.help()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "listaccounts":
- try:
- mc = raw_input("Minimum confirmations (optional): ")
- try:
- print access.listaccounts(mc)
- except:
- print access.listaccounts()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "listreceivedbyaccount":
- try:
- mc = raw_input("Minimum confirmations (optional): ")
- incemp = raw_input("Include empty? (true/false, optional): ")
- try:
- print access.listreceivedbyaccount(mc, incemp)
- except:
- print access.listreceivedbyaccount()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "listreceivedbyaddress":
- try:
- mc = raw_input("Minimum confirmations (optional): ")
- incemp = raw_input("Include empty? (true/false, optional): ")
- try:
- print access.listreceivedbyaddress(mc, incemp)
- except:
- print access.listreceivedbyaddress()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "listtransactions":
- try:
- acct = raw_input("Account (optional): ")
- count = raw_input("Number of transactions (optional): ")
- frm = raw_input("Skip (optional):")
- try:
- print access.listtransactions(acct, count, frm)
- except:
- print access.listtransactions()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "move":
- try:
- frm = raw_input("From: ")
- to = raw_input("To: ")
- amt = raw_input("Amount:")
- mc = raw_input("Minimum confirmations (optional): ")
- comment = raw_input("Comment (optional): ")
- try:
- print access.move(frm, to, amt, mc, comment)
- except:
- print access.move(frm, to, amt)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "sendfrom":
- try:
- frm = raw_input("From: ")
- to = raw_input("To: ")
- amt = raw_input("Amount:")
- mc = raw_input("Minimum confirmations (optional): ")
- comment = raw_input("Comment (optional): ")
- commentto = raw_input("Comment-to (optional): ")
- try:
- print access.sendfrom(frm, to, amt, mc, comment, commentto)
- except:
- print access.sendfrom(frm, to, amt)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "sendmany":
- try:
- frm = raw_input("From: ")
- to = raw_input("To (in format address1:amount1,address2:amount2,...): ")
- mc = raw_input("Minimum confirmations (optional): ")
- comment = raw_input("Comment (optional): ")
- try:
- print access.sendmany(frm,to,mc,comment)
- except:
- print access.sendmany(frm,to)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "sendtoaddress":
- try:
- to = raw_input("To (in format address1:amount1,address2:amount2,...): ")
- amt = raw_input("Amount:")
- comment = raw_input("Comment (optional): ")
- commentto = raw_input("Comment-to (optional): ")
- try:
- print access.sendtoaddress(to,amt,comment,commentto)
- except:
- print access.sendtoaddress(to,amt)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "setaccount":
- try:
- addr = raw_input("Address: ")
- acct = raw_input("Account:")
- print access.setaccount(addr,acct)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "setgenerate":
- try:
- gen= raw_input("Generate? (true/false): ")
- cpus = raw_input("Max processors/cores (-1 for unlimited, optional):")
- try:
- print access.setgenerate(gen, cpus)
- except:
- print access.setgenerate(gen)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "settxfee":
- try:
- amt = raw_input("Amount:")
- print access.settxfee(amt)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "stop":
- try:
- print access.stop()
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "validateaddress":
- try:
- addr = raw_input("Address: ")
- print access.validateaddress(addr)
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "walletpassphrase":
- try:
- pwd = getpass.getpass(prompt="Enter wallet passphrase: ")
- access.walletpassphrase(pwd, 60)
- print "\n---Wallet unlocked---\n"
- except:
- print "\n---An error occurred---\n"
-
-elif cmd == "walletpassphrasechange":
- try:
- pwd = getpass.getpass(prompt="Enter old wallet passphrase: ")
- pwd2 = getpass.getpass(prompt="Enter new wallet passphrase: ")
- access.walletpassphrasechange(pwd, pwd2)
- print
- print "\n---Passphrase changed---\n"
- except:
- print
- print "\n---An error occurred---\n"
- print
-
-else:
- print "Command not found or not supported"
diff --git a/contrib/debian/bitcoin-tx.install b/contrib/debian/bitcoin-tx.install
new file mode 100644
index 0000000000..2c21052a68
--- /dev/null
+++ b/contrib/debian/bitcoin-tx.install
@@ -0,0 +1 @@
+usr/local/bin/bitcoin-tx usr/bin
diff --git a/contrib/debian/bitcoind.manpages b/contrib/debian/bitcoind.manpages
index 3e4ca63d4e..6d3e683855 100644
--- a/contrib/debian/bitcoind.manpages
+++ b/contrib/debian/bitcoind.manpages
@@ -1,2 +1,3 @@
debian/manpages/bitcoind.1
debian/manpages/bitcoin.conf.5
+debian/manpages/bitcoin-cli.1
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
index 4f22567f85..110bfe03ef 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,3 +1,51 @@
+bitcoin (0.11.0-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 14 Jul 2015 14:39:00 -1000
+
+bitcoin (0.10.2-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Mon, 29 Jun 2015 17:33:00 -1000
+
+bitcoin (0.10.1-precise3) precise; urgency=medium
+
+ * Fix build dep (include python).
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 5 May 2015 09:28:00 -1000
+
+bitcoin (0.10.1-precise2) precise; urgency=medium
+
+ * Fix miniupnpc dep.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 5 May 2015 00:33:00 -1000
+
+bitcoin (0.10.1-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 5 May 2015 00:07:00 -1000
+
+bitcoin (0.10.0-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 18 Feb 2015 13:22:00 -1000
+
+bitcoin (0.9.4-precise1) precise; urgency=high
+
+ * New upstream releases.
+
+ -- Matt Corallo (laptop - only while traveling) <matt@mattcorallo.com> Mon, 12 Jan 2015 23:30:00 -1000
+
+bitcoin (0.9.3-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Fri, 26 Sep 2014 12:01:00 -0700
+
bitcoin (0.9.1-precise1) precise; urgency=medium
* New upstream release.
@@ -131,7 +179,7 @@ bitcoin (0.5.3-natty0) natty; urgency=low
bitcoin (0.5.2-natty1) natty; urgency=low
* Remove mentions on anonymity in package descriptions and manpage.
- These should never have been there, bitcoin isnt anonymous without
+ These should never have been there, bitcoin isn't anonymous without
a ton of work that virtually no users will ever be willing and
capable of doing
@@ -172,7 +220,7 @@ bitcoin (0.5.0~rc1-natty1) natty; urgency=low
* Add test_bitcoin to build test
* Fix clean
- * Remove uneccessary build-dependancies
+ * Remove unnecessary build-dependancies
-- Matt Corallo <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400
@@ -332,7 +380,7 @@ bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low
bitcoin (0.3.19~dfsg-6) unstable; urgency=low
- * Fix override agressive optimizations.
+ * Fix override aggressive optimizations.
* Fix tighten build-dependencies to really fit backporting to Lenny:
+ Add fallback build-dependency on libdb4.6++-dev.
+ Tighten unversioned Boost build-dependencies to recent versions,
diff --git a/contrib/debian/control b/contrib/debian/control
index ac635f43e0..490b2571c3 100644
--- a/contrib/debian/control
+++ b/contrib/debian/control
@@ -12,7 +12,7 @@ Build-Depends: debhelper,
libdb4.8++-dev,
libssl-dev,
pkg-config,
- libminiupnpc8-dev,
+ libminiupnpc8-dev | libminiupnpc-dev (>> 1.6),
libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev,
libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev,
libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev,
@@ -20,26 +20,23 @@ Build-Depends: debhelper,
qt4-qmake,
libqt4-dev,
libqrencode-dev,
- libprotobuf-dev, protobuf-compiler
+ libprotobuf-dev, protobuf-compiler,
+ python
Standards-Version: 3.9.2
-Homepage: http://www.bitcoin.org/
+Homepage: https://www.bitcoin.org/
Vcs-Git: git://github.com/bitcoin/bitcoin.git
-Vcs-Browser: http://github.com/bitcoin/bitcoin
+Vcs-Browser: https://github.com/bitcoin/bitcoin
Package: bitcoind
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer network based digital currency - daemon
- Bitcoin is a free open source peer-to-peer electronic cash system that
- is completely decentralized, without the need for a central server or
- trusted parties. Users hold the crypto keys to their own money and
- transact directly with each other, with the help of a P2P network to
- check for double-spending.
+ Bitcoin is an experimental new digital currency that enables instant
+ payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer
+ technology to operate with no central authority: managing transactions
+ and issuing money are carried out collectively by the network. Bitcoin Core
+ is the name of the open source software which enables the use of this currency.
.
- Full transaction history is stored locally at each client. This
- requires 20+ GB of space, slowly growing.
- .
-
This package provides the daemon, bitcoind, and the CLI tool
bitcoin-cli to interact with the daemon.
@@ -47,13 +44,24 @@ Package: bitcoin-qt
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: peer-to-peer network based digital currency - Qt GUI
- Bitcoin is a free open source peer-to-peer electronic cash system that
- is completely decentralized, without the need for a central server or
- trusted parties. Users hold the crypto keys to their own money and
- transact directly with each other, with the help of a P2P network to
- check for double-spending.
- .
- Full transaction history is stored locally at each client. This
- requires 20+ GB of space, slowly growing.
+ Bitcoin is an experimental new digital currency that enables instant
+ payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer
+ technology to operate with no central authority: managing transactions
+ and issuing money are carried out collectively by the network. Bitcoin Core
+ is the name of the open source software which enables the use of this currency.
.
This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt.
+
+Package: bitcoin-tx
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: peer-to-peer digital currency - standalone transaction tool
+ Bitcoin is an experimental new digital currency that enables instant
+ payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer
+ technology to operate with no central authority: managing transactions
+ and issuing money are carried out collectively by the network. Bitcoin Core
+ is the name of the open source software which enables the use of this currency.
+ .
+ This package provides bitcoin-tx, a command-line transaction creation
+ tool which can be used without a bitcoin daemon. Some means of
+ exchanging minimal transaction data with peers is still required.
diff --git a/contrib/debian/copyright b/contrib/debian/copyright
index a6ee201991..83ce560a79 100644
--- a/contrib/debian/copyright
+++ b/contrib/debian/copyright
@@ -1,24 +1,15 @@
-Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=174
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Bitcoin
Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
irc://#bitcoin@freenode.net
-Source: http://sourceforge.net/projects/bitcoin/files/
- https://github.com/bitcoin/bitcoin
+Source: https://github.com/bitcoin/bitcoin
Files: *
-Copyright: 2009-2012, Bitcoin Core Developers
+Copyright: 2009-2015, Bitcoin Core Developers
License: Expat
Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org,
as well as the numerous contributors to the project.
-Files: src/json/*
-Copyright: 2007-2009, John W. Wilkinson
-License: Expat
-
-Files: src/strlcpy.h
-Copyright: 1998, Todd C. Miller <Todd.Miller@courtesan.com>
-License: ISC
-
Files: debian/*
Copyright: 2010-2011, Jonas Smedegaard <dr@jones.dk>
2011, Matt Corallo <matt@bluematt.me>
@@ -28,60 +19,66 @@ Files: debian/manpages/*
Copyright: Micah Anderson <micah@debian.org>
License: GPL-3+
-Files: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
- src/qt/res/src/*.svg
-Copyright: Wladimir van der Laan
+Files: src/qt/res/icons/add.png
+ src/qt/res/icons/address-book.png
+ src/qt/res/icons/configure.png
+ src/qt/res/icons/debugwindow.png
+ src/qt/res/icons/edit.png
+ src/qt/res/icons/editcopy.png
+ src/qt/res/icons/editpaste.png
+ src/qt/res/icons/export.png
+ src/qt/res/icons/eye.png
+ src/qt/res/icons/filesave.png
+ src/qt/res/icons/history.png
+ src/qt/res/icons/info.png
+ src/qt/res/icons/key.png
+ src/qt/res/icons/lock_*.png
+ src/qt/res/icons/open.png
+ src/qt/res/icons/overview.png
+ src/qt/res/icons/quit.png
+ src/qt/res/icons/receive.png
+ src/qt/res/icons/remove.png
+ src/qt/res/icons/send.png
+ src/qt/res/icons/synced.png
+ src/qt/res/icons/transaction*.png
+ src/qt/res/icons/tx_output.png
+ src/qt/res/icons/warning.png
+Copyright: Stephen Hutchings (and more)
+ http://typicons.com
License: Expat
-
-Files: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png,
- src/qt/res/icons/history.png, src/qt/res/icons/key.png,
- src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png,
- src/qt/res/icons/receive.png, src/qt/res/icons/send.png,
- src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png
-Copyright: David Vignoni (david@icon-king.com)
- ICON KING - www.icon-king.com
-License: LGPL
-Comment: NUVOLA ICON THEME for KDE 3.x
- Original icons: kaddressbook, klipper_dock, view-list-text,
- key-password, encrypted/decrypted, go-home, go-down,
- go-next, dialog-ok
- Site: http://www.icon-king.com/projects/nuvola/
+Comment: Site: https://github.com/stephenhutchings/typicons.font
Files: src/qt/res/icons/connect*.png
-Copyright: schollidesign
-License: GPL-3+
-Comment: Icon Pack: Human-O2
- Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0
-
-Files: src/qt/res/icons/transaction*.png
-Copyright: md2k7
+ src/qt/res/src/connect-*.svg
+Copyright: Marco Falke
License: Expat
-Comment: Site: https://bitcointalk.org/index.php?topic=15276.0
+Comment: Inspired by Stephan Hutchings Typicons
-Files: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png,
- src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png,
- src/qt/res/icons/add.png, src/qt/res/icons/edit.png,
- src/qt/res/icons/remove.png
-Copyright: http://www.everaldo.com
-License: LGPL
-Comment: Icon Pack: Crystal SVG
+Files: src/qt/res/icons/tx_mined.png
+ src/qt/res/src/mine.svg
+Copyright: Jonas Schnelli
+License: Expat
+Comment:
-Files: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png
-Copyright: Bitboy (optimized for 16x16 by Wladimir van der Laan)
-License: PUB-DOM
+Files: src/qt/res/icons/clock*.png
+ src/qt/res/icons/eye_*.png
+ src/qt/res/icons/verify.png
+ src/qt/res/icons/tx_in*.png
+ src/qt/res/src/clock_*.svg
+ src/qt/res/src/tx_*.svg
+ src/qt/res/src/verify.svg
+Copyright: Stephan Hutching, Jonas Schnelli
+License: Expat
+Comment: Modifications of Stephan Hutchings Typicons
+
+Files: src/qt/res/icons/about.png
+ src/qt/res/icons/bitcoin.*
+ share/pixmaps/bitcoin*
+ src/qt/res/src/bitcoin.svg
+Copyright: Bitboy, Jonas Schnelli
+License: public-domain
Comment: Site: https://bitcointalk.org/?topic=1756.0
-Files: scripts/img/reload.xcf, src/qt/res/movies/*.png
-Copyright: Everaldo (Everaldo Coelho)
-License: GPL-3+
-Comment: Icon Pack: Kids
- Site: http://findicons.com/icon/17102/reload?id=17102
-
-Files: src/qt/res/images/splash2.jpg
-License: PUB-DOM
-Copyright: Crobbo (forum)
-Comment: Site: https://bitcointalk.org/index.php?topic=32273.0
-
License: Expat
Permission is hereby granted, free of charge, to any person obtaining a
@@ -103,20 +100,6 @@ License: Expat
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-License: ISC
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
- .
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
- BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
- OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
-
License: GPL-2+
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -145,22 +128,5 @@ Comment:
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
-License: LGPL
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- .
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-Comment:
- On Debian systems the GNU Lesser General Public License (LGPL) is
- located in '/usr/share/common-licenses/LGPL'.
- .
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-License: PUB-DOM
+License: public-domain
This work is in the public domain.
diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf
index 31cca981e0..2831c07292 100644
--- a/contrib/debian/examples/bitcoin.conf
+++ b/contrib/debian/examples/bitcoin.conf
@@ -13,6 +13,12 @@
# Connect via a SOCKS5 proxy
#proxy=127.0.0.1:9050
+# Bind to given address and always listen on it. Use [host]:port notation for IPv6
+#bind=<addr>
+
+# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6
+#whitebind=<addr>
+
##############################################################
## Quick Primer on addnode vs connect ##
## Let's say for instance you use addnode=4.2.2.4 ##
@@ -54,16 +60,20 @@
# JSON-RPC options (for controlling a running Bitcoin/bitcoind process)
#
-# server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands
+# server=1 tells Bitcoin-Qt and bitcoind to accept JSON-RPC commands
#server=0
+# Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6.
+# This option can be specified multiple times (default: bind to all interfaces)
+#rpcbind=<addr>
+
# You must set rpcuser and rpcpassword to secure the JSON-RPC api
#rpcuser=Ulysseys
#rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593
# How many seconds bitcoin will wait for a complete RPC HTTP request.
# after the HTTP connection is established.
-#rpctimeout=30
+#rpcclienttimeout=30
# By default, only RPC connections from localhost are allowed.
# Specify as many rpcallowip= settings as you like to allow connections from other hosts,
@@ -72,7 +82,7 @@
# NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED,
# because the rpcpassword is transmitted over the network unencrypted.
-# server=1 tells Bitcoin-QT to accept JSON-RPC commands.
+# server=1 tells Bitcoin-Qt to accept JSON-RPC commands.
# it is also read by bitcoind to determine if RPC should be enabled
#rpcallowip=10.1.1.34/255.255.255.0
#rpcallowip=1.2.3.4/24
@@ -85,15 +95,14 @@
# running on another host using this option:
#rpcconnect=127.0.0.1
-# Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate
-# with Bitcoin -server or bitcoind
-#rpcssl=1
+# Transaction Fee Changes in 0.10.0
-# OpenSSL settings used when rpcssl=1
-#rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH
-#rpcsslcertificatechainfile=server.cert
-#rpcsslprivatekeyfile=server.pem
+# Send transactions as zero-fee transactions if possible (default: 0)
+#sendfreetransactions=0
+# Create transactions that have enough fees (or priority) so they are likely to begin confirmation within n blocks (default: 1).
+# This setting is over-ridden by the -paytxfee option.
+#txconfirmtarget=n
# Miscellaneous options
diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1
new file mode 100644
index 0000000000..16c338dd3e
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-cli.1
@@ -0,0 +1,21 @@
+.TH BITCOIN-CLI "1" "February 2016" "bitcoin-cli 0.12"
+.SH NAME
+bitcoin-cli \- a remote procedure call client for Bitcoin Core.
+.SH SYNOPSIS
+bitcoin-cli [options] <command> [params] \- Send command to Bitcoin Core.
+.TP
+bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands.
+.SH DESCRIPTION
+This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core.
+
+.SH OPTIONS
+.TP
+\fB\-?\fR
+Show possible options.
+
+.SH "SEE ALSO"
+\fBbitcoind\fP, \fBbitcoin.conf\fP
+.SH AUTHOR
+This manual page was written by Ciemon Dunville <ciemon@gmail.com>. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License.
+
+The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP.
diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1
index a023582bc0..685a282080 100644
--- a/contrib/debian/manpages/bitcoin-qt.1
+++ b/contrib/debian/manpages/bitcoin-qt.1
@@ -1,4 +1,4 @@
-.TH BITCOIN-QT "1" "April 2013" "bitcoin-qt 1"
+.TH BITCOIN-QT "1" "February 2016" "bitcoin-qt 0.12"
.SH NAME
bitcoin-qt \- peer-to-peer network based digital currency
.SH DESCRIPTION
@@ -8,196 +8,6 @@ bitcoin\-qt [command\-line options]
.SH OPTIONS
.TP
\-?
-This help message
-.TP
-\fB\-conf=\fR<file>
-Specify configuration file (default: bitcoin.conf)
-.TP
-\fB\-pid=\fR<file>
-Specify pid file (default: bitcoind.pid)
-.TP
-\fB\-gen\fR
-Generate coins
-.TP
-\fB\-gen\fR=\fI0\fR
-Don't generate coins
-.TP
-\fB\-datadir=\fR<dir>
-Specify data directory
-.TP
-\fB\-dbcache=\fR<n>
-Set database cache size in megabytes (default: 25)
-.TP
-\fB\-timeout=\fR<n>
-Specify connection timeout in milliseconds (default: 5000)
-.TP
-\fB\-proxy=\fR<ip:port>
-Connect through SOCKS5 proxy
-.TP
-\fB\-tor=\fR<ip:port>
-Use proxy to reach tor hidden services (default: same as \fB\-proxy\fR)
-.TP
-\fB\-dns\fR
-Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR
-.TP
-\fB\-port=\fR<port>
-Listen for connections on <port> (default: 8333 or testnet: 18333)
-.TP
-\fB\-maxconnections=\fR<n>
-Maintain at most <n> connections to peers (default: 125)
-.TP
-\fB\-addnode=\fR<ip>
-Add a node to connect to and attempt to keep the connection open
-.TP
-\fB\-connect=\fR<ip>
-Connect only to the specified node(s)
-.TP
-\fB\-seednode=\fR<ip>
-Connect to a node to retrieve peer addresses, and disconnect
-.TP
-\fB\-externalip=\fR<ip>
-Specify your own public address
-.TP
-\fB\-onlynet=\fR<net>
-Only connect to nodes in network <net> (IPv4, IPv6 or Tor)
-.TP
-\fB\-discover\fR
-Discover own IP address (default: 1 when listening and no \fB\-externalip\fR)
-.TP
-\fB\-checkpoints\fR
-Only accept block chain matching built\-in checkpoints (default: 1)
-.TP
-\fB\-listen\fR
-Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR)
-.TP
-\fB\-bind=\fR<addr>
-Bind to given address and always listen on it. Use [host]:port notation for IPv6
-.TP
-\fB\-dnsseed\fR
-Find peers using DNS lookup (default: 1 unless \fB\-connect\fR)
-.TP
-\fB\-banscore=\fR<n>
-Threshold for disconnecting misbehaving peers (default: 100)
-.TP
-\fB\-bantime=\fR<n>
-Number of seconds to keep misbehaving peers from reconnecting (default: 86400)
-.TP
-\fB\-maxreceivebuffer=\fR<n>
-Maximum per\-connection receive buffer, <n>*1000 bytes (default: 5000)
-.TP
-\fB\-maxsendbuffer=\fR<n>
-Maximum per\-connection send buffer, <n>*1000 bytes (default: 1000)
-.TP
-\fB\-upnp\fR
-Use UPnP to map the listening port (default: 1 when listening)
-.TP
-\fB\-paytxfee=\fR<amt>
-Fee per KB to add to transactions you send
-.TP
-\fB\-server\fR
-Accept command line and JSON\-RPC commands
-.TP
-\fB\-testnet\fR
-Use the test network
-.TP
-\fB\-debug\fR
-Output extra debugging information. Implies all other \fB\-debug\fR* options
-.TP
-\fB\-debugnet\fR
-Output extra network debugging information
-.TP
-\fB\-logtimestamps\fR
-Prepend debug output with timestamp
-.TP
-\fB\-shrinkdebugfile\fR
-Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR)
-.TP
-\fB\-printtoconsole\fR
-Send trace/debug info to console instead of debug.log file
-.TP
-\fB\-rpcuser=\fR<user>
-Username for JSON\-RPC connections
-.TP
-\fB\-rpcpassword=\fR<pw>
-Password for JSON\-RPC connections
-.TP
-\fB\-rpcport=\fR<port>
-Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332)
-.TP
-\fB\-rpcallowip=\fR<ip>
-Allow JSON\-RPC connections from specified IP address
-.TP
-\fB\-rpcthreads=\fR<n>
-Set the number of threads to service RPC calls (default: 4)
-.TP
-\fB\-blocknotify=\fR<cmd>
-Execute command when the best block changes (%s in cmd is replaced by block hash)
-.TP
-\fB\-walletnotify=\fR<cmd>
-Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)
-.TP
-\fB\-alertnotify=\fR<cmd>
-Execute command when a relevant alert is received (%s in cmd is replaced by message)
-.TP
-\fB\-upgradewallet\fR
-Upgrade wallet to latest format
-.TP
-\fB\-keypool=\fR<n>
-Set key pool size to <n> (default: 100)
-.TP
-\fB\-rescan\fR
-Rescan the block chain for missing wallet transactions
-.TP
-\fB\-salvagewallet\fR
-Attempt to recover private keys from a corrupt wallet.dat
-.TP
-\fB\-checkblocks=\fR<n>
-How many blocks to check at startup (default: 288, 0 = all)
-.TP
-\fB\-checklevel=\fR<n>
-How thorough the block verification is (0\-4, default: 3)
-.TP
-\fB\-txindex\fR
-Maintain a full transaction index (default: 0)
-.TP
-\fB\-loadblock=\fR<file>
-Imports blocks from external blk000??.dat file
-.TP
-\fB\-reindex\fR
-Rebuild block chain index from current blk000??.dat files
-.TP
-\fB\-par=\fR<n>
-Set the number of script verification threads (1\-16, 0=auto, default: 0)
-.SS "Block creation options:"
-.TP
-\fB\-blockminsize=\fR<n>
-Set minimum block size in bytes (default: 0)
-.TP
-\fB\-blockmaxsize=\fR<n>
-Set maximum block size in bytes (default: 250000)
-.HP
-\fB\-blockprioritysize=\fR<n> Set maximum size of high\-priority/low\-fee transactions in bytes (default: 27000)
-.PP
-SSL options: (see the Bitcoin Wiki for SSL setup instructions)
-.TP
-\fB\-rpcssl\fR
-Use OpenSSL (https) for JSON\-RPC connections
-.TP
-\fB\-rpcsslcertificatechainfile=\fR<file.cert>
-Server certificate file (default: server.cert)
-.TP
-\fB\-rpcsslprivatekeyfile=\fR<file.pem>
-Server private key (default: server.pem)
-.TP
-\fB\-rpcsslciphers=\fR<ciphers>
-Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)
-.SS "UI options:"
-.TP
-\fB\-lang=\fR<lang>
-Set language, for example "de_DE" (default: system locale)
-.TP
-\fB\-min\fR
-Start minimized
-.TP
-\fB\-splash\fR
-Show splash screen on startup (default: 1)
+List options.
+.SH "SEE ALSO"
+bitcoind(1)
diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5
index 8a0078d5d5..839dc26c1a 100644
--- a/contrib/debian/manpages/bitcoin.conf.5
+++ b/contrib/debian/manpages/bitcoin.conf.5
@@ -1,85 +1,15 @@
-.TH BITCOIN.CONF "5" "January 2011" "bitcoin.conf 3.19"
+.TH BITCOIN.CONF "5" "February 2016" "bitcoin.conf 0.12"
.SH NAME
bitcoin.conf \- bitcoin configuration file
.SH SYNOPSIS
All command-line options (except for '\-conf') may be specified in a configuration file, and all configuration file options may also be specified on the command line. Command-line options override values set in the configuration file.
.TP
-The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character.
+The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. Please refer to bitcoind(1) for a up to date list of valid options.
.TP
The configuration file is not automatically created; you can create it using your favorite plain-text editor. By default, bitcoind(1) will look for a file named bitcoin.conf(5) in the bitcoin data directory, but both the data directory and the configuration file path may be changed using the '\-datadir' and '\-conf' command-line arguments.
.SH LOCATION
bitcoin.conf should be located in $HOME/.bitcoin
-.SH NETWORK-RELATED SETTINGS
-.TP
-.TP
-\fBtestnet=\fR[\fI'1'\fR|\fI'0'\fR]
-Enable or disable run on the test network instead of the real *bitcoin* network.
-.TP
-\fBproxy=\fR\fI'127.0.0.1:9050'\fR
-Connect via a socks4 proxy.
-.TP
-\fBaddnode=\fR\fI'10.0.0.2:8333'\fR
-Use as many *addnode=* settings as you like to connect to specific peers.
-.TP
-\fBconnect=\fR\fI'10.0.0.1:8333'\fR
-Use as many *connect=* settings as you like to connect ONLY to specific peers.
-.TP
-\fRmaxconnections=\fR\fI'value'\fR
-Maximum number of inbound+outbound connections.
-.SH JSON-RPC OPTIONS
-.TP
-\fBserver=\fR[\fI'1'\fR|\fI'0'\fR]
-Tells *bitcoin* to accept or not accept JSON-RPC commands.
-.TP
-\fBrpcuser=\fR\fI'username'\fR
-You must set *rpcuser* to secure the JSON-RPC api.
-.TP
-\fBrpcpassword=\fR\fI'password'\fR
-You must set *rpcpassword* to secure the JSON-RPC api.
-.TP
-\fBrpcallowip=\fR\fI'192.168.1.*'\fR
-By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character).
-.TP
-\fBrpcport=\fR\fI'8332'\fR
-Listen for RPC connections on this TCP port.
-.TP
-\fBrpcconnect=\fR\fI'127.0.0.1'\fR
-You can use *bitcoin* or *bitcoind(1)* to send commands to *bitcoin*/*bitcoind(1)* running on another host using this option.
-.TP
-\fBrpcssl=\fR\fI'1'\fR
-Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate with *bitcoin* '\-server' or *bitcoind(1)*. Example of OpenSSL settings used when *rpcssl*='1':
-.TP
-\fB\-rpcsslciphers=\fR<ciphers>
-Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH)
-.TP
-\fBrpcsslcertificatechainfile=\fR\fI'server.cert'\fR
-.TP
-\fBrpcsslprivatekeyfile=\fR\fI'server.pem'\fR
-.TP
-.SH MISCELLANEOUS OPTIONS
-.TP
-\fBgen=\fR[\fI'0'\fR|\fI'1'\fR]
-Enable or disable attempt to generate bitcoins.
-.TP
-\fB4way=\fR[\fI'0'\fR|\fI'1'\fR]
-Enable or disable use SSE instructions to try to generate bitcoins faster.
-.TP
-\fBkeypool=\fR\fI'100'\fR
-Pre-generate this many public/private key pairs, so wallet backups will be valid for both prior transactions and several dozen future transactions.
-.TP
-\fBpaytxfee=\fR\fI'0.00'\fR
-Pay an optional transaction fee every time you send bitcoins. Transactions with fees are more likely than free transactions to be included in generated blocks, so may be validated sooner.
-.TP
-\fBallowreceivebyip=\fR\fI'1'\fR
-Allow direct connections for the 'pay via IP address' feature.
-.TP
-.SH USER INTERFACE OPTIONS
-.TP
-\fBmin=\fR[\fI'0'\fR|\fI'1'\fR]
-Enable or disable start bitcoind minimized.
-.TP
-\fBminimizetotray=\fR[\fI'0'\fR|\fI'1'\fR]
-Enable or disable minimize to the system tray.
+
.SH "SEE ALSO"
bitcoind(1)
.SH AUTHOR
diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1
index a1b17d6077..5c3e52f441 100644
--- a/contrib/debian/manpages/bitcoind.1
+++ b/contrib/debian/manpages/bitcoind.1
@@ -1,4 +1,4 @@
-.TH BITCOIND "1" "January 2011" "bitcoind 3.19"
+.TH BITCOIND "1" "February 2016" "bitcoind 0.12"
.SH NAME
bitcoind \- peer-to-peer network based digital currency
.SH SYNOPSIS
@@ -6,199 +6,20 @@ bitcoin [options] <command> [params]
.TP
bitcoin [options] help <command> \- Get help for a command
.SH DESCRIPTION
-This manual page documents the bitcoind program. Bitcoin is a peer-to-peer digital currency. Peer-to-peer (P2P) means that there is no central authority to issue new money or keep track of transactions. Instead, these tasks are managed collectively by the nodes of the network. Advantages:
-
-Bitcoins can be sent easily through the Internet, without having to trust middlemen. Transactions are designed to be irreversible. Be safe from instability caused by fractional reserve banking and central banks. The limited inflation of the Bitcoin system’s money supply is distributed evenly (by CPU power) throughout the network, not monopolized by banks.
+This manual page documents the bitcoind program. Bitcoin is an experimental new digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency.
.SH OPTIONS
.TP
-\fB\-conf=\fR<file>
-Specify configuration file (default: bitcoin.conf)
-.TP
-\fB\-gen\fR
-Generate coins
-.TP
-\fB\-gen\fR=\fI0\fR
-Don't generate coins
-.TP
-\fB\-min\fR
-Start minimized
-.TP
-\fB\-datadir=\fR<dir>
-Specify data directory
-.TP
-\fB\-proxy=\fR<ip:port>
-Connect through SOCKS5 proxy
-.TP
-\fB\-addnode=\fR<ip>
-Add a node to connect to
-.TP
-\fB\-connect=\fR<ip>
-Connect only to the specified node
-.TP
-\fB\-paytxfee=\fR<amt>
-Fee per KB to add to transactions you send
-.TP
-\fB\-server\fR
-Accept command line and JSON\-RPC commands
-.TP
-\fB\-daemon\fR
-Run in the background as a daemon and accept commands
-.TP
-\fB\-testnet\fR
-Use the test network
-.TP
-\fB\-rpcuser=\fR<user>
-Username for JSON\-RPC connections
-.TP
-\fB\-rpcpassword=\fR<pw>
-Password for JSON\-RPC connections
-.TP
-\fB\-rpcport=\fR<port>
-Listen for JSON\-RPC connections on <port>
-.TP
-\fB\-rpcallowip=\fR<ip>
-Allow JSON\-RPC connections from specified IP address
-.TP
-\fB\-rpcconnect=\fR<ip>
-Send commands to node running on <ip>
-.PP
-SSL options: (see the Bitcoin Wiki for SSL setup instructions)
-.TP
-\fB\-rpcssl\fR=\fI1\fR
-Use OpenSSL (https) for JSON\-RPC connections
-.TP
-\fB\-rpcsslcertificatchainfile=\fR<file.cert>
-Server certificate file (default: server.cert)
-.TP
-\fB\-rpcsslprivatekeyfile=\fR<file.pem>
-Server private key (default: server.pem)
-.TP
-\fB\-rpcsslciphers=\fR<ciphers>
-Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH)
-.TP
\-?
-This help message
+List of possible options.
.SH COMMANDS
.TP
-\fBbackupwallet 'destination'\fR
-Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename.
-.TP
-\fBgetaccount 'bitcoinaddress'\fR
-Returns the account associated with the given address.
-.TP
-\fBsetaccount 'bitcoinaddress' ['account']\fR
-Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
-.TP
-\fBgetaccountaddress 'account'\fR
-Returns a new bitcoin address for 'account'.
-.TP
-\fBgetaddressesbyaccount 'account'\fR
-Returns the list of addresses associated with the given 'account'.
-.TP
-\fBgetbalance 'account'\fR
-Returns the server's available balance, or the balance for 'account'.
-.TP
-\fBgetblockcount\fR
-Returns the number of blocks in the longest block chain.
-.TP
-\fBgetblocknumber\fR
-Returns the block number of the latest block in the longest block chain.
-.TP
-\fBgetconnectioncount\fR
-Returns the number of connections to other nodes.
-.TP
-\fBgetdifficulty\fR
-Returns the proof-of-work difficulty as a multiple of the minimum difficulty.
-.TP
-\fBgetgenerate\fR
-Returns boolean true if server is trying to generate bitcoins, false otherwise.
-.TP
-\fBsetgenerate 'generate' ['genproclimit']\fR
-Generation is limited to ['genproclimit'] processors, \-1 is unlimited.
-.TP
-\fBgethashespersec\fR
-Returns a recent hashes per second performance measurement while generating.
-.TP
-\fBgetinfo\fR
-Returns an object containing server information.
-.TP
-\fBgetnewaddress 'account'\fR
-Returns a new bitcoin address for receiving payments. If 'account' is specified (recommended), it is added to the address book so payments received with the address will be credited to 'account'.
-.TP
-\fBgetreceivedbyaccount 'account' ['minconf=1']\fR
-Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations.
-.TP
-\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR
-Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations.
-.TP
-\fBgettransaction 'txid'\fR
-Returns information about a specific transaction, given hexadecimal transaction ID.
-.TP
-\fBgetwork 'data'\fR
-If 'data' is specified, tries to solve the block and returns true if it was successful. If 'data' is not specified, returns formatted hash 'data' to work on:
+\fBhelp\fR
+List commands.
- "midstate" : precomputed hash state after hashing the first half of the data.
- "data" : block data.
- "hash1" : formatted hash buffer for second hash.
- "target" : little endian hash target.
.TP
\fBhelp 'command'\fR
-List commands, or get help for a command.
-.TP
-\fBlistaccounts ['minconf=1']\fR
-List accounts and their current balances.
- *note: requires bitcoin 0.3.20 or later.
-.TP
-\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR
-['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
-
- "account" : the account of the receiving address.
- "amount" : total amount received by the address.
- "confirmations" : number of confirmations of the most recent transaction included.
-.TP
-\fBlistreceivedbyaddress ['minconf=1'] ['includeempty=false']\fR
-['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
-
- "address" : receiving address.
- "account" : the account of the receiving address.
- "amount" : total amount received by the address.
- "confirmations" : number of confirmations of the most recent transaction included.
-.TP
-\fBlisttransactions 'account' ['count=10']\fR
-Returns a list of the last ['count'] transactions for 'account' \- for all accounts if 'account' is not specified or is "*". Each entry in the list may contain:
-
- "category" : will be generate, send, receive, or move.
- "amount" : amount of transaction.
- "fee" : Fee (if any) paid (only for send transactions).
- "confirmations" : number of confirmations (only for generate/send/receive).
- "txid" : transaction ID (only for generate/send/receive).
- "otheraccount" : account funds were moved to or from (only for move).
- "message" : message associated with transaction (only for send).
- "to" : message-to associated with transaction (only for send).
-
- *note: requires bitcoin 0.3.20 or later.
-.TP
-\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR
-Moves funds between accounts.
-.TP
-\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR
-Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success.
-.TP
-\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR
-Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success.
-.TP
-\fBstop\fR
-Stops the bitcoin server.
-.TP
-\fBvalidateaddress 'bitcoinaddress'\fR
-Checks that 'bitcoinaddress' looks like a proper bitcoin address. Returns an object containing:
-
- "isvalid" : true or false.
- "ismine" : true if the address is in the server's wallet.
- "address" : bitcoinaddress.
-
- *note: ismine and address are only returned if the address is valid.
+Get help for a command.
.SH "SEE ALSO"
bitcoin.conf(5)
diff --git a/contrib/debian/watch b/contrib/debian/watch
index c96d2f8e75..4d9e0cfa57 100644
--- a/contrib/debian/watch
+++ b/contrib/debian/watch
@@ -1,7 +1,5 @@
# Run the "uscan" command to check for upstream updates and more.
version=3
# use qa.debian.org redirector; see man uscan
-opts=uversionmangle=s/(\d)(alpha|beta|rc)/$1~$2/;s/\-src//,dversionmangle=s/~dfsg\d*// \
- http://sf.net/bitcoin/bitcoin-(\d.*)-linux\.tar\.gz debian
opts=uversionmangle=s/(\d)(alpha|beta|rc)/$1~$2/,dversionmangle=s/~dfsg\d*// \
http://githubredir.debian.net/github/bitcoin/bitcoin v(.*).tar.gz
diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md
index a57b4e561e..a58b8733a6 100644
--- a/contrib/devtools/README.md
+++ b/contrib/devtools/README.md
@@ -1,9 +1,45 @@
Contents
-===========
+========
This directory contains tools for developers working on this repository.
+clang-format.py
+===============
+
+A script to format cpp source code according to [.clang-format](../../src/.clang-format). This should only be applied to new files or files which are currently not actively developed on. Also, git subtrees are not subject to formatting.
+
+fix-copyright-headers.py
+========================
+
+Every year newly updated files need to have its copyright headers updated to reflect the current year.
+If you run this script from src/ it will automatically update the year on the copyright header for all
+.cpp and .h files if these have a git commit from the current year.
+
+For example a file changed in 2014 (with 2014 being the current year):
+
+```// Copyright (c) 2009-2013 The Bitcoin Core developers```
+
+would be changed to:
+
+```// Copyright (c) 2009-2014 The Bitcoin Core developers```
+
+git-subtree-check.sh
+====================
+
+Run this script from the root of the repository to verify that a subtree matches the contents of
+the commit it claims to have been updated to.
+
+To use, make sure that you have fetched the upstream repository branch in which the subtree is
+maintained:
+* for `src/secp256k1`: https://github.com/bitcoin/secp256k1.git (branch master)
+* for `src/leveldb`: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork)
+* for `src/univalue`: https://github.com/bitcoin/univalue.git (branch master)
+
+Usage: `git-subtree-check.sh DIR COMMIT`
+
+`COMMIT` may be omitted, in which case `HEAD` is used.
+
github-merge.sh
-==================
+===============
A small script to automate merging pull-requests securely and sign them with GPG.
@@ -36,24 +72,22 @@ Configuring the github-merge tool for the bitcoin repository is done in the foll
git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing)
git config --global user.signingkey mykeyid (if you want to GPG sign)
-fix-copyright-headers.py
-===========================
+optimize-pngs.py
+================
-Every year newly updated files need to have its copyright headers updated to reflect the current year.
-If you run this script from src/ it will automatically update the year on the copyright header for all
-.cpp and .h files if these have a git commit from the current year.
+A script to optimize png files in the bitcoin
+repository (requires pngcrush).
-For example a file changed in 2014 (with 2014 being the current year):
-```// Copyright (c) 2009-2013 The Bitcoin developers```
+security-check.py and test-security-check.py
+============================================
-would be changed to:
-```// Copyright (c) 2009-2014 The Bitcoin developers```
+Perform basic ELF security checks on a series of executables.
symbol-check.py
-==================
+===============
A script to check that the (Linux) executables produced by gitian only contain
-allowed gcc, glibc and libstdc++ version symbols. This makes sure they are
+allowed gcc, glibc and libstdc++ version symbols. This makes sure they are
still compatible with the minimum supported Linux distribution versions.
Example usage after a gitian build:
@@ -70,7 +104,7 @@ If there are 'unsupported' symbols, the return value will be 1 a list like this
.../64/test_bitcoin: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15
update-translations.py
-=======================
+======================
Run this script from the root of the repository to update all translations from transifex.
It will do the following automatically:
@@ -80,4 +114,3 @@ It will do the following automatically:
- add missing translations to the build system (TODO)
See doc/translation-process.md for more information.
-
diff --git a/contrib/devtools/clang-format.py b/contrib/devtools/clang-format.py
new file mode 100755
index 0000000000..cee99047ac
--- /dev/null
+++ b/contrib/devtools/clang-format.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+'''
+Wrapper script for clang-format
+
+Copyright (c) 2015 MarcoFalke
+Copyright (c) 2015 The Bitcoin Core developers
+Distributed under the MIT software license, see the accompanying
+file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+
+import os
+import sys
+import subprocess
+
+tested_versions = ['3.6.0', '3.6.1', '3.6.2'] # A set of versions known to produce the same output
+accepted_file_extensions = ('.h', '.cpp') # Files to format
+
+def check_clang_format_version(clang_format_exe):
+ try:
+ output = subprocess.check_output([clang_format_exe, '-version'])
+ for ver in tested_versions:
+ if ver in output:
+ print "Detected clang-format version " + ver
+ return
+ raise RuntimeError("Untested version: " + output)
+ except Exception as e:
+ print 'Could not verify version of ' + clang_format_exe + '.'
+ raise e
+
+def check_command_line_args(argv):
+ required_args = ['{clang-format-exe}', '{files}']
+ example_args = ['clang-format-3.x', 'src/main.cpp', 'src/wallet/*']
+
+ if(len(argv) < len(required_args) + 1):
+ for word in (['Usage:', argv[0]] + required_args):
+ print word,
+ print ''
+ for word in (['E.g:', argv[0]] + example_args):
+ print word,
+ print ''
+ sys.exit(1)
+
+def run_clang_format(clang_format_exe, files):
+ for target in files:
+ if os.path.isdir(target):
+ for path, dirs, files in os.walk(target):
+ run_clang_format(clang_format_exe, (os.path.join(path, f) for f in files))
+ elif target.endswith(accepted_file_extensions):
+ print "Format " + target
+ subprocess.check_call([clang_format_exe, '-i', '-style=file', target], stdout=open(os.devnull, 'wb'), stderr=subprocess.STDOUT)
+ else:
+ print "Skip " + target
+
+def main(argv):
+ check_command_line_args(argv)
+ clang_format_exe = argv[1]
+ files = argv[2:]
+ check_clang_format_version(clang_format_exe)
+ run_clang_format(clang_format_exe, files)
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py
index 52fdc99144..5e84952548 100755
--- a/contrib/devtools/fix-copyright-headers.py
+++ b/contrib/devtools/fix-copyright-headers.py
@@ -7,11 +7,11 @@ a perl regex one liner.
For example: if it finds something like this and we're in 2014
-// Copyright (c) 2009-2013 The Bitcoin developers
+// Copyright (c) 2009-2013 The Bitcoin Core developers
it will change it to
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
It will do this for all the files in the folder and its children.
diff --git a/contrib/devtools/git-subtree-check.sh b/contrib/devtools/git-subtree-check.sh
new file mode 100755
index 0000000000..1cb82fe682
--- /dev/null
+++ b/contrib/devtools/git-subtree-check.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+DIR="$1"
+COMMIT="$2"
+if [ -z "$COMMIT" ]; then
+ COMMIT=HEAD
+fi
+
+# Taken from git-subtree (Copyright (C) 2009 Avery Pennarun <apenwarr@gmail.com>)
+find_latest_squash()
+{
+ dir="$1"
+ sq=
+ main=
+ sub=
+ git log --grep="^git-subtree-dir: $dir/*\$" \
+ --pretty=format:'START %H%n%s%n%n%b%nEND%n' "$COMMIT" |
+ while read a b junk; do
+ case "$a" in
+ START) sq="$b" ;;
+ git-subtree-mainline:) main="$b" ;;
+ git-subtree-split:) sub="$b" ;;
+ END)
+ if [ -n "$sub" ]; then
+ if [ -n "$main" ]; then
+ # a rejoin commit?
+ # Pretend its sub was a squash.
+ sq="$sub"
+ fi
+ echo "$sq" "$sub"
+ break
+ fi
+ sq=
+ main=
+ sub=
+ ;;
+ esac
+ done
+}
+
+latest_squash="$(find_latest_squash "$DIR")"
+if [ -z "$latest_squash" ]; then
+ echo "ERROR: $DIR is not a subtree" >&2
+ exit 2
+fi
+
+set $latest_squash
+old=$1
+rev=$2
+if [ "d$(git cat-file -t $rev 2>/dev/null)" != dcommit ]; then
+ echo "ERROR: subtree commit $rev unavailable. Fetch/update the subtree repository" >&2
+ exit 2
+fi
+tree_subtree=$(git show -s --format="%T" $rev)
+echo "$DIR in $COMMIT was last updated to upstream commit $rev (tree $tree_subtree)"
+tree_actual=$(git ls-tree -d "$COMMIT" "$DIR" | head -n 1)
+if [ -z "$tree_actual" ]; then
+ echo "FAIL: subtree directory $DIR not found in $COMMIT" >&2
+ exit 1
+fi
+set $tree_actual
+tree_actual_type=$2
+tree_actual_tree=$3
+echo "$DIR in $COMMIT currently refers to $tree_actual_type $tree_actual_tree"
+if [ "d$tree_actual_type" != "dtree" ]; then
+ echo "FAIL: subtree directory $DIR is not a tree in $COMMIT" >&2
+ exit 1
+fi
+if [ "$tree_actual_tree" != "$tree_subtree" ]; then
+ git diff-tree $tree_actual_tree $tree_subtree >&2
+ echo "FAIL: subtree directory tree doesn't match subtree commit tree" >&2
+ exit 1
+fi
+echo "GOOD"
diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh
index 3217a06195..afb53f0390 100755
--- a/contrib/devtools/github-merge.sh
+++ b/contrib/devtools/github-merge.sh
@@ -136,6 +136,9 @@ else
echo "Dropping you on a shell so you can try building/testing the merged source." >&2
echo "Run 'git diff HEAD~' to show the changes being merged." >&2
echo "Type 'exit' when done." >&2
+ if [[ -f /etc/debian_version ]]; then # Show pull number in prompt on Debian default prompt
+ export debian_chroot="$PULL"
+ fi
bash -i
read -p "Press 'm' to accept the merge. " -n 1 -r >&2
echo
@@ -153,12 +156,21 @@ read -p "Press 's' to sign off on the merge. " -n 1 -r >&2
echo
if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then
if [[ "$(git config --get user.signingkey)" == "" ]]; then
- echo "WARNING: No GPG signing key set, not signing. Set one using:" >&2
+ echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2
echo "git config --global user.signingkey <key>" >&2
- git commit -q --signoff --amend --no-edit
+ cleanup
+ exit 1
else
- git commit -q --gpg-sign --amend --no-edit
+ if ! git commit -q --gpg-sign --amend --no-edit; then
+ echo "Error signing, exiting."
+ cleanup
+ exit 1
+ fi
fi
+else
+ echo "Not signing off on merge, exiting."
+ cleanup
+ exit 1
fi
# Clean up temporary branches, and put the result in $BRANCH.
diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py
new file mode 100755
index 0000000000..799e0cc7d0
--- /dev/null
+++ b/contrib/devtools/optimize-pngs.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+'''
+Run this script every time you change one of the png files. Using pngcrush, it will optimize the png files, remove various color profiles, remove ancillary chunks (alla) and text chunks (text).
+#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
+'''
+import os
+import sys
+import subprocess
+import hashlib
+from PIL import Image
+
+def file_hash(filename):
+ '''Return hash of raw file contents'''
+ with open(filename, 'rb') as f:
+ return hashlib.sha256(f.read()).hexdigest()
+
+def content_hash(filename):
+ '''Return hash of RGBA contents of image'''
+ i = Image.open(filename)
+ i = i.convert('RGBA')
+ data = i.tobytes()
+ return hashlib.sha256(data).hexdigest()
+
+pngcrush = 'pngcrush'
+git = 'git'
+folders = ["src/qt/res/movies", "src/qt/res/icons", "share/pixmaps"]
+basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
+totalSaveBytes = 0
+noHashChange = True
+
+outputArray = []
+for folder in folders:
+ absFolder=os.path.join(basePath, folder)
+ for file in os.listdir(absFolder):
+ extension = os.path.splitext(file)[1]
+ if extension.lower() == '.png':
+ print("optimizing "+file+"..."),
+ file_path = os.path.join(absFolder, file)
+ fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)};
+ fileMetaMap['contentHashPre'] = content_hash(file_path)
+
+ pngCrushOutput = ""
+ try:
+ pngCrushOutput = subprocess.check_output(
+ [pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path],
+ stderr=subprocess.STDOUT).rstrip('\n')
+ except:
+ print "pngcrush is not installed, aborting..."
+ sys.exit(0)
+
+ #verify
+ if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT):
+ print "PNG file "+file+" is corrupted after crushing, check out pngcursh version"
+ sys.exit(1)
+
+ fileMetaMap['sha256New'] = file_hash(file_path)
+ fileMetaMap['contentHashPost'] = content_hash(file_path)
+
+ if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']:
+ print "Image contents of PNG file "+file+" before and after crushing don't match"
+ sys.exit(1)
+
+ fileMetaMap['psize'] = os.path.getsize(file_path)
+ outputArray.append(fileMetaMap)
+ print("done\n"),
+
+print "summary:\n+++++++++++++++++"
+for fileDict in outputArray:
+ oldHash = fileDict['sha256Old']
+ newHash = fileDict['sha256New']
+ totalSaveBytes += fileDict['osize'] - fileDict['psize']
+ noHashChange = noHashChange and (oldHash == newHash)
+ print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n"
+
+print "completed. Checksum stable: "+str(noHashChange)+". Total reduction: "+str(totalSaveBytes)+" bytes"
diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py
new file mode 100755
index 0000000000..e96eaa9c38
--- /dev/null
+++ b/contrib/devtools/security-check.py
@@ -0,0 +1,181 @@
+#!/usr/bin/python2
+'''
+Perform basic ELF security checks on a series of executables.
+Exit status will be 0 if succesful, and the program will be silent.
+Otherwise the exit status will be 1 and it will log which executables failed which checks.
+Needs `readelf` (for ELF) and `objdump` (for PE).
+'''
+from __future__ import division,print_function
+import subprocess
+import sys
+import os
+
+READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
+OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
+
+def check_ELF_PIE(executable):
+ '''
+ Check for position independent executable (PIE), allowing for address space randomization.
+ '''
+ p = subprocess.Popen([READELF_CMD, '-h', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Error opening file')
+
+ ok = False
+ for line in stdout.split('\n'):
+ line = line.split()
+ if len(line)>=2 and line[0] == 'Type:' and line[1] == 'DYN':
+ ok = True
+ return ok
+
+def get_ELF_program_headers(executable):
+ '''Return type and flags for ELF program headers'''
+ p = subprocess.Popen([READELF_CMD, '-l', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Error opening file')
+ in_headers = False
+ count = 0
+ headers = []
+ for line in stdout.split('\n'):
+ if line.startswith('Program Headers:'):
+ in_headers = True
+ if line == '':
+ in_headers = False
+ if in_headers:
+ if count == 1: # header line
+ ofs_typ = line.find('Type')
+ ofs_offset = line.find('Offset')
+ ofs_flags = line.find('Flg')
+ ofs_align = line.find('Align')
+ if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1:
+ raise ValueError('Cannot parse elfread -lW output')
+ elif count > 1:
+ typ = line[ofs_typ:ofs_offset].rstrip()
+ flags = line[ofs_flags:ofs_align].rstrip()
+ headers.append((typ, flags))
+ count += 1
+ return headers
+
+def check_ELF_NX(executable):
+ '''
+ Check that no sections are writable and executable (including the stack)
+ '''
+ have_wx = False
+ have_gnu_stack = False
+ for (typ, flags) in get_ELF_program_headers(executable):
+ if typ == 'GNU_STACK':
+ have_gnu_stack = True
+ if 'W' in flags and 'E' in flags: # section is both writable and executable
+ have_wx = True
+ return have_gnu_stack and not have_wx
+
+def check_ELF_RELRO(executable):
+ '''
+ Check for read-only relocations.
+ GNU_RELRO program header must exist
+ Dynamic section must have BIND_NOW flag
+ '''
+ have_gnu_relro = False
+ for (typ, flags) in get_ELF_program_headers(executable):
+ # Note: not checking flags == 'R': here as linkers set the permission differently
+ # This does not affect security: the permission flags of the GNU_RELRO program header are ignored, the PT_LOAD header determines the effective permissions.
+ # However, the dynamic linker need to write to this area so these are RW.
+ # Glibc itself takes care of mprotecting this area R after relocations are finished.
+ # See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347
+ if typ == 'GNU_RELRO':
+ have_gnu_relro = True
+
+ have_bindnow = False
+ p = subprocess.Popen([READELF_CMD, '-d', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Error opening file')
+ for line in stdout.split('\n'):
+ tokens = line.split()
+ if len(tokens)>1 and tokens[1] == '(BIND_NOW)':
+ have_bindnow = True
+ return have_gnu_relro and have_bindnow
+
+def check_ELF_Canary(executable):
+ '''
+ Check for use of stack canary
+ '''
+ p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Error opening file')
+ ok = False
+ for line in stdout.split('\n'):
+ if '__stack_chk_fail' in line:
+ ok = True
+ return ok
+
+def get_PE_dll_characteristics(executable):
+ '''
+ Get PE DllCharacteristics bits
+ '''
+ p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Error opening file')
+ for line in stdout.split('\n'):
+ tokens = line.split()
+ if len(tokens)>=2 and tokens[0] == 'DllCharacteristics':
+ return int(tokens[1],16)
+ return 0
+
+
+def check_PE_PIE(executable):
+ '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
+ return bool(get_PE_dll_characteristics(executable) & 0x40)
+
+def check_PE_NX(executable):
+ '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)'''
+ return bool(get_PE_dll_characteristics(executable) & 0x100)
+
+CHECKS = {
+'ELF': [
+ ('PIE', check_ELF_PIE),
+ ('NX', check_ELF_NX),
+ ('RELRO', check_ELF_RELRO),
+ ('Canary', check_ELF_Canary)
+],
+'PE': [
+ ('PIE', check_PE_PIE),
+ ('NX', check_PE_NX)
+]
+}
+
+def identify_executable(executable):
+ with open(filename, 'rb') as f:
+ magic = f.read(4)
+ if magic.startswith(b'MZ'):
+ return 'PE'
+ elif magic.startswith(b'\x7fELF'):
+ return 'ELF'
+ return None
+
+if __name__ == '__main__':
+ retval = 0
+ for filename in sys.argv[1:]:
+ try:
+ etype = identify_executable(filename)
+ if etype is None:
+ print('%s: unknown format' % filename)
+ retval = 1
+ continue
+
+ failed = []
+ for (name, func) in CHECKS[etype]:
+ if not func(filename):
+ failed.append(name)
+ if failed:
+ print('%s: failed %s' % (filename, ' '.join(failed)))
+ retval = 1
+ except IOError:
+ print('%s: cannot open' % filename)
+ retval = 1
+ exit(retval)
+
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index f3999f1c0b..93acfcdda4 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -1,6 +1,6 @@
-#!/usr/bin/python
+#!/usr/bin/python2
# Copyright (c) 2014 Wladimir J. van der Laan
-# Distributed under the MIT/X11 software license, see the accompanying
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
A script to check that the (Linux) executables produced by gitian only contain
@@ -15,6 +15,7 @@ from __future__ import division, print_function
import subprocess
import re
import sys
+import os
# Debian 6.0.9 (Squeeze) has:
#
@@ -45,8 +46,27 @@ MAX_VERSIONS = {
IGNORE_EXPORTS = {
'_edata', '_end', '_init', '__bss_start', '_fini'
}
-READELF_CMD = '/usr/bin/readelf'
-CPPFILT_CMD = '/usr/bin/c++filt'
+READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
+CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
+# Allowed NEEDED libraries
+ALLOWED_LIBRARIES = {
+# bitcoind and bitcoin-qt
+'libgcc_s.so.1', # GCC base support
+'libc.so.6', # C library
+'libpthread.so.0', # threading
+'libanl.so.1', # DNS resolve
+'libm.so.6', # math library
+'librt.so.1', # real-time (clock)
+'ld-linux-x86-64.so.2', # 64-bit dynamic linker
+'ld-linux.so.2', # 32-bit dynamic linker
+# bitcoin-qt only
+'libX11-xcb.so.1', # part of X11
+'libX11.so.6', # part of X11
+'libxcb.so.1', # part of X11
+'libfontconfig.so.1', # font support
+'libfreetype.so.6', # font parsing
+'libdl.so.2' # programming interface to dynamic linker
+}
class CPPFilt(object):
'''
@@ -98,6 +118,22 @@ def check_version(max_versions, version):
return False
return ver <= max_versions[lib]
+def read_libraries(filename):
+ p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ if p.returncode:
+ raise IOError('Error opening file')
+ libraries = []
+ for line in stdout.split('\n'):
+ tokens = line.split()
+ if len(tokens)>2 and tokens[1] == '(NEEDED)':
+ match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:]))
+ if match:
+ libraries.append(match.group(1))
+ else:
+ raise ValueError('Unparseable (NEEDED) specification')
+ return libraries
+
if __name__ == '__main__':
cppfilt = CPPFilt()
retval = 0
@@ -113,6 +149,11 @@ if __name__ == '__main__':
continue
print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
retval = 1
+ # Check dependency libraries
+ for library_name in read_libraries(filename):
+ if library_name not in ALLOWED_LIBRARIES:
+ print('%s: NEEDED library %s is not allowed' % (filename, library_name))
+ retval = 1
exit(retval)
diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py
new file mode 100755
index 0000000000..fed7626aab
--- /dev/null
+++ b/contrib/devtools/test-security-check.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python2
+'''
+Test script for security-check.py
+'''
+from __future__ import division,print_function
+import subprocess
+import sys
+import unittest
+
+def write_testcode(filename):
+ with open(filename, 'w') as f:
+ f.write('''
+ #include <stdio.h>
+ int main()
+ {
+ printf("the quick brown fox jumps over the lazy god\\n");
+ return 0;
+ }
+ ''')
+
+def call_security_check(cc, source, executable, options):
+ subprocess.check_call([cc,source,'-o',executable] + options)
+ p = subprocess.Popen(['./security-check.py',executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ (stdout, stderr) = p.communicate()
+ return (p.returncode, stdout.rstrip())
+
+class TestSecurityChecks(unittest.TestCase):
+ def test_ELF(self):
+ source = 'test1.c'
+ executable = 'test1'
+ cc = 'gcc'
+ write_testcode(source)
+
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro']),
+ (1, executable+': failed PIE NX RELRO Canary'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro']),
+ (1, executable+': failed PIE RELRO Canary'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro']),
+ (1, executable+': failed PIE RELRO'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE']),
+ (1, executable+': failed RELRO'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE']),
+ (0, ''))
+
+ def test_PE(self):
+ source = 'test1.c'
+ executable = 'test1.exe'
+ cc = 'i686-w64-mingw32-gcc'
+ write_testcode(source)
+
+ self.assertEqual(call_security_check(cc, source, executable, []),
+ (1, executable+': failed PIE NX'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat']),
+ (1, executable+': failed PIE'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase']),
+ (0, ''))
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py
index 3e34b33971..2b6e807b47 100755
--- a/contrib/devtools/update-translations.py
+++ b/contrib/devtools/update-translations.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
# Copyright (c) 2014 Wladimir J. van der Laan
-# Distributed under the MIT/X11 software license, see the accompanying
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Run this script from the root of the repository to update all translations from
@@ -29,6 +29,8 @@ TX = 'tx'
SOURCE_LANG = 'bitcoin_en.ts'
# Directory with locale files
LOCALE_DIR = 'src/qt/locale'
+# Minimum number of messages for translation to be considered at all
+MIN_NUM_MESSAGES = 10
def check_at_repository_root():
if not os.path.exists('.git'):
@@ -37,7 +39,7 @@ def check_at_repository_root():
exit(1)
def fetch_all_translations():
- if subprocess.call([TX, 'pull', '-f']):
+ if subprocess.call([TX, 'pull', '-f', '-a']):
print('Error while fetching translations', file=sys.stderr)
exit(1)
@@ -169,6 +171,15 @@ def postprocess_translations(reduce_diff_hacks=False):
if translation_node.get('type') == 'unfinished':
context.remove(message)
+ # check if document is (virtually) empty, and remove it if so
+ num_messages = 0
+ for context in root.findall('context'):
+ for message in context.findall('message'):
+ num_messages += 1
+ if num_messages < MIN_NUM_MESSAGES:
+ print('Removing %s, as it contains only %i messages' % (filepath, num_messages))
+ continue
+
# write fixed-up tree
# if diff reduction requested, replace some XML to 'sanitize' to qt formatting
if reduce_diff_hacks:
diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md
index 7a67263ee4..6149706596 100644
--- a/contrib/gitian-descriptors/README.md
+++ b/contrib/gitian-descriptors/README.md
@@ -1,8 +1,7 @@
-### Gavin's notes on getting gitian builds up and running using KVM:###
+### Gavin's notes on getting gitian builds up and running using KVM
-These instructions distilled from:
-[ https://help.ubuntu.com/community/KVM/Installation]( https://help.ubuntu.com/community/KVM/Installation)
-... see there for complete details.
+These instructions distilled from
+[https://help.ubuntu.com/community/KVM/Installation](https://help.ubuntu.com/community/KVM/Installation).
You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization.
@@ -27,21 +26,20 @@ Once you've got the right hardware and software:
# Create base images
cd gitian-builder
- bin/make-base-vm --suite precise --arch i386
- bin/make-base-vm --suite precise --arch amd64
+ bin/make-base-vm --suite trusty --arch amd64
cd ..
# Get inputs (see doc/release-process.md for exact inputs needed and where to get them)
...
- # For further build instructions see doc/release-notes.md
+ # For further build instructions see doc/release-process.md
...
---------------------
`gitian-builder` now also supports building using LXC. See
-[ https://help.ubuntu.com/12.04/serverguide/lxc.html]( https://help.ubuntu.com/12.04/serverguide/lxc.html)
-... for how to get LXC up and running under Ubuntu.
+[help.ubuntu.com](https://help.ubuntu.com/14.04/serverguide/lxc.html)
+for how to get LXC up and running under Ubuntu.
If your main machine is a 64-bit Mac or PC with a few gigabytes of memory
and at least 10 gigabytes of free disk space, you can `gitian-build` using
diff --git a/contrib/gitian-descriptors/boost-linux.yml b/contrib/gitian-descriptors/boost-linux.yml
deleted file mode 100644
index bd35346337..0000000000
--- a/contrib/gitian-descriptors/boost-linux.yml
+++ /dev/null
@@ -1,55 +0,0 @@
----
-name: "boost"
-suites:
-- "precise"
-architectures:
-- "i386"
-- "amd64"
-packages:
-- "g++"
-- "unzip"
-- "pkg-config"
-- "libtool"
-- "faketime"
-- "bsdmainutils"
-- "zip"
-- "libz-dev"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "boost_1_55_0.tar.bz2"
-script: |
- STAGING="$HOME/install"
- TEMPDIR="$HOME/tmp"
- export LIBRARY_PATH="$STAGING/lib"
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- # Input Integrity Check
- echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | shasum -c
-
- mkdir -p "$STAGING"
- tar --warning=no-timestamp -xjf boost_1_55_0.tar.bz2
- cd boost_1_55_0
- GCCVERSION=$(g++ -E -dM $(mktemp --suffix=.h) | grep __VERSION__ | cut -d ' ' -f 3 | cut -d '"' -f 2)
- # note: bjam with -d+2 reveals that -O3 is implied by default, no need to provide it in cxxflags
- echo "using gcc : $GCCVERSION : g++
- :
- <cxxflags>\"-frandom-seed=boost1 -fPIC\"
- ;" > user-config.jam
-
- ./bootstrap.sh --without-icu
-
- ./bjam toolset=gcc threadapi=pthread threading=multi variant=release link=static runtime-link=shared --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 --layout=tagged --build-type=complete --prefix="$STAGING" $MAKEOPTS -d+2 install
-
- # post-process all generated libraries to be deterministic
- # extract them to a temporary directory then re-build them deterministically
- for LIB in $(find $STAGING -name \*.a); do
- rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR
- ar xv $LIB | cut -b5- > /tmp/list.txt
- rm $LIB
- ar crsD $LIB $(cat /tmp/list.txt)
- done
- #
- cd "$STAGING"
- find | sort | zip -X@ $OUTDIR/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip
diff --git a/contrib/gitian-descriptors/boost-win.yml b/contrib/gitian-descriptors/boost-win.yml
deleted file mode 100644
index db5d6bab1d..0000000000
--- a/contrib/gitian-descriptors/boost-win.yml
+++ /dev/null
@@ -1,86 +0,0 @@
----
-name: "boost"
-suites:
-- "precise"
-architectures:
-- "amd64"
-packages:
-- "mingw-w64"
-- "g++-mingw-w64"
-- "faketime"
-- "zip"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "boost_1_55_0.tar.bz2"
-- "boost-mingw-gas-cross-compile-2013-03-03.patch"
-script: |
- # Defines
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- INDIR=$HOME/build
- TEMPDIR=$HOME/tmp
- # Input Integrity Check
- echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | shasum -c
- echo "d2b7f6a1d7051faef3c9cf41a92fa3671d905ef1e1da920d07651a43299f6268 boost-mingw-gas-cross-compile-2013-03-03.patch" | shasum -c
-
- for BITS in 32 64; do # for architectures
- #
- INSTALLPREFIX=$HOME/staging${BITS}
- BUILDDIR=$HOME/build${BITS}
- if [ "$BITS" == "32" ]; then
- HOST=i686-w64-mingw32
- else
- HOST=x86_64-w64-mingw32
- fi
- #
- mkdir -p $INSTALLPREFIX $BUILDDIR
- cd $BUILDDIR
- #
- tar --warning=no-timestamp -xjf $INDIR/boost_1_55_0.tar.bz2
- cd boost_1_55_0
- GCCVERSION=$($HOST-g++ -E -dM $(mktemp --suffix=.h) | grep __VERSION__ | cut -d ' ' -f 3 | cut -d '"' -f 2)
- echo "using gcc : $GCCVERSION : $HOST-g++
- :
- <rc>$HOST-windres
- <archiver>$HOST-ar
- <cxxflags>-frandom-seed=boost1
- <ranlib>$HOST-ranlib
- ;" > user-config.jam
- ./bootstrap.sh --without-icu
-
- # Workaround: Upstream boost dev refuses to include patch that would allow Free Software cross-compile toolchain to work
- # This patch was authored by the Fedora package developer and ships in Fedora's mingw32-boost.
- # Please obtain the exact patch that matches the above sha256sum from one of the following mirrors.
- #
- # Read History: https://svn.boost.org/trac/boost/ticket/7262
- # History Mirror: http://rose.makesad.us/~paulproteus/mirrors/7262%20Boost.Context%20fails%20to%20build%20using%20MinGW.html
- #
- # Patch: https://svn.boost.org/trac/boost/raw-attachment/ticket/7262/boost-mingw.patch
- # Patch Mirror: http://wtogami.fedorapeople.org/boost-mingw-gas-cross-compile-2013-03-03.patch
- # Patch Mirror: http://mindstalk.net/host/boost-mingw-gas-cross-compile-2013-03-03.patch
- # Patch Mirror: http://rose.makesad.us/~paulproteus/mirrors/boost-mingw-gas-cross-compile-2013-03-03.patch
- patch -p0 < $INDIR/boost-mingw-gas-cross-compile-2013-03-03.patch
-
- # Bug Workaround: boost-1.54.0 broke the ability to disable zlib, still broken in 1.55
- # https://svn.boost.org/trac/boost/ticket/9156
- sed -i 's^\[ ac.check-library /zlib//zlib : <library>/zlib//zlib^^' libs/iostreams/build/Jamfile.v2
- sed -i 's^<source>zlib.cpp <source>gzip.cpp \]^^' libs/iostreams/build/Jamfile.v2
-
- # http://statmt.org/~s0565741/software/boost_1_52_0/libs/context/doc/html/context/requirements.html
- # "For cross-compiling the lib you must specify certain additional properties at bjam command line: target-os, abi, binary-format, architecture and address-model."
- ./bjam toolset=gcc binary-format=pe target-os=windows threadapi=win32 address-model=$BITS threading=multi variant=release link=static runtime-link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete --prefix="$INSTALLPREFIX" $MAKEOPTS install
- # post-process all generated libraries to be deterministic
- # extract them to a temporary directory then re-build them deterministically
- for LIB in $(find $INSTALLPREFIX -name \*.a); do
- rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR
- $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt
- rm $LIB
- $HOST-ar crsD $LIB $(cat /tmp/list.txt)
- done
- #
- cd "$INSTALLPREFIX"
- find | sort | zip -X@ $OUTDIR/boost-win$BITS-1.55.0-gitian-r6.zip
- done # for BITS in
-
diff --git a/contrib/gitian-descriptors/deps-linux.yml b/contrib/gitian-descriptors/deps-linux.yml
deleted file mode 100644
index 8221222133..0000000000
--- a/contrib/gitian-descriptors/deps-linux.yml
+++ /dev/null
@@ -1,98 +0,0 @@
----
-name: "bitcoin"
-suites:
-- "precise"
-architectures:
-- "i386"
-- "amd64"
-packages:
-- "g++"
-- "unzip"
-- "zip"
-- "pkg-config"
-- "libtool"
-- "faketime"
-- "bsdmainutils"
-reference_datetime: "2013-06-01 00:00:00"
-remotes: []
-files:
-- "openssl-1.0.1h.tar.gz"
-- "miniupnpc-1.9.tar.gz"
-- "qrencode-3.4.3.tar.bz2"
-- "protobuf-2.5.0.tar.bz2"
-- "db-4.8.30.NC.tar.gz"
-script: |
- STAGING="$HOME/install"
- TEMPDIR="$HOME/tmp"
- OPTFLAGS='-O2'
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- export LIBRARY_PATH="$STAGING/lib"
- # Integrity Check
- echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c
- echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c
- echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c
- echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
- echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c
-
- #
- tar xzf openssl-1.0.1h.tar.gz
- cd openssl-1.0.1h
- # need -fPIC to avoid relocation error in 64 bit builds
- ./config no-shared no-zlib no-dso no-krb5 --openssldir=$STAGING -fPIC
- # need to build OpenSSL with faketime because a timestamp is embedded into cversion.o
- make
- make install_sw
- cd ..
- #
- tar xzfm miniupnpc-1.9.tar.gz
- cd miniupnpc-1.9
- # miniupnpc is always built with -fPIC
- INSTALLPREFIX=$STAGING make $MAKEOPTS install
- rm -f $STAGING/lib/libminiupnpc.so* # no way to skip shared lib build
- cd ..
- #
- tar xjf qrencode-3.4.3.tar.bz2
- cd qrencode-3.4.3
- unset FAKETIME # unset fake time during configure, as it does some clock sanity tests
- # need --with-pic to avoid relocation error in 64 bit builds
- ./configure --prefix=$STAGING --enable-static --disable-shared --with-pic --without-tools --disable-dependency-tracking
- # Workaround to prevent re-configuring by make; make all files have a date in the past
- find . -print0 | xargs -r0 touch -t 200001010000
- export FAKETIME=$REFERENCE_DATETIME
- make $MAKEOPTS install
- cd ..
- #
- tar xjf protobuf-2.5.0.tar.bz2
- cd protobuf-2.5.0
- mkdir -p $STAGING/host/bin
- unset FAKETIME # unset fake time during configure, as it does some clock sanity tests
- # need --with-pic to avoid relocation error in 64 bit builds
- ./configure --prefix=$STAGING --bindir=$STAGING/host/bin --enable-static --disable-shared --with-pic --without-zlib
- # Workaround to prevent re-configuring by make; make all files have a date in the past
- find . -print0 | xargs -r0 touch -t 200001010000
- export FAKETIME=$REFERENCE_DATETIME
- make $MAKEOPTS install
- cd ..
- #
- tar xzf db-4.8.30.NC.tar.gz
- cd db-4.8.30.NC/build_unix
- # need --with-pic to avoid relocation error in 64 bit builds
- ../dist/configure --prefix=$STAGING --enable-cxx --disable-shared --with-pic
- # Workaround to prevent re-configuring by make; make all files have a date in the past
- find . -print0 | xargs -r0 touch -t 200001010000
- make $MAKEOPTS library_build
- make install_lib install_include
- cd ../..
- # post-process all generated libraries to be deterministic
- # extract them to a temporary directory then re-build them deterministically
- for LIB in $(find $STAGING -name \*.a); do
- rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR
- ar xv $LIB | cut -b5- > /tmp/list.txt
- rm $LIB
- ar crsD $LIB $(cat /tmp/list.txt)
- done
- #
- cd $STAGING
- find include lib bin host | sort | zip -X@ $OUTDIR/bitcoin-deps-linux${GBUILD_BITS}-gitian-r6.zip
diff --git a/contrib/gitian-descriptors/deps-win.yml b/contrib/gitian-descriptors/deps-win.yml
deleted file mode 100644
index fabc2949eb..0000000000
--- a/contrib/gitian-descriptors/deps-win.yml
+++ /dev/null
@@ -1,128 +0,0 @@
----
-name: "bitcoin-deps"
-suites:
-- "precise"
-architectures:
-- "amd64"
-packages:
-- "mingw-w64"
-- "g++-mingw-w64"
-- "git-core"
-- "zip"
-- "faketime"
-- "psmisc"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "openssl-1.0.1h.tar.gz"
-- "db-4.8.30.NC.tar.gz"
-- "miniupnpc-1.9.tar.gz"
-- "zlib-1.2.8.tar.gz"
-- "libpng-1.6.8.tar.gz"
-- "qrencode-3.4.3.tar.bz2"
-script: |
- #
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- INDIR=$HOME/build
- TEMPDIR=$HOME/tmp
- # Input Integrity Check
- echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c
- echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c
- echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c
- echo "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d zlib-1.2.8.tar.gz" | sha256sum -c
- echo "32c7acf1608b9c8b71b743b9780adb7a7b347563dbfb4a5263761056da44cc96 libpng-1.6.8.tar.gz" | sha256sum -c
- echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c
-
- for BITS in 32 64; do # for architectures
- #
- INSTALLPREFIX=$HOME/staging${BITS}
- BUILDDIR=$HOME/build${BITS}
- if [ "$BITS" == "32" ]; then
- HOST=i686-w64-mingw32
- else
- HOST=x86_64-w64-mingw32
- fi
- #
- mkdir -p $INSTALLPREFIX $BUILDDIR
- cd $BUILDDIR
- #
- tar xzf $INDIR/openssl-1.0.1h.tar.gz
- cd openssl-1.0.1h
- if [ "$BITS" == "32" ]; then
- OPENSSL_TGT=mingw
- else
- OPENSSL_TGT=mingw64
- fi
- ./Configure --cross-compile-prefix=$HOST- ${OPENSSL_TGT} no-shared no-dso --openssldir=$INSTALLPREFIX
- make
- make install_sw
- cd ..
- #
- tar xzf $INDIR/db-4.8.30.NC.tar.gz
- cd db-4.8.30.NC/build_unix
- ../dist/configure --prefix=$INSTALLPREFIX --enable-mingw --enable-cxx --host=$HOST --disable-shared
- make $MAKEOPTS library_build
- make install_lib install_include
- cd ../..
- #
- tar xzf $INDIR/miniupnpc-1.9.tar.gz
- cd miniupnpc-1.9
- echo "
- --- miniupnpc-1.9/Makefile.mingw.orig 2013-09-29 18:52:51.014087958 -1000
- +++ miniupnpc-1.9/Makefile.mingw 2013-09-29 19:09:29.663318691 -1000
- @@ -67,8 +67,8 @@
-
- wingenminiupnpcstrings.o: wingenminiupnpcstrings.c
-
- -miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings
- - wingenminiupnpcstrings \$< \$@
- +miniupnpcstrings.h: miniupnpcstrings.h.in
- + sed -e 's|OS/version|MSWindows/5.1.2600|' -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"VERSIONHERE\"|' \$< > \$@
-
- minixml.o: minixml.c minixml.h miniupnpcstrings.h
-
- " | sed "s/VERSIONHERE/$(cat VERSION)/" | patch -p1
- mkdir -p dll
- make -f Makefile.mingw CC=$HOST-gcc AR=$HOST-ar libminiupnpc.a
- install -d $INSTALLPREFIX/include/miniupnpc
- install *.h $INSTALLPREFIX/include/miniupnpc
- install libminiupnpc.a $INSTALLPREFIX/lib
- cd ..
- #
- tar xzf $INDIR/zlib-1.2.8.tar.gz
- cd zlib-1.2.8
- CROSS_PREFIX=$HOST- ./configure --prefix=$INSTALLPREFIX --static
- make
- make install
- cd ..
- #
- tar xzf $INDIR/libpng-1.6.8.tar.gz
- cd libpng-1.6.8
- OPT="-O2"
- CPPFLAGS="${OPT} -I$INSTALLPREFIX/include" CFLAGS="${OPT} -I$INSTALLPREFIX/include" LDFLAGS="${OPT} -L$INSTALLPREFIX/lib" ./configure --disable-shared --prefix=$INSTALLPREFIX --host=$HOST
- make $MAKEOPTS
- make install
- cd ..
- #
- tar xjf $INDIR/qrencode-3.4.3.tar.bz2
- cd qrencode-3.4.3
- png_CFLAGS="-I$INSTALLPREFIX/include" png_LIBS="-L$INSTALLPREFIX/lib -lpng" ./configure --prefix=$INSTALLPREFIX --host=$HOST --enable-static --disable-shared --without-tools --disable-dependency-tracking
- # Workaround to prevent re-configuring by make (resulting in missing m4 error); make all files have a date in the past
- find . -print0 | xargs -r0 touch -t 200001010000
- make
- make install
- cd ..
- # post-process all generated libraries to be deterministic
- # extract them to a temporary directory then re-build them deterministically
- for LIB in $(find $INSTALLPREFIX -name \*.a); do
- rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR
- $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt
- rm $LIB
- $HOST-ar crsD $LIB $(cat /tmp/list.txt)
- done
- #
- cd $INSTALLPREFIX
- find include lib | sort | zip -X@ $OUTDIR/bitcoin-deps-win$BITS-gitian-r13.zip
- done # for BITS in
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
index 30b0227bdd..ee852ff138 100644
--- a/contrib/gitian-descriptors/gitian-linux.yml
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -1,86 +1,109 @@
---
-name: "bitcoin"
+name: "bitcoin-linux-0.13"
+enable_cache: true
suites:
-- "precise"
+- "trusty"
architectures:
-- "i386"
- "amd64"
packages:
-- "g++"
+- "g++-multilib"
- "git-core"
-- "unzip"
- "pkg-config"
-- "autoconf2.13"
+- "autoconf"
- "libtool"
- "automake"
- "faketime"
- "bsdmainutils"
-- "libqt4-core"
-- "libqt4-gui"
-- "libqt4-dbus"
-- "libqt4-network"
-- "libqt4-test"
-reference_datetime: "2013-06-01 00:00:00"
+- "binutils-gold"
+reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
-files:
-- "bitcoin-deps-linux32-gitian-r6.zip"
-- "bitcoin-deps-linux64-gitian-r6.zip"
-- "boost-linux32-1.55.0-gitian-r1.zip"
-- "boost-linux64-1.55.0-gitian-r1.zip"
-- "qt-linux32-4.6.4-gitian-r1.tar.gz"
-- "qt-linux64-4.6.4-gitian-r1.tar.gz"
+files: []
script: |
- STAGING="$HOME/install"
- OPTFLAGS='-O2'
- BINDIR="${OUTDIR}/bin/${GBUILD_BITS}" # 32/64 bit build specific output directory
- TEMPDIR="$HOME/tempdir"
- export TZ=UTC
- export LIBRARY_PATH="$STAGING/lib"
- export PATH="$STAGING/bin:$PATH"
- mkdir -p ${BINDIR}
- #
- mkdir -p $STAGING
- cd $STAGING
- unzip ../build/bitcoin-deps-linux${GBUILD_BITS}-gitian-r6.zip
- unzip ../build/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip
- tar -zxf ../build/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz
- cd ../build
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
+ CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
+ FAKETIME_HOST_PROGS=""
+ FAKETIME_PROGS="date ar ranlib nm strip"
+
+ export QT_RCC_TEST=1
+ export GZIP="-9n"
+ export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
+ export TZ="UTC"
+ export BUILD_DIR=`pwd`
+ mkdir -p ${WRAP_DIR}
+ if test -n "$GBUILD_CACHE_ENABLED"; then
+ export SOURCES_PATH=${GBUILD_COMMON_CACHE}
+ export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
+ mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
+ fi
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ # Create per-host faketime wrappers
+ for i in $HOSTS; do
+ for prog in ${FAKETIME_HOST_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+ export PATH=${WRAP_DIR}:${PATH}
- # Avoid exporting *any* symbols from the executable
- # This avoids conflicts between the libraries statically linked into bitcoin and any
- # libraries we may link dynamically (such as Qt and OpenSSL, see issue #4094).
- # It also avoids start-up overhead to not export any unnecessary symbols.
- # To do this, build a linker script that marks all symbols as local.
- LINKER_SCRIPT=$HOME/build/linker_version_script
- echo '
- {
- local: *;
- };' > $LINKER_SCRIPT
- function do_configure {
- ./configure "$@" --enable-upnp-default --prefix=$STAGING --with-protoc-bindir=$STAGING/host/bin --with-qt-bindir=$STAGING/bin --with-boost=$STAGING --disable-maintainer-mode --disable-dependency-tracking PKG_CONFIG_PATH="$STAGING/lib/pkgconfig" CPPFLAGS="-I$STAGING/include ${OPTFLAGS}" LDFLAGS="-L$STAGING/lib -Wl,--version-script=$LINKER_SCRIPT ${OPTFLAGS}" CXXFLAGS="-frandom-seed=bitcoin ${OPTFLAGS}" --enable-glibc-back-compat
- }
- #
cd bitcoin
+ BASEPREFIX=`pwd`/depends
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Create the release tarball using (arbitrarily) the first host
./autogen.sh
- do_configure
+ ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
make dist
- DISTNAME=`echo bitcoin-*.tar.gz`
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
+ # Correct tar file order
+ mkdir -p temp
+ pushd temp
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
+ popd
- # Build dynamic versions of everything
- # (with static linking to boost and openssl as well a some non-OS deps)
- mkdir -p distsrc
- cd distsrc
- tar --strip-components=1 -xf ../$DISTNAME
- do_configure --bindir=$BINDIR
- make $MAKEOPTS
- make $MAKEOPTS install-strip
- make $MAKEOPTS clean
+ ORIGPATH="$PATH"
+ # Extract the release tarball into a dir for each host and build
+ for i in ${HOSTS}; do
+ export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
+ mkdir -p distsrc-${i}
+ cd distsrc-${i}
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
- # sort distribution tar file and normalize user/group/mtime information for deterministic output
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ make ${MAKEOPTS}
+ make install-strip
+ cd installed
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ cd ../../
+ done
mkdir -p $OUTDIR/src
- rm -rf $TEMPDIR
- mkdir -p $TEMPDIR
- cd $TEMPDIR
- tar -xvf $HOME/build/bitcoin/$DISTNAME | sort | tar --no-recursion -cT /dev/stdin --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 --mtime="$REFERENCE_DATETIME" | gzip -n > $OUTDIR/src/$DISTNAME
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz
+
diff --git a/contrib/gitian-descriptors/gitian-osx-bitcoin.yml b/contrib/gitian-descriptors/gitian-osx-bitcoin.yml
deleted file mode 100644
index bc3d561c35..0000000000
--- a/contrib/gitian-descriptors/gitian-osx-bitcoin.yml
+++ /dev/null
@@ -1,61 +0,0 @@
----
-name: "bitcoin"
-suites:
-- "precise"
-architectures:
-- "i386"
-packages:
-- "git-core"
-- "automake"
-- "faketime"
-- "bsdmainutils"
-- "pkg-config"
-- "p7zip-full"
-- "libtool"
-
-reference_datetime: "2013-06-01 00:00:00"
-remotes:
-- "url": "https://github.com/bitcoin/bitcoin.git"
- "dir": "bitcoin"
-files:
-- "osx-native-depends-r3.tar.gz"
-- "osx-depends-r4.tar.gz"
-- "osx-depends-qt-5.2.1-r4.tar.gz"
-- "MacOSX10.7.sdk.tar.gz"
-
-script: |
-
- HOST=x86_64-apple-darwin11
- PREFIX=`pwd`/osx-cross-depends/prefix
- SDK=`pwd`/osx-cross-depends/SDKs/MacOSX10.7.sdk
- NATIVEPREFIX=`pwd`/osx-cross-depends/native-prefix
- export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
-
- export SOURCES_PATH=`pwd`
-
- mkdir -p osx-cross-depends/SDKs
-
- tar -C osx-cross-depends/SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
-
- tar -C osx-cross-depends -xf osx-native-depends-r3.tar.gz
- tar -C osx-cross-depends -xf osx-depends-r4.tar.gz
- tar -C osx-cross-depends -xf osx-depends-qt-5.2.1-r4.tar.gz
- export PATH=`pwd`/osx-cross-depends/native-prefix/bin:$PATH
-
- cd bitcoin
-
- export ZERO_AR_DATE=1
- export QT_RCC_TEST=1
- ./autogen.sh
- ./configure --host=${HOST} --with-boost=${PREFIX} CC=clang CXX=clang++ OBJC=clang OBJCXX=clang++ CFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" CXXFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" LDFLAGS="-B${NATIVEPREFIX}/bin -L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" CPPFLAGS="-I${NATIVEPREFIX}/lib/clang/3.2/include -I${PREFIX}/include" SSL_LIBS="-lz -lssl -lcrypto" --disable-tests -with-gui=qt5 PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig" --disable-dependency-tracking --disable-maintainer-mode
- make dist
- mkdir -p distsrc
- cd distsrc
- tar --strip-components=1 -xf ../bitcoin-*.tar*
- ./configure --host=${HOST} --with-boost=${PREFIX} CC=clang CXX=clang++ OBJC=clang OBJCXX=clang++ CFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" CXXFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" LDFLAGS="-B${NATIVEPREFIX}/bin -L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" CPPFLAGS="-I${NATIVEPREFIX}/lib/clang/3.2/include -I${PREFIX}/include" SSL_LIBS="-lz -lssl -lcrypto" --disable-tests -with-gui=qt5 PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig" --disable-dependency-tracking --disable-maintainer-mode
- make $MAKEOPTS
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- make deploy
- dmg dmg Bitcoin-Qt.dmg $OUTDIR/Bitcoin-Qt.dmg
diff --git a/contrib/gitian-descriptors/gitian-osx-depends.yml b/contrib/gitian-descriptors/gitian-osx-depends.yml
deleted file mode 100644
index 07a021cf0c..0000000000
--- a/contrib/gitian-descriptors/gitian-osx-depends.yml
+++ /dev/null
@@ -1,159 +0,0 @@
----
-name: "osx-depends"
-suites:
-- "precise"
-architectures:
-- "i386"
-packages:
-- "git-core"
-- "automake"
-- "p7zip-full"
-
-reference_datetime: "2013-06-01 00:00:00"
-remotes: []
-files:
-- "boost_1_55_0.tar.bz2"
-- "db-4.8.30.NC.tar.gz"
-- "miniupnpc-1.9.tar.gz"
-- "openssl-1.0.1h.tar.gz"
-- "protobuf-2.5.0.tar.bz2"
-- "qrencode-3.4.3.tar.bz2"
-- "MacOSX10.7.sdk.tar.gz"
-- "osx-native-depends-r3.tar.gz"
-
-script: |
-
- echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | sha256sum -c
- echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c
- echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c
- echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c
- echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
- echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c
-
- REVISION=r4
- export SOURCES_PATH=`pwd`
- export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
- export PATH=$HOME:$PATH
- export SOURCES_PATH=`pwd`
- export ZERO_AR_DATE=1
-
- mkdir -p osx-cross-depends/build
- cd osx-cross-depends
-
- PREFIX=`pwd`/prefix
- NATIVEPREFIX=`pwd`/native-prefix
- BUILD_BASE=`pwd`/build
- SDK=`pwd`/SDKs/MacOSX10.7.sdk
- HOST=x86_64-apple-darwin11
- MIN_VERSION=10.6
-
- INT_CFLAGS="-target ${HOST} -mmacosx-version-min=${MIN_VERSION} --sysroot ${SDK} -msse2 -Qunused-arguments"
- INT_CXXFLAGS="${INT_CFLAGS}"
- INT_LDFLAGS="-L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1"
- INT_LDFLAGS_CLANG="-B${NATIVEPREFIX}/bin"
- INT_CPPFLAGS="-I${PREFIX}/include"
- INT_CC=clang
- INT_CXX=clang++
- INT_OBJC=clang
- INT_OBJCXX=clang++
- INT_AR=${HOST}-ar
- INT_RANLIB=${HOST}-ranlib
- INT_LIBTOOL=${HOST}-libtool
- INT_INSTALL_NAME_TOOL=${HOST}-install_name_tool
-
- export PATH=${NATIVEPREFIX}/bin:${PATH}
-
- mkdir -p ${NATIVEPREFIX}/bin
- mkdir -p ${NATIVEPREFIX}/lib
- mkdir -p ${PREFIX}/bin
- mkdir -p ${PREFIX}/lib
- mkdir -p ${BUILD_BASE}
-
- mkdir -p SDKs
- tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
-
- tar xf /home/ubuntu/build/osx-native-depends-r3.tar.gz
-
- # bdb
- SOURCE_FILE=${SOURCES_PATH}/db-4.8.30.NC.tar.gz
- BUILD_DIR=${BUILD_BASE}/db-4.8.30.NC
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- sed -i 's/__atomic_compare_exchange/__atomic_compare_exchange_db/g' ${BUILD_DIR}/dbinc/atomic.h
- pushd ${BUILD_DIR}
- cd build_unix;
- ../dist/configure --host=${HOST} --prefix="${PREFIX}" --disable-shared --enable-cxx CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}"
- make $MAKEOPTS libdb.a libdb_cxx.a
- make install_lib install_include
- popd
-
- # openssl
- SOURCE_FILE=${SOURCES_PATH}/openssl-1.0.1h.tar.gz
- BUILD_DIR=${BUILD_BASE}/openssl-1.0.1h
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- pushd ${BUILD_DIR}
- sed -ie "s|cc:|${INT_CC}:|" ${BUILD_DIR}/Configure
- sed -ie "s|\(-arch [_a-zA-Z0-9]*\)|\1 --sysroot ${SDK} -target ${HOST} -msse2|" ${BUILD_DIR}/Configure
- AR="${INT_AR}" RANLIB="${INT_RANLIB}" ./Configure --prefix=${PREFIX} --openssldir=${PREFIX}/etc/openssl zlib shared no-krb5 darwin64-x86_64-cc ${INT_LDFLAGS} ${INT_CLANG_LDFLAGS} ${INT_CPPFLAGS}
- sed -i "s|engines apps test|engines|" ${BUILD_DIR}/Makefile
- sed -i "/define DATE/d" ${BUILD_DIR}/crypto/Makefile
- make -j1 build_libs libcrypto.pc libssl.pc openssl.pc
- make -j1 install_sw
- popd
-
- #libminiupnpc
- SOURCE_FILE=${SOURCES_PATH}/miniupnpc-1.9.tar.gz
- BUILD_DIR=${BUILD_BASE}/miniupnpc-1.9
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- pushd ${BUILD_DIR}
- CFLAGS="${INT_CFLAGS} ${INT_CPPFLAGS}" make $MAKEOPTS OS=Darwin CC="${INT_CC}" AR="${INT_AR}" libminiupnpc.a
- install -d ${PREFIX}/include/miniupnpc
- install *.h ${PREFIX}/include/miniupnpc
- install libminiupnpc.a ${PREFIX}/lib
- popd
-
- # qrencode
- SOURCE_FILE=${SOURCES_PATH}/qrencode-3.4.3.tar.bz2
- BUILD_DIR=${BUILD_BASE}/qrencode-3.4.3
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- pushd ${BUILD_DIR}
-
- # m4 folder is not included in the stable release, which can confuse aclocal
- # if its timestamp ends up being earlier than configure.ac when extracted
- touch aclocal.m4
- ./configure --host=${HOST} --prefix="${PREFIX}" --disable-shared CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" --disable-shared -without-tools --disable-sdltest --disable-dependency-tracking
- make $MAKEOPTS
- make install
- popd
-
- # libprotobuf
- SOURCE_FILE=${SOURCES_PATH}/protobuf-2.5.0.tar.bz2
- BUILD_DIR=${BUILD_BASE}/protobuf-2.5.0
-
- tar -C ${BUILD_BASE} -xjf ${SOURCE_FILE}
- pushd ${BUILD_DIR}
- ./configure --host=${HOST} --prefix="${PREFIX}" --disable-shared --enable-cxx CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" --enable-shared=no --disable-dependency-tracking --with-protoc=${NATIVEPREFIX}/bin/protoc
- cd src
- make $MAKEOPTS libprotobuf.la
- make install-libLTLIBRARIES install-nobase_includeHEADERS
- cd ..
- make install-pkgconfigDATA
- popd
-
- # boost
- SOURCE_FILE=${SOURCES_PATH}/boost_1_55_0.tar.bz2
- BUILD_DIR=${BUILD_BASE}/boost_1_55_0
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- pushd ${BUILD_DIR}
- ./bootstrap.sh --with-libraries=chrono,filesystem,program_options,system,thread,test
- echo "using darwin : : ${INT_CXX} : <cxxflags>\"${INT_CFLAGS} ${INT_CPPFLAGS}\" <linkflags>\"${INT_LDFLAGS} ${INT_CLANG_LDFLAGS}\" <archiver>\"${INT_LIBTOOL}\" <striper>\"${INT_STRIP}\" : ;" > "user-config.jam"
- ./b2 -d2 --layout=tagged --build-type=complete --prefix="${PREFIX}" --toolset=darwin-4.2.1 --user-config=user-config.jam variant=release threading=multi link=static install
- popd
-
- export GZIP="-9n"
- find prefix | sort | tar --no-recursion -czf osx-depends-${REVISION}.tar.gz -T -
-
- mv osx-depends-${REVISION}.tar.gz $OUTDIR
diff --git a/contrib/gitian-descriptors/gitian-osx-native.yml b/contrib/gitian-descriptors/gitian-osx-native.yml
deleted file mode 100644
index a753ad704f..0000000000
--- a/contrib/gitian-descriptors/gitian-osx-native.yml
+++ /dev/null
@@ -1,178 +0,0 @@
----
-name: "osx-native"
-suites:
-- "precise"
-architectures:
-- "i386"
-packages:
-- "git-core"
-- "automake"
-- "faketime"
-- "libssl-dev"
-- "libbz2-dev"
-- "libz-dev"
-- "cmake"
-- "libcap-dev"
-- "p7zip-full"
-- "uuid-dev"
-
-reference_datetime: "2013-06-01 00:00:00"
-remotes: []
-files:
-- "10cc648683617cca8bcbeae507888099b41b530c.tar.gz"
-- "cctools-809.tar.gz"
-- "dyld-195.5.tar.gz"
-- "ld64-127.2.tar.gz"
-- "protobuf-2.5.0.tar.bz2"
-- "MacOSX10.7.sdk.tar.gz"
-- "cdrkit-1.1.11.tar.gz"
-- "libdmg-hfsplus-v0.1.tar.gz"
-- "clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz"
-- "cdrkit-deterministic.patch"
-
-
-script: |
-
- echo "18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca 10cc648683617cca8bcbeae507888099b41b530c.tar.gz" | sha256sum -c
- echo "03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad cctools-809.tar.gz" | sha256sum -c
- echo "2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c dyld-195.5.tar.gz" | sha256sum -c
- echo "97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142 ld64-127.2.tar.gz" | sha256sum -c
- echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
- echo "d1c030756ecc182defee9fe885638c1785d35a2c2a297b4604c0e0dcc78e47da cdrkit-1.1.11.tar.gz" | sha256sum -c
- echo "6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3 libdmg-hfsplus-v0.1.tar.gz" | sha256sum -c
- echo "b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz" | sha256sum -c
- echo "cc12bdbd7a09f71cb2a6a3e6ec3e0abe885ca7111c2b47857f5095e5980caf4f cdrkit-deterministic.patch" | sha256sum -c
-
-
- REVISION=r3
- export REFERENCE_DATETIME
- export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
-
- REAL_AR=`which ar`
- REAL_RANLIB=`which ranlib`
- REAL_DATE=`which date`
-
- echo '#!/bin/bash' > $HOME/ar
- echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ar
- echo "$REAL_AR \"\$@\"" >> $HOME/ar
-
- echo '#!/bin/bash' > $HOME/ranlib
- echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ranlib
- echo "$REAL_RANLIB \"\$@\"" >> $HOME/ranlib
-
- echo '#!/bin/bash' > $HOME/date
- echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/date
- echo "$REAL_DATE \"\$@\"" >> $HOME/date
-
- chmod +x $HOME/ar $HOME/ranlib $HOME/date
-
-
- export PATH=$HOME:$PATH
- export SOURCES_PATH=`pwd`
-
- mkdir -p osx-cross-depends/build
- cd osx-cross-depends
-
- NATIVEPREFIX=`pwd`/native-prefix
- BUILD_BASE=`pwd`/build
- SDK=`pwd`/SDKs/MacOSX10.7.sdk
- HOST=x86_64-apple-darwin11
- MIN_VERSION=10.6
-
- CFLAGS=""
- CXXFLAGS="${CFLAGS}"
- LDFLAGS="-L${NATIVEPREFIX}/lib"
-
- export PATH=${NATIVEPREFIX}/bin:${PATH}
-
- mkdir -p ${NATIVEPREFIX}/bin
- mkdir -p ${NATIVEPREFIX}/lib
-
- mkdir -p SDKs
- tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
-
- # Clang
- SOURCE_FILE=${SOURCES_PATH}/clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
- BUILD_DIR=${BUILD_BASE}/clang+llvm-3.2-x86-linux-ubuntu-12.04
-
- mkdir -p ${NATIVEPREFIX}/lib/clang/3.2/include
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- cp ${BUILD_DIR}/bin/clang ${NATIVEPREFIX}/bin/
- cp ${BUILD_DIR}/bin/clang++ ${NATIVEPREFIX}/bin/
- cp ${BUILD_DIR}/lib/libLTO.so ${NATIVEPREFIX}/lib/
- cp ${BUILD_DIR}/lib/clang/3.2/include/* ${NATIVEPREFIX}/lib/clang/3.2/include
-
- # cctools
- SOURCE_FILE=${SOURCES_PATH}/10cc648683617cca8bcbeae507888099b41b530c.tar.gz
- BUILD_DIR=${BUILD_BASE}/toolchain4-10cc648683617cca8bcbeae507888099b41b530c
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- mkdir -p ${BUILD_DIR}/sdks
- pushd ${BUILD_DIR}/sdks;
- ln -sf ${SDK} MacOSX10.7.sdk
- ln -sf ${SOURCES_PATH}/cctools-809.tar.gz ${BUILD_DIR}/cctools2odcctools/cctools-809.tar.gz
- ln -sf ${SOURCES_PATH}/ld64-127.2.tar.gz ${BUILD_DIR}/cctools2odcctools/ld64-127.2.tar.gz
- ln -sf ${SOURCES_PATH}/dyld-195.5.tar.gz ${BUILD_DIR}/cctools2odcctools/dyld-195.5.tar.gz
-
- tar -C ${BUILD_DIR} -xf ${SOURCES_PATH}/clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
- # Hack in the use of our llvm headers rather than grabbing the old llvm-gcc.
- sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" ${BUILD_DIR}/cctools2odcctools/extract.sh
- sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" ${BUILD_DIR}/cctools2odcctools/extract.sh
- sed -i "s|\${LLVM_CLANG_DIR}/llvmCore/include/llvm-c|\${LLVM_CLANG_DIR}/include/llvm-c \${LLVM_CLANG_DIR}/include/llvm |" ${BUILD_DIR}/cctools2odcctools/extract.sh
-
- sed -i "s|fAC_INIT|AC_INIT|" ${BUILD_DIR}/cctools2odcctools/files/configure.ac
- sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' ${BUILD_DIR}/cctools2odcctools/files/configure.ac
-
- cd ${BUILD_DIR}/cctools2odcctools
- ./extract.sh --osxver 10.7
- cd odcctools-809
- ./configure --prefix=${NATIVEPREFIX} --target=${HOST} CFLAGS="${CFLAGS} -I${NATIVEPREFIX}/include -D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" LDFLAGS="${LDFLAGS} -Wl,-rpath=\\\$\$ORIGIN/../lib" --with-sysroot=${SDK}
-
- # The 'PC' define in sparc/reg.h conflicts but doesn't get used anyway. Just rename it.
- sed -i "s|define\tPC|define\tPC_|" ${BUILD_DIR}/cctools2odcctools/odcctools-809/include/architecture/sparc/reg.h
- make $MAKEOPTS
- make install
- popd
-
- # protoc
- SOURCE_FILE=${SOURCES_PATH}/protobuf-2.5.0.tar.bz2
- BUILD_DIR=${BUILD_BASE}/protobuf-2.5.0
-
- tar -C ${BUILD_BASE} -xjf ${SOURCE_FILE}
- pushd ${BUILD_DIR};
- ./configure --enable-shared=no --disable-dependency-tracking --prefix=${NATIVEPREFIX}
- make $MAKEOPTS
- cp ${BUILD_DIR}/src/protoc ${NATIVEPREFIX}/bin/
- popd
-
- # cdrkit
- SOURCE_FILE=${SOURCES_PATH}/cdrkit-1.1.11.tar.gz
- BUILD_DIR=${BUILD_BASE}/cdrkit-1.1.11
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- pushd ${BUILD_DIR}
- patch -p1 < ${SOURCES_PATH}/cdrkit-deterministic.patch
- cmake -DCMAKE_INSTALL_PREFIX=${NATIVEPREFIX}
- make $MAKEOPTS genisoimage
- make -C genisoimage install
- popd
-
- # libdmg-hfsplus
- SOURCE_FILE=${SOURCES_PATH}/libdmg-hfsplus-v0.1.tar.gz
- BUILD_DIR=${BUILD_BASE}/libdmg-hfsplus-libdmg-hfsplus-v0.1
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
- mkdir -p ${BUILD_DIR}/build
- pushd ${BUILD_DIR}/build
- cmake -DCMAKE_INSTALL_PREFIX:PATH=${NATIVEPREFIX}/bin ..
- make $MAKEOPTS
- make install
- popd
-
- rm -rf native-prefix/docs
-
- export GZIP="-9n"
- find native-prefix | sort | tar --no-recursion -czf osx-native-depends-$REVISION.tar.gz -T -
- mv osx-native-depends-$REVISION.tar.gz $OUTDIR
diff --git a/contrib/gitian-descriptors/gitian-osx-qt.yml b/contrib/gitian-descriptors/gitian-osx-qt.yml
deleted file mode 100644
index 5e0ad9222a..0000000000
--- a/contrib/gitian-descriptors/gitian-osx-qt.yml
+++ /dev/null
@@ -1,186 +0,0 @@
----
-name: "osx-qt"
-suites:
-- "precise"
-architectures:
-- "i386"
-packages:
-- "git-core"
-- "automake"
-- "p7zip-full"
-
-reference_datetime: "2013-06-01 00:00:00"
-remotes: []
-files:
-- "qt-everywhere-opensource-src-5.2.1.tar.gz"
-- "osx-native-depends-r3.tar.gz"
-- "osx-depends-r4.tar.gz"
-- "MacOSX10.7.sdk.tar.gz"
-
-script: |
-
- echo "84e924181d4ad6db00239d87250cc89868484a14841f77fb85ab1f1dbdcd7da1 qt-everywhere-opensource-src-5.2.1.tar.gz" | sha256sum -c
-
- REVISION=r4
- export SOURCES_PATH=`pwd`
- export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
- export ZERO_AR_DATE=1
-
- export TZ=UTC
-
- REAL_DATE=`which date`
- echo '#!/bin/bash' > $HOME/date
- echo "$REAL_DATE -d \"${REFERENCE_DATETIME}\" \"\$@\"" >> $HOME/date
-
- chmod +x $HOME/date
- export PATH=$HOME:$PATH
-
- mkdir -p osx-cross-depends/build
- cd osx-cross-depends
-
- PREFIX=`pwd`/prefix
- NATIVEPREFIX=`pwd`/native-prefix
- BUILD_BASE=`pwd`/build
- SDK=`pwd`/SDKs/MacOSX10.7.sdk
- HOST=x86_64-apple-darwin11
- MIN_VERSION=10.6
-
- INT_CFLAGS="-target ${HOST} -mmacosx-version-min=${MIN_VERSION} --sysroot ${SDK} -msse2 -Qunused-arguments"
- INT_CXXFLAGS="${INT_CFLAGS}"
- INT_LDFLAGS="-L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1"
- INT_LDFLAGS_CLANG="-B${NATIVEPREFIX}/bin"
- INT_CPPFLAGS="-I${PREFIX}/include"
- INT_CC=clang
- INT_CXX=clang++
- INT_OBJC=clang
- INT_OBJCXX=clang++
- INT_AR=${HOST}-ar
- INT_RANLIB=${HOST}-ranlib
- INT_LIBTOOL=${HOST}-libtool
- INT_INSTALL_NAME_TOOL=${HOST}-install_name_tool
-
- export PATH=${NATIVEPREFIX}/bin:${PATH}
-
- mkdir -p ${NATIVEPREFIX}/bin
- mkdir -p ${NATIVEPREFIX}/lib
- mkdir -p ${PREFIX}/bin
- mkdir -p ${PREFIX}/lib
- mkdir -p ${BUILD_BASE}
-
- mkdir -p SDKs
- tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
-
- tar xf /home/ubuntu/build/osx-native-depends-r3.tar.gz
-
- export PATH=`pwd`/native-prefix/bin:$PATH
- tar xf /home/ubuntu/build/osx-depends-r4.tar.gz
-
- SOURCE_FILE=${SOURCES_PATH}/qt-everywhere-opensource-src-5.2.1.tar.gz
- BUILD_DIR=${BUILD_BASE}/qt-everywhere-opensource-src-5.2.1
-
-
- tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
-
- # Install our mkspec. All files are pulled from the macx-clang spec, except for
- # our custom qmake.conf
- SPECFILE=${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/qmake.conf
-
- mkdir -p ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux
- cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/Info.plist.lib ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/
- cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/Info.plist.app ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/
- cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/qplatformdefs.h ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/
-
- cat > ${SPECFILE} <<ENDCONF
-
- MAKEFILE_GENERATOR = UNIX
- CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname
- QMAKE_INCREMENTAL_STYLE = sublib
-
- include(../common/macx.conf)
- include(../common/gcc-base-mac.conf)
- include(../common/clang.conf)
- include(../common/clang-mac.conf)
-
- QMAKE_XCODE_VERSION=4.3
- QMAKE_XCODE_DEVELOPER_PATH=/Developer
-
- QMAKE_MACOSX_DEPLOYMENT_TARGET = ${MIN_VERSION}
-
- QMAKE_MAC_SDK=macosx
- QMAKE_MAC_SDK.macosx.path = ${SDK}
- QMAKE_MAC_SDK.macosx.platform_name = macosx
- QMAKE_MAC_SDK_PATH=${SDK}
-
- QMAKE_CFLAGS += -target ${HOST}
- QMAKE_OBJECTIVE_CFLAGS += -target ${HOST}
- QMAKE_CXXFLAGS += -target ${HOST}
-
- QMAKE_LFLAGS += -target ${HOST}
- QMAKE_AR = ${HOST}-ar cq
- QMAKE_RANLIB=${HOST}-ranlib
- QMAKE_LIBTOOL=${HOST}-libtool
- QMAKE_INSTALL_NAME_TOOL=${HOST}-install_name_tool
-
- load(qt_config)
-
- ENDCONF
-
- pushd ${BUILD_DIR}
- ./configure -release -opensource -openssl-linked \
- -no-audio-backend -no-javascript-jit -no-sql-sqlite -no-sql-tds \
- -no-cups -no-iconv -no-dbus -no-gif -no-audio-backend -no-freetype \
- -no-javascript-jit -no-sql-sqlite -no-nis -no-cups -no-iconv -no-pch \
- -no-dbus -no-gif -no-sm -nomake examples -no-feature-style-plastique \
- -no-xcb -no-qml-debug -no-pch -no-nis \
- -no-feature-style-cde -no-feature-style-s60 -no-feature-style-motif \
- -no-feature-style-windowsmobile -no-feature-style-windowsce \
- -no-feature-style-cleanlooks \
- -no-sql-db2 -no-sql-ibase -no-sql-oci -no-sql-tds -no-sql-mysql \
- -no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2 \
- -skip qtsvg -skip qtwebkit -skip qtwebkit-examples -skip qtserialport \
- -skip qtdeclarative -skip qtmultimedia -skip qtimageformats \
- -skip qtlocation -skip qtsensors -skip qtquick1 -skip qtxmlpatterns \
- -skip qtquickcontrols -skip qtactiveqt -skip qtconnectivity \
- -skip qtwinextras -skip qtscript \
- -prefix ${PREFIX} -bindir ${NATIVEPREFIX}/bin \
- -confirm-license -xplatform macx-clang-linux -v ${INT_LDFLAGS}
-
- # RCC's output is sorted using each file entry's hash as the key. Unfortunately,
- # the hash function uses a random seed for each run so the results aren't
- # deterministic. This leads to static resources being defined in a random order,
- # which in-turn means that object files are not predictable.
- # Fortunately, this upsets Qt's unit tests as well, so they've added the
- # QT_RCC_TEST environment variable to set a pre-defined seed. Here, do the same
- # thing for the same reason.
- QT_RCC_TEST=1 make $MAKEOPTS module-qtbase-make_first
-
-
- make $MAKEOPTS module-qttranslations-make_first
- make $MAKEOPTS module-qttools-make_first
- make $MAKEOPTS -C qtbase
- make -C qtbase install
- make -C qttranslations install
- make -C qttools/src/linguist install
- popd
-
- # This file should not be installed to the destination. It's native and
- # non-deterministic. Remove it.
- # See: https://bugreports.qt-project.org/browse/QTBUG-31393
- rm -f ${PREFIX}/lib/libQt5Bootstrap.a
-
- rm -f ${PREFIX}/lib/Qt*.framework/Qt*.prl
- pushd ${PREFIX}/include
- ln -sf ../lib/QtNetwork.framework/Headers/ QtNetwork
- ln -sf ../lib/QtWidgets.framework/Headers/ QtWidgets
- ln -sf ../lib/QtGui.framework/Headers/ QtGui
- ln -sf ../lib/QtCore.framework/Headers/ QtCore
- ln -sf ../lib/QtTest.framework/Headers/ QtTest
- popd
-
- rm -f ${PREFIX}/lib/*.la
- find ${PREFIX}/lib -name "*.prl" -delete
-
- export GZIP="-9n"
- find native-prefix prefix | sort | tar --no-recursion -czf osx-depends-qt-5.2.1-${REVISION}.tar.gz -T -
-
- mv osx-depends-qt-5.2.1-${REVISION}.tar.gz $OUTDIR
diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml
new file mode 100644
index 0000000000..5b52c492fd
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-osx-signer.yml
@@ -0,0 +1,38 @@
+---
+name: "bitcoin-dmg-signer"
+suites:
+- "trusty"
+architectures:
+- "amd64"
+packages:
+- "libc6:i386"
+- "faketime"
+reference_datetime: "2016-01-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git"
+ "dir": "signature"
+files:
+- "bitcoin-osx-unsigned.tar.gz"
+script: |
+ WRAP_DIR=$HOME/wrapped
+ mkdir -p ${WRAP_DIR}
+ export PATH=`pwd`:$PATH
+ FAKETIME_PROGS="dmg genisoimage"
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ UNSIGNED=bitcoin-osx-unsigned.tar.gz
+ SIGNED=bitcoin-osx-signed.dmg
+
+ tar -xf ${UNSIGNED}
+ ./detached-sig-apply.sh ${UNSIGNED} signature/osx
+ ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -apple -o uncompressed.dmg signed-app
+ ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED}
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
new file mode 100644
index 0000000000..7e40803a07
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -0,0 +1,134 @@
+---
+name: "bitcoin-osx-0.13"
+enable_cache: true
+suites:
+- "trusty"
+architectures:
+- "amd64"
+packages:
+- "g++"
+- "git-core"
+- "pkg-config"
+- "autoconf"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "cmake"
+- "libcap-dev"
+- "libz-dev"
+- "libbz2-dev"
+reference_datetime: "2016-01-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin.git"
+ "dir": "bitcoin"
+files:
+- "MacOSX10.9.sdk.tar.gz"
+script: |
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="x86_64-apple-darwin11"
+ CONFIGFLAGS="--enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage"
+ FAKETIME_HOST_PROGS=""
+ FAKETIME_PROGS="ar ranlib date dmg genisoimage"
+
+ export QT_RCC_TEST=1
+ export GZIP="-9n"
+ export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
+ export TZ="UTC"
+ export BUILD_DIR=`pwd`
+ mkdir -p ${WRAP_DIR}
+ if test -n "$GBUILD_CACHE_ENABLED"; then
+ export SOURCES_PATH=${GBUILD_COMMON_CACHE}
+ export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
+ mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
+ fi
+
+ export ZERO_AR_DATE=1
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ # Create per-host faketime wrappers
+ for i in $HOSTS; do
+ for prog in ${FAKETIME_HOST_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+ export PATH=${WRAP_DIR}:${PATH}
+
+ cd bitcoin
+ BASEPREFIX=`pwd`/depends
+
+ mkdir -p ${BASEPREFIX}/SDKs
+ tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz
+
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Create the release tarball using (arbitrarily) the first host
+ ./autogen.sh
+ ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ make dist
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
+
+ # Correct tar file order
+ mkdir -p temp
+ pushd temp
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
+ popd
+
+ ORIGPATH="$PATH"
+ # Extract the release tarball into a dir for each host and build
+ for i in ${HOSTS}; do
+ export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
+ mkdir -p distsrc-${i}
+ cd distsrc-${i}
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
+
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ make ${MAKEOPTS}
+ make install-strip
+
+ make deploydir
+ mkdir -p unsigned-app-${i}
+ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i}
+ cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i}
+ cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i}
+ cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate
+ cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff
+ mv dist unsigned-app-${i}
+ pushd unsigned-app-${i}
+ find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz
+ popd
+
+ make deploy
+ ${WRAP_DIR}/dmg dmg Bitcoin-Core.dmg ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg
+
+ cd installed
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ cd ../../
+ done
+ mkdir -p $OUTDIR/src
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz
diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml
new file mode 100644
index 0000000000..27c4f01eb4
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-win-signer.yml
@@ -0,0 +1,39 @@
+---
+name: "bitcoin-win-signer"
+suites:
+- "trusty"
+architectures:
+- "amd64"
+packages:
+- "libssl-dev"
+- "autoconf"
+reference_datetime: "2016-01-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git"
+ "dir": "signature"
+files:
+- "osslsigncode-1.7.1.tar.gz"
+- "osslsigncode-Backports-to-1.7.1.patch"
+- "bitcoin-win-unsigned.tar.gz"
+script: |
+ BUILD_DIR=`pwd`
+ SIGDIR=${BUILD_DIR}/signature/win
+ UNSIGNED_DIR=${BUILD_DIR}/unsigned
+
+ echo "f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 osslsigncode-1.7.1.tar.gz" | sha256sum -c
+ echo "a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 osslsigncode-Backports-to-1.7.1.patch" | sha256sum -c
+
+ mkdir -p ${UNSIGNED_DIR}
+ tar -C ${UNSIGNED_DIR} -xf bitcoin-win-unsigned.tar.gz
+
+ tar xf osslsigncode-1.7.1.tar.gz
+ cd osslsigncode-1.7.1
+ patch -p1 < ${BUILD_DIR}/osslsigncode-Backports-to-1.7.1.patch
+
+ ./configure --without-gsf --without-curl --disable-dependency-tracking
+ make
+ find ${UNSIGNED_DIR} -name "*-unsigned.exe" | while read i; do
+ INFILE="`basename "${i}"`"
+ OUTFILE="`echo "${INFILE}" | sed s/-unsigned//`"
+ ./osslsigncode attach-signature -in "${i}" -out "${OUTDIR}/${OUTFILE}" -sigin "${SIGDIR}/${INFILE}.pem"
+ done
diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml
index 245f15ccab..c8fbe32eee 100644
--- a/contrib/gitian-descriptors/gitian-win.yml
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -1,97 +1,142 @@
---
-name: "bitcoin"
+name: "bitcoin-win-0.13"
+enable_cache: true
suites:
-- "precise"
+- "trusty"
architectures:
- "amd64"
-packages:
-- "mingw-w64"
-- "g++-mingw-w64"
+packages:
+- "g++"
- "git-core"
-- "unzip"
-- "nsis"
-- "faketime"
-- "autoconf2.13"
+- "pkg-config"
+- "autoconf"
- "libtool"
- "automake"
-- "pkg-config"
+- "faketime"
- "bsdmainutils"
-
-reference_datetime: "2013-06-01 00:00:00"
+- "mingw-w64"
+- "g++-mingw-w64"
+- "nsis"
+- "zip"
+reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
-files:
-- "qt-win32-5.2.0-gitian-r3.zip"
-- "qt-win64-5.2.0-gitian-r3.zip"
-- "boost-win32-1.55.0-gitian-r6.zip"
-- "boost-win64-1.55.0-gitian-r6.zip"
-- "bitcoin-deps-win32-gitian-r13.zip"
-- "bitcoin-deps-win64-gitian-r13.zip"
-- "protobuf-win32-2.5.0-gitian-r4.zip"
-- "protobuf-win64-2.5.0-gitian-r4.zip"
+files: []
script: |
- # Defines
- export TZ=UTC
- INDIR=$HOME/build
- OPTFLAGS='-O2'
- TEMPDIR="$HOME/tempdir"
- NEEDDIST=1
- # Qt: workaround for determinism in resource ordering
- # Qt5's rcc uses a QHash to store the files for the resource.
- # A security fix in QHash makes the ordering of keys to be different on every run
- # (https://qt.gitorious.org/qt/qtbase/commit/c01eaa438200edc9a3bbcd8ae1e8ded058bea268).
- # This is good in general but qrc shouldn't be doing a traversal over a randomized container.
- # The thorough solution would be to use QMap instead of QHash, but this requires patching Qt.
- # For now luckily there is a test mode that forces a fixed seed.
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
+ CONFIGFLAGS="--enable-reduce-exports"
+ FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
+ FAKETIME_PROGS="date makensis zip"
+
export QT_RCC_TEST=1
- for BITS in 32 64; do # for architectures
- #
- STAGING=$HOME/staging${BITS}
- BUILDDIR=$HOME/build${BITS}
- BINDIR=$OUTDIR/$BITS
- if [ "$BITS" == "32" ]; then
- HOST=i686-w64-mingw32
- else
- HOST=x86_64-w64-mingw32
- fi
- export PATH=$STAGING/host/bin:$PATH
- mkdir -p $STAGING $BUILDDIR $BINDIR
- #
- cd $STAGING
- unzip $INDIR/qt-win${BITS}-5.2.0-gitian-r3.zip
- unzip $INDIR/boost-win${BITS}-1.55.0-gitian-r6.zip
- unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip
- unzip $INDIR/protobuf-win${BITS}-2.5.0-gitian-r4.zip
- if [ "$NEEDDIST" == "1" ]; then
- # Make source code archive which is architecture independent so it only needs to be done once
- cd $HOME/build/bitcoin
- ./autogen.sh
- ./configure --bindir=$OUTDIR --prefix=$STAGING --host=$HOST --with-qt-plugindir=$STAGING/plugins --with-qt-incdir=$STAGING/include --with-qt-bindir=$STAGING/host/bin --with-boost=$STAGING --disable-maintainer-mode --with-protoc-bindir=$STAGING/host/bin --disable-dependency-tracking CPPFLAGS="-I$STAGING/include ${OPTFLAGS}" LDFLAGS="-L$STAGING/lib ${OPTFLAGS}" CXXFLAGS="-frandom-seed=bitcoin ${OPTFLAGS}"
- make dist
- DISTNAME=`echo bitcoin-*.tar.gz`
- NEEDDIST=0
- fi
- # Build platform-dependent executables from source archive
- cd $BUILDDIR
- mkdir -p distsrc
- cd distsrc
- tar --strip-components=1 -xf $HOME/build/bitcoin/$DISTNAME
- ./configure --enable-upnp-default --bindir=$BINDIR --prefix=$STAGING --host=$HOST --with-qt-plugindir=$STAGING/plugins --with-qt-incdir=$STAGING/include --with-qt-bindir=$STAGING/host/bin --with-boost=$STAGING --disable-maintainer-mode --with-protoc-bindir=$STAGING/host/bin --disable-dependency-tracking CPPFLAGS="-I$STAGING/include ${OPTFLAGS}" LDFLAGS="-L$STAGING/lib ${OPTFLAGS}" CXXFLAGS="-frandom-seed=bitcoin ${OPTFLAGS}"
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- make $MAKEOPTS
- make deploy
- make install-strip
- cp -f bitcoin-*setup*.exe $BINDIR/
- unset LD_PRELOAD
- unset FAKETIME
- done # for BITS in
+ export GZIP="-9n"
+ export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
+ export TZ="UTC"
+ export BUILD_DIR=`pwd`
+ mkdir -p ${WRAP_DIR}
+ if test -n "$GBUILD_CACHE_ENABLED"; then
+ export SOURCES_PATH=${GBUILD_COMMON_CACHE}
+ export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
+ mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
+ fi
+
+ # Create global faketime wrappers
+ for prog in ${FAKETIME_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${prog}
+ echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${prog}
+ chmod +x ${WRAP_DIR}/${prog}
+ done
+
+ # Create per-host faketime wrappers
+ for i in $HOSTS; do
+ for prog in ${FAKETIME_HOST_PROGS}; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+
+ # Create per-host linker wrapper
+ # This is only needed for trusty, as the mingw linker leaks a few bytes of
+ # heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900
+ for i in $HOSTS; do
+ mkdir -p ${WRAP_DIR}/${i}
+ for prog in collect2; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}/${prog}
+ REAL=$(${i}-gcc -print-prog-name=${prog})
+ echo "export MALLOC_PERTURB_=255" >> ${WRAP_DIR}/${i}/${prog}
+ echo "${REAL} \$@" >> $WRAP_DIR/${i}/${prog}
+ chmod +x ${WRAP_DIR}/${i}/${prog}
+ done
+ for prog in gcc g++; do
+ echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog}
+ echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog}
+ echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog}
+ echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog}
+ echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog}
+ echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog}
+ chmod +x ${WRAP_DIR}/${i}-${prog}
+ done
+ done
+
+ export PATH=${WRAP_DIR}:${PATH}
- # sort distribution tar file and normalize user/group/mtime information for deterministic output
+ cd bitcoin
+ BASEPREFIX=`pwd`/depends
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Create the release tarball using (arbitrarily) the first host
+ ./autogen.sh
+ ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
+ make dist
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
+
+ # Correct tar file order
+ mkdir -p temp
+ pushd temp
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
mkdir -p $OUTDIR/src
- rm -rf $TEMPDIR
- mkdir -p $TEMPDIR
- cd $TEMPDIR
- tar -xvf $HOME/build/bitcoin/$DISTNAME | sort | tar --no-recursion -cT /dev/stdin --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 --mtime="$REFERENCE_DATETIME" | gzip -n > $OUTDIR/src/$DISTNAME
+ cp ../$SOURCEDIST $OUTDIR/src
+ popd
+
+ ORIGPATH="$PATH"
+ # Extract the release tarball into a dir for each host and build
+ for i in ${HOSTS}; do
+ export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
+ mkdir -p distsrc-${i}
+ cd distsrc-${i}
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
+ make ${MAKEOPTS}
+ make deploy
+ make install-strip
+ cp -f bitcoin-*setup*.exe $OUTDIR/
+ cd installed
+ mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
+ cd ../..
+ done
+ cd $OUTDIR
+ rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe
+ find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip
+ mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip
diff --git a/contrib/gitian-descriptors/protobuf-win.yml b/contrib/gitian-descriptors/protobuf-win.yml
deleted file mode 100644
index d2fdcaa7f2..0000000000
--- a/contrib/gitian-descriptors/protobuf-win.yml
+++ /dev/null
@@ -1,65 +0,0 @@
----
-name: "protobuf-win32"
-suites:
-- "precise"
-architectures:
-- "amd64"
-packages:
-- "mingw-w64"
-- "g++-mingw-w64"
-- "zip"
-- "faketime"
-reference_datetime: "2013-04-15 00:00:00"
-remotes: []
-files:
-- "protobuf-2.5.0.tar.bz2"
-script: |
- #
- export TZ=UTC
- INDIR=$HOME/build
- TEMPDIR=$HOME/tmp
- OPTFLAGS="-O2"
- # Integrity Check
- echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
-
- for BITS in 32 64; do # for architectures
- #
- INSTALLPREFIX=$HOME/staging${BITS}
- BUILDDIR=$HOME/build${BITS}
- if [ "$BITS" == "32" ]; then
- HOST=i686-w64-mingw32
- else
- HOST=x86_64-w64-mingw32
- fi
- #
- mkdir -p $INSTALLPREFIX $BUILDDIR
- cd $BUILDDIR
- #
- tar xjf $INDIR/protobuf-2.5.0.tar.bz2
- cd protobuf-2.5.0
- # First: build a native (linux) protoc
- ./configure --enable-shared=no --disable-dependency-tracking --without-zlib CXXFLAGS="-frandom-seed=11 ${OPTFLAGS}"
- make
- mkdir -p $INSTALLPREFIX/host/bin
- cp src/protoc $INSTALLPREFIX/host/bin
- # Now recompile with the mingw cross-compiler:
- make distclean
- ./configure --prefix=$INSTALLPREFIX --enable-shared=no --disable-dependency-tracking --without-zlib --with-protoc=$INSTALLPREFIX/host/bin/protoc --host=$HOST CXXFLAGS="-frandom-seed=11 ${OPTFLAGS}"
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- make
- make install
- # post-process all generated libraries to be deterministic
- # extract them to a temporary directory then re-build them deterministically
- for LIB in $(find $INSTALLPREFIX -name \*.a); do
- rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR
- $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt
- rm $LIB
- $HOST-ar crsD $LIB $(cat /tmp/list.txt)
- done
- #
- cd $INSTALLPREFIX
- find include lib host | sort | zip -X@ $OUTDIR/protobuf-win$BITS-2.5.0-gitian-r4.zip
- unset LD_PRELOAD
- unset FAKETIME
- done # for BITS in
diff --git a/contrib/gitian-descriptors/qt-linux.yml b/contrib/gitian-descriptors/qt-linux.yml
deleted file mode 100644
index b163b4bb8c..0000000000
--- a/contrib/gitian-descriptors/qt-linux.yml
+++ /dev/null
@@ -1,264 +0,0 @@
----
-name: "qt-linux"
-suites:
-- "precise"
-architectures:
-- "i386"
-- "amd64"
-packages:
-- "zip"
-- "unzip"
-- "faketime"
-- "unzip"
-- "libxext-dev"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "qt-everywhere-opensource-src-4.6.4.tar.gz"
-script: |
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- if [ "$GBUILD_BITS" == "32" ]; then
- ARCH='i386-linux-gnu'
- else
- ARCH='x86_64-linux-gnu'
- fi
- # The purpose of this gitian build is not to actually build Qt, but to export
- # the headers as well as pkgconfig files in a useable format so that we can
- # pretend to link against an older version. The goal is to link to the
- # system version of Qt 4.
- # Also build development tools.
- INSTALLPREFIX="$HOME/install"
- # Integrity Check
- echo "9ad4d46c721b53a429ed5a2eecfd3c239a9ab566562f183f99d3125f1a234250 qt-everywhere-opensource-src-4.6.4.tar.gz" | sha256sum -c
- # Make install directories
- mkdir -p $INSTALLPREFIX
- mkdir -p $INSTALLPREFIX/include
- PKGCONFIGDIR=$INSTALLPREFIX/lib/pkgconfig
- mkdir -p $PKGCONFIGDIR
- #
- tar xzf qt-everywhere-opensource-src-4.6.4.tar.gz
- cd qt-everywhere-opensource-src-4.6.4
- QTBUILDDIR=$(pwd)
- sed 's/TODAY=`date +%Y-%m-%d`/TODAY=2011-01-30/' -i configure
-
- # Need to build 4.6-versioned host utilities as well (lrelease/qrc/lupdate/...)
- ./configure -prefix $INSTALLPREFIX -confirm-license -release -opensource -no-qt3support -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -no-opengl -nomake examples -nomake demos -nomake docs
- #
- make $MAKEOPTS -C src/tools install # (rcc, uic, moc)
- make $MAKEOPTS -C tools/linguist/lrelease install # (lrelease)
- # install includes and pkgconfig files
- for DIR in src/corelib src/gui src/testlib src/dbus src/network; do
- (
- cd $DIR
- # extract module (QtCore/QtNetwork/...) from Makefile
- MODULE=$(grep "QMAKE_TARGET *=" Makefile | cut -d = -f 2 | xargs)
- # patch makefile so that not everything is build first
- sed -i 's/first: all/first:/g' Makefile
- make install_flat_headers install_class_headers install_targ_headers
- # create and install pkgconfig descriptor
- make ../../lib/pkgconfig/$MODULE.pc
- sed -e "s,$QTBUILDDIR,$INSTALLPREFIX,g" ../../lib/pkgconfig/$MODULE.pc > $PKGCONFIGDIR/$MODULE.pc
- # create links to existing Qt libraries
- ln -sf /usr/lib/${ARCH}/lib${MODULE}.so.4 ${INSTALLPREFIX}/lib/lib${MODULE}.so
- )
- done
-
- # Write our own configuration header, same as Ubuntu
- # When we don't do this, the configuration will be without STL support (the QString from/to stdString methods)
- QCONFIG=$INSTALLPREFIX/include/Qt/qconfig.h
- echo '
- /* Qt Edition */
- #ifndef QT_EDITION
- # define QT_EDITION QT_EDITION_OPENSOURCE
- #endif
- ' > $QCONFIG
-
- if [ "$GBUILD_BITS" == "32" ]; then
- echo '
- /* Machine byte-order */
- #define Q_BIG_ENDIAN 4321
- #define Q_LITTLE_ENDIAN 1234
- #define QT_BUILD_KEY "i386 linux g++-4 full-config"
- #define QT_BUILD_KEY_COMPAT "i686 Linux g++-4 full-config"
-
- #ifdef QT_BOOTSTRAPPED
- #define Q_BYTE_ORDER Q_LITTLE_ENDIAN
- #else
- #define Q_BYTE_ORDER Q_LITTLE_ENDIAN
- #endif
- /* Machine Architecture */
- #ifndef QT_BOOTSTRAPPED
- # define QT_ARCH_I386
- #else
- # define QT_ARCH_I386
- #endif
- /* Compile time features */
- #define QT_LARGEFILE_SUPPORT 64
- #define QT_POINTER_SIZE 4
- ' >> $QCONFIG
- else
- echo '
- /* Machine byte-order */
- #define Q_BIG_ENDIAN 4321
- #define Q_LITTLE_ENDIAN 1234
- #define QT_BUILD_KEY "x86_64 linux g++-4 full-config"
- #define QT_BUILD_KEY_COMPAT "x86_64 Linux g++-4 full-config"
-
- #ifdef QT_BOOTSTRAPPED
- #define Q_BYTE_ORDER Q_LITTLE_ENDIAN
- #else
- #define Q_BYTE_ORDER Q_LITTLE_ENDIAN
- #endif
- /* Machine Architecture */
- #ifndef QT_BOOTSTRAPPED
- # define QT_ARCH_X86_64
- #else
- # define QT_ARCH_X86_64
- #endif
- /* Compile time features */
- #define QT_LARGEFILE_SUPPORT 64
- #define QT_POINTER_SIZE 8
- ' >> $QCONFIG
- fi
-
- echo '
- #ifndef QT_BOOTSTRAPPED
-
- #if defined(QT_NO_EGL) && defined(QT_EGL)
- # undef QT_NO_EGL
- #elif !defined(QT_NO_EGL) && !defined(QT_EGL)
- # define QT_NO_EGL
- #endif
-
- #if defined(QT_NO_GSTREAMER) && defined(QT_GSTREAMER)
- # undef QT_NO_GSTREAMER
- #elif !defined(QT_NO_GSTREAMER) && !defined(QT_GSTREAMER)
- # define QT_NO_GSTREAMER
- #endif
-
- #if defined(QT_NO_ICD) && defined(QT_ICD)
- # undef QT_NO_ICD
- #elif !defined(QT_NO_ICD) && !defined(QT_ICD)
- # define QT_NO_ICD
- #endif
-
- #if defined(QT_NO_IMAGEFORMAT_JPEG) && defined(QT_IMAGEFORMAT_JPEG)
- # undef QT_NO_IMAGEFORMAT_JPEG
- #elif !defined(QT_NO_IMAGEFORMAT_JPEG) && !defined(QT_IMAGEFORMAT_JPEG)
- # define QT_NO_IMAGEFORMAT_JPEG
- #endif
-
- #if defined(QT_NO_IMAGEFORMAT_MNG) && defined(QT_IMAGEFORMAT_MNG)
- # undef QT_NO_IMAGEFORMAT_MNG
- #elif !defined(QT_NO_IMAGEFORMAT_MNG) && !defined(QT_IMAGEFORMAT_MNG)
- # define QT_NO_IMAGEFORMAT_MNG
- #endif
-
- #if defined(QT_NO_IMAGEFORMAT_TIFF) && defined(QT_IMAGEFORMAT_TIFF)
- # undef QT_NO_IMAGEFORMAT_TIFF
- #elif !defined(QT_NO_IMAGEFORMAT_TIFF) && !defined(QT_IMAGEFORMAT_TIFF)
- # define QT_NO_IMAGEFORMAT_TIFF
- #endif
-
- #if defined(QT_NO_MULTIMEDIA) && defined(QT_MULTIMEDIA)
- # undef QT_NO_MULTIMEDIA
- #elif !defined(QT_NO_MULTIMEDIA) && !defined(QT_MULTIMEDIA)
- # define QT_NO_MULTIMEDIA
- #endif
-
- #if defined(QT_NO_OPENVG) && defined(QT_OPENVG)
- # undef QT_NO_OPENVG
- #elif !defined(QT_NO_OPENVG) && !defined(QT_OPENVG)
- # define QT_NO_OPENVG
- #endif
-
- #if defined(QT_NO_PHONON) && defined(QT_PHONON)
- # undef QT_NO_PHONON
- #elif !defined(QT_NO_PHONON) && !defined(QT_PHONON)
- # define QT_NO_PHONON
- #endif
-
- #if defined(QT_NO_PULSEAUDIO) && defined(QT_PULSEAUDIO)
- # undef QT_NO_PULSEAUDIO
- #elif !defined(QT_NO_PULSEAUDIO) && !defined(QT_PULSEAUDIO)
- # define QT_NO_PULSEAUDIO
- #endif
-
- #if defined(QT_NO_S60) && defined(QT_S60)
- # undef QT_NO_S60
- #elif !defined(QT_NO_S60) && !defined(QT_S60)
- # define QT_NO_S60
- #endif
-
- #if defined(QT_NO_STYLE_S60) && defined(QT_STYLE_S60)
- # undef QT_NO_STYLE_S60
- #elif !defined(QT_NO_STYLE_S60) && !defined(QT_STYLE_S60)
- # define QT_NO_STYLE_S60
- #endif
-
- #if defined(QT_NO_SXE) && defined(QT_SXE)
- # undef QT_NO_SXE
- #elif !defined(QT_NO_SXE) && !defined(QT_SXE)
- # define QT_NO_SXE
- #endif
-
- #if defined(QT_NO_WEBKIT) && defined(QT_WEBKIT)
- # undef QT_NO_WEBKIT
- #elif !defined(QT_NO_WEBKIT) && !defined(QT_WEBKIT)
- # define QT_NO_WEBKIT
- #endif
-
- #if defined(QT_NO_ZLIB) && defined(QT_ZLIB)
- # undef QT_NO_ZLIB
- #elif !defined(QT_NO_ZLIB) && !defined(QT_ZLIB)
- # define QT_NO_ZLIB
- #endif
-
- #if defined(QT_RUNTIME_XCURSOR) && defined(QT_NO_RUNTIME_XCURSOR)
- # undef QT_RUNTIME_XCURSOR
- #elif !defined(QT_RUNTIME_XCURSOR) && !defined(QT_NO_RUNTIME_XCURSOR)
- # define QT_RUNTIME_XCURSOR
- #endif
-
- #if defined(QT_RUNTIME_XFIXES) && defined(QT_NO_RUNTIME_XFIXES)
- # undef QT_RUNTIME_XFIXES
- #elif !defined(QT_RUNTIME_XFIXES) && !defined(QT_NO_RUNTIME_XFIXES)
- # define QT_RUNTIME_XFIXES
- #endif
-
- #if defined(QT_RUNTIME_XINERAMA) && defined(QT_NO_RUNTIME_XINERAMA)
- # undef QT_RUNTIME_XINERAMA
- #elif !defined(QT_RUNTIME_XINERAMA) && !defined(QT_NO_RUNTIME_XINERAMA)
- # define QT_RUNTIME_XINERAMA
- #endif
-
- #if defined(QT_RUNTIME_XINPUT) && defined(QT_NO_RUNTIME_XINPUT)
- # undef QT_RUNTIME_XINPUT
- #elif !defined(QT_RUNTIME_XINPUT) && !defined(QT_NO_RUNTIME_XINPUT)
- # define QT_RUNTIME_XINPUT
- #endif
-
- #if defined(QT_RUNTIME_XRANDR) && defined(QT_NO_RUNTIME_XRANDR)
- # undef QT_RUNTIME_XRANDR
- #elif !defined(QT_RUNTIME_XRANDR) && !defined(QT_NO_RUNTIME_XRANDR)
- # define QT_RUNTIME_XRANDR
- #endif
-
- #if defined(QT_USE_MATH_H_FLOATS) && defined(QT_NO_USE_MATH_H_FLOATS)
- # undef QT_USE_MATH_H_FLOATS
- #elif !defined(QT_USE_MATH_H_FLOATS) && !defined(QT_NO_USE_MATH_H_FLOATS)
- # define QT_USE_MATH_H_FLOATS
- #endif
-
- #endif // QT_BOOTSTRAPPED
-
- #define QT_VISIBILITY_AVAILABLE
- ' >> $QCONFIG
- cp $QCONFIG $INSTALLPREFIX/include/QtCore/qconfig.h
-
- cd $INSTALLPREFIX
- # as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- # Create a .tar.gz because .zip has problems with symbolic links
- find | sort | tar --no-recursion -cT /dev/stdin --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 --mtime="$REFERENCE_DATETIME" | gzip -n > $OUTDIR/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz
diff --git a/contrib/gitian-descriptors/qt-win.yml b/contrib/gitian-descriptors/qt-win.yml
deleted file mode 100644
index 7000c70051..0000000000
--- a/contrib/gitian-descriptors/qt-win.yml
+++ /dev/null
@@ -1,92 +0,0 @@
----
-name: "qt"
-suites:
-- "precise"
-architectures:
-- "amd64"
-packages:
-- "mingw-w64"
-- "g++-mingw-w64"
-- "zip"
-- "unzip"
-- "faketime"
-- "libz-dev"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "qt-everywhere-opensource-src-5.2.0.tar.gz"
-- "bitcoin-deps-win32-gitian-r13.zip"
-- "bitcoin-deps-win64-gitian-r13.zip"
-script: |
- # Defines
- export TZ=UTC
- INDIR=$HOME/build
- TEMPDIR=$HOME/tmp
- # Qt: workaround for determinism in resource ordering
- # Qt5's rcc uses a QHash to store the files for the resource.
- # A security fix in QHash makes the ordering of keys to be different on every run
- # (https://qt.gitorious.org/qt/qtbase/commit/c01eaa438200edc9a3bbcd8ae1e8ded058bea268).
- # This is good in general but qrc shouldn't be doing a traversal over a randomized container.
- # The thorough solution would be to use QMap instead of QHash, but this requires patching Qt.
- # For now luckily there is a test mode that forces a fixed seed.
- export QT_RCC_TEST=1
- # Integrity Check
- echo "395ec72277c5786c65b8163ef5817fd03d0a1f524a6d47f53624baf8056f1081 qt-everywhere-opensource-src-5.2.0.tar.gz" | sha256sum -c
-
- for BITS in 32 64; do # for architectures
- #
- INSTALLPREFIX=$HOME/staging${BITS}
- BUILDDIR=$HOME/build${BITS}
- DEPSDIR=$HOME/deps${BITS}
- if [ "$BITS" == "32" ]; then
- HOST=i686-w64-mingw32
- else
- HOST=x86_64-w64-mingw32
- fi
- #
- mkdir -p $INSTALLPREFIX $INSTALLPREFIX/host/bin $DEPSDIR $BUILDDIR
- #
- # Need mingw-compiled openssl from bitcoin-deps:
- cd $DEPSDIR
- unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip
- #
- cd $BUILDDIR
- #
- tar xzf $INDIR/qt-everywhere-opensource-src-5.2.0.tar.gz
- cd qt-everywhere-opensource-src-5.2.0
- SPECNAME="win32-g++"
- SPECFILE="qtbase/mkspecs/${SPECNAME}/qmake.conf"
- sed 's/qt_instdate=`date +%Y-%m-%d`/qt_instdate=2011-01-30/' -i qtbase/configure
- sed --posix "s|QMAKE_CFLAGS = -pipe -fno-keep-inline-dllexport|QMAKE_CFLAGS\t\t= -pipe -fno-keep-inline-dllexport -isystem /usr/$HOST/include/ -frandom-seed=qtbuild -I$DEPSDIR/include|" -i ${SPECFILE}
- sed --posix "s|QMAKE_LFLAGS =|QMAKE_LFLAGS\t\t= -L$DEPSDIR/lib|" -i ${SPECFILE}
- # Before we tried to pass arguments to ar (static linking) in using QMAKE_LIB, however
- # qt removes the arguments for ar and provides a script which makes it impossible to pass the determinism flag -
- # so rather than try to replace ar, post-process all libraries and plugins at the end.
- #
- # Don't load faketime while compiling Qt, qmake will get stuck in nearly infinite loops
- #export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- #export FAKETIME=$REFERENCE_DATETIME
- #
- # Compile static libraries, and use statically linked openssl (-openssl-linked):
- OPENSSL_LIBS="-L$DEPSDIR/lib -lssl -lcrypto -lgdi32" ./configure -prefix $INSTALLPREFIX -bindir $INSTALLPREFIX/host/bin -confirm-license -release -opensource -static -xplatform $SPECNAME -device-option CROSS_COMPILE="$HOST-" -no-audio-backend -no-javascript-jit -no-sql-sqlite -no-sql-odbc -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-opengl -no-compile-examples -no-feature-style-windowsce -no-feature-style-windowsmobile -no-qml-debug -openssl-linked -skip qtsvg -skip qtwebkit -skip qtwebkit-examples -skip qtserialport -skip qtdeclarative -skip qtmultimedia -skip qtimageformats -skip qtlocation -skip qtsensors -skip qtquick1 -skip qtquickcontrols -skip qtactiveqt -skip qtconnectivity -skip qtwinextras -skip qtxmlpatterns -skip qtscript -skip qtdoc -system-libpng -system-zlib
- make $MAKEOPTS install
- # post-process all generated libraries and plugins to be deterministic
- # extract them to a temporary directory then re-build them deterministically
- for LIB in $(find $INSTALLPREFIX -name *.a); do
- rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR
- $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt
- rm $LIB
- $HOST-ar crsD $LIB $(cat /tmp/list.txt)
- done
- #
- cd $INSTALLPREFIX
- # Remove unused non-deterministic stuff
- rm host/bin/qtpaths.exe lib/libQt5Bootstrap.a lib/libQt5Bootstrap.la
- # as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- find -print0 | xargs -r0 touch # fix up timestamps before packaging
- find | sort | zip -X@ $OUTDIR/qt-win${BITS}-5.2.0-gitian-r3.zip
- unset LD_PRELOAD
- unset FAKETIME
- done # for BITS in
diff --git a/contrib/gitian-downloader/bluematt-key.pgp b/contrib/gitian-downloader/bluematt-key.pgp
index fb6d9eb284..2389d4657f 100644
--- a/contrib/gitian-downloader/bluematt-key.pgp
+++ b/contrib/gitian-downloader/bluematt-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/btcdrak-key.pgp b/contrib/gitian-downloader/btcdrak-key.pgp
new file mode 100644
index 0000000000..60d76c0ec7
--- /dev/null
+++ b/contrib/gitian-downloader/btcdrak-key.pgp
@@ -0,0 +1,142 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+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
+eEaG0RH54+pi4gw=
+=fFMC
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/cdecker-key.pgp b/contrib/gitian-downloader/cdecker-key.pgp
new file mode 100644
index 0000000000..928a74b315
--- /dev/null
+++ b/contrib/gitian-downloader/cdecker-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/centaur1-key.pgp b/contrib/gitian-downloader/centaur1-key.pgp
new file mode 100644
index 0000000000..71a42e5148
--- /dev/null
+++ b/contrib/gitian-downloader/centaur1-key.pgp
@@ -0,0 +1,30 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+mQENBFTjy20BCAC7q/tpPQ9tdEALpDqe8kpVAT5ysOJDLDeFEE1J5O8NuDFuibiN
+XYkb2nAt4Vdr23in9z0LAiTSgr7znndnab/rOSn6pXbXQfLTHrSnAeClTHVQVPSq
+m5kNg1vWvNxFtIpZ/fGsc6LLmIHxdgeLn+NOpvNx7RzF/N5ctX51vMxMUeDq3daZ
+tLneJVRj5tXHRJcjW62cyiNFasYAZ3JC8wjwzr0SOndc7kygbEVCTWNkTAGd1Lax
+KSJW6TjhBPK7j+RljS5nfx/Tf+OG4AoA7/53593YL7Shfx8rwWVIeF4nS6efFnuf
+eIj+aS5haGyFvNgw8DE7QUCrPiUxeA8wuXu7ABEBAAG0H2NlbnRhdXIgPGNlbnRh
+dXJAcGhvbmVib29rLmNvbT6JATgEEwECACIFAlTjy20CGwMGCwkIBwMCBhUIAgkK
+CwQWAgMBAh4BAheAAAoJEP+V+qlxaXQF8r4IAKnE8D9AOTdM/YvYxpCeI6ndEUUs
+8NcotpbIBJ67vr1Dsot7Ee0PrmIYOiInA+T81lPUDecJYrnemVefhquiyJ5VJ4/d
+z2zUKBfxjeOsj/PHgcowVxMco8fNEWQa2fZX6X8RVADIsUnIIwpRFVUcbssK/3xJ
+k46vjWwYNQywht/ZgFBesOgywyz5GozmwrK6TixJxKk8M69GFz2fHhJjp1bxDZuk
+Rs3YmWeOcCasoJ6GbvIboKQSPHGyEOCqIuiBL63YMa0n1FU0ooDteNZ04eRinIhc
+fo9JC66fQrUFn8CmmRTtdZOrZ/efYjQtfLAunCkzSM3p6DE9u4Y7d8E5Ar65AQ0E
+VOPLbQEIANhxtouZuQmw+k89toBWXw75s+csxKHKZuhw8QntaFyFYq3IOnIeV1sK
+PRENkWsqDInjEM8k9eZ6pnS11EQ1rrFffss+mprTbL3I4S489tJETYZKHrmmox7h
+ustRi5eXBEmGeKW0mqpb/9r4okpTaIfs+EJ4C9jj0ghWkqU0acyzanJiUY/0R46F
+vPfGfHnhZ5TAl3eiL0H2JkF6taG8K1XOLemahdZHE9wJh0ZFWnDDkA1l6j2rtYga
+jEi/ucOp5GkmumxbFiVgponDBqBpsscRrCV6SbZs9gz3dQNgqe5A3CKGZRuVCY6s
+djRJelgqCF5+dV0fAT0oF3C/3E5KAgcAEQEAAYkBHwQYAQIACQUCVOPLbQIbDAAK
+CRD/lfqpcWl0BUSxCACjEFwQSHcfZINWD+KdNMayxyHQlBwsEDX+xQkgnn+/Q3hW
+9VI3SSSfFV3ustlUa3IaNHwuWzsrSqG6mLG47LAQ6vPAWVh723gVCpyJf42Oms/e
+qeyn0f/PT/6RuNMXQeHbfddmRp4PFjyKOms5Bmf3oi4t4JSvOS4yABBBKzhDQYC9
+e+qv6Y1sDYpSiCxstQLzIHKiB5bfZ8Szfk09EyyLdqLGkiB0MFhHoXWwQxKiLVc+
+xNFj2a/jw0rQVgN5DZgHBWU5WqvS5CWIczi+2S9MFI26iBhCn3urZToaaQ/DObqC
+qmekFrJ/GOj5vB1Mm014lWjG2X3EovLZ1XkgWI7W
+=vtNZ
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/erkmos.pgp b/contrib/gitian-downloader/erkmos.pgp
new file mode 100644
index 0000000000..9d3f060627
--- /dev/null
+++ b/contrib/gitian-downloader/erkmos.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/fanquake-key.pgp b/contrib/gitian-downloader/fanquake-key.pgp
new file mode 100644
index 0000000000..9c03ff4522
--- /dev/null
+++ b/contrib/gitian-downloader/fanquake-key.pgp
@@ -0,0 +1,63 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG/MacGPG2 v2.0.26
+
+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
+XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg==
+=3o2I
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-downloader/jonasschnelli-key.pgp
new file mode 100644
index 0000000000..3831eaea11
--- /dev/null
+++ b/contrib/gitian-downloader/jonasschnelli-key.pgp
@@ -0,0 +1,110 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+mQINBFSBrDIBEACrZEqObmtlTf7fOKttE39qqisFfMg0VeEPS37uETMGYsgTEvzv
+kfMsXCGsGFLQ78XsHqUeW4uQrtpJH3nUP/Sua1Q12K3lNKTSvVQyEpKoPJwXZahp
+jm6GA1ApDxZ/KlmxyobR3X0urnMYNZobl5IKJXlxoKGl4OkGNeFlh42pCXZDnR9n
+1Y17ZcDdybkWcqPbDAz8ilOQcFMhDBFg3Di3IVMAaDZP1uwWFb5vx60YB5NhkOpF
+nZUH09NJx/7u7QdGPSHOdzW4Xo1HUYtYNDkdOvgZtxpbYEFIaBtVBURMUGwAFagA
+3a6qaGnCBWEQftyISLiqcKqKqXudOg/cLa1CAiQFkz+IBhY9BCGDRnB8Dcae6EGI
+Djt2lqZTuMSiheTWeNFMGBioHfPLedcwae8KflrIBC+hNS4ay6HJdIc03WMQ4JKK
+At8Y8CRLym30/RlqZ2v8CHYqg9Ddlz3+g5JkRKaJTQwFRcX46/tAX+I2NZ8Ra1ea
+rF5cRHuCk/oaw5ZXYhj4zJO74rjAoSewAARlrTMSM541atJU1u6aWT7rNiF9QKIj
+i8vEufUxN0YfdmvDD3OXwbO7GnfWXS4sPklFIRACp+Y4ib+QnRY0/qGE0yh3RAG4
+r/dyIQ1m3z7Pc9eyPKAhE4S7SxAwoR4yOqQ5NAfZXgFuqWzkW51gkQgGzQARAQAB
+tCtKb25hcyBTY2huZWxsaSA8am9uYXMuc2NobmVsbGlAaW5jbHVkZTcuY2g+iQI+
+BBMBAgAoBQJUgawyAhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
+CRAicOMMUic59iKUD/93DF04C3lptLjtrhyd4wgpBMJV8yzagGyG+Wk0UR7elQw4
+F1MIvEtIFpuGrcnNfKcqeGGmnnKFTeBjkmgcYvej2fW9XlRA1HgIS0t0ttDv8uVX
+vy1xVj1qISB+17EiftxJjCOl2pZFEVpLQ7sSgqnVRMsCS45ag6rioGxtq1j3ifQN
+TENnJWhzOXvwzZhLgsyWLjeYvTDbzfAQLpZFowAMibOwu6ObCkn4dhaW+lI3AnPu
+76pLsrOljqGvXes6o2d28vjqMrlmsz2xVEJ4bnRPUbLv3bUl6t+19XpiMj94ZCZX
+/kvepzSNAs+aYvoldFn0/8haU5wIDXO/zgXSlm4KnhaDf1zutVq/Ng6TGb66mZKc
+RoiGHnnuQ45e7VIXRfOmgbbUTUIg+h4YvgCTR8dMoOWpd5AL8lZ3bjYVi1yFd+p1
+dPfrrnN9Yd5ojoZBSrV2j1wLgv7jRIeXL5dWzeAs/JBzltAHWO+9O6NsYXtRTUky
+eQa+oBKG1OsEXf63k8PgQf6Nw+di3gy23tKEiCz8lbA2MtekxaZ9Xu9CSEEPIH7t
+Aoki6Ey6rD1NUZQPuxQ3aCUTRE2JK4b6nPuAsOEv+cZL0VxNENpbedtGPh4aAA8U
+9yvBykWIjRS95k4NDVKIdzhd1geJsUJZq4BKh9Atf/kI+Gb0sqq2Lrf8a1pNX7kC
+DQRUgawyARAAwLiAxqv7PsdtJg8tBO+dAnTYtAtBHn8g5GlXtorymB9Aqy0Nzpd1
+de27dYlBdlWdHZavMh27JieZ4rk++74SMAo0PACp6FDnfuu2PmJZTr/Bzvld+B9+
+lOZrMWwDIVSW1npJGUjF1rjgPjvmcGo/IreVFpJ0A33J1p/qsYZsLTXTDDoz0fq8
+3XvwTlkTOkuk6Z6LPo2feDHYydUmdG+9MrgIMpidvywRHRC8nnkix/aX0S72kZuR
+qvWwSVs229gtfuWHfvmaQgbugZMqANla3ZYdzExhIIizu7qQPXSYfhsCoywWE2So
+9QXZIiVJge2P/hUr2gTiRNTfmhupDeqb1E+i7x9txTrNc40gbTu3qs3/fjKIWrXw
+Dy5tuZsviLQnEQtY4sEnHl7oL1crOuIHjZfgZfoZ5CK+jqb2b0B9uIm/SMl6Kt8S
+m6ZtK0QTjtUSIputPEYdLycdOpWDDtAHrWkTlRzKJoLG4hsywBAgQe7n9nLf7Zmi
+DhXyXRKyJuuuG5mt7UZhjW95loFFVcGXHIxNmxVqNb1YaG3kEa9PdQMoOc0hRZb9
+77yaGfpLV8Vo4CB1eAuVU0UdNRyChrZK5dKXBN/0uZq5HgpI1GiK/C3YUuQI3t9p
+zeJYD3jPGYCI9xxLaqt7whoOILPmZ1KW2UfXTvcMgBUMkFpZrqhTGscAEQEAAYkC
+JQQYAQIADwUCVIGsMgIbDAUJA8JnAAAKCRAicOMMUic59oqeD/9SvgUx60AhyCPl
+1G64eII9M2LU4vmHj8g6wnjh3xaWXvlQU1xnz/5I0XrlbHm31ExEHK+7Zla4AQ/P
+OrJhMNZh9oes3iOh+pAEn/vtixddM/oiivLBxMcIzq31PS8lZWrAjqOX/FFYa8GM
+NZI0bNWu92J7cL/bRVwsIVUXh2DkUu7wXwicNERYkKDTBaK7FE06C/hIGTwmENlR
+b1+H7e00nzWqoHyd0fhG7d8RaF2IF95YH5+r+aS20cHVCTI/0Z32FmlnCA6QlkZx
+JZiXKssHLpegeegAOOR3t2keB5rN4J/8KSzIEWUG5sjXkshMIM7w1a6urc/iE9PW
+YGgbG7Wt1AcEO5cnU72DzoENrOxRKdFLZWemLbncLPTY2GERPutJgDSYvaxmwnQy
+eGsnRIOmAMgN9+8NEs9wZnzrYpkvk/Vw1FwNcCCUYb0ZPYoRVRhP2UXYm7OxdKdk
+zPXfS7Uqs9oto1FiD7iomhtBs+RW8ndaO9wHGoCn2/UAD9fxNIkTQvK61amyjGX3
+gdwrOwt73I+wjgt78jmZsKfnPWYnOIUg2/12P4iB6KhWD8MIIeFLl9TFfZ8f06WV
+WIUTcA4cgSYgGOScxB0En+B3LDCkmVabu/JzBedT9N8rXvgdywk2UR4vKqiyJT1O
+9ArEfToN7J0gclhUoadr0im67BGyMZkCDQRVXu6kARAAwR/cg0kJja6u1YToEM+g
+SOOPZK6Bn745y0cvf6+YFVefLcManUCyI+/DWZhO+D/im569MApbTz1qdaLE54Kh
+z2CtOJBlWP8cjlnVZ95hBK+Z9COuk60dXI7DySRn3DVryNpYjRCe+8SBTQJSj8b0
+JEk5VVYPYUOIc3L6g7LBL2/ycxV3LVFTQ/A9LGBev7y2emgC7lqkPPoDU1vJeO1N
+4G0nFsIxuml81pfgi/2aMbGF8l7LVAI8qMc0c4RAjL/yTPzVX5qq5+zAaXMcyhgy
+yqOvlXlCG9aisnmPCEiShxmLvGfGdPmi+apxZNUW3384vVcOxzl1VcU6sVZT30/a
+Jaa8RxZqC6S5kOr7uPO8CD1wB1rXzD8SA4Adcq9SwOkVE7QfnQi6+BIgdrsLKUfg
+2vBjcgA/IsLETlnp2792m3w01OKe2/w9Uq3N45lWVTNVx2UcbWAIz6bwWoMDJ1DN
+B4XQHb5Ag+VI7lIGr45Ep4ohOfIcpBCMa1WVGyTYoQFc66mPZ2MotADOHtgGpm6v
+ZyJEp2qWj0at+tDepf0bFPHmGGhVj+N4HTBWMzsu3sLCAh3QWStr+gkffUl2CsdG
+Y3RL6kVkCCW0o/o+V0mc8ZV8kAtFPyYGllsP9HEvjeXkHg+DAvRFZhSPI1mxGkGg
+gZlEtHqZ9Lofoco9wedCJPEAEQEAAbQlSm9uYXMgU2NobmVsbGkgPGRldkBqb25h
+c3NjaG5lbGxpLmNoPokCPgQTAQIAKAUCVV7upAIbAwUJCWYBgAYLCQgHAwIGFQgC
+CQoLBBYCAwECHgECF4AACgkQKdS8tkFvU+ytjhAAwQqTK7pSjSSK91QZAvsV+CgN
+AzC8AydcdpWAnJpsE+nw76snAexMctDfae9uPSGSVM9PAgouUg2YJxNd9RzPCv7j
+vx3bevO3ArNZxvdKSXffPVzt01j53z99/Ltmev5rpIcNQk2nqL3iZaZ5O7Vxre8k
+H5KxncFCUxlnX/stLz9WOmnIN1X5qVq3lSzh8xvm7DuyOmi1Z94GHCW4BHN6wxtX
+nXqYeI45jPcbuJWC8P8qtNicZ0N2XLjpAoLSvQ68VTrvvLN0X2HT9Ol9y5t7re8J
+PEY52TvrPCLYz4hQD0fPe3w14LkcdbWTjJwQ3Y7KWd67SOn+l8VDPj2jT0yDBDG2
+YazByLqV29SgXm9WsfYXYF4FB9NSApbrAmhTWVa4K4DFXrLvcIpaIR4Ii3JQZDag
+2tO1VTgxF+10S66qrwXwawBbGfDVchWgSi9T1hNn2wgLypsLN1ZDy7ixPCD+SHHd
+xgTN8yv+/WNRNZ+LtUKNCIBHQmUBesNfN+wOrvOoWPAP6XjlUIlA2RIH6zKcNbDb
+a4jjx1ENiHAlapVxzPTQiTfj0TDRXBdjboiswXfkN76upHdgdMdeFz9hiH0PSbxA
+TmlmA7NrsENHLp89SB/gnGT2I/lLP5/DsoN3Qv8GCoy7aUNDT7abi1AeoBVVye2c
+AL3d+hDPgOzJHjf0eJGJAhwEEAECAAYFAlZFyF4ACgkQInDjDFInOfZtGg//f4xQ
+PvS6gQdIosesV458LtIUnrqdPx/8PGnIbkObSzjevEoj3RQ+D7PHvF57lj6m45aB
+Tr6huXC2RQzOIjRXM9dYi6SVZzQ1xnjMep72ylVYawQS3VBeuQbhU2BgYTeLa55+
+0sHBA/hX9ufH7a3UvSTgvssX44SH5mGg2h4I3O+4cNQIDf/G7xkzkJKcQmATRmIR
+10JaaBKtx4JVNVzCWTOpEqW6/QA8X94LapK8Rh/mhKyd38v3CEHI7hH0ex0o2mOF
+kAsPY1vvfxWzGKMolJp1b/1FPcb7Fl+nCoqlfnv0cCnZYsQvYXrOs/1Kj0anv9yR
+iutEp2DyaAnhadadrFpWjXQNUeYtFlJ1aC+6HO//uw2spKFqcQ4tTvu9HgHJO1gn
+GTsmDskwXqHOYNvH9QjtwlhPhOWQdHgLPrWBiUBvkT9H8uoNRGWg0VGA4J51IkRh
+0ZyoLmRgejpj7SOpwLX6gemprn0Z4fgohKyj6z4/Bop2gliXSPB37qdun6M92g8m
+SkxaEXF2ZyIXdeVRT6Xgp+zoGDNbMG3PlhZiFFCvH3Hk8o9zAz/65de6D+14EHYj
+WBRKfu7jaL2RSwUSRwRAAYKwu6kgRy8G7+4SihuSHT2k/90il6iwpzXdyY7qQXWG
+VxfrmGWZLYT0u7d+EZ1pc02UKYCFptlVCIZtaQK5Ag0EVV7upAEQAKpWFoCqFFqQ
+5xH6+TFvbUFWBb1dWy89GMXCkmqAsoy8Ss2Ru8gNuy7Xt4l1dQhVpN0QWiuVGkEO
+f2PmXQhnLquaSz7XLZjjdO5E3kYzcwOpIbb2TCWH4QQtHEotowRslQAXAZ53jN9u
+NIEQHCPPBNocj0CLQmZl+av1MqRJrRcYzgkPIs34mBo6iVoRrD5CkSohbz01BMWJ
+ZLk0E+JvalML7+ttiwu+gI90uRGiKEz5xsDMtyx0mAcAm+/EjcuQbhGrD6p7dLKv
+9nuUU/T743N2LoDTBMzvX/JXjoQ/uS1nzuiJrc/vYHqy9uucgviuYWFH/Q+LhwMr
+6tjJYUiN4JIQ85OLvq6g71RnpWzy3ce25HL1YWbLNuzi8ZKIB/sL4LXG2iTwwSFk
+tVjfAc4zP/VWpRC5VbxG76atRkPLatgA6b2sawgQ6L/7XB5Wd5F0bJc3ndwPBKos
+FFXgzOBgOkI6kYERQo8h2GzWfU8LWxl0a420ZHEfUZoYmitg/evA3v+23FrCMGg6
+2cdNzU5/mqsQ5HWktTQ5BZQZyn5UT3zpNCOVyeZc/ezzGXcWbEXOLQwDcolxjatL
+ED3eNA1OMQD8S++FPPGCukIzCyYiPq49zJCTMCWd3qTt2Bwea9xOQnoetCTU9goX
+/eEGj/1zQDAXCGOVgdd34VrOX4qtpmp3ABEBAAGJAiUEGAECAA8FAlVe7qQCGwwF
+CQlmAYAACgkQKdS8tkFvU+xj8Q//VNzFYM/kyHSa0xio4e8vBZA2vmR8IEUmtOSR
+zr487Z8W1dapGxR7OLQ52oWdRZVpG1B5rCuJtsWbjdY94Y8RpcO6FBemneGebBhu
+UKc60qwEanYnZva9PEFNyBzpj3xk3Ms7K4O2dZTcXPGj+hlep9Tjo09sklqbKfgW
+2fCUu2EKXWwUrnZ2LZtb/Ya8WPCrsbJFk+WbrLhWt7jIsadVl4AfblcgBGb8aN98
+GxnYOh+TGSMJtq1NSfchQwLHrpTPYm4McAwOBBYDdA+ik3//eLbwRiX9szFk658p
++4LErMBJAKLreSluBkqOG3AzT22Hdffvl8G2U4WhPPG33NzWomb+wKohjjzMVUlx
+YRCO57wkURqEW9/+a4riuBWGQqqRsW1wHEMu1lYdAhLJ5f0s3vO/fVe43ktaXNjW
+6k+mXDlIdKkQgQ736sBk3DAUc+YcmWmStPr1+TtT91eC23GLWP7gVDnNGEOBOscw
+U+m1bEOJN2duAMJSRK7U0r2ipmRKDcwK9XmVpJcTePfB2l+T3RdHEZIOlaTELEX6
+WJfpU4Kc1KJeKdp+l9gf2JD8eOZAlwxA4r2wxyzoCVg1Bk3XiBfoI7Gl78Wysp+/
+ChQcErPJWEUglBfrESpqmjxH/qSy6yjyNmd4Az2ii7IzWILfuheZR4drjHQj6mCA
+S5rowLE=
+=ZVPf
+-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file
diff --git a/contrib/gitian-downloader/linux-download-config b/contrib/gitian-downloader/linux-download-config
deleted file mode 100644
index f5e6382b84..0000000000
--- a/contrib/gitian-downloader/linux-download-config
+++ /dev/null
@@ -1,42 +0,0 @@
----
-name: bitcoin
-urls:
-- http://bitcoin.org/bitcoin-latest-linux-gitian.zip
-rss:
-- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss
- xpath: //item/link/text()
- pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip
-signers:
- 0A82509767C7D4A5D14DA2301AE1D35043E08E54:
- name: BlueMatt
- key: bluematt
- BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
- name: Devrandom
- key: devrandom
- E463A93F5F3117EEDE6C7316BD02942421F4889F:
- name: Luke-Jr
- key: luke-jr
- D762373D24904A3E42F33B08B9A408E71DAAC974:
- name: "Pieter Wuille"
- key: sipa
- 77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
- name: tcatm
- key: tcatm
- 01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
- name: "Gavin Andresen"
- key: gavinandresen
- 71A3B16735405025D447E8F274810B012346C9A6:
- name: "Wladimir J. van der Laan"
- key: laanwj
- AEC1884398647C47413C1C3FB1179EB7347DC10D:
- name: "Warren Togami"
- key: wtogami
- 9692B91BBF0E8D34DFD33B1882C5C009628ECF0C:
- name: michagogo
- key: michagogo
- E944AE667CF960B1004BC32FCA662BE18B877A60:
- name: "Andreas Schildbach"
- key: aschildbach
- C060A6635913D98A3587D7DB1C2491FFEB0EF770:
- name: "Cory Fields"
- key: "cfields"
diff --git a/contrib/gitian-downloader/luke-jr-key.pgp b/contrib/gitian-downloader/luke-jr-key.pgp
index 275b041d20..4406e6d5be 100644
--- a/contrib/gitian-downloader/luke-jr-key.pgp
+++ b/contrib/gitian-downloader/luke-jr-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/petertodd-key.pgp b/contrib/gitian-downloader/petertodd-key.pgp
new file mode 100644
index 0000000000..5ee82a6f7e
--- /dev/null
+++ b/contrib/gitian-downloader/petertodd-key.pgp
@@ -0,0 +1,1901 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+BSGsRbgvDNIR6RczbQ3j53l5j7ReYKP1yLnPwiNC3noPewqGephy6gH3BjYCtYZt
+Vq4+OeNgCLi5fhy1xNCeqto6qQlbms7hw5YKB/x12QnsdgxGV9guuKYiJEOG37A0
+qdmYOBkHt3TfZWlLCDVRaHvb30eGSKS01aHmK4pJLAFYVgLw/ggBjegj6AxdnpT5
+NQM9uWCfwZ2qa3vBPaw7FYhjcB/nSvpZ9I4dC1F3lffLucgpg73p6OO5aU6w952M
+hGDMKBGovbG2hvIaqs1RwaKZNtZZcBCXfIsQnGU11LYs/3w8cSyxWE/35HlveXW6
++YBXHIaY8nrJCQHwLlmRj7w1RXVODBy75iUd6mYURPZyadpVfTKIpFkddIFPLKPl
+6QkByMAno4dWS/p/2/xek9zBnhUhBjiQ+F9+rbF0K5LswiMK/BwzB8UXOXeueZXH
+H1vDCDOBzrDit8bgxJy8j2YGT2Vq7ThMnhSLLC3hRcWJAz+0rSJ51OxWLS3CQGgQ
+lmMOc2Wmz+K7JKvat3eZesBTQEZre6MpxXiebna53RnK/jFlEiqeZqPDWfry81ew
+qzDnWaQ/m43L0V8QVVeJBLEEEgECAJsFAlGVbM6UGmh0dHA6Ly93d3cuamVuc2Vy
+YXQuZGUvZmlsZXMvb3BlbnBncC9BNEZGMjI3OS1jZXJ0LXBvbGljeS0yMDEzLTA1
+LTE3LnR4dD9zaGE1MTJzdW09OGM4NTgyZjI1Mjk5MjRkZDY5Mjk3Yjc0YzM0MGEw
+YTI5YTFjMWQ3NWIxODFiZmY2MDJmZGRkNzllN2YwNDk2NAAKCRBOH3mapP8ieSuD
+H/90vmcaUOrfHXiDON3WzGU9lkk2K5GEauttX6p2gRRhzTqy47zUl5Wu8KWetkft
+XOf/4yhPwDyFzCElArReLBg0gM4vgCAH+jeZqSWcMvgv9M11cA8rSF7aRLdpPfR6
+m4RwS8niwpvInNG4DNCQxqZqSBB6XDyrtmjJP6PNhJD6Nd24nMzImyJ7QB1JrSjK
+lk539GS7fgEhhrBh5nKhVlvzzusvAc7MKysUCMduQrRYbkWQxw41OdIlIZMc6ErC
+SGEEKgrVB4xFZR2DNTd93PDggjHTtvXKnydCZC1XL94qvvHMmSagXfk76QwtHBG8
+099QR60buDGLnZvyDbR7H5ts7UPbIwIRWA0v/p7hhT9PRRLLVuK1oLUa1gEN/IAf
+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
+peBNXREPb4kkfF+RpT7HWD0u+i6sWb5+Yzt+vuRip7JkVu+7FDefLJ6ke0nEu6xJ
++HbAmZznOjnAg3o8M+XD9NIJT8Z5yB+ikQ3AZuZ1bJfNC85++oKGq14xJSvcA/4f
+hLdGNmj05ijBMYLsdzDL+Wkdl/69sultxs4nD6mhlw2epZtiw5qj4dgbzz7p6O78
+3pZgXBvy5UFxgxx8hZsjDAayodfyebFNSLXC06uVjafFbtbQZc83UfJAxwaW0jF6
+cl0n7nquGPk1TNMVCHOd9VNCdhPlFJHctUbIv0+HNrzgWCrmN1JzP4BJZsIK/Oqs
+j1SoFdGwxRWpSNwgO3WJASIEEAECAAwFAlKOadAFAwASdQAACgkQlxC4m8pXrXz8
+wQgAj0li8ga7DxoPNue6DzfKUbXw/LqjZUgs+d/MlHiEXS9hEMBDKLAnpDVIwSQl
+Ldu7UvanjpWK5UVj4jTMnNKjJXHRlFc1WBRrehOFej6tob//cd3czFKDG+IewnQX
+OLI7TA3uP5rg9PikGJOUW7wHUwunBdQl9XpLJe2XIhR7BAC4ppYl14OLDXM87f4J
+grEDv8po/xdY+s2ysI31g8/v8mg2ROromZ12HMrsirqyVb+dyNFxcQi9U9ZC6h8V
+00G4+duTjJt8YpQ/DYybVpMmVa40ePV+Z113OFZn9JdKs3p0kSi8csyLyItyJ62K
+c3/yfspKE3ZDrd+FVJ/VJXUIXohGBBARAgAGBQJTGOluAAoJEHc3YWR7U2QV/1AA
+n1bPtu6ZiSp+10U6yMmEvc9jWGlbAJ9tSDXgb9k3bFr1scJJ5kBsFJLGJYkCHAQQ
+AQoABgUCUp+JYAAKCRCkTD3TpUjY4lRZEACqIACFZ0JHma1seks08qGrOYAIJxd7
+VS7Pgk4w8/kYaoXePs+F2Liaevnd06aCytJBxa32yR9fsgoPwoF2I4tRMCBn68Sn
+lw/te9SU7M9Prrf8Rq02gEO7a2kqAH6ZNcUHdQDw2U0Rj4ArnZkHUh2Ey4TJwVUc
+tZzeXxlpgqYRTBLNaJyyBP53N8A+nHtpcqJYdxDYMMdTYVNs8epvRMcRfO/dWnnR
+lnco1ptge3cwm7E1/zX96/7GTPDwvtWseo0PF9W6wbaWTNm3c71iDXJbNbcVWdFt
+BEJZBhHzciyN3sysHEI6IwGzmmpAKpQJ2foXpYhxy1LuHBT3kW7dq/mOnr1zyjkI
+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
+TnaxBZk5kjROOetXQapW02twdC4k9tXLzuxjZ5w4zul9j0DFvXXIENHRMZVQDODr
+e9SkkzfvYyhqLMB5hFMZK7bnY6LvtWWM+aLZRa1B/j+thWwhM0JnCyKtqOXS8sGK
+rfpj7et2f66fi+i2yNhk/UBBHGwNlhYkeZG+ovcWTAtRjdGJASIEEAECAAwFAlQX
+PQ4FAwASdQAACgkQlxC4m8pXrXyvNQgAq8NazgIJu3cuGoIkel7tDAdPjFtQuznc
+pARNRSwVyG2jdZHOrNf76AoZK0NIqcenuKVyLe/o/U9+P4ufbBPajqnhSqEiu4f0
+mk1TWoJxWC2jW+Ew2ZLNu0adtoAqBE+FDCieAObUKF++4cxiU4r5npilADucQ4Fy
+UGLTA5RUQy4j9w0rQJ4xCAhzxBT/SiULlKQgEpj2XdOOiHSMS76fbIkw991L8ECN
+/1DiNDAzbExE2BwS0WwPb3KUiT0ookS91Q2i6mWaJbCa4iJUvK3i2YTxPpFb4N2e
+YmCCvKMLT4RC/2JQlUSjEozMImdYbFh1c0snzXmRatWK9THyyFuXx9HTt9O1ARAA
+AQEAAAAAAAAAAAAAAAD/2P/gABBKRklGAAEBAQBIAEgAAP/bAEMAEAsMDgwKEA4N
+DhIREBMYKRsYFhYYMiQmHik7ND49OjQ5OEFJXlBBRVlGODlSb1NZYWRpamk/T3N7
+cmZ6XmdpZf/bAEMBERISGBUYMBsbMGVDOUNlZWVlZWVlZWVlZWVlZWVlZWVlZWVl
+ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZf/AABEIASAA8AMBIgACEQEDEQH/
+xAAaAAACAwEBAAAAAAAAAAAAAAADBAABAgUG/8QAMBAAAgIBBAAGAQMFAAIDAAAA
+AQIAAxEEEiExBRMiQVFhcRQygQYjQpGhFbEzUsH/xAAYAQEBAQEBAAAAAAAAAAAA
+AAAAAQIDBP/EAB8RAQEBAQADAAIDAAAAAAAAAAABEQISITFBUQMiMv/aAAwDAQAC
+EQMRAD8AyohAJSiEUTyuy1E2BIomgIRAJoCWBLAgQCXiSXAmJJckCSSSZgSSZZ1X
+kkCZ8+v2YQCyTC2ofcTW4QLkkEuVEkxJJAkmJckDOJWJuTEKGRMkQuJREgERMkQp
+EwRAERFr+RG2EXuEirUQiiZUTYEqNATYEoCaAgSalS4ElypCcQixMPYqD1HEV1Wq
+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
+U2SsTgUAXL3GANeTM4N/XzzPXokCHAQQAQgABgUCUy3cVAAKCRBgtDFx2LpfQac8
+D/4kXKRRhtT8U+ViibJHXE8/MpGIqF373wbfs2y9S3D+kd/JOxC6ibnev2b+Wq29
+qdMk6BcyUaVzP0dxcnJj2CygYl2RD5dfIp8PzSilTHNfXGbJr9xPTcAjamXhUoJZ
+p8/C1ODwf2y11EB8CLDVVZmqgtxUOJNfh6is3cfzbYF8O2CX9ai5x9UykV9g////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////4kBHAQTAQIABgUCVK48
+ZgAKCRA82MB/C1zhTgoVB/9j6/khep6CXjyIoghxycm/4qhuCs2M8kM6G1B2W0sv
+lkaeqha+A96lCS43YoaRWkto2k496rrHfoC5f/8Vb36nQS7hd59DYANbtr5KJzwf
+yYsP/7+bkaiuC1E5SqmHjFiYYe7enQWdrcbsDfj420ScL9t2P0gO3vKJ5S8m7hkc
+a4OdCmYJkdaYxJcHK7BC4vkJmbxfnmmyGJaEPP/oxNCeZiyL37Y62N4DqCQpDj5C
+Ngk5w93+6H4oI8CIMzWEQZt9bZ2k9ipGobYhaLgVk5UMWkVJ8CuZESCgHLCuz7hG
+gDoDmXTnz3zbp038QPusF9zb307DEsWq7XwJB33/ljm4uQENBE+Xo6MBCADB0197
+HdK48SqvipyPB49vlzfP6KHfcACZCg1JTqOt8KRJFwTP3PTi/GJuUvt4io1UVG29
++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
+IemulKZaOJ7LLNmKTjOZnj12+S76emwpNEduQajYMDXPtHnc1FpF2jo4tfOQBO5h
+7z+UJzsGPO9O0pkYPxO3h/RS12R3uyvVE8Ej0w/8wiPFA29QgGf3zBRJ6GK2rAV+
+N/qhlMnE0agSy2+cmZzPDe33gtjLVZ7YmVp0YxbKa35DtvukhliGKH1cqkLKUt6Y
+ytvzuckpEQPEtI/7KTYmCfaT2hlOo7uSfGn9FtV0xzlcVy0dMk24xKllyeyeennJ
+jOuudVo5CQFRssnBDbkBDQRTG+drAQgAlo+QtN3XwYnuaRheTFnOLD7h9XBqZapO
+DwqQbod7MXZqp4jEfGqfQKleL0Xs9Dh5I66Hhwr9GIuciVSQbSEcqBEznHJGM6n1
+ssG662b5a+W3WC11SUGpuZJOUgOEHVLgVqSe7td8w8bFD841kfPXRTYmtNgzki/K
+RK7FFR1M5C5fBaQb7KGH/Cj/jUKKS9EwrMTW4jQxdcz881MFOGLM9hB4MCRXv+W4
+yUGqXurvFaEvYzVrYF1XNJFHheQ0Iw5GNUGxk0+F01kTBRNjJ+fnu/G/rIkHUYAc
+E3VHqsd1l6NStMwn2o2a+po/xeS3CIdxsRBx4NYepBrZdRjUrRzNiQARAQABiQGE
+BBgBCABuBQJTG+drXhSAAAAAABUAQGJsb2NraGFzaEBiaXRjb2luLm9yZzAwMDAw
+MDAwMDAwMDAwMDBmNGY1YmEzMzQ3OTFhNDEwMjkxN2U0ZDNmMjJmNmFkN2YyYzRm
+MTVkOTczMDdmZTICGyAFCQlmAYAACgkQf6sRQmfk+gTTNwf/XK8IGaPMASckFU1c
+EHM8ruYAC4b1wzzAY2733geJJlIMd4pYVhPWcczwMozc2AWJrhHzMS6Ho/r+FmAQ
+H+s0csYdhw0hL8w60bPXHSWu9wu6zlUJEY8G4pKjisEokYY7Aje/oEGfg8KJLHXA
+hYrPauW++O/NFCZ6ZNimFf40JRSjSUGzTKuBYW0/25dfV017De1XZvD+Qd198CfA
+9ojvBP2Rn7PYQkCMYA7xsViNz+tD0eC+BRdyO0cffCzoOOHHXy/1KSOnCry+JReA
+jnpviOsUyfY2bqGsmOpxyo5VfZ3OoHOOV7nucBEmQojuhl/xvU+Lc2airaR6UIAm
+jWDWrrkBjQRTG+GcAQwAk8T4liMdVQMjh6WFsmY38lEGu5FxirVSrMKjVQAq52XO
+l0I2jc6zTdqzyinW0sEswcQhmkTANzCspaU2kIBr/QVbdtPxPakwysV3RsqHPlAI
+rVQIdBU7ENnE9uzRzJtZfc5m+buknQ3MBjMdXlAceO4w7i+uhu5zXW4tSVwgKzhU
+uy1IexvK7ni4EZHzsOAarFbZpHozUqNZol7ALJrWkpQWqjuJZEIN0vefgSf3AV/r
+vGFlbI/PwEWDZlYlwDV9scuHRqqu0S1LArcLDmf78vnnclZYVUNl2kaVgRKmu2ra
+CWCSctmkyC5rqM9Xj+6B0ZVxhXReqfCnRn06Zwf7WwJuMWMfbAfZjDbksIMgKWpT
+/8UrH2RrI/6b4w5hXa7/C8zp8H109f7xcRgdLyj748P0bsrrVSfUWxMP+XRRGPY0
+4spkhNUVFlYc2BroIRXS+REKuI5WfWnUeSNWfAqbexaHRSgQQIydN2qp2sSxAe6Q
+FE3aXZyCHC4DMqIlUml7ABEBAAGJA7IEGAEIAG4FAlMb4ZxeFIAAAAAAFQBAYmxv
+Y2toYXNoQGJpdGNvaW4ub3JnMDAwMDAwMDAwMDAwMDAwMGY0ZjViYTMzNDc5MWE0
+MTAyOTE3ZTRkM2YyMmY2YWQ3ZjJjNGYxNWQ5NzMwN2ZlMgIbAgUJCWYBgAI4CRB/
+qxFCZ+T6BMFsIAQZAQgAlQUCUxvhnF4UgAAAAAAVAEBibG9ja2hhc2hAYml0Y29p
+bi5vcmcwMDAwMDAwMDAwMDAwMDAwZjRmNWJhMzM0NzkxYTQxMDI5MTdlNGQzZjIy
+ZjZhZDdmMmM0ZjE1ZDk3MzA3ZmUyLxSAAAAAABUAEXBrYS1hZGRyZXNzQGdudXBn
+Lm9yZ3BldGVAcGV0ZXJ0b2Qub3JnAAoJEGJeboN5AaHKDGcL/R3/aZoKC3OgtAkb
+o2g/ykbMt8pIko2cofAB/3zwl1p2qvwO3QV/vTVt6y4uEPEHItaFLiKTSH2KpTVl
+YflOh4M2/LXwXQmOiixpyDY3w42R6AZqY4g6q2SLDpNQLWaxVOerPgvDpSkIbcwH
+j8Fvai3Mrxtr2J+Jq3KW6TQnW9m5G/j4SqmQ2sRfkl6EEHiGcZp7pbKkE+qYGsmV
+HEirfCjlf03N3c7zcs6Nic9AEq2ghcnLwRAqmyRU59wOvIHlbQtnpJ9TI2zaOp2n
+U+4wOVkdolzN6TfPPLwATXsUFlQRS0ygarQXF4ifZ55MGZ56pc3GOR6fEH0FaUbr
+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
+=BHZ+
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/prab-key.pgp b/contrib/gitian-downloader/prab-key.pgp
new file mode 100644
index 0000000000..0870c88b9b
--- /dev/null
+++ b/contrib/gitian-downloader/prab-key.pgp
@@ -0,0 +1,81 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2
+
+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
+RFdDYRHByRDDL1I=
+=dOwX
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/sipa-key.pgp b/contrib/gitian-downloader/sipa-key.pgp
index ffa09bb4ad..a1930ddee9 100644
--- a/contrib/gitian-downloader/sipa-key.pgp
+++ b/contrib/gitian-downloader/sipa-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/win32-download-config b/contrib/gitian-downloader/win32-download-config
deleted file mode 100644
index 06c164180d..0000000000
--- a/contrib/gitian-downloader/win32-download-config
+++ /dev/null
@@ -1,42 +0,0 @@
----
-name: bitcoin
-urls:
-- http://bitcoin.org/bitcoin-latest-win32-gitian.zip
-rss:
-- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss
- xpath: //item/link/text()
- pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip
-signers:
- 0A82509767C7D4A5D14DA2301AE1D35043E08E54:
- name: BlueMatt
- key: bluematt
- BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
- name: Devrandom
- key: devrandom
- E463A93F5F3117EEDE6C7316BD02942421F4889F:
- name: Luke-Jr
- key: luke-jr
- D762373D24904A3E42F33B08B9A408E71DAAC974:
- name: "Pieter Wuille"
- key: sipa
- 77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
- name: tcatm
- key: tcatm
- 01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
- name: "Gavin Andresen"
- key: gavinandresen
- 71A3B16735405025D447E8F274810B012346C9A6:
- name: "Wladimir J. van der Laan"
- key: laanwj
- AEC1884398647C47413C1C3FB1179EB7347DC10D:
- name: "Warren Togami"
- key: wtogami
- 9692B91BBF0E8D34DFD33B1882C5C009628ECF0C:
- name: michagogo
- key: michagogo
- E944AE667CF960B1004BC32FCA662BE18B877A60:
- name: "Andreas Schildbach"
- key: aschildbach
- C060A6635913D98A3587D7DB1C2491FFEB0EF770:
- name: "Cory Fields"
- key: "cfields"
diff --git a/contrib/init/README.md b/contrib/init/README.md
new file mode 100644
index 0000000000..eb5d30acce
--- /dev/null
+++ b/contrib/init/README.md
@@ -0,0 +1,12 @@
+Sample configuration files for:
+
+SystemD: bitcoind.service
+Upstart: bitcoind.conf
+OpenRC: bitcoind.openrc
+ bitcoind.openrcconf
+CentOS: bitcoind.init
+OS X: org.bitcoin.bitcoind.plist
+
+have been made available to assist packagers in creating node packages here.
+
+See doc/init.md for more information.
diff --git a/contrib/init/bitcoind.conf b/contrib/init/bitcoind.conf
new file mode 100644
index 0000000000..f9554eecde
--- /dev/null
+++ b/contrib/init/bitcoind.conf
@@ -0,0 +1,65 @@
+description "Bitcoin Core Daemon"
+
+start on runlevel [2345]
+stop on starting rc RUNLEVEL=[016]
+
+env BITCOIND_BIN="/usr/bin/bitcoind"
+env BITCOIND_USER="bitcoin"
+env BITCOIND_GROUP="bitcoin"
+env BITCOIND_PIDDIR="/var/run/bitcoind"
+# upstart can't handle variables constructed with other variables
+env BITCOIND_PIDFILE="/var/run/bitcoind/bitcoind.pid"
+env BITCOIND_CONFIGFILE="/etc/bitcoin/bitcoin.conf"
+env BITCOIND_DATADIR="/var/lib/bitcoind"
+
+expect fork
+
+respawn
+respawn limit 5 120
+kill timeout 60
+
+pre-start script
+ # this will catch non-existent config files
+ # bitcoind will check and exit with this very warning, but it can do so
+ # long after forking, leaving upstart to think everything started fine.
+ # since this is a commonly encountered case on install, just check and
+ # warn here.
+ if ! grep -qs '^rpcpassword=' "$BITCOIND_CONFIGFILE" ; then
+ echo "ERROR: You must set a secure rpcpassword to run bitcoind."
+ echo "The setting must appear in $BITCOIND_CONFIGFILE"
+ echo
+ echo "This password is security critical to securing wallets "
+ echo "and must not be the same as the rpcuser setting."
+ echo "You can generate a suitable random password using the following"
+ echo "command from the shell:"
+ echo
+ echo "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'"
+ echo
+ echo "It is also recommended that you also set alertnotify so you are "
+ echo "notified of problems:"
+ echo
+ echo "ie: alertnotify=echo %%s | mail -s \"Bitcoin Alert\"" \
+ "admin@foo.com"
+ echo
+ exit 1
+ fi
+
+ mkdir -p "$BITCOIND_PIDDIR"
+ chmod 0755 "$BITCOIND_PIDDIR"
+ chown $BITCOIND_USER:$BITCOIND_GROUP "$BITCOIND_PIDDIR"
+ chown $BITCOIND_USER:$BITCOIND_GROUP "$BITCOIND_CONFIGFILE"
+ chmod 0660 "$BITCOIND_CONFIGFILE"
+end script
+
+exec start-stop-daemon \
+ --start \
+ --pidfile "$BITCOIND_PIDFILE" \
+ --chuid $BITCOIND_USER:$BITCOIND_GROUP \
+ --exec "$BITCOIND_BIN" \
+ -- \
+ -pid="$BITCOIND_PIDFILE" \
+ -conf="$BITCOIND_CONFIGFILE" \
+ -datadir="$BITCOIND_DATADIR" \
+ -disablewallet \
+ -daemon
+
diff --git a/contrib/init/bitcoind.init b/contrib/init/bitcoind.init
new file mode 100644
index 0000000000..db5061874b
--- /dev/null
+++ b/contrib/init/bitcoind.init
@@ -0,0 +1,67 @@
+#!/bin/bash
+#
+# bitcoind The bitcoin core server.
+#
+#
+# chkconfig: 345 80 20
+# description: bitcoind
+# processname: bitcoind
+#
+
+# Source function library.
+. /etc/init.d/functions
+
+# you can override defaults in /etc/sysconfig/bitcoind, see below
+if [ -f /etc/sysconfig/bitcoind ]; then
+ . /etc/sysconfig/bitcoind
+fi
+
+RETVAL=0
+
+prog=bitcoind
+# you can override the lockfile via BITCOIND_LOCKFILE in /etc/sysconfig/bitcoind
+lockfile=${BITCOIND_LOCKFILE-/var/lock/subsys/bitcoind}
+
+# bitcoind defaults to /usr/bin/bitcoind, override with BITCOIND_BIN
+bitcoind=${BITCOIND_BIN-/usr/bin/bitcoind}
+
+# bitcoind opts default to -disablewallet, override with BITCOIND_OPTS
+bitcoind_opts=${BITCOIND_OPTS--disablewallet}
+
+start() {
+ echo -n $"Starting $prog: "
+ daemon $DAEMONOPTS $bitcoind $bitcoind_opts
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch $lockfile
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Stopping $prog: "
+ killproc $prog
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f $lockfile
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status $prog
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ *)
+ echo "Usage: service $prog {start|stop|status|restart}"
+ exit 1
+ ;;
+esac
diff --git a/contrib/init/bitcoind.openrc b/contrib/init/bitcoind.openrc
new file mode 100644
index 0000000000..eda1a96fb4
--- /dev/null
+++ b/contrib/init/bitcoind.openrc
@@ -0,0 +1,92 @@
+#!/sbin/runscript
+
+# backward compatibility for existing gentoo layout
+#
+if [ -d "/var/lib/bitcoin/.bitcoin" ]; then
+ BITCOIND_DEFAULT_DATADIR="/var/lib/bitcoin/.bitcoin"
+else
+ BITCOIND_DEFAULT_DATADIR="/var/lib/bitcoind"
+fi
+
+BITCOIND_CONFIGFILE=${BITCOIND_CONFIGFILE:-/etc/bitcoin/bitcoin.conf}
+BITCOIND_PIDDIR=${BITCOIND_PIDDIR:-/var/run/bitcoind}
+BITCOIND_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid}
+BITCOIND_DATADIR=${BITCOIND_DATADIR:-${BITCOIND_DEFAULT_DATADIR}}
+BITCOIND_USER=${BITCOIND_USER:-${BITCOIN_USER:-bitcoin}}
+BITCOIND_GROUP=${BITCOIND_GROUP:-bitcoin}
+BITCOIND_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind}
+BITCOIND_NICE=${BITCOIND_NICE:-${NICELEVEL:-0}}
+BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}"
+
+name="Bitcoin Core Daemon"
+description="Bitcoin cryptocurrency P2P network daemon"
+
+command="/usr/bin/bitcoind"
+command_args="-pid=\"${BITCOIND_PIDFILE}\" \
+ -conf=\"${BITCOIND_CONFIGFILE}\" \
+ -datadir=\"${BITCOIND_DATADIR}\" \
+ -daemon \
+ ${BITCOIND_OPTS}"
+
+required_files="${BITCOIND_CONFIGFILE}"
+start_stop_daemon_args="-u ${BITCOIND_USER} \
+ -N ${BITCOIND_NICE} -w 2000"
+pidfile="${BITCOIND_PIDFILE}"
+
+# The retry schedule to use when stopping the daemon. Could be either
+# a timeout in seconds or multiple signal/timeout pairs (like
+# "SIGKILL/180 SIGTERM/300")
+retry="${BITCOIND_SIGTERM_TIMEOUT}"
+
+depend() {
+ need localmount net
+}
+
+# verify
+# 1) that the datadir exists and is writable (or create it)
+# 2) that a directory for the pid exists and is writable
+# 3) ownership and permissions on the config file
+start_pre() {
+ checkpath \
+ -d \
+ --mode 0750 \
+ --owner "${BITCOIND_USER}:${BITCOIND_GROUP}" \
+ "${BITCOIND_DATADIR}"
+
+ checkpath \
+ -d \
+ --mode 0755 \
+ --owner "${BITCOIND_USER}:${BITCOIND_GROUP}" \
+ "${BITCOIND_PIDDIR}"
+
+ checkpath -f \
+ -o ${BITCOIND_USER}:${BITCOIND_GROUP} \
+ -m 0660 \
+ ${BITCOIND_CONFIGFILE}
+
+ checkconfig || return 1
+}
+
+checkconfig()
+{
+ if ! grep -qs '^rpcpassword=' "${BITCOIND_CONFIGFILE}" ; then
+ eerror ""
+ eerror "ERROR: You must set a secure rpcpassword to run bitcoind."
+ eerror "The setting must appear in ${BITCOIND_CONFIGFILE}"
+ eerror ""
+ eerror "This password is security critical to securing wallets "
+ eerror "and must not be the same as the rpcuser setting."
+ eerror "You can generate a suitable random password using the following"
+ eerror "command from the shell:"
+ eerror ""
+ eerror "bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'"
+ eerror ""
+ eerror "It is also recommended that you also set alertnotify so you are "
+ eerror "notified of problems:"
+ eerror ""
+ eerror "ie: alertnotify=echo %%s | mail -s \"Bitcoin Alert\"" \
+ "admin@foo.com"
+ eerror ""
+ return 1
+ fi
+}
diff --git a/contrib/init/bitcoind.openrcconf b/contrib/init/bitcoind.openrcconf
new file mode 100644
index 0000000000..0cbff6d30d
--- /dev/null
+++ b/contrib/init/bitcoind.openrcconf
@@ -0,0 +1,33 @@
+# /etc/conf.d/bitcoind: config file for /etc/init.d/bitcoind
+
+# Config file location
+#BITCOIND_CONFIGFILE="/etc/bitcoin/bitcoin.conf"
+
+# What directory to write pidfile to? (created and owned by $BITCOIND_USER)
+#BITCOIND_PIDDIR="/var/run/bitcoind"
+
+# What filename to give the pidfile
+#BITCOIND_PIDFILE="${BITCOIND_PIDDIR}/bitcoind.pid"
+
+# Where to write bitcoind data (be mindful that the blockchain is large)
+#BITCOIND_DATADIR="/var/lib/bitcoind"
+
+# User and group to own bitcoind process
+#BITCOIND_USER="bitcoin"
+#BITCOIND_GROUP="bitcoin"
+
+# Path to bitcoind executable
+#BITCOIND_BIN="/usr/bin/bitcoind"
+
+# Nice value to run bitcoind under
+#BITCOIND_NICE=0
+
+# Additional options (avoid -conf and -datadir, use flags above)
+BITCOIND_OPTS="-disablewallet"
+
+# The timeout in seconds OpenRC will wait for bitcoind to terminate
+# after a SIGTERM has been raised.
+# Note that this will be mapped as argument to start-stop-daemon's
+# '--retry' option, which means you can specify a retry schedule
+# here. For more information see man 8 start-stop-daemon.
+BITCOIND_SIGTERM_TIMEOUT=60
diff --git a/contrib/systemd/bitcoind.service b/contrib/init/bitcoind.service
index edc81cc763..9132957c38 100644
--- a/contrib/systemd/bitcoind.service
+++ b/contrib/init/bitcoind.service
@@ -3,15 +3,20 @@ Description=Bitcoin's distributed currency daemon
After=network.target
[Service]
-User=bitcoind
-Group=bitcoind
+User=bitcoin
+Group=bitcoin
Type=forking
PIDFile=/var/lib/bitcoind/bitcoind.pid
-ExecStart=/usr/bin/bitcoind -daemon -pid=/var/lib/bitcoind/bitcoind.pid -conf=/etc/bitcoind.conf -datadir=/var/lib/bitcoind
+ExecStart=/usr/bin/bitcoind -daemon -pid=/var/lib/bitcoind/bitcoind.pid \
+-conf=/etc/bitcoin/bitcoin.conf -datadir=/var/lib/bitcoind -disablewallet
Restart=always
PrivateTmp=true
+TimeoutStopSec=60s
+TimeoutStartSec=2s
+StartLimitInterval=120s
+StartLimitBurst=5
[Install]
WantedBy=multi-user.target
diff --git a/contrib/init/org.bitcoin.bitcoind.plist b/contrib/init/org.bitcoin.bitcoind.plist
new file mode 100644
index 0000000000..e94cd4466d
--- /dev/null
+++ b/contrib/init/org.bitcoin.bitcoind.plist
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Label</key>
+ <string>org.bitcoin.bitcoind</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/local/bin/bitcoind</string>
+ <string>-daemon</string>
+ </array>
+ <key>RunAtLoad</key>
+ <true/>
+</dict>
+</plist>
diff --git a/contrib/linearize/README.md b/contrib/linearize/README.md
index b5c6e7824e..06f278f3b3 100644
--- a/contrib/linearize/README.md
+++ b/contrib/linearize/README.md
@@ -3,7 +3,7 @@ Construct a linear, no-fork, best version of the blockchain.
## Step 1: Download hash list
- $ ./linearize-hashes.py linearize.cfg > hashlist.txt
+ $ ./linearize-hashes.py linearize.cfg > hashlist.txt
Required configuration file settings for linearize-hashes:
* RPC: rpcuser, rpcpassword
@@ -14,7 +14,7 @@ Optional config file setting for linearize-hashes:
## Step 2: Copy local block data
- $ ./linearize-data.py linearize.cfg
+ $ ./linearize-data.py linearize.cfg
Required configuration file settings:
* "input": bitcoind blocks/ directory containing blkNNNNN.dat
@@ -26,7 +26,8 @@ output.
Optional config file setting for linearize-data:
* "netmagic": network magic number
-* "max_out_sz": maximum output file size (default 1000*1000*1000)
-* "split_year": Split files when a new year is first seen, in addition to
+* "max_out_sz": maximum output file size (default `1000*1000*1000`)
+* "split_timestamp": Split files when a new month is first seen, in addition to
reaching a maximum file size.
-
+* "file_timestamp": Set each file's last-modified time to that of the
+most recent block in that file.
diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg
index 071345f23a..38da02e66c 100644
--- a/contrib/linearize/example-linearize.cfg
+++ b/contrib/linearize/example-linearize.cfg
@@ -4,14 +4,26 @@ rpcuser=someuser
rpcpassword=somepassword
host=127.0.0.1
port=8332
+#port=18332
# bootstrap.dat hashlist settings (linearize-hashes)
max_height=313000
# bootstrap.dat input/output settings (linearize-data)
+
+# mainnet
netmagic=f9beb4d9
+genesis=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
input=/home/example/.bitcoin/blocks
+
+# testnet
+#netmagic=0b110907
+#genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
+#input=/home/example/.bitcoin/testnet3/blocks
+
output_file=/home/example/Downloads/bootstrap.dat
hashlist=hashlist.txt
split_year=1
+# Maxmimum size in bytes of out-of-order blocks cache in memory
+out_of_order_cache_sz = 100000000
diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py
index ea94f25fae..0f6fde2a6e 100755
--- a/contrib/linearize/linearize-data.py
+++ b/contrib/linearize/linearize-data.py
@@ -2,23 +2,27 @@
#
# linearize-data.py: Construct a linear, no-fork version of the chain.
#
-# Copyright (c) 2013 The Bitcoin developers
-# Distributed under the MIT/X11 software license, see the accompanying
+# Copyright (c) 2013-2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
+from __future__ import print_function, division
import json
import struct
import re
+import os
+import os.path
import base64
import httplib
import sys
import hashlib
import datetime
+import time
+from collections import namedtuple
settings = {}
-
def uint32(x):
return x & 0xffffffffL
@@ -58,10 +62,12 @@ def calc_hash_str(blk_hdr):
hash_str = hash.encode('hex')
return hash_str
-def get_blk_year(blk_hdr):
+def get_blk_dt(blk_hdr):
members = struct.unpack("<I", blk_hdr[68:68+4])
- dt = datetime.datetime.fromtimestamp(members[0])
- return dt.year
+ nTime = members[0]
+ dt = datetime.datetime.fromtimestamp(nTime)
+ dt_ym = datetime.datetime(dt.year, dt.month, 1)
+ return (dt_ym, nTime)
def get_block_hashes(settings):
blkindex = []
@@ -74,94 +80,175 @@ def get_block_hashes(settings):
return blkindex
-def mkblockset(blkindex):
+def mkblockmap(blkindex):
blkmap = {}
- for hash in blkindex:
- blkmap[hash] = True
+ for height,hash in enumerate(blkindex):
+ blkmap[hash] = height
return blkmap
-def copydata(settings, blkindex, blkset):
- inFn = 0
- inF = None
- outFn = 0
- outsz = 0
- outF = None
- blkCount = 0
-
- lastYear = 0
- splitYear = False
- fileOutput = True
- maxOutSz = settings['max_out_sz']
- if 'output' in settings:
- fileOutput = False
- if settings['split_year'] != 0:
- splitYear = True
-
- while True:
- if not inF:
- fname = "%s/blk%05d.dat" % (settings['input'], inFn)
- print("Input file" + fname)
- inF = open(fname, "rb")
-
- inhdr = inF.read(8)
- if (not inhdr or (inhdr[0] == "\0")):
- inF.close()
- inF = None
- inFn = inFn + 1
- continue
-
- inMagic = inhdr[:4]
- if (inMagic != settings['netmagic']):
- print("Invalid magic:" + inMagic)
- return
- inLenLE = inhdr[4:]
- su = struct.unpack("<I", inLenLE)
- inLen = su[0]
- rawblock = inF.read(inLen)
- blk_hdr = rawblock[:80]
-
- hash_str = calc_hash_str(blk_hdr)
- if not hash_str in blkset:
- print("Skipping unknown block " + hash_str)
- continue
-
- if not fileOutput and ((outsz + inLen) > maxOutSz):
- outF.close()
- outF = None
- outFn = outFn + 1
- outsz = 0
-
- if splitYear:
- blkYear = get_blk_year(blk_hdr)
- if blkYear > lastYear:
- print("New year " + str(blkYear) + " @ " + hash_str)
- lastYear = blkYear
- if outF:
- outF.close()
- outF = None
- outFn = outFn + 1
- outsz = 0
-
- if not outF:
- if fileOutput:
- fname = settings['output_file']
+# Block header and extent on disk
+BlockExtent = namedtuple('BlockExtent', ['fn', 'offset', 'inhdr', 'blkhdr', 'size'])
+
+class BlockDataCopier:
+ def __init__(self, settings, blkindex, blkmap):
+ self.settings = settings
+ self.blkindex = blkindex
+ self.blkmap = blkmap
+
+ self.inFn = 0
+ self.inF = None
+ self.outFn = 0
+ self.outsz = 0
+ self.outF = None
+ self.outFname = None
+ self.blkCountIn = 0
+ self.blkCountOut = 0
+
+ self.lastDate = datetime.datetime(2000, 1, 1)
+ self.highTS = 1408893517 - 315360000
+ self.timestampSplit = False
+ self.fileOutput = True
+ self.setFileTime = False
+ self.maxOutSz = settings['max_out_sz']
+ if 'output' in settings:
+ self.fileOutput = False
+ if settings['file_timestamp'] != 0:
+ self.setFileTime = True
+ if settings['split_timestamp'] != 0:
+ self.timestampSplit = True
+ # Extents and cache for out-of-order blocks
+ self.blockExtents = {}
+ self.outOfOrderData = {}
+ self.outOfOrderSize = 0 # running total size for items in outOfOrderData
+
+ def writeBlock(self, inhdr, blk_hdr, rawblock):
+ blockSizeOnDisk = len(inhdr) + len(blk_hdr) + len(rawblock)
+ if not self.fileOutput and ((self.outsz + blockSizeOnDisk) > self.maxOutSz):
+ self.outF.close()
+ if self.setFileTime:
+ os.utime(outFname, (int(time.time()), highTS))
+ self.outF = None
+ self.outFname = None
+ self.outFn = self.outFn + 1
+ self.outsz = 0
+
+ (blkDate, blkTS) = get_blk_dt(blk_hdr)
+ if self.timestampSplit and (blkDate > self.lastDate):
+ print("New month " + blkDate.strftime("%Y-%m") + " @ " + hash_str)
+ lastDate = blkDate
+ if outF:
+ outF.close()
+ if setFileTime:
+ os.utime(outFname, (int(time.time()), highTS))
+ self.outF = None
+ self.outFname = None
+ self.outFn = self.outFn + 1
+ self.outsz = 0
+
+ if not self.outF:
+ if self.fileOutput:
+ outFname = self.settings['output_file']
else:
- fname = "%s/blk%05d.dat" % (settings['output'], outFn)
- print("Output file" + fname)
- outF = open(fname, "wb")
-
- outF.write(inhdr)
- outF.write(rawblock)
- outsz = outsz + inLen + 8
-
- blkCount = blkCount + 1
-
- if (blkCount % 1000) == 0:
- print("Wrote " + str(blkCount) + " blocks")
+ outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn)
+ print("Output file " + outFname)
+ self.outF = open(outFname, "wb")
+
+ self.outF.write(inhdr)
+ self.outF.write(blk_hdr)
+ self.outF.write(rawblock)
+ self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock)
+
+ self.blkCountOut = self.blkCountOut + 1
+ if blkTS > self.highTS:
+ self.highTS = blkTS
+
+ if (self.blkCountOut % 1000) == 0:
+ print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' %
+ (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex)))
+
+ def inFileName(self, fn):
+ return os.path.join(self.settings['input'], "blk%05d.dat" % fn)
+
+ def fetchBlock(self, extent):
+ '''Fetch block contents from disk given extents'''
+ with open(self.inFileName(extent.fn), "rb") as f:
+ f.seek(extent.offset)
+ return f.read(extent.size)
+
+ def copyOneBlock(self):
+ '''Find the next block to be written in the input, and copy it to the output.'''
+ extent = self.blockExtents.pop(self.blkCountOut)
+ if self.blkCountOut in self.outOfOrderData:
+ # If the data is cached, use it from memory and remove from the cache
+ rawblock = self.outOfOrderData.pop(self.blkCountOut)
+ self.outOfOrderSize -= len(rawblock)
+ else: # Otherwise look up data on disk
+ rawblock = self.fetchBlock(extent)
+
+ self.writeBlock(extent.inhdr, extent.blkhdr, rawblock)
+
+ def run(self):
+ while self.blkCountOut < len(self.blkindex):
+ if not self.inF:
+ fname = self.inFileName(self.inFn)
+ print("Input file " + fname)
+ try:
+ self.inF = open(fname, "rb")
+ except IOError:
+ print("Premature end of block data")
+ return
+
+ inhdr = self.inF.read(8)
+ if (not inhdr or (inhdr[0] == "\0")):
+ self.inF.close()
+ self.inF = None
+ self.inFn = self.inFn + 1
+ continue
+
+ inMagic = inhdr[:4]
+ if (inMagic != self.settings['netmagic']):
+ print("Invalid magic: " + inMagic.encode('hex'))
+ return
+ inLenLE = inhdr[4:]
+ su = struct.unpack("<I", inLenLE)
+ inLen = su[0] - 80 # length without header
+ blk_hdr = self.inF.read(80)
+ inExtent = BlockExtent(self.inFn, self.inF.tell(), inhdr, blk_hdr, inLen)
+
+ hash_str = calc_hash_str(blk_hdr)
+ if not hash_str in blkmap:
+ print("Skipping unknown block " + hash_str)
+ self.inF.seek(inLen, os.SEEK_CUR)
+ continue
+
+ blkHeight = self.blkmap[hash_str]
+ self.blkCountIn += 1
+
+ if self.blkCountOut == blkHeight:
+ # If in-order block, just copy
+ rawblock = self.inF.read(inLen)
+ self.writeBlock(inhdr, blk_hdr, rawblock)
+
+ # See if we can catch up to prior out-of-order blocks
+ while self.blkCountOut in self.blockExtents:
+ self.copyOneBlock()
+
+ else: # If out-of-order, skip over block data for now
+ self.blockExtents[blkHeight] = inExtent
+ if self.outOfOrderSize < self.settings['out_of_order_cache_sz']:
+ # If there is space in the cache, read the data
+ # Reading the data in file sequence instead of seeking and fetching it later is preferred,
+ # but we don't want to fill up memory
+ self.outOfOrderData[blkHeight] = self.inF.read(inLen)
+ self.outOfOrderSize += inLen
+ else: # If no space in cache, seek forward
+ self.inF.seek(inLen, os.SEEK_CUR)
+
+ print("Done (%i blocks written)" % (self.blkCountOut))
if __name__ == '__main__':
if len(sys.argv) != 2:
- print "Usage: linearize-data.py CONFIG-FILE"
+ print("Usage: linearize-data.py CONFIG-FILE")
sys.exit(1)
f = open(sys.argv[1])
@@ -180,29 +267,37 @@ if __name__ == '__main__':
if 'netmagic' not in settings:
settings['netmagic'] = 'f9beb4d9'
+ if 'genesis' not in settings:
+ settings['genesis'] = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
if 'input' not in settings:
settings['input'] = 'input'
if 'hashlist' not in settings:
settings['hashlist'] = 'hashlist.txt'
- if 'split_year' not in settings:
- settings['split_year'] = 0
+ if 'file_timestamp' not in settings:
+ settings['file_timestamp'] = 0
+ if 'split_timestamp' not in settings:
+ settings['split_timestamp'] = 0
if 'max_out_sz' not in settings:
settings['max_out_sz'] = 1000L * 1000 * 1000
+ if 'out_of_order_cache_sz' not in settings:
+ settings['out_of_order_cache_sz'] = 100 * 1000 * 1000
settings['max_out_sz'] = long(settings['max_out_sz'])
- settings['split_year'] = int(settings['split_year'])
+ settings['split_timestamp'] = int(settings['split_timestamp'])
+ settings['file_timestamp'] = int(settings['file_timestamp'])
settings['netmagic'] = settings['netmagic'].decode('hex')
+ settings['out_of_order_cache_sz'] = int(settings['out_of_order_cache_sz'])
if 'output_file' not in settings and 'output' not in settings:
print("Missing output file / directory")
sys.exit(1)
blkindex = get_block_hashes(settings)
- blkset = mkblockset(blkindex)
+ blkmap = mkblockmap(blkindex)
- if not "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" in blkset:
- print("not found")
+ if not settings['genesis'] in blkmap:
+ print("Genesis block not found in hashlist")
else:
- copydata(settings, blkindex, blkset)
+ BlockDataCopier(settings, blkindex, blkmap).run()
diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py
index 791b71bc33..854cf1f9ee 100755
--- a/contrib/linearize/linearize-hashes.py
+++ b/contrib/linearize/linearize-hashes.py
@@ -2,11 +2,12 @@
#
# linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
#
-# Copyright (c) 2013 The Bitcoin developers
-# Distributed under the MIT/X11 software license, see the accompanying
+# Copyright (c) 2013-2014 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
+from __future__ import print_function
import json
import struct
import re
@@ -17,59 +18,65 @@ import sys
settings = {}
class BitcoinRPC:
- OBJID = 1
-
def __init__(self, host, port, username, password):
authpair = "%s:%s" % (username, password)
self.authhdr = "Basic %s" % (base64.b64encode(authpair))
self.conn = httplib.HTTPConnection(host, port, False, 30)
- def rpc(self, method, params=None):
- self.OBJID += 1
- obj = { 'version' : '1.1',
- 'method' : method,
- 'id' : self.OBJID }
- if params is None:
- obj['params'] = []
- else:
- obj['params'] = params
+
+ def execute(self, obj):
self.conn.request('POST', '/', json.dumps(obj),
{ 'Authorization' : self.authhdr,
'Content-type' : 'application/json' })
resp = self.conn.getresponse()
if resp is None:
- print "JSON-RPC: no response"
+ print("JSON-RPC: no response", file=sys.stderr)
return None
body = resp.read()
resp_obj = json.loads(body)
- if resp_obj is None:
- print "JSON-RPC: cannot JSON-decode body"
- return None
- if 'error' in resp_obj and resp_obj['error'] != None:
- return resp_obj['error']
- if 'result' not in resp_obj:
- print "JSON-RPC: no result in object"
- return None
+ return resp_obj
- return resp_obj['result']
- def getblock(self, hash, verbose=True):
- return self.rpc('getblock', [hash, verbose])
- def getblockhash(self, index):
- return self.rpc('getblockhash', [index])
+ @staticmethod
+ def build_request(idx, method, params):
+ obj = { 'version' : '1.1',
+ 'method' : method,
+ 'id' : idx }
+ if params is None:
+ obj['params'] = []
+ else:
+ obj['params'] = params
+ return obj
+
+ @staticmethod
+ def response_is_error(resp_obj):
+ return 'error' in resp_obj and resp_obj['error'] is not None
-def get_block_hashes(settings):
+def get_block_hashes(settings, max_blocks_per_call=10000):
rpc = BitcoinRPC(settings['host'], settings['port'],
settings['rpcuser'], settings['rpcpassword'])
- for height in xrange(settings['min_height'], settings['max_height']+1):
- hash = rpc.getblockhash(height)
+ height = settings['min_height']
+ while height < settings['max_height']+1:
+ num_blocks = min(settings['max_height']+1-height, max_blocks_per_call)
+ batch = []
+ for x in range(num_blocks):
+ batch.append(rpc.build_request(x, 'getblockhash', [height + x]))
+
+ reply = rpc.execute(batch)
+
+ for x,resp_obj in enumerate(reply):
+ if rpc.response_is_error(resp_obj):
+ print('JSON-RPC: error at height', height+x, ': ', resp_obj['error'], file=sys.stderr)
+ exit(1)
+ assert(resp_obj['id'] == x) # assume replies are in-sequence
+ print(resp_obj['result'])
- print(hash)
+ height += num_blocks
if __name__ == '__main__':
if len(sys.argv) != 2:
- print "Usage: linearize-hashes.py CONFIG-FILE"
+ print("Usage: linearize-hashes.py CONFIG-FILE")
sys.exit(1)
f = open(sys.argv[1])
@@ -95,7 +102,7 @@ if __name__ == '__main__':
if 'max_height' not in settings:
settings['max_height'] = 313000
if 'rpcuser' not in settings or 'rpcpassword' not in settings:
- print "Missing username and/or password in cfg file"
+ print("Missing username and/or password in cfg file", file=stderr)
sys.exit(1)
settings['port'] = int(settings['port'])
diff --git a/contrib/macdeploy/Base.lproj/InfoPlist.strings b/contrib/macdeploy/Base.lproj/InfoPlist.strings
new file mode 100644
index 0000000000..b259ea141c
--- /dev/null
+++ b/contrib/macdeploy/Base.lproj/InfoPlist.strings
@@ -0,0 +1 @@
+{ CFBundleDisplayName = "Bitcoin Core"; CFBundleName = "Bitcoin Core"; }
diff --git a/contrib/macdeploy/DS_Store b/contrib/macdeploy/DS_Store
index b9a1e14864..db9d16f1d7 100644
--- a/contrib/macdeploy/DS_Store
+++ b/contrib/macdeploy/DS_Store
Binary files differ
diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md
index 0aa57b4777..6163734e62 100644
--- a/contrib/macdeploy/README.md
+++ b/contrib/macdeploy/README.md
@@ -11,5 +11,5 @@ This script should not be run manually, instead, after building as usual:
During the process, the disk image window will pop up briefly where the fancy
settings are applied. This is normal, please do not interfere.
-When finished, it will produce `Bitcoin-Qt.dmg`.
+When finished, it will produce `Bitcoin-Core.dmg`.
diff --git a/contrib/macdeploy/background.png b/contrib/macdeploy/background.png
index fce12e3807..f88a2ae74b 100644
--- a/contrib/macdeploy/background.png
+++ b/contrib/macdeploy/background.png
Binary files differ
diff --git a/contrib/macdeploy/background.psd b/contrib/macdeploy/background.psd
index 5889676f8e..fdc4f4ca4a 100644
--- a/contrib/macdeploy/background.psd
+++ b/contrib/macdeploy/background.psd
Binary files differ
diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff
new file mode 100644
index 0000000000..4b44ac672e
--- /dev/null
+++ b/contrib/macdeploy/background.tiff
Binary files differ
diff --git a/contrib/macdeploy/background@2x.png b/contrib/macdeploy/background@2x.png
new file mode 100644
index 0000000000..4858183f75
--- /dev/null
+++ b/contrib/macdeploy/background@2x.png
Binary files differ
diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh
new file mode 100755
index 0000000000..781fe315ed
--- /dev/null
+++ b/contrib/macdeploy/detached-sig-apply.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+set -e
+
+UNSIGNED="$1"
+SIGNATURE="$2"
+ARCH=x86_64
+ROOTDIR=dist
+TEMPDIR=signed.temp
+OUTDIR=signed-app
+
+if [ -z "$UNSIGNED" ]; then
+ echo "usage: $0 <unsigned app> <signature>"
+ exit 1
+fi
+
+if [ -z "$SIGNATURE" ]; then
+ echo "usage: $0 <unsigned app> <signature>"
+ exit 1
+fi
+
+rm -rf ${TEMPDIR} && mkdir -p ${TEMPDIR}
+tar -C ${TEMPDIR} -xf ${UNSIGNED}
+cp -rf "${SIGNATURE}"/* ${TEMPDIR}
+
+if [ -z "${PAGESTUFF}" ]; then
+ PAGESTUFF=${TEMPDIR}/pagestuff
+fi
+
+if [ -z "${CODESIGN_ALLOCATE}" ]; then
+ CODESIGN_ALLOCATE=${TEMPDIR}/codesign_allocate
+fi
+
+find ${TEMPDIR} -name "*.sign" | while read i; do
+ SIZE=`stat -c %s "${i}"`
+ TARGET_FILE="`echo "${i}" | sed 's/\.sign$//'`"
+
+ echo "Allocating space for the signature of size ${SIZE} in ${TARGET_FILE}"
+ ${CODESIGN_ALLOCATE} -i "${TARGET_FILE}" -a ${ARCH} ${SIZE} -o "${i}.tmp"
+
+ OFFSET=`${PAGESTUFF} "${i}.tmp" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
+ if [ -z ${QUIET} ]; then
+ echo "Attaching signature at offset ${OFFSET}"
+ fi
+
+ dd if="$i" of="${i}.tmp" bs=1 seek=${OFFSET} count=${SIZE} 2>/dev/null
+ mv "${i}.tmp" "${TARGET_FILE}"
+ rm "${i}"
+ echo "Success."
+done
+mv ${TEMPDIR}/${ROOTDIR} ${OUTDIR}
+rm -rf ${TEMPDIR}
+echo "Signed: ${OUTDIR}"
diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh
new file mode 100755
index 0000000000..89a2da32f7
--- /dev/null
+++ b/contrib/macdeploy/detached-sig-create.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+set -e
+
+ROOTDIR=dist
+BUNDLE="${ROOTDIR}/Bitcoin-Qt.app"
+CODESIGN=codesign
+TEMPDIR=sign.temp
+TEMPLIST=${TEMPDIR}/signatures.txt
+OUT=signature.tar.gz
+OUTROOT=osx
+
+if [ ! -n "$1" ]; then
+ echo "usage: $0 <codesign args>"
+ echo "example: $0 -s MyIdentity"
+ exit 1
+fi
+
+rm -rf ${TEMPDIR} ${TEMPLIST}
+mkdir -p ${TEMPDIR}
+
+${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}"
+
+grep -v CodeResources < "${TEMPLIST}" | while read i; do
+ TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`"
+ SIZE=`pagestuff "$i" -p | tail -2 | grep size | sed 's/[^0-9]*//g'`
+ OFFSET=`pagestuff "$i" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
+ SIGNFILE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}.sign"
+ DIRNAME="`dirname "${SIGNFILE}"`"
+ mkdir -p "${DIRNAME}"
+ echo "Adding detached signature for: ${TARGETFILE}. Size: ${SIZE}. Offset: ${OFFSET}"
+ dd if="$i" of="${SIGNFILE}" bs=1 skip=${OFFSET} count=${SIZE} 2>/dev/null
+done
+
+grep CodeResources < "${TEMPLIST}" | while read i; do
+ TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`"
+ RESOURCE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}"
+ DIRNAME="`dirname "${RESOURCE}"`"
+ mkdir -p "${DIRNAME}"
+ echo "Adding resource for: "${TARGETFILE}""
+ cp "${i}" "${RESOURCE}"
+done
+
+rm ${TEMPLIST}
+
+tar -C "${TEMPDIR}" -czf "${OUT}" .
+rm -rf "${TEMPDIR}"
+echo "Created ${OUT}"
diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist
index e73b9b697e..ef277a7f14 100644
--- a/contrib/macdeploy/fancy.plist
+++ b/contrib/macdeploy/fancy.plist
@@ -10,7 +10,7 @@
<integer>620</integer>
</array>
<key>background_picture</key>
- <string>background.png</string>
+ <string>background.tiff</string>
<key>icon_size</key>
<integer>96</integer>
<key>applications_symlink</key>
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
index 23b57a76b3..2253c40af1 100755
--- a/contrib/macdeploy/macdeployqtplus
+++ b/contrib/macdeploy/macdeployqtplus
@@ -37,7 +37,10 @@ class FrameworkInfo(object):
self.sourceFilePath = ""
self.destinationDirectory = ""
self.sourceResourcesDirectory = ""
+ self.sourceVersionContentsDirectory = ""
+ self.sourceContentsDirectory = ""
self.destinationResourcesDirectory = ""
+ self.destinationVersionContentsDirectory = ""
def __eq__(self, other):
if self.__class__ == other.__class__:
@@ -141,14 +144,18 @@ class FrameworkInfo(object):
info.destinationDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, info.binaryDirectory)
info.sourceResourcesDirectory = os.path.join(info.frameworkPath, "Resources")
+ info.sourceContentsDirectory = os.path.join(info.frameworkPath, "Contents")
+ info.sourceVersionContentsDirectory = os.path.join(info.frameworkPath, "Versions", info.version, "Contents")
info.destinationResourcesDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Resources")
+ info.destinationContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Contents")
+ info.destinationVersionContentsDirectory = os.path.join(cls.bundleFrameworkDirectory, info.frameworkName, "Versions", info.version, "Contents")
return info
class ApplicationBundleInfo(object):
def __init__(self, path):
self.path = path
- appName = os.path.splitext(os.path.basename(path))[0]
+ appName = "Bitcoin-Qt"
self.binaryPath = os.path.join(path, "Contents", "MacOS", appName)
if not os.path.exists(self.binaryPath):
raise RuntimeError("Could not find bundle binary for " + path)
@@ -275,18 +282,35 @@ def copyFramework(framework, path, verbose):
os.chmod(toPath, permissions.st_mode | stat.S_IWRITE)
if not framework.isDylib(): # Copy resources for real frameworks
+
+ linkfrom = os.path.join(path, "Contents","Frameworks", framework.frameworkName, "Versions", "Current")
+ linkto = framework.version
+ if not os.path.exists(linkfrom):
+ os.symlink(linkto, linkfrom)
+ if verbose >= 2:
+ print "Linked:", linkfrom, "->", linkto
fromResourcesDir = framework.sourceResourcesDirectory
if os.path.exists(fromResourcesDir):
toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory)
- shutil.copytree(fromResourcesDir, toResourcesDir)
+ shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True)
if verbose >= 3:
print "Copied resources:", fromResourcesDir
print " to:", toResourcesDir
+ fromContentsDir = framework.sourceVersionContentsDirectory
+ if not os.path.exists(fromContentsDir):
+ fromContentsDir = framework.sourceContentsDirectory
+ if os.path.exists(fromContentsDir):
+ toContentsDir = os.path.join(path, framework.destinationVersionContentsDirectory)
+ shutil.copytree(fromContentsDir, toContentsDir, symlinks=True)
+ contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory)
+ if verbose >= 3:
+ print "Copied Contents:", fromContentsDir
+ print " to:", toContentsDir
elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout)
qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib")
qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib")
if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath):
- shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath)
+ shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True)
if verbose >= 3:
print "Copied for libQtGui:", qtMenuNibSourcePath
print " to:", qtMenuNibDestinationPath
@@ -369,7 +393,7 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Deploy the script plugins only if QtScript is in use
if not deploymentInfo.usesFramework("QtScript"):
continue
- elif pluginDirectory == "qmltooling":
+ elif pluginDirectory == "qmltooling" or pluginDirectory == "qml1tooling":
# Deploy the qml plugins only if QtDeclarative is in use
if not deploymentInfo.usesFramework("QtDeclarative"):
continue
@@ -377,7 +401,23 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Deploy the bearer plugins only if QtNetwork is in use
if not deploymentInfo.usesFramework("QtNetwork"):
continue
-
+ elif pluginDirectory == "position":
+ # Deploy the position plugins only if QtPositioning is in use
+ if not deploymentInfo.usesFramework("QtPositioning"):
+ continue
+ elif pluginDirectory == "sensors" or pluginDirectory == "sensorgestures":
+ # Deploy the sensor plugins only if QtSensors is in use
+ if not deploymentInfo.usesFramework("QtSensors"):
+ continue
+ elif pluginDirectory == "audio" or pluginDirectory == "playlistformats":
+ # Deploy the audio plugins only if QtMultimedia is in use
+ if not deploymentInfo.usesFramework("QtMultimedia"):
+ continue
+ elif pluginDirectory == "mediaservice":
+ # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use
+ if not deploymentInfo.usesFramework("QtMultimediaWidgets"):
+ continue
+
for pluginName in filenames:
pluginPath = os.path.join(pluginDirectory, pluginName)
if pluginName.endswith("_debug.dylib"):
@@ -395,7 +435,11 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Deploy the opengl graphicssystem plugin only if QtOpenGL is in use
if not deploymentInfo.usesFramework("QtOpenGL"):
continue
-
+ elif pluginPath == "accessible/libqtaccessiblequick.dylib":
+ # Deploy the accessible qtquick plugin only if QtQuick is in use
+ if not deploymentInfo.usesFramework("QtQuick"):
+ continue
+
plugins.append((pluginDirectory, pluginName))
for pluginDirectory, pluginName in plugins:
@@ -552,7 +596,7 @@ if os.path.exists("dist"):
# ------------------------------------------------
-target = os.path.join("dist", app_bundle)
+target = os.path.join("dist", "Bitcoin-Qt.app")
if verbose >= 2:
print "+ Copying source bundle +"
@@ -560,7 +604,7 @@ if verbose >= 3:
print app_bundle, "->", target
os.mkdir("dist")
-shutil.copytree(app_bundle, target)
+shutil.copytree(app_bundle, target, symlinks=True)
applicationBundle = ApplicationBundleInfo(target)
@@ -647,7 +691,7 @@ for p in config.add_resources:
if verbose >= 3:
print p, "->", t
if os.path.isdir(p):
- shutil.copytree(p, t)
+ shutil.copytree(p, t, symlinks=True)
else:
shutil.copy2(p, t)
@@ -713,7 +757,7 @@ if config.dmg is not None:
if fancy is None:
try:
- runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname=app_bundle_name, ov=True)
+ runHDIUtil("create", dmg_name, srcfolder="dist", format="UDBZ", volname="Bitcoin-Core", ov=True)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
else:
@@ -723,12 +767,12 @@ if config.dmg is not None:
for path, dirs, files in os.walk("dist"):
for file in files:
size += os.path.getsize(os.path.join(path, file))
- size += int(size * 0.1)
+ size += int(size * 0.15)
if verbose >= 3:
print "Creating temp image for modification..."
try:
- runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname=app_bundle_name, ov=True)
+ runHDIUtil("create", dmg_name + ".temp", srcfolder="dist", format="UDRW", size=size, volname="Bitcoin-Core", ov=True)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
@@ -747,7 +791,8 @@ if config.dmg is not None:
print "+ Applying fancy settings +"
if fancy.has_key("background_picture"):
- bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"]))
+ bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"]))
+ os.mkdir(os.path.dirname(bg_path))
if verbose >= 3:
print fancy["background_picture"], "->", bg_path
shutil.copy2(fancy["background_picture"], bg_path)
@@ -792,7 +837,7 @@ if config.dmg is not None:
items_positions.append(itemscript.substitute(params))
params = {
- "disk" : "Bitcoin-Qt",
+ "disk" : "Bitcoin-Core",
"window_bounds" : "300,300,800,620",
"icon_size" : "96",
"background_commands" : "",
@@ -805,8 +850,8 @@ if config.dmg is not None:
if bg_path is not None:
# Set background file, then call SetFile to make it invisible.
# (note: making it invisible first makes set background picture fail)
- bgscript = Template("""set background picture of theViewOptions to file "$bgpic"
- do shell script "SetFile -a V /Volumes/$disk/$bgpic" """)
+ bgscript = Template("""set background picture of theViewOptions to file ".background:$bgpic"
+ do shell script "SetFile -a V /Volumes/$disk/.background/$bgpic" """)
params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]})
s = appscript.substitute(params)
diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md
index f9a0c277e2..63647fa11a 100644
--- a/contrib/seeds/README.md
+++ b/contrib/seeds/README.md
@@ -1,11 +1,8 @@
### Seeds ###
-Utility to generate the pnSeed[] array that is compiled into the client
-(see [src/net.cpp](/src/net.cpp)).
+Utility to generate the seeds.txt list that is compiled into the client
+(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)).
-The 600 seeds compiled into the 0.8 release were created from sipa's DNS seed data, like this:
+The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
- curl -s http://bitcoin.sipa.be/seeds.txt | head -1000 | makeseeds.py
-
-The input to makeseeds.py is assumed to be approximately sorted from most-reliable to least-reliable,
-with IP:port first on each line (lines that don't match IPv4:port are ignored).
+ curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py
diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
new file mode 100755
index 0000000000..a3d0352187
--- /dev/null
+++ b/contrib/seeds/generate-seeds.py
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+# Copyright (c) 2014 Wladimir J. van der Laan
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+Script to generate list of seed nodes for chainparams.cpp.
+
+This script expects two text files in the directory that is passed as an
+argument:
+
+ nodes_main.txt
+ nodes_test.txt
+
+These files must consist of lines in the format
+
+ <ip>
+ <ip>:<port>
+ [<ipv6>]
+ [<ipv6>]:<port>
+ <onion>.onion
+ 0xDDBBCCAA (IPv4 little-endian old pnSeeds format)
+
+The output will be two data structures with the peers in binary format:
+
+ static SeedSpec6 pnSeed6_main[]={
+ ...
+ }
+ static SeedSpec6 pnSeed6_test[]={
+ ...
+ }
+
+These should be pasted into `src/chainparamsseeds.h`.
+'''
+from __future__ import print_function, division
+from base64 import b32decode
+from binascii import a2b_hex
+import sys, os
+import re
+
+# ipv4 in ipv6 prefix
+pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff])
+# tor-specific ipv6 prefix
+pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43])
+
+def name_to_ipv6(addr):
+ if len(addr)>6 and addr.endswith('.onion'):
+ vchAddr = b32decode(addr[0:-6], True)
+ if len(vchAddr) != 16-len(pchOnionCat):
+ raise ValueError('Invalid onion %s' % s)
+ return pchOnionCat + vchAddr
+ elif '.' in addr: # IPv4
+ return pchIPv4 + bytearray((int(x) for x in addr.split('.')))
+ elif ':' in addr: # IPv6
+ sub = [[], []] # prefix, suffix
+ x = 0
+ addr = addr.split(':')
+ for i,comp in enumerate(addr):
+ if comp == '':
+ if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end
+ continue
+ x += 1 # :: skips to suffix
+ assert(x < 2)
+ else: # two bytes per component
+ val = int(comp, 16)
+ sub[x].append(val >> 8)
+ sub[x].append(val & 0xff)
+ nullbytes = 16 - len(sub[0]) - len(sub[1])
+ assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
+ return bytearray(sub[0] + ([0] * nullbytes) + sub[1])
+ elif addr.startswith('0x'): # IPv4-in-little-endian
+ return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:])))
+ else:
+ raise ValueError('Could not parse address %s' % addr)
+
+def parse_spec(s, defaultport):
+ match = re.match('\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s)
+ if match: # ipv6
+ host = match.group(1)
+ port = match.group(2)
+ elif s.count(':') > 1: # ipv6, no port
+ host = s
+ port = ''
+ else:
+ (host,_,port) = s.partition(':')
+
+ if not port:
+ port = defaultport
+ else:
+ port = int(port)
+
+ host = name_to_ipv6(host)
+
+ return (host,port)
+
+def process_nodes(g, f, structname, defaultport):
+ g.write('static SeedSpec6 %s[] = {\n' % structname)
+ first = True
+ for line in f:
+ comment = line.find('#')
+ if comment != -1:
+ line = line[0:comment]
+ line = line.strip()
+ if not line:
+ continue
+ if not first:
+ g.write(',\n')
+ first = False
+
+ (host,port) = parse_spec(line, defaultport)
+ hoststr = ','.join(('0x%02x' % b) for b in host)
+ g.write(' {{%s}, %i}' % (hoststr, port))
+ g.write('\n};\n')
+
+def main():
+ if len(sys.argv)<2:
+ print(('Usage: %s <path_to_nodes_txt>' % sys.argv[0]), file=sys.stderr)
+ exit(1)
+ g = sys.stdout
+ indir = sys.argv[1]
+ g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n')
+ g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n')
+ g.write('/**\n')
+ g.write(' * List of fixed seed nodes for the bitcoin network\n')
+ g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n')
+ g.write(' *\n')
+ g.write(' * Each line contains a 16-byte IPv6 address and a port.\n')
+ g.write(' * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.\n')
+ g.write(' */\n')
+ with open(os.path.join(indir,'nodes_main.txt'),'r') as f:
+ process_nodes(g, f, 'pnSeed6_main', 8333)
+ g.write('\n')
+ with open(os.path.join(indir,'nodes_test.txt'),'r') as f:
+ process_nodes(g, f, 'pnSeed6_test', 18333)
+ g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')
+
+if __name__ == '__main__':
+ main()
+
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 1d01fd7d20..4072405ef5 100755
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -1,32 +1,169 @@
#!/usr/bin/env python
#
-# Generate pnSeed[] from Pieter's DNS seeder
+# Generate seeds.txt from Pieter's DNS seeder
#
-NSEEDS=600
+NSEEDS=512
+
+MAX_SEEDS_PER_ASN=2
+
+MIN_BLOCKS = 337600
+
+# These are hosts that have been observed to be behaving strangely (e.g.
+# aggressively connecting to every node).
+SUSPICIOUS_HOSTS = set([
+ "130.211.129.106", "178.63.107.226",
+ "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
+ "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
+ "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
+ "54.94.195.96", "54.94.200.247"
+])
import re
import sys
-from subprocess import check_output
+import dns.resolver
+import collections
-def main():
- lines = sys.stdin.readlines()
+PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$")
+PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$")
+PATTERN_ONION = re.compile(r"^([abcdefghijklmnopqrstuvwxyz234567]{16}\.onion):(\d+)$")
+PATTERN_AGENT = re.compile(r"^(\/Satoshi:0\.8\.6\/|\/Satoshi:0\.9\.(2|3|4|5)\/|\/Satoshi:0\.10\.\d{1,2}\/|\/Satoshi:0\.11\.\d{1,2}\/)$")
- ips = []
- pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):8333")
- for line in lines:
- m = pattern.match(line)
+def parseline(line):
+ sline = line.split()
+ if len(sline) < 11:
+ return None
+ m = PATTERN_IPV4.match(sline[0])
+ sortkey = None
+ ip = None
+ if m is None:
+ m = PATTERN_IPV6.match(sline[0])
if m is None:
- continue
+ m = PATTERN_ONION.match(sline[0])
+ if m is None:
+ return None
+ else:
+ net = 'onion'
+ ipstr = sortkey = m.group(1)
+ port = int(m.group(2))
+ else:
+ net = 'ipv6'
+ if m.group(1) in ['::']: # Not interested in localhost
+ return None
+ ipstr = m.group(1)
+ sortkey = ipstr # XXX parse IPv6 into number, could use name_to_ipv6 from generate-seeds
+ port = int(m.group(2))
+ else:
+ # Do IPv4 sanity check
ip = 0
for i in range(0,4):
- ip = ip + (int(m.group(i+1)) << (8*(i)))
+ if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
+ return None
+ ip = ip + (int(m.group(i+2)) << (8*(3-i)))
if ip == 0:
- continue
- ips.append(ip)
+ return None
+ net = 'ipv4'
+ sortkey = ip
+ ipstr = m.group(1)
+ port = int(m.group(6))
+ # Skip bad results.
+ if sline[1] == 0:
+ return None
+ # Extract uptime %.
+ uptime30 = float(sline[7][:-1])
+ # Extract Unix timestamp of last success.
+ lastsuccess = int(sline[2])
+ # Extract protocol version.
+ version = int(sline[10])
+ # Extract user agent.
+ agent = sline[11][1:-1]
+ # Extract service flags.
+ service = int(sline[9], 16)
+ # Extract blocks.
+ blocks = int(sline[8])
+ # Construct result.
+ return {
+ 'net': net,
+ 'ip': ipstr,
+ 'port': port,
+ 'ipnum': ip,
+ 'uptime': uptime30,
+ 'lastsuccess': lastsuccess,
+ 'version': version,
+ 'agent': agent,
+ 'service': service,
+ 'blocks': blocks,
+ 'sortkey': sortkey,
+ }
+
+def filtermultiport(ips):
+ '''Filter out hosts with more nodes per IP'''
+ hist = collections.defaultdict(list)
+ for ip in ips:
+ hist[ip['sortkey']].append(ip)
+ return [value[0] for (key,value) in hist.items() if len(value)==1]
+
+# Based on Greg Maxwell's seed_filter.py
+def filterbyasn(ips, max_per_asn, max_total):
+ # Sift out ips by type
+ ips_ipv4 = [ip for ip in ips if ip['net'] == 'ipv4']
+ ips_ipv6 = [ip for ip in ips if ip['net'] == 'ipv6']
+ ips_onion = [ip for ip in ips if ip['net'] == 'onion']
+
+ # Filter IPv4 by ASN
+ result = []
+ asn_count = {}
+ for ip in ips_ipv4:
+ if len(result) == max_total:
+ break
+ try:
+ asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
+ if asn not in asn_count:
+ asn_count[asn] = 0
+ if asn_count[asn] == max_per_asn:
+ continue
+ asn_count[asn] += 1
+ result.append(ip)
+ except:
+ sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
+
+ # TODO: filter IPv6 by ASN
+
+ # Add back non-IPv4
+ result.extend(ips_ipv6)
+ result.extend(ips_onion)
+ return result
+
+def main():
+ lines = sys.stdin.readlines()
+ ips = [parseline(line) for line in lines]
+
+ # Skip entries with valid address.
+ ips = [ip for ip in ips if ip is not None]
+ # Skip entries from suspicious hosts.
+ ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
+ # Enforce minimal number of blocks.
+ ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
+ # Require service bit 1.
+ ips = [ip for ip in ips if (ip['service'] & 1) == 1]
+ # Require at least 50% 30-day uptime.
+ ips = [ip for ip in ips if ip['uptime'] > 50]
+ # Require a known and recent user agent.
+ ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])]
+ # Sort by availability (and use last success as tie breaker)
+ ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True)
+ # Filter out hosts with multiple bitcoin ports, these are likely abusive
+ ips = filtermultiport(ips)
+ # Look up ASNs and limit results, both per ASN and globally.
+ ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
+ # Sort the results by IP address (for deterministic output).
+ ips.sort(key=lambda x: (x['net'], x['sortkey']))
- for row in range(0, min(NSEEDS,len(ips)), 8):
- print " " + ", ".join([ "0x%08x"%i for i in ips[row:row+8] ]) + ","
+ for ip in ips:
+ if ip['net'] == 'ipv6':
+ print '[%s]:%i' % (ip['ip'], ip['port'])
+ else:
+ print '%s:%i' % (ip['ip'], ip['port'])
if __name__ == '__main__':
main()
diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt
new file mode 100644
index 0000000000..17339d514a
--- /dev/null
+++ b/contrib/seeds/nodes_main.txt
@@ -0,0 +1,879 @@
+1.34.168.128:8333
+1.202.128.218:8333
+2.30.0.210:8333
+5.9.96.203:8333
+5.45.71.130:8333
+5.45.98.141:8333
+5.102.145.68:8333
+5.135.160.77:8333
+5.189.134.246:8333
+5.199.164.132:8333
+5.249.135.102:8333
+8.19.44.110:8333
+8.22.230.8:8333
+14.200.200.145:8333
+18.228.0.188:8333
+18.228.0.200:8333
+23.24.168.97:8333
+23.28.35.227:8333
+23.92.76.170:8333
+23.99.64.119:8333
+23.228.166.128:8333
+23.229.45.32:8333
+24.8.105.128:8333
+24.16.69.137:8333
+24.94.98.96:8333
+24.102.118.7:8333
+24.118.166.228:8333
+24.122.133.49:8333
+24.166.97.162:8333
+24.213.235.242:8333
+24.226.107.64:8333
+24.228.192.171:8333
+27.140.133.18:8333
+31.41.40.25:8333
+31.43.101.59:8333
+31.184.195.181:8333
+31.193.139.66:8333
+37.200.70.102:8333
+37.205.10.151:8333
+42.3.106.227:8333
+42.60.133.106:8333
+45.56.85.231:8333
+45.56.102.228:8333
+45.79.130.235:8333
+46.28.204.61:11101
+46.38.235.229:8333
+46.59.2.74:8333
+46.101.132.37:8333
+46.101.168.50:8333
+46.163.76.230:8333
+46.166.161.103:8333
+46.182.132.100:8333
+46.223.36.94:8333
+46.227.66.132:8333
+46.227.66.138:8333
+46.239.107.74:8333
+46.249.39.100:8333
+46.250.98.108:8333
+50.7.37.114:8333
+50.81.53.151:8333
+50.115.43.253:8333
+50.116.20.87:8333
+50.116.33.92:8333
+50.125.167.245:8333
+50.143.9.51:8333
+50.188.192.133:8333
+54.77.162.76:8333
+54.153.97.109:8333
+54.165.192.125:8333
+58.96.105.85:8333
+59.167.196.135:8333
+60.29.227.163:8333
+61.35.225.19:8333
+62.43.130.178:8333
+62.109.49.26:8333
+62.202.0.97:8333
+62.210.66.227:8333
+62.210.192.169:8333
+64.74.98.205:8333
+64.156.193.100:8333
+64.203.102.86:8333
+64.229.142.48:8333
+65.96.193.165:8333
+66.30.3.7:8333
+66.114.33.49:8333
+66.118.133.194:8333
+66.135.10.126:8333
+66.172.10.4:8333
+66.194.38.250:8333
+66.194.38.253:8333
+66.215.192.104:8333
+67.60.98.115:8333
+67.164.35.36:8333
+67.191.162.244:8333
+67.207.195.77:8333
+67.219.233.140:8333
+67.221.193.55:8333
+67.228.162.228:8333
+68.50.67.199:8333
+68.62.3.203:8333
+68.65.205.226:9000
+68.106.42.191:8333
+68.150.181.198:8333
+68.196.196.106:8333
+68.224.194.81:8333
+69.46.5.194:8333
+69.50.171.238:8333
+69.64.43.152:8333
+69.65.41.13:8333
+69.90.132.200:8333
+69.143.1.243:8333
+69.146.98.216:8333
+69.165.246.38:8333
+69.207.6.135:8333
+69.251.208.26:8333
+70.38.1.101:8333
+70.38.9.66:8333
+70.90.2.18:8333
+71.58.228.226:8333
+71.199.11.189:8333
+71.199.193.202:8333
+71.205.232.181:8333
+71.236.200.162:8333
+72.24.73.186:8333
+72.52.130.110:8333
+72.53.111.37:8333
+72.235.38.70:8333
+73.31.171.149:8333
+73.32.137.72:8333
+73.137.133.238:8333
+73.181.192.103:8333
+73.190.2.60:8333
+73.195.192.137:8333
+73.222.35.117:8333
+74.57.199.180:8333
+74.82.233.205:8333
+74.85.66.82:8333
+74.101.224.127:8333
+74.113.69.16:8333
+74.122.235.68:8333
+74.193.68.141:8333
+74.208.164.219:8333
+75.100.37.122:8333
+75.145.149.169:8333
+75.168.34.20:8333
+76.20.44.240:8333
+76.100.70.17:8333
+76.168.3.239:8333
+76.186.140.103:8333
+77.92.68.221:8333
+77.109.101.142:8333
+77.110.11.86:8333
+77.242.108.18:8333
+78.46.96.150:9020
+78.84.100.95:8333
+79.132.230.144:8333
+79.133.43.63:8333
+79.160.76.153:8333
+79.169.34.24:8333
+79.188.7.78:8333
+80.217.226.25:8333
+80.223.100.179:8333
+80.240.129.221:8333
+81.1.173.243:8333
+81.7.11.50:8333
+81.7.16.17:8333
+81.66.111.3:8333
+81.80.9.71:8333
+81.140.43.138:8333
+81.171.34.37:8333
+81.174.247.50:8333
+81.181.155.53:8333
+81.184.5.253:8333
+81.187.69.130:8333
+81.230.3.84:8333
+82.42.128.51:8333
+82.74.226.21:8333
+82.142.75.50:8333
+82.199.102.10:8333
+82.200.205.30:8333
+82.221.108.21:8333
+82.221.128.35:8333
+82.238.124.41:8333
+82.242.0.245:8333
+83.76.123.110:8333
+83.150.9.196:8333
+83.162.196.192:8333
+83.162.234.224:8333
+83.170.104.91:8333
+83.255.66.118:8334
+84.2.34.104:8333
+84.45.98.91:8333
+84.47.161.150:8333
+84.212.192.131:8333
+84.215.169.101:8333
+84.238.140.176:8333
+84.245.71.31:8333
+85.17.4.212:8333
+85.114.128.134:8333
+85.159.237.191:8333
+85.166.130.189:8333
+85.199.4.228:8333
+85.214.66.168:8333
+85.214.195.210:8333
+85.229.0.73:8333
+86.21.96.45:8333
+87.48.42.199:8333
+87.81.143.82:8333
+87.81.251.72:8333
+87.104.24.185:8333
+87.104.168.104:8333
+87.117.234.71:8333
+87.118.96.197:8333
+87.145.12.57:8333
+87.159.170.190:8333
+88.150.168.160:8333
+88.208.0.79:8333
+88.208.0.149:8333
+88.214.194.226:8343
+89.1.11.32:8333
+89.36.235.108:8333
+89.67.96.2:15321
+89.98.16.41:8333
+89.108.72.195:8333
+89.156.35.157:8333
+89.163.227.28:8333
+89.212.33.237:8333
+89.212.160.165:8333
+89.231.96.83:8333
+89.248.164.64:8333
+90.149.193.199:8333
+91.77.239.245:8333
+91.106.194.97:8333
+91.126.77.77:8333
+91.134.38.195:8333
+91.156.97.181:8333
+91.207.68.144:8333
+91.209.77.101:8333
+91.214.200.205:8333
+91.220.131.242:8333
+91.220.163.18:8333
+91.233.23.35:8333
+92.13.96.93:8333
+92.14.74.114:8333
+92.27.7.209:8333
+92.221.228.13:8333
+92.255.207.73:8333
+93.72.167.148:8333
+93.74.163.234:8333
+93.123.174.66:8333
+93.152.166.29:8333
+93.181.45.188:8333
+94.19.12.244:8333
+94.190.227.112:8333
+94.198.135.29:8333
+94.224.162.65:8333
+94.226.107.86:8333
+94.242.198.161:8333
+95.31.10.209:8333
+95.65.72.244:8333
+95.84.162.95:8333
+95.90.139.46:8333
+95.183.49.27:8005
+95.215.47.133:8333
+96.23.67.85:8333
+96.44.166.190:8333
+97.93.225.74:8333
+98.26.0.34:8333
+98.27.225.102:8333
+98.229.117.229:8333
+98.249.68.125:8333
+98.255.5.155:8333
+99.101.240.114:8333
+101.100.174.138:8333
+101.251.203.6:8333
+103.3.60.61:8333
+103.30.42.189:8333
+103.224.165.48:8333
+104.36.83.233:8333
+104.37.129.22:8333
+104.54.192.251:8333
+104.128.228.252:8333
+104.128.230.185:8334
+104.130.161.47:8333
+104.131.33.60:8333
+104.143.0.156:8333
+104.156.111.72:8333
+104.167.111.84:8333
+104.193.40.248:8333
+104.197.7.174:8333
+104.197.8.250:8333
+104.223.1.133:8333
+104.236.97.140:8333
+104.238.128.214:8333
+104.238.130.182:8333
+106.38.234.84:8333
+106.185.36.204:8333
+107.6.4.145:8333
+107.150.2.6:8333
+107.150.40.234:8333
+107.155.108.130:8333
+107.161.182.115:8333
+107.170.66.231:8333
+107.190.128.226:8333
+107.191.106.115:8333
+108.16.2.61:8333
+109.70.4.168:8333
+109.162.35.196:8333
+109.163.235.239:8333
+109.190.196.220:8333
+109.191.39.60:8333
+109.234.106.191:8333
+109.238.81.82:8333
+114.76.147.27:8333
+115.28.224.127:8333
+115.68.110.82:18333
+118.97.79.218:8333
+118.189.207.197:8333
+119.228.96.233:8333
+120.147.178.81:8333
+121.41.123.5:8333
+121.67.5.230:8333
+122.107.143.110:8333
+123.2.170.98:8333
+123.110.65.94:8333
+123.193.139.19:8333
+125.239.160.41:8333
+128.101.162.193:8333
+128.111.73.10:8333
+128.140.229.73:8333
+128.175.195.31:8333
+128.199.107.63:8333
+128.199.192.153:8333
+128.253.3.193:20020
+129.123.7.7:8333
+130.89.160.234:8333
+131.72.139.164:8333
+131.191.112.98:8333
+133.1.134.162:8333
+134.19.132.53:8333
+137.226.34.42:8333
+141.41.2.172:8333
+141.255.128.204:8333
+142.217.12.106:8333
+143.215.129.126:8333
+146.0.32.101:8337
+147.229.13.199:8333
+149.210.133.244:8333
+149.210.162.187:8333
+150.101.163.241:8333
+151.236.11.189:8333
+153.121.66.211:8333
+154.20.2.139:8333
+159.253.23.132:8333
+162.209.106.123:8333
+162.210.198.184:8333
+162.218.65.121:8333
+162.222.161.49:8333
+162.243.132.6:8333
+162.243.132.58:8333
+162.248.99.164:53011
+162.248.102.117:8333
+163.158.35.110:8333
+164.15.10.189:8333
+164.40.134.171:8333
+166.230.71.67:8333
+167.160.161.199:8333
+168.103.195.250:8333
+168.144.27.112:8333
+168.158.129.29:8333
+170.75.162.86:8333
+172.90.99.174:8333
+172.245.5.156:8333
+173.23.166.47:8333
+173.32.11.194:8333
+173.34.203.76:8333
+173.171.1.52:8333
+173.175.136.13:8333
+173.230.228.139:8333
+173.247.193.70:8333
+174.49.132.28:8333
+174.52.202.72:8333
+174.53.76.87:8333
+174.109.33.28:8333
+176.28.12.169:8333
+176.35.182.214:8333
+176.36.33.113:8333
+176.36.33.121:8333
+176.58.96.173:8333
+176.121.76.84:8333
+178.62.70.16:8333
+178.62.111.26:8333
+178.76.169.59:8333
+178.79.131.32:8333
+178.162.199.216:8333
+178.175.134.35:8333
+178.248.111.4:8333
+178.254.1.170:8333
+178.254.34.161:8333
+179.43.143.120:8333
+179.208.156.198:8333
+180.200.128.58:8333
+183.78.169.108:8333
+183.96.96.152:8333
+184.68.2.46:8333
+184.73.160.160:8333
+184.94.227.58:8333
+184.152.68.163:8333
+185.7.35.114:8333
+185.28.76.179:8333
+185.31.160.202:8333
+185.45.192.129:8333
+185.66.140.15:8333
+186.2.167.23:8333
+186.220.101.142:8333
+188.26.5.33:8333
+188.75.136.146:8333
+188.120.194.140:8333
+188.121.5.150:8333
+188.138.0.114:8333
+188.138.33.239:8333
+188.166.0.82:8333
+188.182.108.129:8333
+188.191.97.208:8333
+188.226.198.102:8001
+190.10.9.217:8333
+190.75.143.144:8333
+190.139.102.146:8333
+191.237.64.28:8333
+192.3.131.61:8333
+192.99.225.3:8333
+192.110.160.122:8333
+192.146.137.1:8333
+192.183.198.204:8333
+192.203.228.71:8333
+193.0.109.3:8333
+193.12.238.204:8333
+193.91.200.85:8333
+193.234.225.156:8333
+194.6.233.38:8333
+194.63.143.136:8333
+194.126.100.246:8333
+195.134.99.195:8333
+195.159.111.98:8333
+195.159.226.139:8333
+195.197.175.190:8333
+198.48.199.108:8333
+198.57.208.134:8333
+198.57.210.27:8333
+198.62.109.223:8333
+198.167.140.8:8333
+198.167.140.18:8333
+199.91.173.234:8333
+199.127.226.245:8333
+199.180.134.116:8333
+200.7.96.99:8333
+201.160.106.86:8333
+202.55.87.45:8333
+202.60.68.242:8333
+202.60.69.232:8333
+202.124.109.103:8333
+203.30.197.77:8333
+203.88.160.43:8333
+203.151.140.14:8333
+203.219.14.204:8333
+205.147.40.62:8333
+207.235.39.214:8333
+207.244.73.8:8333
+208.12.64.225:8333
+208.76.200.200:8333
+209.40.96.121:8333
+209.126.107.176:8333
+209.141.40.149:8333
+209.190.75.59:8333
+209.208.111.142:8333
+210.54.34.164:8333
+211.72.66.229:8333
+212.51.144.42:8333
+212.112.33.157:8333
+212.116.72.63:8333
+212.126.14.122:8333
+213.66.205.194:8333
+213.111.196.21:8333
+213.122.107.102:8333
+213.136.75.175:8333
+213.155.7.24:8333
+213.163.64.31:8333
+213.163.64.208:8333
+213.165.86.136:8333
+213.184.8.22:8333
+216.15.78.182:8333
+216.55.143.154:8333
+216.115.235.32:8333
+216.126.226.166:8333
+216.145.67.87:8333
+216.169.141.169:8333
+216.249.92.230:8333
+216.250.138.230:8333
+217.20.171.43:8333
+217.23.2.71:8333
+217.23.2.242:8333
+217.25.9.76:8333
+217.40.226.169:8333
+217.123.98.9:8333
+217.155.36.62:8333
+217.172.32.18:20993
+218.61.196.202:8333
+218.231.205.41:8333
+220.233.77.200:8333
+223.18.226.85:8333
+223.197.203.82:8333
+223.255.166.142:8333
+[2001:1291:2bf:1::100]:8333
+[2001:1418:100:5c2::2]:8333
+[2001:16d8:dd24:0:86c9:681e:f931:256]:8333
+[2001:19f0:1624:e6::579d:9428]:8333
+[2001:19f0:300:1340:225:90ff:fec9:2b6d]:8333
+[2001:19f0:4009:1405::64]:8333
+[2001:1b40:5000:2e::3fb0:6571]:8333
+[2001:410:a000:4050:8463:90b0:fffb:4e58]:8333
+[2001:410:a002:cafe:8463:90b0:fffb:4e58]:8333
+[2001:41d0:1:541e::1]:8333
+[2001:41d0:1:6a34::3]:8333
+[2001:41d0:1:6cd3::]:8333
+[2001:41d0:1:8b26::1]:8333
+[2001:41d0:1:a33d::1]:8333
+[2001:41d0:1:b855::1]:8333
+[2001:41d0:1:c139::1]:8333
+[2001:41d0:1:c8d7::1]:8333
+[2001:41d0:1:dd3f::1]:8333
+[2001:41d0:1:e29d::1]:8333
+[2001:41d0:1:f59f::33]:8333
+[2001:41d0:1:f7cc::1]:8333
+[2001:41d0:1:ff87::1]:8333
+[2001:41d0:2:2f05::1]:8333
+[2001:41d0:2:37c3::]:8200
+[2001:41d0:2:3e13::1]:8333
+[2001:41d0:2:8619::]:8333
+[2001:41d0:2:9c94::1]:8333
+[2001:41d0:2:a24f::]:8333
+[2001:41d0:2:adbf::]:8333
+[2001:41d0:2:b721::1]:8333
+[2001:41d0:2:ee52::1]:8333
+[2001:41d0:2:f1a5::]:8333
+[2001:41d0:2:fa54::1]:8333
+[2001:41d0:51:1::2036]:8333
+[2001:41d0:52:a00::1a1]:8333
+[2001:41d0:52:cff::6f5]:8333
+[2001:41d0:52:d00::2c0]:8333
+[2001:41d0:52:d00::cf2]:8333
+[2001:41d0:8:1087::1]:8333
+[2001:41d0:8:4a3c::b7c]:8333
+[2001:41d0:8:6728::]:8333
+[2001:41d0:8:b779::1]:8333
+[2001:41d0:8:c30f::1]:8333
+[2001:41d0:8:d2b2::1]:8333
+[2001:41d0:8:d5c3::1]:8333
+[2001:41d0:8:eb8b::]:8333
+[2001:41d0:a:16d0::1]:8333
+[2001:41d0:a:2b18::1]:8333
+[2001:41d0:a:3a9c::1]:8333
+[2001:41d0:a:4903::]:8333
+[2001:41d0:a:57b::1]:8333
+[2001:41d0:a:5c7a::]:8333
+[2001:41d0:a:6c29::1]:8333
+[2001:41d0:a:f482::1]:8333
+[2001:41d0:b:854:b7c:b7c:b7c:b7c]:8333
+[2001:41d0:d:111c::]:8333
+[2001:44b8:4116:7801:4216:7eff:fe78:3fe4]:8333
+[2001:470:1f08:837::2]:8333
+[2001:470:1f08:c33::2]:8333
+[2001:470:1f09:bca:218:7dff:fe10:be33]:8333
+[2001:470:1f0f:22d::212:26]:8333
+[2001:470:1f11:12d5::ae1:5611]:8333
+[2001:470:1f14:57a::2]:8333
+[2001:470:1f14:7d::2]:8333
+[2001:470:1f15:57c::1]:8333
+[2001:470:1f15:dda:3d9a:3f11:9a56:ed64]:8333
+[2001:470:25:482::2]:8333
+[2001:470:25:e4::2]:8333
+[2001:470:4:26b::2]:8333
+[2001:470:5f:5f::232]:8333
+[2001:470:66:119::2]:8333
+[2001:470:67:39d::71]:8333
+[2001:470:6c4f::cafe]:8333
+[2001:470:8:2e1::43]:8333
+[2001:470:90a7:96::afe:6021]:8333
+[2001:470:95c1::2]:8333
+[2001:470:b1d0:ffff::1000]:8333
+[2001:470:c1f2:3::201]:8333
+[2001:470:d00d:0:3664:a9ff:fe9a:5150]:8333
+[2001:470:e250:0:211:11ff:feb9:924c]:8333
+[2001:4800:7817:101:be76:4eff:fe04:dc52]:8333
+[2001:4800:7819:104:be76:4eff:fe04:7809]:8333
+[2001:4800:7819:104:be76:4eff:fe05:c828]:8333
+[2001:4802:7800:2:30d7:1775:ff20:1858]:8333
+[2001:4802:7802:101:be76:4eff:fe20:256]:8333
+[2001:4802:7802:103:be76:4eff:fe20:2de8]:8333
+[2001:4830:1100:2e8::2]:8333
+[2001:4ba0:fff7:181:dead::1]:8333
+[2001:4ba0:fffa:5d::93]:8333
+[2001:4ba0:ffff:1be:1:1005:0:1]:8335
+[2001:4c48:110:101:216:3eff:fe24:1162]:8333
+[2001:4dd0:f101::32]:8333
+[2001:4dd0:ff00:867f::3]:8333
+[2001:4dd0:ff00:9a67::9]:8333
+[2001:4dd0:ff00:9c55:c23f:d5ff:fe6c:7ee9]:8333
+[2001:5c0:1400:b::3cc7]:8333
+[2001:5c0:1400:b::3d01]:8333
+[2001:5c0:1400:b::8df]:8333
+[2001:5c0:1501:300::3]:8333
+[2001:610:1b19::3]:8333
+[2001:620:500:fff0:f21f:afff:fecf:91cc]:8333
+[2001:67c:1220:80c:ad:8de2:f7e2:c784]:8333
+[2001:67c:21ec:1000::b]:8333
+[2001:6f8:1296:0:76d4:35ff:feba:1d26]:8333
+[2001:840:f000:4250:3e4a:92ff:fe6d:145f]:8333
+[2001:8d8:840:500::39:1ae]:8333
+[2001:980:efd8:0:21:de4a:2709:912]:8333
+[2001:981:46:1::3]:8333
+[2001:981:9319:2:c0:a8:c8:8]:8333
+[2001:9d8:cafe:3::91]:8333
+[2001:ad0:1:1:26be:5ff:fe25:959d]:8333
+[2001:ba8:1f1:f34c::2]:8333
+[2001:bc8:381c:100::1]:8333
+[2002:175c:4caa::175c:4caa]:8333
+[2002:4404:82f1:0:8d55:8fbb:15fa:f4e0]:8333
+[2002:4475:2233:0:21f:5bff:fe33:9f70]:8333
+[2002:596c:48c3::596c:48c3]:8333
+[2002:8c6d:6521:9617:12bf:48ff:fed8:1724]:8333
+[2002:a646:5e6a::1:2]:8333
+[2002:b009:20c5::b009:20c5]:8333
+[2400:8900::f03c:91ff:fe6e:823e]:8333
+[2400:8900::f03c:91ff:fe70:d164]:8333
+[2400:8901::f03c:91ff:fe37:9761]:8333
+[2403:4200:403:2::ff]:8333
+[2403:b800:1000:64:40a:e9ff:fe5f:94c1]:8333
+[2403:b800:1000:64:9879:17ff:fe6a:a59f]:8333
+[2600:3c00::f03c:91ff:fe18:59b2]:8333
+[2600:3c00::f03c:91ff:fe37:a4b1]:8333
+[2600:3c00::f03c:91ff:fe56:2973]:8333
+[2600:3c00::f03c:91ff:fe6e:7297]:8333
+[2600:3c00::f03c:91ff:fe84:8a6e]:8333
+[2600:3c01::f03c:91ff:fe18:6adf]:8333
+[2600:3c01::f03c:91ff:fe18:e217]:8333
+[2600:3c01::f03c:91ff:fe33:1b31]:8333
+[2600:3c01::f03c:91ff:fe33:2fe1]:8333
+[2600:3c01::f03c:91ff:fe33:a03f]:8333
+[2600:3c01::f03c:91ff:fe50:5e06]:8333
+[2600:3c01::f03c:91ff:fe56:d645]:8333
+[2600:3c01::f03c:91ff:fe6e:a3dc]:8333
+[2600:3c01::f03c:91ff:fe89:a659]:8333
+[2600:3c02::f03c:91ff:fe6e:6f0b]:8333
+[2600:3c03::f03c:91ff:fe33:f6fb]:8333
+[2600:3c03::f03c:91ff:fe50:5fa7]:8333
+[2600:3c03::f03c:91ff:fe6e:1803]:8333
+[2600:3c03::f03c:91ff:fe6e:4ac0]:8333
+[2601:6:4800:47f:1e4e:1f4d:332c:3bf6]:8333
+[2601:d:5400:fed:8d54:c1e8:7ed7:d45e]:8333
+[2602:100:4b8f:6d2a:20c:29ff:feaf:c4c2]:8333
+[2602:ffc5:1f::1f:2d61]:8333
+[2602:ffc5:1f::1f:9211]:8333
+[2602:ffc5::ffc5:b844]:8333
+[2602:ffe8:100:2::457:936b]:8333
+[2602:ffea:1001:125::2ad4]:8333
+[2602:ffea:1001:6ff::837d]:8333
+[2602:ffea:1001:72b::578b]:8333
+[2602:ffea:1001:77a::9cae]:8333
+[2602:ffea:1:2fe::6bc8]:8333
+[2602:ffea:1:701::7968]:8333
+[2602:ffea:1:70d::82ec]:8333
+[2602:ffea:1:9ff::e957]:8333
+[2602:ffea:1:a5d::4acb]:8333
+[2602:ffea:a::24c4:d9fd]:8333
+[2602:ffea:a::c06:ae32]:8333
+[2604:0:c1:100:1ec1:deff:fe54:2235]:8333
+[2604:180:1:1af::42a9]:8333
+[2604:180::b208:398]:8333
+[2604:2880::6072:aed]:8333
+[2604:4080:1114:0:3285:a9ff:fe93:850c]:8333
+[2604:7c00:17:3d0::5a4d]:8333
+[2604:9a00:2100:a009:2::]:8333
+[2604:a880:1:20::22a:4001]:8333
+[2604:a880:800:10::752:f001]:8333
+[2604:c00:88:32:216:3eff:fee4:fcca]:8333
+[2604:c00:88:32:216:3eff:fef5:bc21]:8333
+[2605:7980:1:2::1761:3d4e]:8333
+[2605:e000:1417:4068:223:32ff:fe96:e2d]:8333
+[2606:6000:a441:9903:5054:ff:fe78:66ff]:8333
+[2606:df00:2::ae85:8fc6]:8333
+[2607:5300:100:200::e7f]:8333
+[2607:5300:10::a1]:8333
+[2607:5300:60:116e::1]:8333
+[2607:5300:60:1535::]:8333
+[2607:5300:60:1b32::1]:8333
+[2607:5300:60:2337::1]:8333
+[2607:5300:60:2b90::1]:8333
+[2607:5300:60:2d99::1]:8333
+[2607:5300:60:3cb::1]:8333
+[2607:5300:60:4a85::]:8333
+[2607:5300:60:5112:0:2:4af5:63fe]:8333
+[2607:5300:60:6dd5::]:8333
+[2607:5300:60:a91::1]:8333
+[2607:f1c0:820:1500::7f:3f44]:8333
+[2607:f1c0:848:1000::48:943c]:8333
+[2607:f948:0:1::7]:8333
+[2607:fcd0:100:2300::4ad:e594]:8333
+[2607:fcd0:100:2300::659e:9cb3]:8333
+[2607:fcd0:100:2300::c74b:a8ae]:8333
+[2607:fcd0:100:2300::d82:d8c2]:8333
+[2607:fcd0:100:4300::8795:2fa8]:8333
+[2607:fcd0:daaa:901::9561:e043]:8333
+[2a00:1178:2:43:5054:ff:fee7:2eb6]:8333
+[2a00:1328:e100:cc42:230:48ff:fe92:55d]:8333
+[2a00:14f0:e000:80d2:cd1a::1]:8333
+[2a00:16d8:c::5b6a:c261]:8333
+[2a00:61e0:4083:6d01:6852:1376:e972:2091]:8333
+[2a00:c98:2030:a02f:2::2]:8333
+[2a01:1b0:7999:402::131]:8333
+[2a01:1e8:e100:811c:700f:65f0:f72a:1084]:8333
+[2a01:238:42da:c500:6546:1293:5422:ab40]:8333
+[2a01:348:6:473::2]:8333
+[2a01:368:e010:2::2]:8333
+[2a01:430:17:1::ffff:549]:8333
+[2a01:430:17:1::ffff:830]:8333
+[2a01:488:66:1000:53a9:d04:0:1]:8333
+[2a01:488:66:1000:57e6:578c:0:1]:8333
+[2a01:488:66:1000:b01c:178d:0:1]:8333
+[2a01:488:67:1000:523:fdce:0:1]:8333
+[2a01:488:67:1000:b01c:30ab:0:1]:8333
+[2a01:4f8:100:24aa::2]:8333
+[2a01:4f8:100:44e7::2]:8333
+[2a01:4f8:100:5128::2]:8333
+[2a01:4f8:100:84a7::1:1]:8333
+[2a01:4f8:110:516c::2]:8333
+[2a01:4f8:110:536e::2]:8333
+[2a01:4f8:120:62e6::2]:8333
+[2a01:4f8:120:702e::2]:8333
+[2a01:4f8:120:8005::2]:8333
+[2a01:4f8:120:8203::2]:8333
+[2a01:4f8:120:8422::2]:8333
+[2a01:4f8:121:11eb::2]:8333
+[2a01:4f8:121:261::2]:8333
+[2a01:4f8:130:242b::10]:8333
+[2a01:4f8:130:242b::5]:8333
+[2a01:4f8:130:2468::3]:8333
+[2a01:4f8:130:632c::2]:8333
+[2a01:4f8:130:6366::2]:8333
+[2a01:4f8:130:6426::2]:8333
+[2a01:4f8:130:934f::2]:8333
+[2a01:4f8:131:2070::2]:8333
+[2a01:4f8:131:54a2::2]:8333
+[2a01:4f8:140:80ad::2]:8333
+[2a01:4f8:141:186::2]:8333
+[2a01:4f8:150:210b::2]:8333
+[2a01:4f8:150:2263::5]:8333
+[2a01:4f8:150:2349::2]:8333
+[2a01:4f8:150:61ee::2]:8333
+[2a01:4f8:150:7088:5054:ff:fe45:bff2]:8333
+[2a01:4f8:150:8324::2]:9001
+[2a01:4f8:151:1d8::2]:8333
+[2a01:4f8:151:5128::2]:8333
+[2a01:4f8:151:6347::2]:9001
+[2a01:4f8:161:526d::2]:8333
+[2a01:4f8:161:9349::2]:8333
+[2a01:4f8:162:23c6::2]:8333
+[2a01:4f8:162:4348::2]:8333
+[2a01:4f8:162:7345::2]:8333
+[2a01:4f8:162:7383::2]:8333
+[2a01:4f8:162:74e3::2]:8333
+[2a01:4f8:190:6065::2]:8333
+[2a01:4f8:190:6349::2]:8333
+[2a01:4f8:190:64c9::2]:8333
+[2a01:4f8:190:91ce::2]:8333
+[2a01:4f8:191:2194::83]:8333
+[2a01:4f8:191:40a1::2]:8333
+[2a01:4f8:191:4a7::2]:8333
+[2a01:4f8:191:63b4:5000::1]:8333
+[2a01:4f8:191:7121::2]:8333
+[2a01:4f8:191:83a2::2]:8333
+[2a01:4f8:191:93c4::2]:8333
+[2a01:4f8:192:60a9:0:1:5:2]:8333
+[2a01:4f8:192:73b2::2]:8333
+[2a01:4f8:192:8098::2]:8333
+[2a01:4f8:192:db::2]:8333
+[2a01:4f8:200:1012::2]:8333
+[2a01:4f8:200:22e3::2]:8333
+[2a01:4f8:200:414e::2]:8333
+[2a01:4f8:200:63af::222]:8333
+[2a01:4f8:200:71e3:78b4:f3ff:fead:e8cf]:8333
+[2a01:4f8:201:5164::2]:8333
+[2a01:4f8:201:6011::4]:8333
+[2a01:4f8:201:60d5::2]:8333
+[2a01:4f8:202:53c3::2]:8333
+[2a01:4f8:210:24aa::2]:8333
+[2a01:4f8:210:502f::2]:8333
+[2a01:4f8:211:14cf::2]:8333
+[2a01:4f8:211:1a59::2]:8333
+[2a01:4f8:211:2ac1::2]:8333
+[2a01:4f8:211:cca::2]:8333
+[2a01:4f8:a0:22a5::2]:8333
+[2a01:4f8:a0:5023::2]:8333
+[2a01:4f8:a0:5243::2]:8333
+[2a01:4f8:a0:74c8::2]:8333
+[2a01:4f8:a0:8227::2]:8333
+[2a01:4f8:a0:822d::2]:8333
+[2a01:4f8:d13:2183::2]:8333
+[2a01:608:ffff:a009:8bf5:879d:e51a:f837]:8333
+[2a01:79d:469e:ed94:c23f:d5ff:fe65:20c5]:8333
+[2a01:7c8:aab5:3e6:5054:ff:fed7:4e54]:8333
+[2a01:7e00::f03c:91ff:fe18:301e]:8333
+[2a01:7e00::f03c:91ff:fe18:7749]:8333
+[2a01:7e00::f03c:91ff:fe33:2d67]:8333
+[2a01:7e00::f03c:91ff:fe33:347c]:8333
+[2a01:7e00::f03c:91ff:fe33:ae50]:8333
+[2a01:7e00::f03c:91ff:fe56:6b5c]:8333
+[2a01:7e00::f03c:91ff:fe56:bee6]:8333
+[2a01:7e00::f03c:91ff:fe69:4895]:8333
+[2a01:7e00::f03c:91ff:fe69:9912]:8333
+[2a01:7e00::f03c:91ff:fe6e:26ee]:8333
+[2a01:7e00::f03c:91ff:fe73:42f1]:8333
+[2a01:7e00::f03c:91ff:fe84:434f]:8333
+[2a01:7e00::f03c:91ff:fe84:b36b]:8333
+[2a01:7e00::f03c:91ff:fe89:1faa]:8333
+[2a01:7e00::f03c:91ff:fe98:816]:8333
+[2a01:7e00::f03c:91ff:fedb:352e]:8333
+[2a01:7e00::f03c:91ff:fedb:4a1d]:8333
+[2a01:e34:edbb:6750:224:1dff:fe89:3897]:8333
+[2a01:e35:2f1d:3fb0:7187:c7ba:bcfc:80ce]:8333
+[2a01:e35:8787:96f0:9032:9297:39ae:496d]:8333
+[2a01:e35:8a3f:47c0:c617:feff:fe3c:9fbd]:8333
+[2a01:e35:8b66:6a0:4900:9dfd:d841:d025]:8333
+[2a02:168:4a01::39]:8333
+[2a02:168:5404:2:c23f:d5ff:fe6a:512e]:8333
+[2a02:180:1:1::5b8f:538c]:8333
+[2a02:2028:1016::2]:8333
+[2a02:2528:503:2::14]:8333
+[2a02:2528:503:2::15]:8333
+[2a02:2528:ff00:81a6:21e:c5ff:fe8d:f9a5]:8333
+[2a02:2770:5:0:21a:4aff:fee4:c7db]:8333
+[2a02:2770:8:0:21a:4aff:fe7b:3dcd]:8333
+[2a02:348:5e:5a29::1]:8333
+[2a02:7aa0:1619::202f:c06a]:8333
+[2a02:8109:8e40:35fc:ba27:ebff:feae:cf16]:8333
+[2a02:af8:6:1500::1:130]:8333
+[2a02:c200:0:10:1:0:6314:2222]:8333
+[2a02:c200:0:10:2:3:3295:1]:8332
+[2a02:c200:0:10:3:0:5449:1]:8333
+[2a02:c200:1:10:2:3:5899:1]:8333
+[2a02:c200:1:10::2705:1]:8333
+[2a02:ce80:0:20::1]:8333
+[2a02:fe0:c321:27e0:6ef0:49ff:fe11:a61d]:8333
+[2a03:4000:2:496::8]:8333
+[2a03:b0c0:0:1010::62:f001]:8333
+[2a03:f80:ed16:ca7:ea75:b12d:2af:9e2a]:8333
+3ffk7iumtx3cegbi.onion:8333
+3hshaantu6ot4upz.onion:8333
+45c5lc77qgpikafy.onion:8333
+77mx2jsxaoyesz2p.onion:8333
+7g7j54btiaxhtsiy.onion:8333
+b6fr7dlbu2kpiysf.onion:8333
+bitcoincfqcssig5.onion:8333
+bitcoinostk4e4re.onion:8333
+bmutjfrj5btseddb.onion:8333
+drp4pvejybx2ejdr.onion:8333
+gixnv56d63buypan.onion:8333
+h2vlpudzphzqxutd.onion:8333
+hhiv5pnxenvbf4am.onion:8333
+lzxpkn6ptp3ohh63.onion:8333
+msphsgfiqfq5stne.onion:8333
+ncwk3lutemffcpc4.onion:8333
+okdzjarwekbshnof.onion:8333
+sjdomi4yb2dwkjbc.onion:8333
+uvwozwxlihntigbb.onion:8333
+v6ylz45dn5ybpk4d.onion:8333
+vk3qjdehyy4dwcxw.onion:8333
+vqpye2k5rcqvj5mq.onion:8333
+xudkoztdfrsuyyou.onion:8333
+z55v4ostefnwfy32.onion:8333
diff --git a/contrib/seeds/nodes_test.txt b/contrib/seeds/nodes_test.txt
new file mode 100644
index 0000000000..98365ee505
--- /dev/null
+++ b/contrib/seeds/nodes_test.txt
@@ -0,0 +1,11 @@
+# List of fixed seed nodes for testnet
+
+# Onion nodes
+thfsmmn2jbitcoin.onion
+it2pj4f7657g3rhi.onion
+nkf5e6b7pl4jfd4a.onion
+4zhkir2ofl7orfom.onion
+t6xj6wilh4ytvcs7.onion
+i6y6ivorwakd7nw3.onion
+ubqj4rsu3nqtxmtp.onion
+
diff --git a/contrib/test-patches/README.md b/contrib/test-patches/README.md
deleted file mode 100644
index def40b0d6c..0000000000
--- a/contrib/test-patches/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-### Test Patches ###
-
-These patches are applied when the automated pull-tester
-tests each pull and when master is tested using jenkins.
-You can find more information about the tests run at
-[http://jenkins.bluematt.me/pull-tester/files/
-](http://jenkins.bluematt.me/pull-tester/files/) \ No newline at end of file
diff --git a/contrib/test-patches/temp-revert-2.patch b/contrib/test-patches/temp-revert-2.patch
deleted file mode 100644
index 1cd043d0d7..0000000000
--- a/contrib/test-patches/temp-revert-2.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-commit cfae26916dba311f6f75d444301c1f9362267c3e
-Author: Matt Corallo <git@bluematt.me>
-Date: Sun Mar 24 20:45:50 2013 -0400
-
- Revert "Checkpoint at first block in 11 March chain fork"
-
- This reverts commit f817c496a1482d05b22c8e539de67f07db1c09d9.
-
-diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
-index 62234b9..9b11f0b 100644
---- a/src/checkpoints.cpp
-+++ b/src/checkpoints.cpp
-@@ -44,7 +44,6 @@ namespace Checkpoints
- (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
- (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
- (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
-- (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
- ;
- static const CCheckpointData data = {
- &mapCheckpoints,
diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits
new file mode 100644
index 0000000000..31aeb8f3d3
--- /dev/null
+++ b/contrib/verify-commits/allow-revsig-commits
@@ -0,0 +1,2 @@
+586a29253dabec3ca0f1ccba9091daabd16b8411
+eddaba7b5692288087a926da5733e86b47274e4e
diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh
new file mode 100755
index 0000000000..0218b82e11
--- /dev/null
+++ b/contrib/verify-commits/gpg.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+INPUT=$(</dev/stdin)
+VALID=false
+REVSIG=false
+IFS=$'\n'
+for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do
+ case "$LINE" in
+ "[GNUPG:] VALIDSIG "*)
+ while read KEY; do
+ case "$LINE" in "[GNUPG:] VALIDSIG $KEY "*) VALID=true;; esac
+ done < ./contrib/verify-commits/trusted-keys
+ ;;
+ "[GNUPG:] REVKEYSIG "*)
+ [ "$BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG" != 1 ] && exit 1
+ while read KEY; do
+ case "$LINE" in "[GNUPG:] REVKEYSIG ${KEY:24:40} "*)
+ REVSIG=true
+ GOODREVSIG="[GNUPG:] GOODSIG ${KEY:24:40} "
+ ;;
+ esac
+ done < ./contrib/verify-commits/trusted-keys
+ ;;
+ esac
+done
+if ! $VALID; then
+ exit 1
+fi
+if $VALID && $REVSIG; then
+ echo "$INPUT" | gpg --trust-model always "$@" | grep "\[GNUPG:\] \(NEWSIG\|SIG_ID\|VALIDSIG\)" 2>/dev/null
+ echo "$GOODREVSIG"
+else
+ echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
+fi
diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh
new file mode 100755
index 0000000000..c57222818a
--- /dev/null
+++ b/contrib/verify-commits/pre-push-hook.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+if ! [[ "$2" =~ ^(git@)?(www.)?github.com(:|/)bitcoin/bitcoin(.git)?$ ]]; then
+ exit 0
+fi
+
+while read LINE; do
+ set -- A $LINE
+ if [ "$4" != "refs/heads/master" ]; then
+ continue
+ fi
+ if ! ./contrib/verify-commits/verify-commits.sh $3 > /dev/null 2>&1; then
+ echo "ERROR: A commit is not signed, can't push"
+ ./contrib/verify-commits/verify-commits.sh
+ exit 1
+ fi
+done < /dev/stdin
diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root
new file mode 100644
index 0000000000..838b8d1ea8
--- /dev/null
+++ b/contrib/verify-commits/trusted-git-root
@@ -0,0 +1 @@
+165e323d851cc87213c7673c6f278e87a6f2e752
diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys
new file mode 100644
index 0000000000..a0d0f82db3
--- /dev/null
+++ b/contrib/verify-commits/trusted-keys
@@ -0,0 +1,7 @@
+71A3B16735405025D447E8F274810B012346C9A6
+1F4410F6A89268CE3197A84C57896D2FF8F0B657
+01CDF4627A3B88AAE4A571C87588242FBE38D3A8
+AF8BE07C7049F3A26B239D5325B3083201782B2F
+81291FA67D2C379A006A053FEAB5AF94D9E9ABE7
+3F1888C6DCA92A6499C4911FDBA1A67379A1A931
+32EE5C4C3FA15CCADB46ABE529D4BCB6416F53EC
diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh
new file mode 100755
index 0000000000..9ba781008a
--- /dev/null
+++ b/contrib/verify-commits/verify-commits.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+DIR=$(dirname "$0")
+
+echo "Please verify all commits in the following list are not evil:"
+git log "$DIR"
+
+VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root")
+
+IS_REVSIG_ALLOWED () {
+ while read LINE; do
+ [ "$LINE" = "$1" ] && return 0
+ done < "${DIR}/allow-revsig-commits"
+ return 1
+}
+
+HAVE_FAILED=false
+IS_SIGNED () {
+ if [ $1 = $VERIFIED_ROOT ]; then
+ return 0;
+ fi
+ if IS_REVSIG_ALLOWED "$1"; then
+ export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1
+ else
+ export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0
+ fi
+ if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then
+ return 1;
+ fi
+ local PARENTS=$(git show -s --format=format:%P $1)
+ for PARENT in $PARENTS; do
+ if IS_SIGNED $PARENT > /dev/null; then
+ return 0;
+ fi
+ done
+ if ! "$HAVE_FAILED"; then
+ echo "No parent of $1 was signed with a trusted key!" > /dev/stderr
+ echo "Parents are:" > /dev/stderr
+ for PARENT in $PARENTS; do
+ git show -s $PARENT > /dev/stderr
+ done
+ HAVE_FAILED=true
+ fi
+ return 1;
+}
+
+if [ x"$1" = "x" ]; then
+ TEST_COMMIT="HEAD"
+else
+ TEST_COMMIT="$1"
+fi
+
+IS_SIGNED "$TEST_COMMIT"
+RES=$?
+if [ "$RES" = 1 ]; then
+ if ! "$HAVE_FAILED"; then
+ echo "$TEST_COMMIT was not signed with a trusted key!"
+ fi
+else
+ echo "There is a valid path from $TEST_COMMIT to $VERIFIED_ROOT where all commits are signed!"
+fi
+
+exit $RES
diff --git a/contrib/verifysfbinaries/verify.sh b/contrib/verifysfbinaries/verify.sh
index 3eb4693883..847c507553 100755
--- a/contrib/verifysfbinaries/verify.sh
+++ b/contrib/verifysfbinaries/verify.sh
@@ -17,15 +17,15 @@ function clean_up {
WORKINGDIR="/tmp/bitcoin"
TMPFILE="hashes.tmp"
-#this URL is used if a version number is not specified as an argument to the script
-SIGNATUREFILE="https://bitcoin.org/bin/0.9.2.1/SHA256SUMS.asc"
-
SIGNATUREFILENAME="SHA256SUMS.asc"
RCSUBDIR="test/"
BASEDIR="https://bitcoin.org/bin/"
-VERSIONPREFIX="bitcoin-"
+VERSIONPREFIX="bitcoin-core-"
RCVERSIONSTRING="rc"
+#this URL is used if a version number is not specified as an argument to the script
+SIGNATUREFILE="$BASEDIR""$VERSIONPREFIX""0.10.4/""$RCSUBDIR""$SIGNATUREFILENAME"
+
if [ ! -d "$WORKINGDIR" ]; then
mkdir "$WORKINGDIR"
fi
@@ -62,7 +62,7 @@ WGETOUT=$(wget -N "$BASEDIR$SIGNATUREFILENAME" 2>&1)
#and then see if wget completed successfully
if [ $? -ne 0 ]; then
echo "Error: couldn't fetch signature file. Have you specified the version number in the following format?"
- echo "[bitcoin-]<version>-[rc[0-9]] (example: bitcoin-0.9.2-rc1)"
+ echo "[$VERSIONPREFIX]<version>-[$RCVERSIONSTRING[0-9]] (example: "$VERSIONPREFIX"0.10.4-"$RCVERSIONSTRING"1)"
echo "wget output:"
echo "$WGETOUT"|sed 's/^/\t/g'
exit 2
@@ -82,7 +82,7 @@ if [ $RET -ne 0 ]; then
echo "Bad signature."
elif [ $RET -eq 2 ]; then
#or if a gpg error has occurred
- echo "gpg error. Do you have Gavin's code signing key installed?"
+ echo "gpg error. Do you have the Bitcoin Core binary release signing key installed?"
fi
echo "gpg output:"
@@ -116,4 +116,6 @@ fi
#everything matches! clean up the mess
clean_up $FILES $SIGNATUREFILENAME $TMPFILE
+echo -e "Verified hashes of \n$FILES"
+
exit 0
diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py
new file mode 100755
index 0000000000..decf29d42a
--- /dev/null
+++ b/contrib/zmq/zmq_sub.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python2
+
+import array
+import binascii
+import zmq
+
+port = 28332
+
+zmqContext = zmq.Context()
+zmqSubSocket = zmqContext.socket(zmq.SUB)
+zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock")
+zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx")
+zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock")
+zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx")
+zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
+
+try:
+ while True:
+ msg = zmqSubSocket.recv_multipart()
+ topic = str(msg[0])
+ body = msg[1]
+
+ if topic == "hashblock":
+ print "- HASH BLOCK -"
+ print binascii.hexlify(body)
+ elif topic == "hashtx":
+ print '- HASH TX -'
+ print binascii.hexlify(body)
+ elif topic == "rawblock":
+ print "- RAW BLOCK HEADER -"
+ print binascii.hexlify(body[:80])
+ elif topic == "rawtx":
+ print '- RAW TX -'
+ print binascii.hexlify(body)
+
+except KeyboardInterrupt:
+ zmqContext.destroy()