aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README.md59
-rw-r--r--contrib/bitcoin-qt.pro21
-rw-r--r--contrib/bitcoind.bash-completion48
-rw-r--r--contrib/bitrpc/README.md8
-rw-r--r--contrib/bitrpc/bitrpc.py491
-rw-r--r--contrib/debian/README.md21
-rwxr-xr-xcontrib/debian/bin/bitcoind14
-rw-r--r--contrib/debian/bitcoin-qt.desktop6
-rw-r--r--contrib/debian/bitcoin-qt.install5
-rw-r--r--contrib/debian/bitcoind.install4
-rw-r--r--contrib/debian/bitcoind.manpages1
-rw-r--r--contrib/debian/changelog110
-rw-r--r--contrib/debian/control23
-rw-r--r--contrib/debian/copyright17
-rw-r--r--contrib/debian/examples/bitcoin.conf115
-rw-r--r--contrib/debian/manpages/bitcoin-cli.148
-rw-r--r--contrib/debian/manpages/bitcoin-qt.1203
-rw-r--r--contrib/debian/manpages/bitcoin.conf.515
-rw-r--r--contrib/debian/manpages/bitcoind.134
-rw-r--r--contrib/debian/patches/1001_use_system_json-spirit.patch26
-rw-r--r--contrib/debian/patches/series2
-rwxr-xr-xcontrib/debian/rules21
-rw-r--r--contrib/devtools/README.md96
-rwxr-xr-xcontrib/devtools/fix-copyright-headers.py53
-rwxr-xr-xcontrib/devtools/git-subtree-check.sh74
-rwxr-xr-xcontrib/devtools/github-merge.sh181
-rwxr-xr-xcontrib/devtools/optimize-pngs.py73
-rwxr-xr-xcontrib/devtools/symbol-check.py119
-rwxr-xr-xcontrib/devtools/update-translations.py186
-rw-r--r--contrib/gitian-descriptors/README31
-rw-r--r--contrib/gitian-descriptors/README.md66
-rw-r--r--contrib/gitian-descriptors/boost-win32.yml38
-rw-r--r--contrib/gitian-descriptors/deps-win32.yml71
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml118
-rw-r--r--contrib/gitian-descriptors/gitian-osx-signer.yml37
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml134
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml115
-rw-r--r--contrib/gitian-descriptors/gitian-win32.yml74
-rw-r--r--contrib/gitian-descriptors/gitian.yml55
-rw-r--r--contrib/gitian-descriptors/qt-win32.yml54
-rw-r--r--contrib/gitian-downloader/aschildbach-key.pgpbin0 -> 1993 bytes
-rw-r--r--contrib/gitian-downloader/cfields-key.pgp52
-rw-r--r--contrib/gitian-downloader/fanquake-key.pgp63
-rw-r--r--contrib/gitian-downloader/jonasschnelli-key.pgpbin0 -> 2230 bytes
-rw-r--r--contrib/gitian-downloader/linux-download-config20
-rw-r--r--contrib/gitian-downloader/michagogo-key.pgp59
-rw-r--r--contrib/gitian-downloader/sipa-key.pgpbin108922 -> 109468 bytes
-rw-r--r--contrib/gitian-downloader/win32-download-config20
-rw-r--r--contrib/gitian-downloader/wtogami-key.pgp131
-rw-r--r--contrib/init/README.md11
-rw-r--r--contrib/init/bitcoind.conf65
-rw-r--r--contrib/init/bitcoind.init67
-rw-r--r--contrib/init/bitcoind.openrc88
-rw-r--r--contrib/init/bitcoind.openrcconf27
-rw-r--r--contrib/init/bitcoind.service22
-rw-r--r--contrib/linearize/README.md33
-rw-r--r--contrib/linearize/example-linearize.cfg29
-rwxr-xr-xcontrib/linearize/linearize-data.py301
-rwxr-xr-xcontrib/linearize/linearize-hashes.py113
-rw-r--r--contrib/macdeploy/DS_Storebin0 -> 10244 bytes
-rw-r--r--contrib/macdeploy/README.md15
-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.sh46
-rw-r--r--contrib/macdeploy/fancy.plist4
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus252
-rw-r--r--contrib/macdeploy/notes.txt26
-rw-r--r--contrib/pyminer/README6
-rw-r--r--contrib/pyminer/example-config.cfg32
-rwxr-xr-xcontrib/pyminer/pyminer.py252
-rw-r--r--contrib/qos/README.md5
-rw-r--r--contrib/qos/tc.sh41
-rw-r--r--contrib/seeds/README.md8
-rwxr-xr-xcontrib/seeds/makeseeds.py118
-rw-r--r--contrib/spendfrom/README.md35
-rw-r--r--contrib/spendfrom/setup.py9
-rwxr-xr-xcontrib/spendfrom/spendfrom.py267
-rw-r--r--contrib/test-patches/README.md7
-rw-r--r--contrib/test-patches/temp-revert-2.patch20
-rw-r--r--contrib/testgen/README.md8
-rw-r--r--contrib/testgen/base58.py104
-rwxr-xr-xcontrib/testgen/gen_base58_test_vectors.py126
-rwxr-xr-xcontrib/tidy_datadir.sh59
-rwxr-xr-xcontrib/verify-commits/gpg.sh15
-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-keys5
-rwxr-xr-xcontrib/verify-commits/verify-commits.sh51
-rw-r--r--contrib/verifysfbinaries/README.md6
-rwxr-xr-xcontrib/verifysfbinaries/verify.sh119
-rw-r--r--contrib/wallettools/walletchangepass.py5
-rw-r--r--contrib/wallettools/walletunlock.py4
95 files changed, 4561 insertions, 1121 deletions
diff --git a/contrib/README.md b/contrib/README.md
new file mode 100644
index 0000000000..7d4b91e887
--- /dev/null
+++ b/contrib/README.md
@@ -0,0 +1,59 @@
+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
+address (or addresses).
+
+Repository Tools
+---------------------
+
+### [Developer tools](/contrib/devtools) ###
+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.
+
+### [Qos](/contrib/qos) ###
+
+A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it.
+
+### [Seeds](/contrib/seeds) ###
+Utility to generate the pnSeed[] array that is compiled into the client.
+
+Build Tools and Keys
+---------------------
+
+### [Debian](/contrib/debian) ###
+Contains files used to package bitcoind/bitcoin-qt
+for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here.
+
+### [Gitian-descriptors](/contrib/gitian-descriptors) ###
+Gavin's notes on getting gitian builds up and running using KVM.
+
+### [Gitian-downloader](/contrib/gitian-downloader)
+Various PGP files of core developers.
+
+### [MacDeploy](/contrib/macdeploy) ###
+Scripts and notes for Mac builds.
+
+Test and Verify Tools
+---------------------
+
+### [TestGen](/contrib/testgen) ###
+Utilities to generate test vectors for the data-driven Bitcoin tests.
+
+### [Test Patches](/contrib/test-patches) ###
+These patches are applied when the automated pull-tester
+tests each pull and when master is tested using jenkins.
+
+### [Verify SF Binaries](/contrib/verifysfbinaries) ###
+This script attempts to download and verify the signature file SHA256SUMS.asc from SourceForge.
diff --git a/contrib/bitcoin-qt.pro b/contrib/bitcoin-qt.pro
new file mode 100644
index 0000000000..3a72d10f47
--- /dev/null
+++ b/contrib/bitcoin-qt.pro
@@ -0,0 +1,21 @@
+FORMS += \
+ ../src/qt/forms/aboutdialog.ui \
+ ../src/qt/forms/addressbookpage.ui \
+ ../src/qt/forms/askpassphrasedialog.ui \
+ ../src/qt/forms/coincontroldialog.ui \
+ ../src/qt/forms/editaddressdialog.ui \
+ ../src/qt/forms/helpmessagedialog.ui \
+ ../src/qt/forms/intro.ui \
+ ../src/qt/forms/openuridialog.ui \
+ ../src/qt/forms/optionsdialog.ui \
+ ../src/qt/forms/overviewpage.ui \
+ ../src/qt/forms/receivecoinsdialog.ui \
+ ../src/qt/forms/receiverequestdialog.ui \
+ ../src/qt/forms/rpcconsole.ui \
+ ../src/qt/forms/sendcoinsdialog.ui \
+ ../src/qt/forms/sendcoinsentry.ui \
+ ../src/qt/forms/signverifymessagedialog.ui \
+ ../src/qt/forms/transactiondescdialog.ui \
+
+RESOURCES += \
+ ../src/qt/bitcoin.qrc
diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion
index dd6c1ce819..3cc959c0a6 100644
--- a/contrib/bitcoind.bash-completion
+++ b/contrib/bitcoind.bash-completion
@@ -1,6 +1,6 @@
-# bash programmable completion for bitcoind(1)
-# Copyright (c) 2012 Christian von Roques <roques@mti.ag>
-# Distributed under the MIT/X11 software license, see the accompanying
+# bash programmable completion for bitcoind(1) and bitcoin-cli(1)
+# Copyright (c) 2012,2014 Christian von Roques <roques@mti.ag>
+# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
have bitcoind && {
@@ -37,9 +37,39 @@ _bitcoind() {
COMPREPLY=()
_get_comp_words_by_ref -n = cur prev words cword
+ 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
+ ;;
+ esac
+ fi
+
+ if ((cword > 3)); then
+ case ${words[cword-3]} in
+ addmultisigaddress)
+ _bitcoin_accounts
+ return 0
+ ;;
+ getbalance|gettxout|importaddress|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock)
+ COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
+ return 0
+ ;;
+ esac
+ fi
+
if ((cword > 2)); then
case ${words[cword-2]} in
- listreceivedbyaccount|listreceivedbyaddress)
+ addnode)
+ COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) )
+ return 0
+ ;;
+ getblock|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction)
COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
return 0
;;
@@ -51,11 +81,11 @@ _bitcoind() {
fi
case "$prev" in
- backupwallet)
+ backupwallet|dumpwallet|importwallet)
_filedir
return 0
;;
- setgenerate)
+ getmempool|lockunspent|setgenerate)
COMPREPLY=( $( compgen -W "true false" -- "$cur" ) )
return 0
;;
@@ -66,7 +96,7 @@ _bitcoind() {
esac
case "$cur" in
- -conf=*|-pid=*|-rpcsslcertificatechainfile=*|-rpcsslprivatekeyfile=*)
+ -conf=*|-pid=*|-loadblock=*|-wallet=*|-rpcsslcertificatechainfile=*|-rpcsslprivatekeyfile=*)
cur="${cur#*=}"
_filedir
return 0
@@ -89,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" ) )
@@ -103,7 +133,7 @@ _bitcoind() {
esac
}
-complete -F _bitcoind bitcoind
+complete -F _bitcoind bitcoind bitcoin-cli
}
# Local variables:
diff --git a/contrib/bitrpc/README.md b/contrib/bitrpc/README.md
new file mode 100644
index 0000000000..f5ef2f0405
--- /dev/null
+++ b/contrib/bitrpc/README.md
@@ -0,0 +1,8 @@
+### 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
index b02b299177..c3ce9d7936 100644
--- a/contrib/bitrpc/bitrpc.py
+++ b/contrib/bitrpc/bitrpc.py
@@ -1,6 +1,7 @@
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
@@ -10,315 +11,325 @@ rpcpass = ""
if rpcpass == "":
- access = ServiceProxy("http://127.0.0.1:8332")
+ access = ServiceProxy("http://127.0.0.1:8332")
else:
- access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8332")
+ 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"
+ try:
+ path = raw_input("Enter destination path/filename: ")
+ print access.backupwallet(path)
+ except Exception as inst:
+ print inst
+
+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 Exception as inst:
+ print inst
elif cmd == "getaccount":
- try:
- addr = raw_input("Enter a Bitcoin address: ")
- print access.getaccount(addr)
- except:
- print "\n---An error occurred---\n"
+ try:
+ addr = raw_input("Enter a Bitcoin address: ")
+ print access.getaccount(addr)
+ except Exception as inst:
+ print inst
elif cmd == "getaccountaddress":
- try:
- acct = raw_input("Enter an account name: ")
- print access.getaccountaddress(acct)
- except:
- print "\n---An error occurred---\n"
+ try:
+ acct = raw_input("Enter an account name: ")
+ print access.getaccountaddress(acct)
+ except Exception as inst:
+ print inst
elif cmd == "getaddressesbyaccount":
- try:
- acct = raw_input("Enter an account name: ")
- print access.getaddressesbyaccount(acct)
- except:
- print "\n---An error occurred---\n"
+ try:
+ acct = raw_input("Enter an account name: ")
+ print access.getaddressesbyaccount(acct)
+ except Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
elif cmd == "getblockbycount":
- try:
- height = raw_input("Height: ")
- print access.getblockbycount(height)
- except:
- print "\n---An error occurred---\n"
+ try:
+ height = raw_input("Height: ")
+ print access.getblockbycount(height)
+ except Exception as inst:
+ print inst
elif cmd == "getblockcount":
- try:
- print access.getblockcount()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.getblockcount()
+ except Exception as inst:
+ print inst
elif cmd == "getblocknumber":
- try:
- print access.getblocknumber()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.getblocknumber()
+ except Exception as inst:
+ print inst
elif cmd == "getconnectioncount":
- try:
- print access.getconnectioncount()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.getconnectioncount()
+ except Exception as inst:
+ print inst
elif cmd == "getdifficulty":
- try:
- print access.getdifficulty()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.getdifficulty()
+ except Exception as inst:
+ print inst
elif cmd == "getgenerate":
- try:
- print access.getgenerate()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.getgenerate()
+ except Exception as inst:
+ print inst
elif cmd == "gethashespersec":
- try:
- print access.gethashespersec()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.gethashespersec()
+ except Exception as inst:
+ print inst
elif cmd == "getinfo":
- try:
- print access.getinfo()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.getinfo()
+ except Exception as inst:
+ print inst
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"
+ try:
+ acct = raw_input("Enter an account name: ")
+ try:
+ print access.getnewaddress(acct)
+ except:
+ print access.getnewaddress()
+ except Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
elif cmd == "gettransaction":
- try:
- txid = raw_input("Enter a transaction ID: ")
- print access.gettransaction(txid)
- except:
- print "\n---An error occurred---\n"
+ try:
+ txid = raw_input("Enter a transaction ID: ")
+ print access.gettransaction(txid)
+ except Exception as inst:
+ print inst
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"
+ try:
+ data = raw_input("Data (optional): ")
+ try:
+ print access.gettransaction(data)
+ except:
+ print access.gettransaction()
+ except Exception as inst:
+ print inst
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"
+ try:
+ cmd = raw_input("Command (optional): ")
+ try:
+ print access.help(cmd)
+ except:
+ print access.help()
+ except Exception as inst:
+ print inst
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"
+ try:
+ mc = raw_input("Minimum confirmations (optional): ")
+ try:
+ print access.listaccounts(mc)
+ except:
+ print access.listaccounts()
+ except Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
elif cmd == "setaccount":
- try:
- addr = raw_input("Address: ")
- acct = raw_input("Account:")
- print access.setaccount(addr,acct)
- except:
- print "\n---An error occurred---\n"
+ try:
+ addr = raw_input("Address: ")
+ acct = raw_input("Account:")
+ print access.setaccount(addr,acct)
+ except Exception as inst:
+ print inst
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"
+ 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 Exception as inst:
+ print inst
elif cmd == "settxfee":
- try:
- amt = raw_input("Amount:")
- print access.settxfee(amt)
- except:
- print "\n---An error occurred---\n"
+ try:
+ amt = raw_input("Amount:")
+ print access.settxfee(amt)
+ except Exception as inst:
+ print inst
elif cmd == "stop":
- try:
- print access.stop()
- except:
- print "\n---An error occurred---\n"
+ try:
+ print access.stop()
+ except Exception as inst:
+ print inst
elif cmd == "validateaddress":
- try:
- addr = raw_input("Address: ")
- print access.validateaddress(addr)
- except:
- print "\n---An error occurred---\n"
+ try:
+ addr = raw_input("Address: ")
+ print access.validateaddress(addr)
+ except Exception as inst:
+ print inst
elif cmd == "walletpassphrase":
- try:
- pwd = raw_input("Enter wallet passphrase: ")
- access.walletpassphrase(pwd, 60)
- print "\n---Wallet unlocked---\n"
- except:
- print "\n---An error occurred---\n"
+ try:
+ pwd = getpass.getpass(prompt="Enter wallet passphrase: ")
+ access.walletpassphrase(pwd, 60)
+ print "\n---Wallet unlocked---\n"
+ except Exception as inst:
+ print inst
elif cmd == "walletpassphrasechange":
- try:
- pwd = raw_input("Enter old wallet passphrase: ")
- pwd2 = raw_input("Enter new wallet passphrase: ")
- access.walletpassphrasechange(pwd, pwd2)
- print
- print "\n---Passphrase changed---\n"
- except:
- print
- print "\n---An error occurred---\n"
- print
+ 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 Exception as inst:
+ print inst
else:
- print "Command not found or not supported" \ No newline at end of file
+ print "Command not found or not supported"
diff --git a/contrib/debian/README.md b/contrib/debian/README.md
new file mode 100644
index 0000000000..fab9cc2381
--- /dev/null
+++ b/contrib/debian/README.md
@@ -0,0 +1,21 @@
+
+Debian
+====================
+This directory contains files used to package bitcoind/bitcoin-qt
+for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here.
+
+## bitcoin: URI support ##
+
+
+bitcoin-qt.desktop (Gnome / Open Desktop)
+To install:
+
+ sudo desktop-file-install bitcoin-qt.desktop
+ sudo update-desktop-database
+
+If you build yourself, you will either need to modify the paths in
+the .desktop file or copy or symlink your bitcoin-qt binary to `/usr/bin`
+and the `../../share/pixmaps/bitcoin128.png` to `/usr/share/pixmaps`
+
+bitcoin-qt.protocol (KDE)
+
diff --git a/contrib/debian/bin/bitcoind b/contrib/debian/bin/bitcoind
deleted file mode 100755
index a2f55a9138..0000000000
--- a/contrib/debian/bin/bitcoind
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-set -e
-
-umask 077
-
-basedir=~/.bitcoin
-cfgfile="$basedir/bitcoin.conf"
-
-[ -e "$basedir" ] || mkdir "$basedir"
-
-[ -e "$cfgfile" ] || perl -le 'print"rpcpassword=",map{(a..z,A..Z,0..9)[rand 62]}0..9' > "$cfgfile"
-
-exec /usr/lib/bitcoin/bitcoind "$@"
diff --git a/contrib/debian/bitcoin-qt.desktop b/contrib/debian/bitcoin-qt.desktop
index 7cb00a2c8b..61e1aca6ad 100644
--- a/contrib/debian/bitcoin-qt.desktop
+++ b/contrib/debian/bitcoin-qt.desktop
@@ -4,9 +4,9 @@ Name=Bitcoin
Comment=Bitcoin P2P Cryptocurrency
Comment[fr]=Bitcoin, monnaie virtuelle cryptographique pair à pair
Comment[tr]=Bitcoin, eÅŸten eÅŸe kriptografik sanal para birimi
-Exec=/usr/bin/bitcoin-qt
+Exec=bitcoin-qt %u
Terminal=false
Type=Application
-Icon=/usr/share/pixmaps/bitcoin80.xpm
+Icon=bitcoin128
MimeType=x-scheme-handler/bitcoin;
-Categories=Office;
+Categories=Office;Finance;
diff --git a/contrib/debian/bitcoin-qt.install b/contrib/debian/bitcoin-qt.install
index ba407134e7..e0b32373be 100644
--- a/contrib/debian/bitcoin-qt.install
+++ b/contrib/debian/bitcoin-qt.install
@@ -1,5 +1,6 @@
-bitcoin-qt usr/bin
+usr/local/bin/bitcoin-qt usr/bin
share/pixmaps/bitcoin32.xpm usr/share/pixmaps
-share/pixmaps/bitcoin80.xpm usr/share/pixmaps
+share/pixmaps/bitcoin16.xpm usr/share/pixmaps
+share/pixmaps/bitcoin128.png usr/share/pixmaps
debian/bitcoin-qt.desktop usr/share/applications
debian/bitcoin-qt.protocol usr/share/kde4/services/
diff --git a/contrib/debian/bitcoind.install b/contrib/debian/bitcoind.install
index e978c44b3f..798ea851f6 100644
--- a/contrib/debian/bitcoind.install
+++ b/contrib/debian/bitcoind.install
@@ -1,2 +1,2 @@
-debian/bin/bitcoind usr/bin
-src/bitcoind usr/lib/bitcoin
+usr/local/bin/bitcoind usr/bin
+usr/local/bin/bitcoin-cli 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 773da6b54f..7ce3babc1b 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,3 +1,113 @@
+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.
+ * Backport pull #4019
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 19 Apr 2014 17:29:00 -0400
+
+bitcoin (0.9.0-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Thu, 20 Mar 2014 13:10:00 -0400
+
+bitcoin (0.8.6-precise1) precise; urgency=medium
+
+ * New upstream release.
+ * Make .desktop paths non-fixed (suggested by prusnak@github)
+
+ -- Matt Corallo <matt@bluematt.me> Fri, 13 Dec 2013 13:31:00 -0400
+
+bitcoin (0.8.5-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sun, 15 Sep 2013 14:02:00 -0400
+
+bitcoin (0.8.4-precise1) precise; urgency=medium
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 4 Sep 2013 10:25:00 -0400
+
+bitcoin (0.8.3-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 26 Jun 2013 00:18:00 +0100
+
+bitcoin (0.8.2-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 29 Mar 2013 23:23:00 +0100
+
+bitcoin (0.8.1-natty3) natty; urgency=low
+
+ * New pixmaps
+
+ -- Jonas Schnelli <jonas.schnelli@include7.ch> Mon, 13 May 2013 16:14:00 +0100
+
+bitcoin (0.8.1-natty2) natty; urgency=low
+
+ * Remove dumb broken launcher script
+
+ -- Matt Corallo <matt@bluematt.me> Sun, 24 Mar 2013 20:01:00 -0400
+
+bitcoin (0.8.1-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Tue, 19 Mar 2013 13:03:00 -0400
+
+bitcoin (0.8.0-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 23 Feb 2013 16:01:00 -0500
+
+bitcoin (0.7.2-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 15 Dec 2012 10:59:00 -0400
+
+bitcoin (0.7.1-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 24 Oct 2012 15:06:00 -0400
+
+bitcoin (0.7.0-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Mon, 17 Sep 2012 13:45:00 +0200
+
+bitcoin (0.6.3-natty1) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Mon, 25 Jun 2012 23:47:00 +0200
+
bitcoin (0.6.2-natty1) natty; urgency=low
* Update package description and launch scripts.
diff --git a/contrib/debian/control b/contrib/debian/control
index 4425e716d8..4392bb3385 100644
--- a/contrib/debian/control
+++ b/contrib/debian/control
@@ -5,19 +5,22 @@ Maintainer: Jonas Smedegaard <dr@jones.dk>
Uploaders: Micah Anderson <micah@debian.org>
Build-Depends: debhelper,
devscripts,
+ automake,
+ libtool,
bash-completion,
libboost-system-dev (>> 1.35) | libboost-system1.35-dev,
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,
libboost-test-dev (>> 1.35) | libboost-test1.35-dev,
qt4-qmake,
libqt4-dev,
- libqrencode-dev
+ libqrencode-dev,
+ libprotobuf-dev, protobuf-compiler
Standards-Version: 3.9.2
Homepage: http://www.bitcoin.org/
Vcs-Git: git://github.com/bitcoin/bitcoin.git
@@ -33,27 +36,23 @@ Description: peer-to-peer network based digital currency - daemon
transact directly with each other, with the help of a P2P network to
check for double-spending.
.
- By default connects to an IRC network to discover other peers.
- .
Full transaction history is stored locally at each client. This
- requires 2+ GB of space, slowly growing.
+ requires 20+ GB of space, slowly growing.
.
- This package provides bitcoind, a combined daemon and CLI tool to
- interact with the daemon.
+ This package provides the daemon, bitcoind, and the CLI tool
+ bitcoin-cli to interact with the daemon.
Package: bitcoin-qt
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: peer-to-peer network based digital currency - QT GUI
+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.
.
- By default connects to an IRC network to discover other peers.
- .
Full transaction history is stored locally at each client. This
- requires 2+ GB of space, slowly growing.
+ requires 20+ GB of space, slowly growing.
.
- This package provides bitcoin-qt, a GUI for Bitcoin based on QT.
+ This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt.
diff --git a/contrib/debian/copyright b/contrib/debian/copyright
index 71fa77cf6c..3741031f9c 100644
--- a/contrib/debian/copyright
+++ b/contrib/debian/copyright
@@ -6,19 +6,15 @@ Source: http://sourceforge.net/projects/bitcoin/files/
https://github.com/bitcoin/bitcoin
Files: *
-Copyright: 2009-2011, Bitcoin Developers
+Copyright: 2009-2012, Bitcoin Core Developers
License: Expat
-Comment: The Bitcoin Developers encompasses the current developers listed on bitcoin.org,
+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>
@@ -55,9 +51,8 @@ Comment: Icon Pack: Human-O2
Files: src/qt/res/icons/transaction*.png
Copyright: md2k7
-License: You are free to do with these icons as you wish, including selling,
- copying, modifying etc.
-Comment: Site: https://forum.bitcoin.org/index.php?topic=15276.0
+License: Expat
+Comment: Site: https://bitcointalk.org/index.php?topic=15276.0
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,
@@ -70,9 +65,9 @@ Comment: Icon Pack: Crystal SVG
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
-Comment: Site: http://forum.bitcoin.org/?topic=1756.0
+Comment: Site: https://bitcointalk.org/?topic=1756.0
-Files: scripts/img/reload.xcf, src/qt/res/movies/update_spinner.mng
+Files: scripts/img/reload.xcf, src/qt/res/movies/*.png
Copyright: Everaldo (Everaldo Coelho)
License: GPL-3+
Comment: Icon Pack: Kids
diff --git a/contrib/debian/examples/bitcoin.conf b/contrib/debian/examples/bitcoin.conf
index e56c43cb50..ade80d60ea 100644
--- a/contrib/debian/examples/bitcoin.conf
+++ b/contrib/debian/examples/bitcoin.conf
@@ -1,83 +1,128 @@
-# bitcoin.conf configuration file. Lines beginning with # are comments.
-
-
+##
+## bitcoin.conf configuration file. Lines beginning with # are comments.
+##
+
# Network-related settings:
# Run on the test network instead of the real bitcoin network.
-#testnet=1
+#testnet=0
-# Connect via a socks4 proxy
+# Run a regression test network
+#regtest=0
+
+# 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 ##
+## addnode will connect you to and tell you about the ##
+## nodes connected to 4.2.2.4. In addition it will tell ##
+## the other nodes connected to it that you exist so ##
+## they can connect to you. ##
+## connect will not do the above when you 'connect' to it. ##
+## It will *only* connect you to 4.2.2.4 and no one else.##
+## ##
+## So if you're behind a firewall, or have other problems ##
+## finding nodes, add some using 'addnode'. ##
+## ##
+## If you want to stay private, use 'connect' to only ##
+## connect to "trusted" nodes. ##
+## ##
+## If you run multiple nodes on a LAN, there's no need for ##
+## all of them to open lots of connections. Instead ##
+## 'connect' them all to one node that is port forwarded ##
+## and has lots of connections. ##
+## Thanks goes to [Noodle] on Freenode. ##
+##############################################################
+
# Use as many addnode= settings as you like to connect to specific peers
#addnode=69.164.218.197
#addnode=10.0.0.2:8333
-# ... or use as many connect= settings as you like to connect ONLY
-# to specific peers:
+# Alternatively use as many connect= settings as you like to connect ONLY to specific peers
#connect=69.164.218.197
#connect=10.0.0.1:8333
-# Do not use Internet Relay Chat (irc.lfnet.org #bitcoin channel) to
-# find other peers.
-#noirc=1
+# Listening mode, enabled by default except when 'connect' is being used
+#listen=1
# Maximum number of inbound+outbound connections.
#maxconnections=
-
+#
# JSON-RPC options (for controlling a running Bitcoin/bitcoind process)
+#
+
+# server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands
+#server=0
-# server=1 tells Bitcoin to accept JSON-RPC commands.
-#server=1
+# 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_385593
+#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
-# 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):
-#rpcallowip=10.1.1.34
-#rpcallowip=192.168.1.*
+# By default, only RPC connections from localhost are allowed.
+# Specify as many rpcallowip= settings as you like to allow connections from other hosts,
+# either as a single IPv4/IPv6 or with a subnet specification.
+
+# 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.
+# 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
+#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96
# Listen for RPC connections on this TCP port:
-rpcport=8332
+#rpcport=8332
# You can use Bitcoin or bitcoind to send commands to Bitcoin/bitcoind
# running on another host using this option:
-rpcconnect=127.0.0.1
+#rpcconnect=127.0.0.1
# Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate
# with Bitcoin -server or bitcoind
#rpcssl=1
# OpenSSL settings used when rpcssl=1
-rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH
-rpcsslcertificatechainfile=server.cert
-rpcsslprivatekeyfile=server.pem
+#rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH
+#rpcsslcertificatechainfile=server.cert
+#rpcsslprivatekeyfile=server.pem
+# Transaction Fee Changes in 0.10.0
-# Miscellaneous options
+# Send transactions as zero-fee transactions if possible (default: 0)
+#sendfreetransactions=0
-# Set gen=1 to attempt to generate bitcoins
-gen=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
-# Use SSE instructions to try to generate bitcoins faster.
-#4way=1
+# Miscellaneous options
# Pre-generate this many public/private key pairs, so wallet backups will be valid for
# both prior transactions and several dozen future transactions.
-keypool=100
+#keypool=100
# 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.
-paytxfee=0.00
-
-# Allow direct connections for the 'pay via IP address' feature.
-#allowreceivebyip=1
-
+#paytxfee=0.00
# User interface options
diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1
new file mode 100644
index 0000000000..f953ae9db7
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-cli.1
@@ -0,0 +1,48 @@
+.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
+.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 the help message.
+.TP
+\fB\-conf=\fR<file>
+Specify configuration file (default: bitcoin.conf).
+.TP
+\fB\-datadir=\fR<dir>
+Specify data directory.
+.TP
+\fB\-testnet\fR
+Connect to a Bitcoin Core instance running in testnet mode.
+.TP
+\fB\-regtest\fR
+Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
+.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\-rpcconnect=\fR<ip>
+Send commands to node running on <ip> (default: 127.0.0.1).
+.TP
+\fB\-rpcssl\fR=\fI1\fR
+Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions).
+
+.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
new file mode 100644
index 0000000000..a023582bc0
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-qt.1
@@ -0,0 +1,203 @@
+.TH BITCOIN-QT "1" "April 2013" "bitcoin-qt 1"
+.SH NAME
+bitcoin-qt \- peer-to-peer network based digital currency
+.SH DESCRIPTION
+.SS "Usage:"
+.IP
+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)
diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5
index 1243253413..8a0078d5d5 100644
--- a/contrib/debian/manpages/bitcoin.conf.5
+++ b/contrib/debian/manpages/bitcoin.conf.5
@@ -2,11 +2,11 @@
.SH NAME
bitcoin.conf \- bitcoin configuration file
.SH SYNOPSIS
-All command-line options (except for '-datadir' and '-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.
+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.
.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.
+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
@@ -24,9 +24,6 @@ Use as many *addnode=* settings as you like to connect to specific peers.
\fBconnect=\fR\fI'10.0.0.1:8333'\fR
Use as many *connect=* settings as you like to connect ONLY to specific peers.
.TP
-\fBnoirc=\fR[\fI'1'\fR|\fI'0'\fR]
-Use or Do not use Internet Relay Chat (irc.lfnet.org #bitcoin channel) to find other peers.
-.TP
\fRmaxconnections=\fR\fI'value'\fR
Maximum number of inbound+outbound connections.
.SH JSON-RPC OPTIONS
@@ -40,9 +37,6 @@ You must set *rpcuser* to secure the JSON-RPC api.
\fBrpcpassword=\fR\fI'password'\fR
You must set *rpcpassword* to secure the JSON-RPC api.
.TP
-\fBrpctimeout=\fR\fI'30'\fR
-How many seconds *bitcoin* will wait for a complete RPC HTTP request, after the HTTP connection is established.
-.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
@@ -53,9 +47,10 @@ Listen for RPC connections on this TCP port.
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':
+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
-\fBrpcsslciphers=\fR\fI'TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH'\fR
+\fB\-rpcsslciphers=\fR<ciphers>
+Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH)
.TP
\fBrpcsslcertificatechainfile=\fR\fI'server.cert'\fR
.TP
diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1
index bf46a6609c..c225b9f3e9 100644
--- a/contrib/debian/manpages/bitcoind.1
+++ b/contrib/debian/manpages/bitcoind.1
@@ -4,7 +4,7 @@ bitcoind \- peer-to-peer network based digital currency
.SH SYNOPSIS
bitcoin [options] <command> [params]
.TP
-bitcoin [options] help <command> - Get help for a command
+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:
@@ -28,7 +28,7 @@ Start minimized
Specify data directory
.TP
\fB\-proxy=\fR<ip:port>
-Connect through socks4 proxy
+Connect through SOCKS5 proxy
.TP
\fB\-addnode=\fR<ip>
Add a node to connect to
@@ -75,7 +75,7 @@ Server certificate file (default: server.cert)
Server private key (default: server.pem)
.TP
\fB\-rpcsslciphers=\fR<ciphers>
-Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)
+Acceptable ciphers (default: TLSv1+HIGH:\:!SSLv2:\:!aNULL:\:!eNULL:\:!AH:\:!3DES:\:@STRENGTH)
.TP
\-?
This help message
@@ -85,19 +85,19 @@ This help message
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.
+DEPRECATED. 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'].
+DEPRECATED. 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'.
+DEPRECATED. Returns a new bitcoin address for 'account'.
.TP
\fBgetaddressesbyaccount 'account'\fR
-Returns the list of addresses associated with the given 'account'.
+DEPRECATED. 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'.
+Returns the server's available balance, or the balance for 'account' (accounts are deprecated).
.TP
\fBgetblockcount\fR
Returns the number of blocks in the longest block chain.
@@ -115,7 +115,7 @@ Returns the proof-of-work difficulty as a multiple of the minimum difficulty.
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.
+Generation is limited to ['genproclimit'] processors, \-1 is unlimited.
.TP
\fBgethashespersec\fR
Returns a recent hashes per second performance measurement while generating.
@@ -124,10 +124,10 @@ Returns a recent hashes per second performance measurement while generating.
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'.
+Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), 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.
+DEPRECATED. 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.
@@ -147,13 +147,13 @@ If 'data' is specified, tries to solve the block and returns true if it was succ
List commands, or get help for a command.
.TP
\fBlistaccounts ['minconf=1']\fR
-List accounts and their current balances.
+DEPRECATED. 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.
+ "account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
@@ -161,12 +161,12 @@ List accounts and their current balances.
['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.
+ "account" : DEPRECATED. 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:
+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.
@@ -180,10 +180,10 @@ Returns a list of the last ['count'] transactions for 'account' - for all accoun
*note: requires bitcoin 0.3.20 or later.
.TP
\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR
-Moves funds between accounts.
+DEPRECATED. 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.
+DEPRECATED. 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.
diff --git a/contrib/debian/patches/1001_use_system_json-spirit.patch b/contrib/debian/patches/1001_use_system_json-spirit.patch
deleted file mode 100644
index 56a20af38c..0000000000
--- a/contrib/debian/patches/1001_use_system_json-spirit.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Description: Use system JSON Spirit library
-Author: Jonas Smedegaard <dr@jones.dk>
-Last-Update: 2011-05-17
---- a/src/rpc.cpp
-+++ b/src/rpc.cpp
-@@ -12,9 +12,7 @@
- #include <boost/asio/ssl.hpp>
- typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
- #endif
--#include "json/json_spirit_reader_template.h"
--#include "json/json_spirit_writer_template.h"
--#include "json/json_spirit_utils.h"
-+#include <json_spirit.h>
- #define printf OutputDebugStringF
- // MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are
- // precompiled in headers.h. The problem might be when the pch file goes over
---- a/src/makefile.unix
-+++ b/src/makefile.unix
-@@ -23,6 +23,7 @@
- -l boost_thread \
- -l db_cxx \
- -l ssl \
-+ -l json_spirit \
- -l crypto
-
- ifdef USE_UPNP
diff --git a/contrib/debian/patches/series b/contrib/debian/patches/series
index bbe3685ac2..8b13789179 100644
--- a/contrib/debian/patches/series
+++ b/contrib/debian/patches/series
@@ -1 +1 @@
-#1001_use_system_json-spirit.patch
+
diff --git a/contrib/debian/rules b/contrib/debian/rules
index 98bb2bba1c..52b357cf01 100755
--- a/contrib/debian/rules
+++ b/contrib/debian/rules
@@ -11,23 +11,14 @@ DEB_INSTALL_MANPAGES_bitcoind += debian/manpages/*
%:
dh --with bash-completion $@
-override_dh_auto_build:
- cd src; $(MAKE) -f makefile.unix bitcoind
- $(MAKE)
-
override_dh_auto_clean:
- if [ -f Makefile ]; then $(MAKE) clean; else rm -rf build/; rm -f bitcoin-qt; fi
- cd src; $(MAKE) -f makefile.unix clean
+ if [ -f Makefile ]; then $(MAKE) distclean; fi
+ rm -rf Makefile.in aclocal.m4 configure src/Makefile.in src/bitcoin-config.h.in src/build-aux src/qt/Makefile.in src/qt/test/Makefile.in src/test/Makefile.in
+# Yea, autogen should be run on the source archive, but I like doing git archive
override_dh_auto_configure:
- qmake bitcoin-qt.pro USE_QRCODE=1
+ ./autogen.sh
+ ./configure
override_dh_auto_test:
- cd src; $(MAKE) -f makefile.unix test_bitcoin
- src/test_bitcoin
-
-# Ensure wrapper is set executable
-binary-post-install/bitcoind:
- chmod +x $(cdbs_curdestdir)usr/bin/bitcoind
-binary-post-install/bitcoin-qt:
- chmod +x $(cdbs_curdestdir)usr/bin/bitcoin-qt
+ make check
diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md
new file mode 100644
index 0000000000..f90afa7f20
--- /dev/null
+++ b/contrib/devtools/README.md
@@ -0,0 +1,96 @@
+Contents
+===========
+This directory contains tools for developers working on this repository.
+
+github-merge.sh
+==================
+
+A small script to automate merging pull-requests securely and sign them with GPG.
+
+For example:
+
+ ./github-merge.sh bitcoin/bitcoin 3077
+
+(in any git repository) will help you merge pull request #3077 for the
+bitcoin/bitcoin repository.
+
+What it does:
+* Fetch master and the pull request.
+* Locally construct a merge commit.
+* Show the diff that merge results in.
+* Ask you to verify the resulting source tree (so you can do a make
+check or whatever).
+* Ask you whether to GPG sign the merge commit.
+* Ask you whether to push the result upstream.
+
+This means that there are no potential race conditions (where a
+pullreq gets updated while you're reviewing it, but before you click
+merge), and when using GPG signatures, that even a compromised github
+couldn't mess with the sources.
+
+Setup
+---------
+Configuring the github-merge tool for the bitcoin repository is done in the following way:
+
+ git config githubmerge.repository bitcoin/bitcoin
+ 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
+===========================
+
+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```
+
+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
+still compatible with the minimum supported Linux distribution versions.
+
+Example usage after a gitian build:
+
+ find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py
+
+If only supported symbols are used the return value will be 0 and the output will be empty.
+
+If there are 'unsupported' symbols, the return value will be 1 a list like this will be printed:
+
+ .../64/test_bitcoin: symbol memcpy from unsupported version GLIBC_2.14
+ .../64/test_bitcoin: symbol __fdelt_chk from unsupported version GLIBC_2.15
+ .../64/test_bitcoin: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15
+ .../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:
+
+- fetch all translations
+- post-process them into valid and committable format
+- add missing translations to the build system (TODO)
+
+See doc/translation-process.md for more information.
+
+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 sec/leveldb: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork)
+
+Usage: git-subtree-check.sh DIR COMMIT
+COMMIT may be omitted, in which case HEAD is used.
diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py
new file mode 100755
index 0000000000..5e84952548
--- /dev/null
+++ b/contrib/devtools/fix-copyright-headers.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+'''
+Run this script inside of src/ and it will look for all the files
+that were changed this year that still have the last year in the
+copyright headers, and it will fix the headers on that file using
+a perl regex one liner.
+
+For example: if it finds something like this and we're in 2014
+
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+
+it will change it to
+
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+
+It will do this for all the files in the folder and its children.
+
+Author: @gubatron
+'''
+import os
+import time
+
+year = time.gmtime()[0]
+last_year = year - 1
+command = "perl -pi -e 's/%s The Bitcoin/%s The Bitcoin/' %s"
+listFilesCommand = "find . | grep %s"
+
+extensions = [".cpp",".h"]
+
+def getLastGitModifiedDate(filePath):
+ gitGetLastCommitDateCommand = "git log " + filePath +" | grep Date | head -n 1"
+ p = os.popen(gitGetLastCommitDateCommand)
+ result = ""
+ for l in p:
+ result = l
+ break
+ result = result.replace("\n","")
+ return result
+
+n=1
+for extension in extensions:
+ foundFiles = os.popen(listFilesCommand % extension)
+ for filePath in foundFiles:
+ filePath = filePath[1:-1]
+ if filePath.endswith(extension):
+ filePath = os.getcwd() + filePath
+ modifiedTime = getLastGitModifiedDate(filePath)
+ if len(modifiedTime) > 0 and str(year) in modifiedTime:
+ print n,"Last Git Modified: ", modifiedTime, " - ", filePath
+ os.popen(command % (last_year,year,filePath))
+ n = n + 1
+
+
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
new file mode 100755
index 0000000000..ec7a1f4c4b
--- /dev/null
+++ b/contrib/devtools/github-merge.sh
@@ -0,0 +1,181 @@
+#!/bin/bash
+
+# This script will locally construct a merge commit for a pull request on a
+# github repository, inspect it, sign it and optionally push it.
+
+# The following temporary branches are created/overwritten and deleted:
+# * pull/$PULL/base (the current master we're merging onto)
+# * pull/$PULL/head (the current state of the remote pull request)
+# * pull/$PULL/merge (github's merge)
+# * pull/$PULL/local-merge (our merge)
+
+# In case of a clean merge that is accepted by the user, the local branch with
+# name $BRANCH is overwritten with the merged result, and optionally pushed.
+
+REPO="$(git config --get githubmerge.repository)"
+if [[ "d$REPO" == "d" ]]; then
+ echo "ERROR: No repository configured. Use this command to set:" >&2
+ echo "git config githubmerge.repository <owner>/<repo>" >&2
+ echo "In addition, you can set the following variables:" >&2
+ echo "- githubmerge.host (default git@github.com)" >&2
+ echo "- githubmerge.branch (default master)" >&2
+ echo "- githubmerge.testcmd (default none)" >&2
+ exit 1
+fi
+
+HOST="$(git config --get githubmerge.host)"
+if [[ "d$HOST" == "d" ]]; then
+ HOST="git@github.com"
+fi
+
+BRANCH="$(git config --get githubmerge.branch)"
+if [[ "d$BRANCH" == "d" ]]; then
+ BRANCH="master"
+fi
+
+TESTCMD="$(git config --get githubmerge.testcmd)"
+
+PULL="$1"
+
+if [[ "d$PULL" == "d" ]]; then
+ echo "Usage: $0 pullnumber [branch]" >&2
+ exit 2
+fi
+
+if [[ "d$2" != "d" ]]; then
+ BRANCH="$2"
+fi
+
+# Initialize source branches.
+git checkout -q "$BRANCH"
+if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then
+ if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then
+ echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2
+ exit 3
+ fi
+ if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then
+ echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2
+ exit 3
+ fi
+else
+ echo "ERROR: Cannot find pull request #$PULL on $HOST:$REPO." >&2
+ exit 3
+fi
+if git fetch -q "$HOST":"$REPO" +refs/heads/"$BRANCH":refs/heads/pull/"$PULL"/base; then
+ true
+else
+ echo "ERROR: Cannot find branch $BRANCH on $HOST:$REPO." >&2
+ exit 3
+fi
+git checkout -q pull/"$PULL"/base
+git branch -q -D pull/"$PULL"/local-merge 2>/dev/null
+git checkout -q -b pull/"$PULL"/local-merge
+TMPDIR="$(mktemp -d -t ghmXXXXX)"
+
+function cleanup() {
+ git checkout -q "$BRANCH"
+ git branch -q -D pull/"$PULL"/head 2>/dev/null
+ git branch -q -D pull/"$PULL"/base 2>/dev/null
+ git branch -q -D pull/"$PULL"/merge 2>/dev/null
+ git branch -q -D pull/"$PULL"/local-merge 2>/dev/null
+ rm -rf "$TMPDIR"
+}
+
+# Create unsigned merge commit.
+(
+ echo "Merge pull request #$PULL"
+ echo ""
+ git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head
+)>"$TMPDIR/message"
+if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then
+ if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then
+ echo "ERROR: Creating merge failed (already merged?)." >&2
+ cleanup
+ exit 4
+ fi
+else
+ echo "ERROR: Cannot be merged cleanly." >&2
+ git merge --abort
+ cleanup
+ exit 4
+fi
+
+# Run test command if configured.
+if [[ "d$TESTCMD" != "d" ]]; then
+ # Go up to the repository's root.
+ while [ ! -d .git ]; do cd ..; done
+ if ! $TESTCMD; then
+ echo "ERROR: Running $TESTCMD failed." >&2
+ cleanup
+ exit 5
+ fi
+ # Show the created merge.
+ git diff pull/"$PULL"/merge..pull/"$PULL"/local-merge >"$TMPDIR"/diff
+ git diff pull/"$PULL"/base..pull/"$PULL"/local-merge
+ if [[ "$(<"$TMPDIR"/diff)" != "" ]]; then
+ echo "WARNING: merge differs from github!" >&2
+ read -p "Type 'ignore' to continue. " -r >&2
+ if [[ "d$REPLY" =~ ^d[iI][gG][nN][oO][rR][eE]$ ]]; then
+ echo "Difference with github ignored." >&2
+ else
+ cleanup
+ exit 6
+ fi
+ fi
+ read -p "Press 'd' to accept the diff. " -n 1 -r >&2
+ echo
+ if [[ "d$REPLY" =~ ^d[dD]$ ]]; then
+ echo "Diff accepted." >&2
+ else
+ echo "ERROR: Diff rejected." >&2
+ cleanup
+ exit 6
+ fi
+else
+ # Verify the result.
+ 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
+ if [[ "d$REPLY" =~ ^d[Mm]$ ]]; then
+ echo "Merge accepted." >&2
+ else
+ echo "ERROR: Merge rejected." >&2
+ cleanup
+ exit 7
+ fi
+fi
+
+# Sign the merge commit.
+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 "ERROR: No GPG signing key set, not signing. Set one using:" >&2
+ echo "git config --global user.signingkey <key>" >&2
+ cleanup
+ exit 1
+ else
+ git commit -q --gpg-sign --amend --no-edit
+ fi
+else
+ echo "Not signing off on merge, exiting."
+ cleanup
+ exit 1
+fi
+
+# Clean up temporary branches, and put the result in $BRANCH.
+git checkout -q "$BRANCH"
+git reset -q --hard pull/"$PULL"/local-merge
+cleanup
+
+# Push the result.
+read -p "Type 'push' to push the result to $HOST:$REPO, branch $BRANCH. " -r >&2
+if [[ "d$REPLY" =~ ^d[Pp][Uu][Ss][Hh]$ ]]; then
+ git push "$HOST":"$REPO" refs/heads/"$BRANCH"
+fi
diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py
new file mode 100755
index 0000000000..38aaa00f31
--- /dev/null
+++ b/contrib/devtools/optimize-pngs.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+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.tostring()
+ return hashlib.sha256(data).hexdigest()
+
+#optimize png, 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
+
+pngcrush = 'pngcrush'
+git = 'git'
+folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"]
+basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
+totalSaveBytes = 0
+
+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']
+ 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. Total reduction: "+str(totalSaveBytes)+" bytes"
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
new file mode 100755
index 0000000000..fad891f800
--- /dev/null
+++ b/contrib/devtools/symbol-check.py
@@ -0,0 +1,119 @@
+#!/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.
+'''
+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
+still compatible with the minimum supported Linux distribution versions.
+
+Example usage:
+
+ find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py
+'''
+from __future__ import division, print_function
+import subprocess
+import re
+import sys
+
+# Debian 6.0.9 (Squeeze) has:
+#
+# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=g%2B%2B)
+# - libc version 2.11.3 (https://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=libc6)
+# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default&section=all&arch=any&searchon=names&keywords=libstdc%2B%2B6)
+#
+# Ubuntu 10.04.4 (Lucid Lynx) has:
+#
+# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid&section=all)
+# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid&section=all)
+# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid&section=all&arch=any&keywords=libstdc%2B%2B&searchon=names)
+#
+# Taking the minimum of these as our target.
+#
+# According to GNU ABI document (http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to:
+# GCC 4.4.0: GCC_4.4.0
+# GCC 4.4.2: GLIBCXX_3.4.13, CXXABI_1.3.3
+# (glibc) GLIBC_2_11
+#
+MAX_VERSIONS = {
+'GCC': (4,4,0),
+'CXXABI': (1,3,3),
+'GLIBCXX': (3,4,13),
+'GLIBC': (2,11)
+}
+# Ignore symbols that are exported as part of every executable
+IGNORE_EXPORTS = {
+'_edata', '_end', '_init', '__bss_start', '_fini'
+}
+READELF_CMD = '/usr/bin/readelf'
+CPPFILT_CMD = '/usr/bin/c++filt'
+
+class CPPFilt(object):
+ '''
+ Demangle C++ symbol names.
+
+ Use a pipe to the 'c++filt' command.
+ '''
+ def __init__(self):
+ self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+
+ def __call__(self, mangled):
+ self.proc.stdin.write(mangled + '\n')
+ return self.proc.stdout.readline().rstrip()
+
+ def close(self):
+ self.proc.stdin.close()
+ self.proc.stdout.close()
+ self.proc.wait()
+
+def read_symbols(executable, imports=True):
+ '''
+ Parse an ELF executable and return a list of (symbol,version) tuples
+ for dynamic, imported symbols.
+ '''
+ 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('Could not read symbols for %s: %s' % (executable, stderr.strip()))
+ syms = []
+ for line in stdout.split('\n'):
+ line = line.split()
+ if len(line)>7 and re.match('[0-9]+:$', line[0]):
+ (sym, _, version) = line[7].partition('@')
+ is_import = line[6] == 'UND'
+ if version.startswith('@'):
+ version = version[1:]
+ if is_import == imports:
+ syms.append((sym, version))
+ return syms
+
+def check_version(max_versions, version):
+ if '_' in version:
+ (lib, _, ver) = version.rpartition('_')
+ else:
+ lib = version
+ ver = '0'
+ ver = tuple([int(x) for x in ver.split('.')])
+ if not lib in max_versions:
+ return False
+ return ver <= max_versions[lib]
+
+if __name__ == '__main__':
+ cppfilt = CPPFilt()
+ retval = 0
+ for filename in sys.argv[1:]:
+ # Check imported symbols
+ for sym,version in read_symbols(filename, True):
+ if version and not check_version(MAX_VERSIONS, version):
+ print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version))
+ retval = 1
+ # Check exported symbols
+ for sym,version in read_symbols(filename, False):
+ if sym in IGNORE_EXPORTS:
+ continue
+ print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
+ retval = 1
+
+ exit(retval)
+
+
diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py
new file mode 100755
index 0000000000..f955e4a1f2
--- /dev/null
+++ b/contrib/devtools/update-translations.py
@@ -0,0 +1,186 @@
+#!/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.
+'''
+Run this script from the root of the repository to update all translations from
+transifex.
+It will do the following automatically:
+
+- fetch all translations using the tx tool
+- post-process them into valid and committable format
+ - remove invalid control characters
+ - remove location tags (makes diffs less noisy)
+
+TODO:
+- auto-add new translations to the build system according to the translation process
+'''
+from __future__ import division, print_function
+import subprocess
+import re
+import sys
+import os
+import io
+import xml.etree.ElementTree as ET
+
+# Name of transifex tool
+TX = 'tx'
+# Name of source language file
+SOURCE_LANG = 'bitcoin_en.ts'
+# Directory with locale files
+LOCALE_DIR = 'src/qt/locale'
+
+def check_at_repository_root():
+ if not os.path.exists('.git'):
+ print('No .git directory found')
+ print('Execute this script at the root of the repository', file=sys.stderr)
+ exit(1)
+
+def fetch_all_translations():
+ if subprocess.call([TX, 'pull', '-f']):
+ print('Error while fetching translations', file=sys.stderr)
+ exit(1)
+
+def find_format_specifiers(s):
+ '''Find all format specifiers in a string.'''
+ pos = 0
+ specifiers = []
+ while True:
+ percent = s.find('%', pos)
+ if percent < 0:
+ break
+ specifiers.append(s[percent+1])
+ pos = percent+2
+ return specifiers
+
+def split_format_specifiers(specifiers):
+ '''Split format specifiers between numeric (Qt) and others (strprintf)'''
+ numeric = []
+ other = []
+ for s in specifiers:
+ if s in {'1','2','3','4','5','6','7','8','9'}:
+ numeric.append(s)
+ else:
+ other.append(s)
+
+ # numeric (Qt) can be present in any order, others (strprintf) must be in specified order
+ return set(numeric),other
+
+def sanitize_string(s):
+ '''Sanitize string for printing'''
+ return s.replace('\n',' ')
+
+def check_format_specifiers(source, translation, errors):
+ source_f = split_format_specifiers(find_format_specifiers(source))
+ # assert that no source messages contain both Qt and strprintf format specifiers
+ # if this fails, go change the source as this is hacky and confusing!
+ assert(not(source_f[0] and source_f[1]))
+ try:
+ translation_f = split_format_specifiers(find_format_specifiers(translation))
+ except IndexError:
+ errors.append("Parse error in translation '%s'" % sanitize_string(translation))
+ return False
+ else:
+ if source_f != translation_f:
+ errors.append("Mismatch between '%s' and '%s'" % (sanitize_string(source), sanitize_string(translation)))
+ return False
+ return True
+
+def all_ts_files(suffix=''):
+ for filename in os.listdir(LOCALE_DIR):
+ # process only language files, and do not process source language
+ if not filename.endswith('.ts'+suffix) or filename == SOURCE_LANG+suffix:
+ continue
+ if suffix: # remove provided suffix
+ filename = filename[0:-len(suffix)]
+ filepath = os.path.join(LOCALE_DIR, filename)
+ yield(filename, filepath)
+
+FIX_RE = re.compile(b'[\x00-\x09\x0b\x0c\x0e-\x1f]')
+def remove_invalid_characters(s):
+ '''Remove invalid characters from translation string'''
+ return FIX_RE.sub(b'', s)
+
+# Override cdata escape function to make our output match Qt's (optional, just for cleaner diffs for
+# comparison, disable by default)
+_orig_escape_cdata = None
+def escape_cdata(text):
+ text = _orig_escape_cdata(text)
+ text = text.replace("'", '&apos;')
+ text = text.replace('"', '&quot;')
+ return text
+
+def postprocess_translations(reduce_diff_hacks=False):
+ print('Checking and postprocessing...')
+
+ if reduce_diff_hacks:
+ global _orig_escape_cdata
+ _orig_escape_cdata = ET._escape_cdata
+ ET._escape_cdata = escape_cdata
+
+ for (filename,filepath) in all_ts_files():
+ os.rename(filepath, filepath+'.orig')
+
+ have_errors = False
+ for (filename,filepath) in all_ts_files('.orig'):
+ # pre-fixups to cope with transifex output
+ parser = ET.XMLParser(encoding='utf-8') # need to override encoding because 'utf8' is not understood only 'utf-8'
+ with open(filepath + '.orig', 'rb') as f:
+ data = f.read()
+ # remove control characters; this must be done over the entire file otherwise the XML parser will fail
+ data = remove_invalid_characters(data)
+ tree = ET.parse(io.BytesIO(data), parser=parser)
+
+ # iterate over all messages in file
+ root = tree.getroot()
+ for context in root.findall('context'):
+ for message in context.findall('message'):
+ numerus = message.get('numerus') == 'yes'
+ source = message.find('source').text
+ translation_node = message.find('translation')
+ # pick all numerusforms
+ if numerus:
+ translations = [i.text for i in translation_node.findall('numerusform')]
+ else:
+ translations = [translation_node.text]
+
+ for translation in translations:
+ if translation is None:
+ continue
+ errors = []
+ valid = check_format_specifiers(source, translation, errors)
+
+ for error in errors:
+ print('%s: %s' % (filename, error))
+
+ if not valid: # set type to unfinished and clear string if invalid
+ translation_node.clear()
+ translation_node.set('type', 'unfinished')
+ have_errors = True
+
+ # Remove location tags
+ for location in message.findall('location'):
+ message.remove(location)
+
+ # Remove entire message if it is an unfinished translation
+ if translation_node.get('type') == 'unfinished':
+ context.remove(message)
+
+ # write fixed-up tree
+ # if diff reduction requested, replace some XML to 'sanitize' to qt formatting
+ if reduce_diff_hacks:
+ out = io.BytesIO()
+ tree.write(out, encoding='utf-8')
+ out = out.getvalue()
+ out = out.replace(b' />', b'/>')
+ with open(filepath, 'wb') as f:
+ f.write(out)
+ else:
+ tree.write(filepath, encoding='utf-8')
+ return have_errors
+
+if __name__ == '__main__':
+ check_at_repository_root()
+ fetch_all_translations()
+ postprocess_translations()
+
diff --git a/contrib/gitian-descriptors/README b/contrib/gitian-descriptors/README
deleted file mode 100644
index a2d902e210..0000000000
--- a/contrib/gitian-descriptors/README
+++ /dev/null
@@ -1,31 +0,0 @@
-Gavin's notes on getting gitian builds up and running:
-
-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.
-
-You probably need to enable hardware virtualization in your machine's BIOS.
-
-You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites:
- sudo apt-get install apache2 git apt-cacher-ng python-vm-builder qemu-kvm
-
-Sanity checks:
- sudo service apt-cacher-ng status # Should return apt-cacher-ng is running
- ls -l /dev/kvm # Should show a /dev/kvm device
-
-Once you've got the right hardware and software:
-
- git clone git://github.com/bitcoin/bitcoin.git
- git clone git://github.com/devrandom/gitian-builder.git
- mkdir gitian-builder/inputs
- wget 'http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.6.tar.gz' -O gitian-builder/inputs/miniupnpc-1.6.tar.gz
-
- cd gitian-builder
- bin/make-base-vm --arch i386
- bin/make-base-vm --arch amd64
- cd ..
-
- # To build
- cd bitcoin
- git pull
- cd ../gitian-builder
- git pull
- ./bin/gbuild --commit bitcoin=HEAD ../bitcoin/contrib/gitian.yml
diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md
new file mode 100644
index 0000000000..061b897d2a
--- /dev/null
+++ b/contrib/gitian-descriptors/README.md
@@ -0,0 +1,66 @@
+### 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.
+
+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.
+
+You probably need to enable hardware virtualization in your machine's BIOS.
+
+You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites:
+
+ sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm
+
+Sanity checks:
+
+ sudo service apt-cacher-ng status # Should return apt-cacher-ng is running
+ ls -l /dev/kvm # Should show a /dev/kvm device
+
+
+Once you've got the right hardware and software:
+
+ git clone git://github.com/bitcoin/bitcoin.git
+ git clone git://github.com/devrandom/gitian-builder.git
+ mkdir gitian-builder/inputs
+ cd gitian-builder/inputs
+
+ # Create base images
+ cd gitian-builder
+ bin/make-base-vm --suite precise --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
+ ...
+
+---------------------
+
+`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.
+
+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
+LXC running inside a virtual machine.
+
+Here's a description of Gavin's setup on OSX 10.6:
+
+1. Download and install VirtualBox from [https://www.virtualbox.org/](https://www.virtualbox.org/)
+
+2. Download the 64-bit Ubuntu Desktop 12.04 LTS .iso CD image from
+ [http://www.ubuntu.com/](http://www.ubuntu.com/)
+
+3. Run VirtualBox and create a new virtual machine, using the Ubuntu .iso (see the [VirtualBox documentation](https://www.virtualbox.org/wiki/Documentation) for details). Create it with at least 2 gigabytes of memory and a disk that is at least 20 gigabytes big.
+
+4. Inside the running Ubuntu desktop, install:
+
+ sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder
+
+5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above:
+
+ export USE_LXC=1
+ git clone git://github.com/bitcoin/bitcoin.git
+ ... etc
diff --git a/contrib/gitian-descriptors/boost-win32.yml b/contrib/gitian-descriptors/boost-win32.yml
deleted file mode 100644
index 61ea50e4fe..0000000000
--- a/contrib/gitian-descriptors/boost-win32.yml
+++ /dev/null
@@ -1,38 +0,0 @@
----
-name: "boost"
-suites:
-- "lucid"
-architectures:
-- "i386"
-packages:
-- "mingw32"
-- "faketime"
-- "zip"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "boost_1_47_0.tar.bz2"
-script: |
- TMPDIR="$HOME/tmpdir"
- mkdir -p $TMPDIR/bin/$GBUILD_BITS $TMPDIR/include
- tar xjf boost_1_47_0.tar.bz2
- cd boost_1_47_0
- echo "using gcc : 4.4 : i586-mingw32msvc-g++
- :
- <rc>i586-mingw32msvc-windres
- <archiver>i586-mingw32msvc-ar
- <cxxflags>-frandom-seed=boost1
- ;" > user-config.jam
- ./bootstrap.sh --without-icu
- ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi variant=release link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage
- for lib in chrono date_time exception filesystem graph iostreams math_c99f math_c99l math_c99 math_tr1f math_tr1l math_tr1 prg_exec_monitor program_options random regex serialization signals system test_exec_monitor thread_win32 unit_test_framework wave wserialization; do
- mkdir $lib
- (cd $lib ; ar xf ../stage/lib/libboost_${lib}-mt-s.a)
- mv $lib $TMPDIR/bin/$GBUILD_BITS
- done
- cp -a boost $TMPDIR/include
- cd $TMPDIR
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- zip -r boost-win32-1.47.0-gitian.zip *
- cp boost-win32-1.47.0-gitian.zip $OUTDIR
diff --git a/contrib/gitian-descriptors/deps-win32.yml b/contrib/gitian-descriptors/deps-win32.yml
deleted file mode 100644
index df1e3de358..0000000000
--- a/contrib/gitian-descriptors/deps-win32.yml
+++ /dev/null
@@ -1,71 +0,0 @@
----
-name: "bitcoin-deps"
-suites:
-- "lucid"
-architectures:
-- "i386"
-packages:
-- "mingw32"
-- "git-core"
-- "zip"
-- "faketime"
-- "wine"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "openssl-1.0.1b.tar.gz"
-- "db-4.8.30.NC.tar.gz"
-- "miniupnpc-1.6.tar.gz"
-- "zlib-1.2.6.tar.gz"
-- "libpng-1.5.9.tar.gz"
-- "qrencode-3.2.0.tar.bz2"
-script: |
- #
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- #
- tar xzf openssl-1.0.1b.tar.gz
- cd openssl-1.0.1b
- ./Configure --cross-compile-prefix=i586-mingw32msvc- mingw
- make
- cd ..
- #
- tar xzf db-4.8.30.NC.tar.gz
- cd db-4.8.30.NC/build_unix
- ../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include"
- make $MAKEOPTS
- cd ../..
- #
- tar xzf miniupnpc-1.6.tar.gz
- cd miniupnpc-1.6
- sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw
- sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw
- make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar
- cd ..
- mv miniupnpc-1.6 miniupnpc
- #
- tar xzf zlib-1.2.6.tar.gz
- cd zlib-1.2.6
- make -f win32/Makefile.gcc PREFIX=i586-mingw32msvc- $MAKEOPTS
- cd ..
- #
- tar xzf libpng-1.5.9.tar.gz
- cd libpng-1.5.9
- ./configure -disable-shared CC=i586-mingw32msvc-cc AR=i586-mingw32msvc-ar STRIP=i586-mingw32msvc-strip RANLIB=i586-mingw32msvc-ranlib OBJDUMP=i586-mingw32msvc-objdump LD=i586-mingw32msvc-ld LDFLAGS="-L../zlib-1.2.6/" CFLAGS="-I../zlib-1.2.6/"
- make $MAKEOPTS
- cd ..
- #
- tar xjf qrencode-3.2.0.tar.bz2
- cd qrencode-3.2.0
- ./configure CC=i586-mingw32msvc-cc AR=i586-mingw32msvc-ar STRIP=i586-mingw32msvc-strip RANLIB=i586-mingw32msvc-ranlib OBJDUMP=i586-mingw32msvc-objdump LD=i586-mingw32msvc-ld png_LIBS="../libpng-1.5.9/.libs/libpng15.a ../zlib-1.2.6/libz.a" png_CFLAGS="-I../libpng-1.5.9"
- make $MAKEOPTS
- cd ..
- #
- zip -r $OUTDIR/bitcoin-deps-0.0.4.zip \
- $(ls qrencode-*/{qrencode.h,.libs/libqrencode.{,l}a} | sort) \
- $(ls db-*/build_unix/{libdb_cxx.a,db.h,db_cxx.h,libdb.a,.libs/libdb_cxx-?.?.a} | sort) \
- $(find openssl-* -name '*.a' -o -name '*.h' | sort) \
- $(find miniupnpc -name '*.h' -o -name 'libminiupnpc.a' | sort)
- # Kill wine processes as gitian won't figure out we are done otherwise
- killall wineserver services.exe explorer.exe winedevice.exe
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
new file mode 100644
index 0000000000..dde4af3491
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -0,0 +1,118 @@
+---
+name: "bitcoin-linux-0.10"
+enable_cache: true
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "g++-multilib"
+- "git-core"
+- "pkg-config"
+- "autoconf2.13"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "binutils-gold"
+- "libstdc++6-4.6-pic"
+reference_datetime: "2013-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin.git"
+ "dir": "bitcoin"
+files: []
+script: |
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
+ CONFIGFLAGS="--enable-upnp-default --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/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/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
+ # Build dependencies for each host
+ for i in $HOSTS; do
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
+ done
+
+ # Ubuntu precise hack: Not an issue in later versions.
+ # Precise's libstdc++.a is non-pic. There's an optional libstdc++6-4.6-pic
+ # package which provides libstdc++_pic.a, but the linker can't find it.
+ # Symlink it to a path that will be included in our link-line so that the
+ # linker picks it up before the default libstdc++.a.
+ # This is only necessary for 64bit.
+ ln -s /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++_pic.a ${BASEPREFIX}/x86_64-unknown-linux-gnu/lib/libstdc++.a
+
+ # 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
+ 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}-linux64.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz
+
diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml
new file mode 100644
index 0000000000..afe03c7a22
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-osx-signer.yml
@@ -0,0 +1,37 @@
+---
+name: "bitcoin-dmg-signer"
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "libc6:i386"
+- "faketime"
+reference_datetime: "2013-06-01 00:00:00"
+remotes: []
+files:
+- "bitcoin-osx-unsigned.tar.gz"
+- "signature.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/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.tar.gz
+ ${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..61eb5b1001
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -0,0 +1,134 @@
+---
+name: "bitcoin-osx-0.10"
+enable_cache: true
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "g++"
+- "git-core"
+- "pkg-config"
+- "autoconf2.13"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "cmake"
+- "libcap-dev"
+- "libz-dev"
+- "libbz2-dev"
+reference_datetime: "2013-06-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-upnp-default --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/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/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.yml b/contrib/gitian-descriptors/gitian-win.yml
new file mode 100644
index 0000000000..2d72f7b6e5
--- /dev/null
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -0,0 +1,115 @@
+---
+name: "bitcoin-win-0.10"
+enable_cache: true
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "g++"
+- "git-core"
+- "pkg-config"
+- "autoconf2.13"
+- "libtool"
+- "automake"
+- "faketime"
+- "bsdmainutils"
+- "mingw-w64"
+- "g++-mingw-w64"
+- "nsis"
+- "zip"
+reference_datetime: "2013-06-01 00:00:00"
+remotes:
+- "url": "https://github.com/bitcoin/bitcoin.git"
+ "dir": "bitcoin"
+files: []
+script: |
+ WRAP_DIR=$HOME/wrapped
+ HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
+ CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports"
+ FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
+ FAKETIME_PROGS="date makensis zip"
+
+ 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/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/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
+ # 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 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
+ mkdir -p $OUTDIR/src
+ mv $SOURCEDIST $OUTDIR/src
+ 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/gitian-win32.yml b/contrib/gitian-descriptors/gitian-win32.yml
deleted file mode 100644
index 9752626d6a..0000000000
--- a/contrib/gitian-descriptors/gitian-win32.yml
+++ /dev/null
@@ -1,74 +0,0 @@
----
-name: "bitcoin"
-suites:
-- "lucid"
-architectures:
-- "i386"
-packages:
-- "mingw32"
-- "git-core"
-- "unzip"
-- "nsis"
-- "faketime"
-reference_datetime: "2011-01-30 00:00:00"
-remotes:
-- "url": "https://github.com/bitcoin/bitcoin.git"
- "dir": "bitcoin"
-files:
-- "qt-win32-4.7.4-gitian.zip"
-- "boost-win32-1.47.0-gitian.zip"
-- "bitcoin-deps-0.0.4.zip"
-script: |
- #
- mkdir $HOME/qt
- cd $HOME/qt
- unzip ../build/qt-win32-4.7.4-gitian.zip
- cd $HOME/build/
- export PATH=$PATH:$HOME/qt/bin/
- #
- mkdir boost_1_47_0
- cd boost_1_47_0
- mkdir -p stage/lib
- unzip ../boost-win32-1.47.0-gitian.zip
- cd bin/$GBUILD_BITS
- for lib in *; do
- i586-mingw32msvc-ar rc ../../stage/lib/libboost_${lib}-mt-s.a $lib/*.o
- i586-mingw32msvc-ranlib ../../stage/lib/libboost_${lib}-mt-s.a
- done
- cd ../..
- mv include/boost .
- cd ..
- #
- unzip bitcoin-deps-0.0.4.zip
- #
- find -type f | xargs touch --date="$REFERENCE_DATETIME"
- #
- cd bitcoin
- mkdir -p $OUTDIR/src
- git archive HEAD | tar -x -C $OUTDIR/src
- cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt
- cp $OUTDIR/src/COPYING $OUTDIR/license.txt
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- $HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.1b OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.1b/include QRENCODE_LIB_PATH=$HOME/build/qrencode-3.2.0/.libs QRENCODE_INCLUDE_PATH=$HOME/build/qrencode-3.2.0 USE_QRCODE=1 INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin USE_BUILD_INFO=1
- make $MAKEOPTS
- cp release/bitcoin-qt.exe $OUTDIR/
- #
- cd src
- export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0 DEBUGFLAGS="-frandom-seed=bitcoin"
- i586-mingw32msvc-strip bitcoind.exe
- mkdir $OUTDIR/daemon
- cp bitcoind.exe $OUTDIR/daemon
- cd ..
- mkdir nsis
- git archive HEAD | tar -x -C nsis
- cd nsis/src
- mkdir ../release
- cp ../../release/* ../release/
- cp ../../src/*.exe .
- makensis ../share/setup.nsi
- cp ../share/bitcoin-*-win32-setup.exe $OUTDIR/
diff --git a/contrib/gitian-descriptors/gitian.yml b/contrib/gitian-descriptors/gitian.yml
deleted file mode 100644
index 8243c5c301..0000000000
--- a/contrib/gitian-descriptors/gitian.yml
+++ /dev/null
@@ -1,55 +0,0 @@
----
-name: "bitcoin"
-suites:
-- "lucid"
-architectures:
-- "i386"
-- "amd64"
-packages:
-- "libdb4.8++-dev"
-- "qt4-qmake"
-- "libqt4-dev"
-- "libboost-system-dev"
-- "libboost-filesystem-dev"
-- "libboost-program-options-dev"
-- "libboost-thread-dev"
-- "libssl-dev"
-- "git-core"
-- "unzip"
-- "pkg-config"
-- "libpng12-dev"
-reference_datetime: "2011-01-30 00:00:00"
-remotes:
-- "url": "https://github.com/bitcoin/bitcoin.git"
- "dir": "bitcoin"
-files:
-- "miniupnpc-1.6.tar.gz"
-- "qrencode-3.2.0.tar.bz2"
-script: |
- INSTDIR="$HOME/install"
- export LIBRARY_PATH="$INSTDIR/lib"
- #
- tar xzf miniupnpc-1.6.tar.gz
- cd miniupnpc-1.6
- INSTALLPREFIX=$INSTDIR make $MAKEOPTS install
- cd ..
- #
- tar xjf qrencode-3.2.0.tar.bz2
- cd qrencode-3.2.0
- ./configure --prefix=$INSTDIR --enable-static --disable-shared
- make $MAKEOPTS install
- cd ..
- #
- cd bitcoin
- mkdir -p $OUTDIR/src
- git archive HEAD | tar -x -C $OUTDIR/src
- cp $OUTDIR/src/doc/README $OUTDIR
- cp $OUTDIR/src/COPYING $OUTDIR
- cd src
- make -f makefile.unix STATIC=1 OPENSSL_INCLUDE_PATH="$INSTDIR/include" OPENSSL_LIB_PATH="$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0 DEBUGFLAGS=
- mkdir -p $OUTDIR/bin/$GBUILD_BITS
- install -s bitcoind $OUTDIR/bin/$GBUILD_BITS
- cd ..
- qmake INCLUDEPATH="$INSTDIR/include" LIBS="-L$INSTDIR/lib" RELEASE=1 USE_QRCODE=1
- make $MAKEOPTS
- install bitcoin-qt $OUTDIR/bin/$GBUILD_BITS
diff --git a/contrib/gitian-descriptors/qt-win32.yml b/contrib/gitian-descriptors/qt-win32.yml
deleted file mode 100644
index 6eb76b2170..0000000000
--- a/contrib/gitian-descriptors/qt-win32.yml
+++ /dev/null
@@ -1,54 +0,0 @@
----
-name: "qt"
-suites:
-- "lucid"
-architectures:
-- "i386"
-packages:
-- "mingw32"
-- "zip"
-- "faketime"
-reference_datetime: "2011-01-30 00:00:00"
-remotes: []
-files:
-- "qt-everywhere-opensource-src-4.7.4.tar.gz"
-script: |
- INSTDIR="$HOME/qt/"
- mkdir $INSTDIR
- SRCDIR="$INSTDIR/src/"
- mkdir $SRCDIR
- #
- tar xzf qt-everywhere-opensource-src-4.7.4.tar.gz
- cd qt-everywhere-opensource-src-4.7.4
- sed 's/$TODAY/2011-01-30/' -i configure
- sed 's/i686-pc-mingw32-/i586-mingw32msvc-/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- sed --posix 's|QMAKE_CFLAGS\t\t= -pipe|QMAKE_CFLAGS\t\t= -pipe -isystem /usr/i586-mingw32msvc/include/ -frandom-seed=qtbuild|' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- sed 's/QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads/QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- sed 's/QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads/QMAKE_LFLAGS_EXCEPTIONS_ON = -lmingwthrd/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- sed --posix 's/QMAKE_MOC\t\t= i586-mingw32msvc-moc/QMAKE_MOC\t\t= moc/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- sed --posix 's/QMAKE_RCC\t\t= i586-mingw32msvc-rcc/QMAKE_RCC\t\t= rcc/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- sed --posix 's/QMAKE_UIC\t\t= i586-mingw32msvc-uic/QMAKE_UIC\t\t= uic/' -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- # ar adds timestamps to every object file included in the static library
- # providing -D as ar argument is supposed to solve it, but doesn't work as qmake strips off the arguments and adds -M to pass a script...
- # which somehow cannot be combined with other flags.
- # use faketime only for ar, as it confuses make/qmake into hanging sometimes
- sed --posix "s|QMAKE_LIB\t\t= i586-mingw32msvc-ar -ru|QMAKE_LIB\t\t= $HOME/ar -Dr|" -i mkspecs/unsupported/win32-g++-cross/qmake.conf
- echo '#!/bin/bash' > $HOME/ar
- echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ar
- echo 'i586-mingw32msvc-ar "$@"' >> $HOME/ar
- chmod +x $HOME/ar
- #export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
- export FAKETIME=$REFERENCE_DATETIME
- export TZ=UTC
- ./configure -prefix $INSTDIR -confirm-license -release -opensource -static -no-qt3support -xplatform unsupported/win32-g++-cross -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 -opengl no -nomake examples -nomake demos -nomake docs
- find . -name *.prl | xargs -l sed 's|/\.||' -i
- find . -name *.prl | xargs -l sed 's|/$||' -i
- make $MAKEOPTS install
- cp -a bin $SRCDIR/
- cd $INSTDIR
- find . -name *.prl | xargs -l sed 's|/$||' -i
- #sed 's|QMAKE_PRL_LIBS.*|QMAKE_PRL_LIBS = -lQtDeclarative -lQtScript -lQtSvg -lQtSql -lQtXmlPatterns -lQtGui -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lmsimg32 -lQtNetwork -lQtCore -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32|' -i imports/Qt/labs/particles/qmlparticlesplugin.prl
-
- # 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
- zip -r $OUTDIR/qt-win32-4.7.4-gitian.zip *
diff --git a/contrib/gitian-downloader/aschildbach-key.pgp b/contrib/gitian-downloader/aschildbach-key.pgp
new file mode 100644
index 0000000000..df06e19fa4
--- /dev/null
+++ b/contrib/gitian-downloader/aschildbach-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/cfields-key.pgp b/contrib/gitian-downloader/cfields-key.pgp
new file mode 100644
index 0000000000..6b0bd240ba
--- /dev/null
+++ b/contrib/gitian-downloader/cfields-key.pgp
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+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
+MrD0ofsytfy1LQ==
+=DE4h
+-----END PGP PUBLIC KEY BLOCK-----
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..fe44c0fbd4
--- /dev/null
+++ b/contrib/gitian-downloader/jonasschnelli-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/linux-download-config b/contrib/gitian-downloader/linux-download-config
index aef614d0ca..f5e6382b84 100644
--- a/contrib/gitian-downloader/linux-download-config
+++ b/contrib/gitian-downloader/linux-download-config
@@ -8,31 +8,35 @@ rss:
pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip
signers:
0A82509767C7D4A5D14DA2301AE1D35043E08E54:
- weight: 40
name: BlueMatt
key: bluematt
BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
- weight: 40
name: Devrandom
key: devrandom
E463A93F5F3117EEDE6C7316BD02942421F4889F:
- weight: 40
name: Luke-Jr
key: luke-jr
D762373D24904A3E42F33B08B9A408E71DAAC974:
- weight: 40
name: "Pieter Wuille"
key: sipa
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
- weight: 40
name: tcatm
key: tcatm
01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
- weight: 40
name: "Gavin Andresen"
key: gavinandresen
71A3B16735405025D447E8F274810B012346C9A6:
- weight: 40
name: "Wladimir J. van der Laan"
key: laanwj
-minimum_weight: 120
+ 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/michagogo-key.pgp b/contrib/gitian-downloader/michagogo-key.pgp
new file mode 100644
index 0000000000..47bc404554
--- /dev/null
+++ b/contrib/gitian-downloader/michagogo-key.pgp
@@ -0,0 +1,59 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (GNU/Linux)
+
+mQENBFGeqJ4BCADb7SI3/+q93gIvN0AGRg9Mtz73OLIOzCHeeoyn+tp7JcYNzxkQ
+9lfeXiEfn72Sh8gHkLtLIqr7HlIMo8DxSS8JPRVjlJGkNyAW4SeEwN2wNa5OV8k0
+N4jBa9a1csFyCyrEkPKvkUpBkQDvNXjNxyEhHwyZqPanKxy6NXIHOJji8ObOMQXI
+T9HwJrpjRth3u4uKG968JBTEyAXAmkt0Zidl1Ykgzcedk4mJSE9uZCW8DjSv2wML
+XcQz8+dYsoskT3KRdkowLHxAfj1BNyNc1+rKLghliM5vSQWi+Lbhi1Bxh4sY1UwA
+lKnAGqrnAGyIvCtkwTq5QI6ufF2ZY44bvVgpABEBAAG0IU1pY2hhZ29nbyA8bWlj
+aGFnb2dvQHNlcnZlci5mYWtlPokBOAQTAQIAIgUCUZ6ongIbAwYLCQgHAwIGFQgC
+CQoLBBYCAwECHgECF4AACgkQgsXACWKOzwzMUAgAuqUmK10xE5C3lUym2f72z0t6
+a2NM5Wfjr9//Y1/okC36C5XAMEtN2UwckPzzJ5p5D5y5yzwfZq5Jd8Py29VQIMsV
+7FbC1a0H3D+bCyX+JJ6FAmUbnWOQ/+mydYc74RvD8iwjePNT6kziZNv6dMGctJTl
+0alwjtQYgyGkeYKnIxbcyjHX/IawLUrunb/6mSKun87T8+NM/omfFCTc3l8TakpM
+0wyNYRiUkIfUBvB8sDUU3A80qKN/hqRKvlFu3+/kMiAc9ZYQrbmsB+sYWdmM+4zw
+8NBw3yuYzWyPuoa4PR5ZmS9F11WLMR5vTRCdLudAqYsWu3LtV6vAIvlOUa2LMLRg
+TWljaGFnb2dvIChSZWdpc3RlcmVkIG5pY2sgbWljaGFnb2dvIG9uIGZyZWVub2Rl
+IGFzIG9mIE9jdG9iZXIgMTIsIDIwMTMpIDxtaWNoYWdvZ29Ac2VydmVyLmZha2U+
+iQE4BBMBAgAiBQJSWarzAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCC
+xcAJYo7PDA7nB/91wAiaMlU5nHLUu0anhNQbGvUdFgKK1zO90S5KzUdJcY438jcS
+UJW1az8l9U9JBRIfPRYVhz/Z1TAJ+dCzD7D8BXHFeGEr0zNOh87ly9aB5du7dpN2
+oSBD6wLcJpqxt4h+XjSS2CX98/2ZIJxXENE2KySaTXP39Xl3eNwvJTUBA4XlcMey
+J8KMp/IERli4H0O7vRyLgu3yYpUArTqAonzG1g2lfB35PQJfeInrRSniQ336otnZ
+A8qwJ63kfUtWVDRz0g1fnvtiLGPivDJaI5hyIaUeJPaXU1+sg7YNroDu60o2NGZh
+F+0IjHlvRfzzA+F9Vw38rpSqR3BmCdjf6Sv3iQEcBBABAgAGBQJSWa9/AAoJEH+r
+EUJn5PoE/hgH/1T2dAthVucA/hzY0nl4SMjbg+dzNlYBq00Qwx8DRKVjk5et8+kY
+oPI3DGILcr+ELnxNekeMv9WQBBtJanUh1K5ohZ6ohoR7lG18LXf5HCdspflB5Me6
+LMA6iMryEP6gIs9GFuoGe2YQavm58YrkqhcPu34dGN7kdurfEXLvDfVlh5ZbKCsP
+Gyd7Pbz04SpqykgK1udiTsLVjc70Xhv+jAMqeaCugDX6TLEwjVmZH/xsyKk2Uh3V
+Oib5FXADAtKH+vSqqhFpXrw7R/NaBzvCbas8l61DFHiUg1/bo8vsV8MtGcyZmzXJ
+C5Gm0njtGOil/g7JF9siUrpxs9Yyt/h+T2W0W01pY2hhZ29nbyAoVXNlciBhY2Nv
+dW50IG1pY2hhZ29nbyBvbiBHaXRodWIgYXMgb2YgT2N0b2JlciAxMiwgMjAxMykg
+PG1pY2hhZ29nb0BzZXJ2ZXIuZmFrZT6JATcEEwECACIFAlJZqxkCGwMGCwkIBwMC
+BhUIAgkKCwQWAgMBAh4BAheAAAoJEILFwAlijs8M+1AH+IU78ARblqTnJeSl0iWH
+mEsg4IBK30Q6/exDAcqOEm1Yc171uw2WnGmIvPYOQqxrRTvj3LoQ816dU6jrj6vY
+s+XX0R2hxy7ILh17D/3UKnHcddu7rmc7pNEqZeBXaMughqQaPOWkAIe52+qK5tsl
+sWllzTYE4jo29uZ3dAtDcKEJjBo/pIXnu1GOslE1+V4X1H9WDlwrS/JXHzyDQAjt
+maPR+3gNesDanhrRmrnT3ZXW2ZVd3vGBibhia8PWUhU1uwOH23ySWXncgsHH0Zad
+UMjd4w3YliZP/mLn2ghAxHB70IO7lgAgN3HYZeFoufP3pcK440A+CezfQiRcjHl/
+oIkBHAQQAQIABgUCUlmvfwAKCRB/qxFCZ+T6BOq9CACItsrUZPKGeWSTkMHknMrV
+K5vxIXJVCBb+Tppc0Q/J5p4EkW/RFhTwIP2zw8NLDKMh5oO9md4LXhvfIZkqQJFo
+6ZtLa3Vf+Kj7uyxezBo4QHA+G7tDsRGaMKVrEMiyLCwS1+hg9VaNzsf7zmQW7mYE
+vTLMHp3cVaSU7Mh2Dl8rnAaM/DpTUZQwZ+32Qrb/Z4HSa4f278iqoFpjEbBE2KCr
+vT5yEVvpCZ4lwSgA2a+uTlRTvVV6NA/kpsxU64tmhuEOjy+ToDqJ8wv4mqvWZxMv
+C6OhfVaXBy3U9gG8aQV0ffXGs+TbCtv8ApHd6E1/AVk0oyZGJaBVrEl688bBIWd/
+uQENBFGeqJ4BCADFmgR7oEGkFFB5qXnuNYFq1nUGDAh0dLNtAD3J6EMxUZEXdmp+
+DQHJw6/eDRQaG9EbjNZheycbVUoI8K2Y/Z268HQueGuIEIJv6cZYXoXdWCbDD4fn
+HMNUX2wNlpDqWxb7PNUEtfU9hI3gmHGlr5OiEh3iV06uiZg4n2rbWPbj45m5LJzv
+wpCrUA+pLcl9Xjw2cajaSTjdXHk9gvXTCo6s2ZS3/3Q4l+xuzZp1MGNzPQHASMKs
+wecSJKkYg6W8I5WsVlPd9a8oQCc/Nfz7BPw31MRVR/SF5FAMqaXx5uLwghVdHB2i
+cLURsOtJlCfP8W06gB7yS+MH45Jq/oxBRiJBABEBAAGJAR8EGAECAAkFAlGeqJ4C
+GwwACgkQgsXACWKOzwwT4wgAy6ICcnBZ9l2jSu+ldy57F6jf5kpKZgB9NV8V2mMA
+NeY1wMQ4VTVpU4t3s4E2LYtGNJNkPQVHbt1Pf4dGPasvMPaHMamgwgyqgYixqs0x
+D5PdKzVrfnjwTTr/ZAFdccSPmvy5/hbY0geQ/+mzdbL07+xaT58JIoG5nySDKhmC
+VeOvhDZtXMVAhEWBDPEgh/H9sEuBgMgZrzfE1j3q802qiXeQs6WtadWlQ1RN9Iq1
+ZzIi6u9/BifEIRI0pO/WwKOZdXLTemFUoakoe7uT3A74N96t0G9LZVihYbEoO+Pc
+5IaHPBV5VLeR3TB1LnnjHVf/Fwi8cnGy50kNWjcbMyEDag==
+=jyQ4
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/sipa-key.pgp b/contrib/gitian-downloader/sipa-key.pgp
index a52a5deb1b..ffa09bb4ad 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
index 0f7032e643..06c164180d 100644
--- a/contrib/gitian-downloader/win32-download-config
+++ b/contrib/gitian-downloader/win32-download-config
@@ -8,31 +8,35 @@ rss:
pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip
signers:
0A82509767C7D4A5D14DA2301AE1D35043E08E54:
- weight: 40
name: BlueMatt
key: bluematt
BF6273FAEF7CC0BA1F562E50989F6B3048A116B5:
- weight: 40
name: Devrandom
key: devrandom
E463A93F5F3117EEDE6C7316BD02942421F4889F:
- weight: 40
name: Luke-Jr
key: luke-jr
D762373D24904A3E42F33B08B9A408E71DAAC974:
- weight: 40
name: "Pieter Wuille"
key: sipa
77E72E69DA7EE0A148C06B21B34821D4944DE5F7:
- weight: 40
name: tcatm
key: tcatm
01CDF4627A3B88AAE4A571C87588242FBE38D3A8:
- weight: 40
name: "Gavin Andresen"
key: gavinandresen
71A3B16735405025D447E8F274810B012346C9A6:
- weight: 40
name: "Wladimir J. van der Laan"
key: laanwj
-minimum_weight: 120
+ 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/wtogami-key.pgp b/contrib/gitian-downloader/wtogami-key.pgp
new file mode 100644
index 0000000000..e0f6c4c5fd
--- /dev/null
+++ b/contrib/gitian-downloader/wtogami-key.pgp
@@ -0,0 +1,131 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.13 (GNU/Linux)
+
+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
+=icdI
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/init/README.md b/contrib/init/README.md
new file mode 100644
index 0000000000..0d19da3039
--- /dev/null
+++ b/contrib/init/README.md
@@ -0,0 +1,11 @@
+Sample configuration files for:
+
+SystemD: bitcoind.service
+Upstart: bitcoind.conf
+OpenRC: bitcoind.openrc
+ bitcoind.openrcconf
+CentOS: bitcoind.init
+
+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..a94f03680d
--- /dev/null
+++ b/contrib/init/bitcoind.openrc
@@ -0,0 +1,88 @@
+#!/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}"
+retry=60
+
+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..d8d7f58337
--- /dev/null
+++ b/contrib/init/bitcoind.openrcconf
@@ -0,0 +1,27 @@
+# /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"
+
diff --git a/contrib/init/bitcoind.service b/contrib/init/bitcoind.service
new file mode 100644
index 0000000000..9132957c38
--- /dev/null
+++ b/contrib/init/bitcoind.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=Bitcoin's distributed currency daemon
+After=network.target
+
+[Service]
+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/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/linearize/README.md b/contrib/linearize/README.md
new file mode 100644
index 0000000000..157586e4d4
--- /dev/null
+++ b/contrib/linearize/README.md
@@ -0,0 +1,33 @@
+# Linearize
+Construct a linear, no-fork, best version of the blockchain.
+
+## Step 1: Download hash list
+
+ $ ./linearize-hashes.py linearize.cfg > hashlist.txt
+
+Required configuration file settings for linearize-hashes:
+* RPC: rpcuser, rpcpassword
+
+Optional config file setting for linearize-hashes:
+* RPC: host, port
+* Block chain: min_height, max_height
+
+## Step 2: Copy local block data
+
+ $ ./linearize-data.py linearize.cfg
+
+Required configuration file settings:
+* "input": bitcoind blocks/ directory containing blkNNNNN.dat
+* "hashlist": text file containing list of block hashes, linearized-hashes.py
+output.
+* "output_file": bootstrap.dat
+ or
+* "output": output directory for linearized blocks/blkNNNNN.dat output
+
+Optional config file setting for linearize-data:
+* "netmagic": network magic number
+* "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
new file mode 100644
index 0000000000..38da02e66c
--- /dev/null
+++ b/contrib/linearize/example-linearize.cfg
@@ -0,0 +1,29 @@
+
+# bitcoind RPC settings (linearize-hashes)
+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
new file mode 100755
index 0000000000..7947c6bf72
--- /dev/null
+++ b/contrib/linearize/linearize-data.py
@@ -0,0 +1,301 @@
+#!/usr/bin/python
+#
+# linearize-data.py: Construct a linear, no-fork version of the chain.
+#
+# 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 base64
+import httplib
+import sys
+import hashlib
+import datetime
+import time
+from collections import namedtuple
+
+settings = {}
+
+def uint32(x):
+ return x & 0xffffffffL
+
+def bytereverse(x):
+ return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
+ (((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
+
+def bufreverse(in_buf):
+ out_words = []
+ for i in range(0, len(in_buf), 4):
+ word = struct.unpack('@I', in_buf[i:i+4])[0]
+ out_words.append(struct.pack('@I', bytereverse(word)))
+ return ''.join(out_words)
+
+def wordreverse(in_buf):
+ out_words = []
+ for i in range(0, len(in_buf), 4):
+ out_words.append(in_buf[i:i+4])
+ out_words.reverse()
+ return ''.join(out_words)
+
+def calc_hdr_hash(blk_hdr):
+ hash1 = hashlib.sha256()
+ hash1.update(blk_hdr)
+ hash1_o = hash1.digest()
+
+ hash2 = hashlib.sha256()
+ hash2.update(hash1_o)
+ hash2_o = hash2.digest()
+
+ return hash2_o
+
+def calc_hash_str(blk_hdr):
+ hash = calc_hdr_hash(blk_hdr)
+ hash = bufreverse(hash)
+ hash = wordreverse(hash)
+ hash_str = hash.encode('hex')
+ return hash_str
+
+def get_blk_dt(blk_hdr):
+ members = struct.unpack("<I", blk_hdr[68:68+4])
+ 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 = []
+ f = open(settings['hashlist'], "r")
+ for line in f:
+ line = line.rstrip()
+ blkindex.append(line)
+
+ print("Read " + str(len(blkindex)) + " hashes")
+
+ return blkindex
+
+def mkblockmap(blkindex):
+ blkmap = {}
+ for height,hash in enumerate(blkindex):
+ blkmap[hash] = height
+ return blkmap
+
+# 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):
+ if not self.fileOutput and ((self.outsz + self.inLen) > self.maxOutSz):
+ self.outF.close()
+ if self.setFileTime:
+ os.utime(outFname, (int(time.time()), highTS))
+ self.outF = None
+ self.outFname = None
+ self.outFn = 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:
+ outFname = "%s/blk%05d.dat" % (self.settings['output'], 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 "%s/blk%05d.dat" % (self.settings['input'], 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")
+ sys.exit(1)
+
+ f = open(sys.argv[1])
+ for line in f:
+ # skip comment lines
+ m = re.search('^\s*#', line)
+ if m:
+ continue
+
+ # parse key=value lines
+ m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
+ if m is None:
+ continue
+ settings[m.group(1)] = m.group(2)
+ f.close()
+
+ 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 '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_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)
+ blkmap = mkblockmap(blkindex)
+
+ if not settings['genesis'] in blkmap:
+ print("Genesis block not found in hashlist")
+ else:
+ BlockDataCopier(settings, blkindex, blkmap).run()
+
+
diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py
new file mode 100755
index 0000000000..854cf1f9ee
--- /dev/null
+++ b/contrib/linearize/linearize-hashes.py
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+#
+# linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
+#
+# 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
+import base64
+import httplib
+import sys
+
+settings = {}
+
+class BitcoinRPC:
+ 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 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", file=sys.stderr)
+ return None
+
+ body = resp.read()
+ resp_obj = json.loads(body)
+ return resp_obj
+
+ @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, max_blocks_per_call=10000):
+ rpc = BitcoinRPC(settings['host'], settings['port'],
+ settings['rpcuser'], settings['rpcpassword'])
+
+ 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'])
+
+ height += num_blocks
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print("Usage: linearize-hashes.py CONFIG-FILE")
+ sys.exit(1)
+
+ f = open(sys.argv[1])
+ for line in f:
+ # skip comment lines
+ m = re.search('^\s*#', line)
+ if m:
+ continue
+
+ # parse key=value lines
+ m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
+ if m is None:
+ continue
+ settings[m.group(1)] = m.group(2)
+ f.close()
+
+ if 'host' not in settings:
+ settings['host'] = '127.0.0.1'
+ if 'port' not in settings:
+ settings['port'] = 8332
+ if 'min_height' not in settings:
+ settings['min_height'] = 0
+ 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", file=stderr)
+ sys.exit(1)
+
+ settings['port'] = int(settings['port'])
+ settings['min_height'] = int(settings['min_height'])
+ settings['max_height'] = int(settings['max_height'])
+
+ get_block_hashes(settings)
+
diff --git a/contrib/macdeploy/DS_Store b/contrib/macdeploy/DS_Store
new file mode 100644
index 0000000000..ca19b207c0
--- /dev/null
+++ b/contrib/macdeploy/DS_Store
Binary files differ
diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md
new file mode 100644
index 0000000000..6163734e62
--- /dev/null
+++ b/contrib/macdeploy/README.md
@@ -0,0 +1,15 @@
+### MacDeploy ###
+
+For Snow Leopard (which uses [Python 2.6](http://www.python.org/download/releases/2.6/)), you will need the param_parser package:
+
+ sudo easy_install argparse
+
+This script should not be run manually, instead, after building as usual:
+
+ make deploy
+
+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-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..169f690438
--- /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}
+tar -C ${TEMPDIR} -xf ${SIGNATURE}
+
+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..fd7314bd7e
--- /dev/null
+++ b/contrib/macdeploy/detached-sig-create.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+set -e
+
+ROOTDIR=dist
+BUNDLE="${ROOTDIR}/Bitcoin Core.app"
+CODESIGN=codesign
+TEMPDIR=sign.temp
+TEMPLIST=${TEMPDIR}/signatures.txt
+OUT=signature.tar.gz
+
+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}/${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}/${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..a333f5dccd 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>
@@ -22,7 +22,7 @@
<integer>370</integer>
<integer>156</integer>
</array>
- <key>Bitcoin-Qt.app</key>
+ <key>Bitcoin Core.app</key>
<array>
<integer>128</integer>
<integer>156</integer>
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
index e159f9bbc3..a625987ca7 100755
--- a/contrib/macdeploy/macdeployqtplus
+++ b/contrib/macdeploy/macdeployqtplus
@@ -17,8 +17,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import subprocess, sys, re, os, shutil, stat, os.path
-from time import sleep
+import subprocess, sys, re, os, shutil, stat, os.path, time
+from string import Template
from argparse import ArgumentParser
# This is ported from the original macdeployqt with modifications
@@ -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)
@@ -169,7 +176,12 @@ class DeploymentInfo(object):
elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")):
# MacPorts layout, e.g. "/opt/local/share/qt4"
self.qtPath = os.path.join(parentDir, "share", "qt4")
-
+ elif os.path.exists(os.path.join(os.path.dirname(parentDir), "share", "qt4", "translations")):
+ # Newer Macports layout
+ self.qtPath = os.path.join(os.path.dirname(parentDir), "share", "qt4")
+ else:
+ self.qtPath = os.getenv("QTDIR", None)
+
if self.qtPath is not None:
pluginPath = os.path.join(self.qtPath, "plugins")
if os.path.exists(pluginPath):
@@ -190,7 +202,8 @@ class DeploymentInfo(object):
def getFrameworks(binaryPath, verbose):
if verbose >= 3:
print "Inspecting with otool: " + binaryPath
- otool = subprocess.Popen(["otool", "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ otoolbin=os.getenv("OTOOL", "otool")
+ otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
o_stdout, o_stderr = otool.communicate()
if otool.returncode != 0:
if verbose >= 1:
@@ -205,6 +218,7 @@ def getFrameworks(binaryPath, verbose):
libraries = []
for line in otoolLines:
+ line = line.replace("@loader_path", os.path.dirname(binaryPath))
info = FrameworkInfo.fromOtoolLibraryLine(line.strip())
if info is not None:
if verbose >= 3:
@@ -215,7 +229,8 @@ def getFrameworks(binaryPath, verbose):
return libraries
def runInstallNameTool(action, *args):
- subprocess.check_call(["install_name_tool", "-"+action] + list(args))
+ installnametoolbin=os.getenv("INSTALLNAMETOOL", "install_name_tool")
+ subprocess.check_call([installnametoolbin, "-"+action] + list(args))
def changeInstallName(oldName, newName, binaryPath, verbose):
if verbose >= 3:
@@ -233,13 +248,18 @@ def changeIdentification(id, binaryPath, verbose):
runInstallNameTool("id", id, binaryPath)
def runStrip(binaryPath, verbose):
+ stripbin=os.getenv("STRIP", "strip")
if verbose >= 3:
print "Using strip:"
print " stripped", binaryPath
- subprocess.check_call(["strip", "-x", binaryPath])
+ subprocess.check_call([stripbin, "-x", binaryPath])
def copyFramework(framework, path, verbose):
- fromPath = framework.sourceFilePath
+ if framework.sourceFilePath.startswith("Qt"):
+ #standard place for Nokia Qt installer's frameworks
+ fromPath = "/Library/Frameworks/" + framework.sourceFilePath
+ else:
+ fromPath = framework.sourceFilePath
toDir = os.path.join(path, framework.destinationDirectory)
toPath = os.path.join(toDir, framework.binaryName)
@@ -262,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
@@ -295,7 +332,7 @@ def deployFrameworks(frameworks, bundlePath, binaryPath, strip, verbose, deploym
if deploymentInfo.qtPath is None and framework.isQtFramework():
deploymentInfo.detectQtPath(framework.frameworkDirectory)
- if framework.installName.startswith("@executable_path"):
+ if framework.installName.startswith("@executable_path") or framework.installName.startswith(bundlePath):
if verbose >= 2:
print framework.frameworkName, "already deployed, skipping."
continue
@@ -337,12 +374,14 @@ def deployFrameworksForAppBundle(applicationBundle, strip, verbose):
def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
# Lookup available plugins, exclude unneeded
plugins = []
+ if deploymentInfo.pluginPath is None:
+ return
for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath):
pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath)
if pluginDirectory == "designer":
# Skip designer plugins
continue
- elif pluginDirectory == "phonon":
+ elif pluginDirectory == "phonon" or pluginDirectory == "phonon_backend":
# Deploy the phonon plugins only if phonon is in use
if not deploymentInfo.usesFramework("phonon"):
continue
@@ -354,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
@@ -362,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"):
@@ -380,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:
@@ -411,8 +470,8 @@ def deployPlugins(appBundleInfo, deploymentInfo, strip, verbose):
deployFrameworks([dependency], appBundleInfo.path, destinationPath, strip, verbose, deploymentInfo)
qt_conf="""[Paths]
-translations=Resources
-plugins=PlugIns
+Translations=Resources
+Plugins=PlugIns
"""
ap = ArgumentParser(description="""Improved version of macdeployqt.
@@ -420,15 +479,21 @@ ap = ArgumentParser(description="""Improved version of macdeployqt.
Outputs a ready-to-deploy app in a folder "dist" and optionally wraps it in a .dmg file.
Note, that the "dist" folder will be deleted before deploying on each run.
-Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.""")
+Optionally, Qt translation files (.qm) and additional resources can be added to the bundle.
+
+Also optionally signs the .app bundle; set the CODESIGNARGS environment variable to pass arguments
+to the codesign tool.
+E.g. CODESIGNARGS='--sign "Developer ID Application: ..." --keychain /encrypted/foo.keychain'""")
ap.add_argument("app_bundle", nargs=1, metavar="app-bundle", help="application bundle to be deployed")
ap.add_argument("-verbose", type=int, nargs=1, default=[1], metavar="<0-3>", help="0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug")
ap.add_argument("-no-plugins", dest="plugins", action="store_false", default=True, help="skip plugin deployment")
ap.add_argument("-no-strip", dest="strip", action="store_false", default=True, help="don't run 'strip' on the binaries")
+ap.add_argument("-sign", dest="sign", action="store_true", default=False, help="sign .app bundle with codesign tool")
ap.add_argument("-dmg", nargs="?", const="", metavar="basename", help="create a .dmg disk image; if basename is not specified, a camel-cased version of the app name is used")
ap.add_argument("-fancy", nargs=1, metavar="plist", default=[], help="make a fancy looking disk image using the given plist file with instructions; requires -dmg to work")
ap.add_argument("-add-qt-tr", nargs=1, metavar="languages", default=[], help="add Qt translation files to the bundle's ressources; the language list must be separated with commas, not with whitespace")
+ap.add_argument("-translations-dir", nargs=1, metavar="path", default=None, help="Path to Qt's translation files")
ap.add_argument("-add-resources", nargs="+", metavar="path", default=[], help="list of additional files or folders to be copied into the bundle's resources; must be the last argument")
config = ap.parse_args()
@@ -447,6 +512,15 @@ if not os.path.exists(app_bundle):
app_bundle_name = os.path.splitext(os.path.basename(app_bundle))[0]
# ------------------------------------------------
+translations_dir = None
+if config.translations_dir and config.translations_dir[0]:
+ if os.path.exists(config.translations_dir[0]):
+ translations_dir = config.translations_dir[0]
+ else:
+ if verbose >= 1:
+ sys.stderr.write("Error: Could not find translation dir \"%s\"\n" % (translations_dir))
+ sys.exit(1)
+# ------------------------------------------------
for p in config.add_resources:
if verbose >= 3:
@@ -468,16 +542,6 @@ if len(config.fancy) == 1:
sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n")
sys.exit(1)
- if verbose >= 3:
- print "Fancy: Importing appscript..."
- try:
- import appscript
- except ImportError:
- if verbose >= 1:
- sys.stderr.write("Error: Could not import appscript which is required for fancy disk images.\n")
- sys.stderr.write("Please install it e.g. with \"sudo easy_install appscript\".\n")
- sys.exit(1)
-
p = config.fancy[0]
if verbose >= 3:
print "Fancy: Loading \"%s\"..." % p
@@ -532,7 +596,7 @@ if os.path.exists("dist"):
# ------------------------------------------------
-target = os.path.join("dist", app_bundle)
+target = os.path.join("dist", "Bitcoin Core.app")
if verbose >= 2:
print "+ Copying source bundle +"
@@ -540,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)
@@ -560,7 +624,7 @@ try:
except RuntimeError as e:
if verbose >= 1:
sys.stderr.write("Error: %s\n" % str(e))
- sys.exit(ret)
+ sys.exit(1)
# ------------------------------------------------
@@ -573,14 +637,21 @@ if config.plugins:
except RuntimeError as e:
if verbose >= 1:
sys.stderr.write("Error: %s\n" % str(e))
- sys.exit(ret)
+ sys.exit(1)
# ------------------------------------------------
if len(config.add_qt_tr) == 0:
add_qt_tr = []
else:
- qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations")
+ if translations_dir is not None:
+ qt_tr_dir = translations_dir
+ else:
+ if deploymentInfo.qtPath is not None:
+ qt_tr_dir = os.path.join(deploymentInfo.qtPath, "translations")
+ else:
+ sys.stderr.write("Error: Could not find Qt translation path\n")
+ sys.exit(1)
add_qt_tr = ["qt_%s.qm" % lng for lng in config.add_qt_tr[0].split(",")]
for lng_file in add_qt_tr:
p = os.path.join(qt_tr_dir, lng_file)
@@ -620,13 +691,39 @@ 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)
# ------------------------------------------------
+if config.sign and 'CODESIGNARGS' not in os.environ:
+ print "You must set the CODESIGNARGS environment variable. Skipping signing."
+elif config.sign:
+ if verbose >= 1:
+ print "Code-signing app bundle %s"%(target,)
+ subprocess.check_call("codesign --force %s %s"%(os.environ['CODESIGNARGS'], target), shell=True)
+
+# ------------------------------------------------
+
if config.dmg is not None:
+
+ #Patch in check_output for Python 2.6
+ if "check_output" not in dir( subprocess ):
+ def f(*popenargs, **kwargs):
+ if 'stdout' in kwargs:
+ raise ValueError('stdout argument not allowed, it will be overridden.')
+ process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
+ output, unused_err = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ raise CalledProcessError(retcode, cmd)
+ return output
+ subprocess.check_output = f
+
def runHDIUtil(verb, image_basename, **kwargs):
hdiutil_args = ["hdiutil", verb, image_basename + ".dmg"]
if kwargs.has_key("capture_stdout"):
@@ -670,7 +767,7 @@ 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..."
@@ -694,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)
@@ -704,33 +802,71 @@ if config.dmg is not None:
if fancy.get("applications_symlink", False):
os.symlink("/Applications", os.path.join(disk_root, "Applications"))
- finder = appscript.app("Finder")
- disk = finder.disks[disk_name]
- disk.open()
- window = disk.container_window
- window.current_view.set(appscript.k.icon_view)
- window.toolbar_visible.set(False)
- window.statusbar_visible.set(False)
- if fancy.has_key("window_bounds"):
- window.bounds.set(fancy["window_bounds"])
- view_options = window.icon_view_options
- view_options.arrangement.set(appscript.k.not_arranged)
- if fancy.has_key("icon_size"):
- view_options.icon_size.set(fancy["icon_size"])
- if bg_path is not None:
- view_options.background_picture.set(disk.files[os.path.basename(bg_path)])
+ # The Python appscript package broke with OSX 10.8 and isn't being fixed.
+ # So we now build up an AppleScript string and use the osascript command
+ # to make the .dmg file pretty:
+ appscript = Template( """
+ on run argv
+ tell application "Finder"
+ tell disk "$disk"
+ open
+ set current view of container window to icon view
+ set toolbar visible of container window to false
+ set statusbar visible of container window to false
+ set the bounds of container window to {$window_bounds}
+ set theViewOptions to the icon view options of container window
+ set arrangement of theViewOptions to not arranged
+ set icon size of theViewOptions to $icon_size
+ $background_commands
+ $items_positions
+ close -- close/reopen works around a bug...
+ open
+ update without registering applications
+ delay 5
+ eject
+ end tell
+ end tell
+ end run
+ """)
+
+ itemscript = Template('set position of item "${item}" of container window to {${position}}')
+ items_positions = []
if fancy.has_key("items_position"):
for name, position in fancy["items_position"].iteritems():
- window.items[name].position.set(position)
- disk.close()
+ params = { "item" : name, "position" : ",".join([str(p) for p in position]) }
+ items_positions.append(itemscript.substitute(params))
+
+ params = {
+ "disk" : "Bitcoin-Core",
+ "window_bounds" : "300,300,800,620",
+ "icon_size" : "96",
+ "background_commands" : "",
+ "items_positions" : "\n ".join(items_positions)
+ }
+ if fancy.has_key("window_bounds"):
+ params["window.bounds"] = ",".join([str(p) for p in fancy["window_bounds"]])
+ if fancy.has_key("icon_size"):
+ params["icon_size"] = str(fancy["icon_size"])
if bg_path is not None:
- subprocess.call(["SetFile", "-a", "V", bg_path])
- disk.update(registering_applications=False)
- sleep(2)
- disk.eject()
-
+ # 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 ".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)
+ if verbose >= 2:
+ print("Running AppleScript:")
+ print(s)
+
+ p = subprocess.Popen(['osascript', '-'], stdin=subprocess.PIPE)
+ p.communicate(input=s)
+ if p.returncode:
+ print("Error running osascript.")
+
if verbose >= 2:
print "+ Finalizing .dmg disk image +"
+ time.sleep(5)
try:
runHDIUtil("convert", dmg_name + ".temp", format="UDBZ", o=dmg_name + ".dmg", ov=True)
diff --git a/contrib/macdeploy/notes.txt b/contrib/macdeploy/notes.txt
deleted file mode 100644
index a3f0b5447d..0000000000
--- a/contrib/macdeploy/notes.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-
-macdeployqtplus works best on OS X Lion, for Snow Leopard you'd need to install
-Python 2.7 and make it your default Python installation.
-
-You will need the appscript package for the fancy disk image creation to work.
-Install it by invoking "sudo easy_install appscript".
-
-Ths script should be invoked in the target directory like this:
-$source_dir/contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist -verbose 2
-
-During the process, the disk image window will pop up briefly where the fancy
-settings are applied. This is normal, please do not interfere.
-
-You can also set up Qt Creator for invoking the script. For this, go to the
-"Projects" tab on the left side, switch to "Run Settings" above and add a
-deploy configuration. Next add a deploy step choosing "Custom Process Step".
-Fill in the following.
-
-Enable custom process step: [x]
-Command: %{sourceDir}/contrib/macdeploy/macdeployqtplus
-Working directory: %{buildDir}
-Command arguments: Bitcoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2
-
-After that you can start the deployment process through the menu with
-Build -> Deploy Project "bitcoin-qt"
-
diff --git a/contrib/pyminer/README b/contrib/pyminer/README
deleted file mode 100644
index d1596575dd..0000000000
--- a/contrib/pyminer/README
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a 'getwork' CPU mining client for bitcoin.
-
-It is pure-python, and therefore very, very slow. The purpose is to
-provide a reference implementation of a miner, for study.
-
diff --git a/contrib/pyminer/example-config.cfg b/contrib/pyminer/example-config.cfg
deleted file mode 100644
index 103e7c1372..0000000000
--- a/contrib/pyminer/example-config.cfg
+++ /dev/null
@@ -1,32 +0,0 @@
-
-#
-# RPC login details
-#
-host=127.0.0.1
-port=8332
-
-rpcuser=myusername
-rpcpass=mypass
-
-
-#
-# mining details
-#
-
-threads=4
-
-# periodic rate for requesting new work, if solution not found
-scantime=60
-
-
-#
-# misc.
-#
-
-# not really used right now
-logdir=/tmp/pyminer
-
-# set to 1, to enable hashmeter output
-hashmeter=0
-
-
diff --git a/contrib/pyminer/pyminer.py b/contrib/pyminer/pyminer.py
deleted file mode 100755
index 2887aba591..0000000000
--- a/contrib/pyminer/pyminer.py
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (c) 2011 The Bitcoin developers
-# Distributed under the MIT/X11 software license, see the accompanying
-# file license.txt or http://www.opensource.org/licenses/mit-license.php.
-#
-
-import time
-import json
-import pprint
-import hashlib
-import struct
-import re
-import base64
-import httplib
-import sys
-from multiprocessing import Process
-
-ERR_SLEEP = 15
-MAX_NONCE = 1000000L
-
-settings = {}
-pp = pprint.PrettyPrinter(indent=4)
-
-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
- 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"
- 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['result']
- def getblockcount(self):
- return self.rpc('getblockcount')
- def getwork(self, data=None):
- return self.rpc('getwork', data)
-
-def uint32(x):
- return x & 0xffffffffL
-
-def bytereverse(x):
- return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) |
- (((x) >> 8) & 0x0000ff00) | ((x) >> 24) ))
-
-def bufreverse(in_buf):
- out_words = []
- for i in range(0, len(in_buf), 4):
- word = struct.unpack('@I', in_buf[i:i+4])[0]
- out_words.append(struct.pack('@I', bytereverse(word)))
- return ''.join(out_words)
-
-def wordreverse(in_buf):
- out_words = []
- for i in range(0, len(in_buf), 4):
- out_words.append(in_buf[i:i+4])
- out_words.reverse()
- return ''.join(out_words)
-
-class Miner:
- def __init__(self, id):
- self.id = id
- self.max_nonce = MAX_NONCE
-
- def work(self, datastr, targetstr):
- # decode work data hex string to binary
- static_data = datastr.decode('hex')
- static_data = bufreverse(static_data)
-
- # the first 76b of 80b do not change
- blk_hdr = static_data[:76]
-
- # decode 256-bit target value
- targetbin = targetstr.decode('hex')
- targetbin = targetbin[::-1] # byte-swap and dword-swap
- targetbin_str = targetbin.encode('hex')
- target = long(targetbin_str, 16)
-
- # pre-hash first 76b of block header
- static_hash = hashlib.sha256()
- static_hash.update(blk_hdr)
-
- for nonce in xrange(self.max_nonce):
-
- # encode 32-bit nonce value
- nonce_bin = struct.pack("<I", nonce)
-
- # hash final 4b, the nonce value
- hash1_o = static_hash.copy()
- hash1_o.update(nonce_bin)
- hash1 = hash1_o.digest()
-
- # sha256 hash of sha256 hash
- hash_o = hashlib.sha256()
- hash_o.update(hash1)
- hash = hash_o.digest()
-
- # quick test for winning solution: high 32 bits zero?
- if hash[-4:] != '\0\0\0\0':
- continue
-
- # convert binary hash to 256-bit Python long
- hash = bufreverse(hash)
- hash = wordreverse(hash)
-
- hash_str = hash.encode('hex')
- l = long(hash_str, 16)
-
- # proof-of-work test: hash < target
- if l < target:
- print time.asctime(), "PROOF-OF-WORK found: %064x" % (l,)
- return (nonce + 1, nonce_bin)
- else:
- print time.asctime(), "PROOF-OF-WORK false positive %064x" % (l,)
-# return (nonce + 1, nonce_bin)
-
- return (nonce + 1, None)
-
- def submit_work(self, rpc, original_data, nonce_bin):
- nonce_bin = bufreverse(nonce_bin)
- nonce = nonce_bin.encode('hex')
- solution = original_data[:152] + nonce + original_data[160:256]
- param_arr = [ solution ]
- result = rpc.getwork(param_arr)
- print time.asctime(), "--> Upstream RPC result:", result
-
- def iterate(self, rpc):
- work = rpc.getwork()
- if work is None:
- time.sleep(ERR_SLEEP)
- return
- if 'data' not in work or 'target' not in work:
- time.sleep(ERR_SLEEP)
- return
-
- time_start = time.time()
-
- (hashes_done, nonce_bin) = self.work(work['data'],
- work['target'])
-
- time_end = time.time()
- time_diff = time_end - time_start
-
- self.max_nonce = long(
- (hashes_done * settings['scantime']) / time_diff)
- if self.max_nonce > 0xfffffffaL:
- self.max_nonce = 0xfffffffaL
-
- if settings['hashmeter']:
- print "HashMeter(%d): %d hashes, %.2f Khash/sec" % (
- self.id, hashes_done,
- (hashes_done / 1000.0) / time_diff)
-
- if nonce_bin is not None:
- self.submit_work(rpc, work['data'], nonce_bin)
-
- def loop(self):
- rpc = BitcoinRPC(settings['host'], settings['port'],
- settings['rpcuser'], settings['rpcpass'])
- if rpc is None:
- return
-
- while True:
- self.iterate(rpc)
-
-def miner_thread(id):
- miner = Miner(id)
- miner.loop()
-
-if __name__ == '__main__':
- if len(sys.argv) != 2:
- print "Usage: pyminer.py CONFIG-FILE"
- sys.exit(1)
-
- f = open(sys.argv[1])
- for line in f:
- # skip comment lines
- m = re.search('^\s*#', line)
- if m:
- continue
-
- # parse key=value lines
- m = re.search('^(\w+)\s*=\s*(\S.*)$', line)
- if m is None:
- continue
- settings[m.group(1)] = m.group(2)
- f.close()
-
- if 'host' not in settings:
- settings['host'] = '127.0.0.1'
- if 'port' not in settings:
- settings['port'] = 8332
- if 'threads' not in settings:
- settings['threads'] = 1
- if 'hashmeter' not in settings:
- settings['hashmeter'] = 0
- if 'scantime' not in settings:
- settings['scantime'] = 30L
- if 'rpcuser' not in settings or 'rpcpass' not in settings:
- print "Missing username and/or password in cfg file"
- sys.exit(1)
-
- settings['port'] = int(settings['port'])
- settings['threads'] = int(settings['threads'])
- settings['hashmeter'] = int(settings['hashmeter'])
- settings['scantime'] = long(settings['scantime'])
-
- thr_list = []
- for thr_id in range(settings['threads']):
- p = Process(target=miner_thread, args=(thr_id,))
- p.start()
- thr_list.append(p)
- time.sleep(1) # stagger threads
-
- print settings['threads'], "mining threads started"
-
- print time.asctime(), "Miner Starts - %s:%s" % (settings['host'], settings['port'])
- try:
- for thr_proc in thr_list:
- thr_proc.join()
- except KeyboardInterrupt:
- pass
- print time.asctime(), "Miner Stops - %s:%s" % (settings['host'], settings['port'])
-
diff --git a/contrib/qos/README.md b/contrib/qos/README.md
new file mode 100644
index 0000000000..5e0a975fc6
--- /dev/null
+++ b/contrib/qos/README.md
@@ -0,0 +1,5 @@
+### Qos ###
+
+This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. It limits outbound TCP traffic with a source or destination port of 8333, but not if the destination IP is within a LAN (defined as 192.168.x.x).
+
+This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it.
diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh
new file mode 100644
index 0000000000..f620604212
--- /dev/null
+++ b/contrib/qos/tc.sh
@@ -0,0 +1,41 @@
+#network interface on which to limit traffic
+IF="eth0"
+#limit of the network interface in question
+LINKCEIL="1gbit"
+#limit outbound Bitcoin protocol traffic to this rate
+LIMIT="160kbit"
+#defines the address space for which you wish to disable rate limiting
+LOCALNET="192.168.0.0/16"
+
+#delete existing rules
+tc qdisc del dev ${IF} root
+
+#add root class
+tc qdisc add dev ${IF} root handle 1: htb default 10
+
+#add parent class
+tc class add dev ${IF} parent 1: classid 1:1 htb rate ${LINKCEIL} ceil ${LINKCEIL}
+
+#add our two classes. one unlimited, another limited
+tc class add dev ${IF} parent 1:1 classid 1:10 htb rate ${LINKCEIL} ceil ${LINKCEIL} prio 0
+tc class add dev ${IF} parent 1:1 classid 1:11 htb rate ${LIMIT} ceil ${LIMIT} prio 1
+
+#add handles to our classes so packets marked with <x> go into the class with "... handle <x> fw ..."
+tc filter add dev ${IF} parent 1: protocol ip prio 1 handle 1 fw classid 1:10
+tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11
+
+#delete any existing rules
+#disable for now
+#ret=0
+#while [ $ret -eq 0 ]; do
+# iptables -t mangle -D OUTPUT 1
+# ret=$?
+#done
+
+#limit outgoing traffic to and from port 8333. but not when dealing with a host on the local network
+# (defined by $LOCALNET)
+# --set-mark marks packages matching these criteria with the number "2"
+# these packages are filtered by the tc filter with "handle 2"
+# this filter sends the packages into the 1:11 class, and this class is limited to ${LIMIT}
+iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8333 ! -d ${LOCALNET} -j MARK --set-mark 0x2
+iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8333 ! -d ${LOCALNET} -j MARK --set-mark 0x2
diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md
new file mode 100644
index 0000000000..bc88201f0f
--- /dev/null
+++ b/contrib/seeds/README.md
@@ -0,0 +1,8 @@
+### Seeds ###
+
+Utility to generate the seeds.txt list that is compiled into the client
+(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and [share/seeds](/share/seeds)).
+
+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 | makeseeds.py
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
new file mode 100755
index 0000000000..b831395f2c
--- /dev/null
+++ b/contrib/seeds/makeseeds.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+#
+# Generate seeds.txt from Pieter's DNS seeder
+#
+
+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
+import dns.resolver
+
+PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):8333$")
+PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$")
+
+def parseline(line):
+ sline = line.split()
+ if len(sline) < 11:
+ return None
+ # Match only IPv4
+ m = PATTERN_IPV4.match(sline[0])
+ if m is None:
+ return None
+ # Do IPv4 sanity check
+ ip = 0
+ for i in range(0,4):
+ 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:
+ return None
+ # 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 {
+ 'ip': m.group(1),
+ 'ipnum': ip,
+ 'uptime': uptime30,
+ 'lastsuccess': lastsuccess,
+ 'version': version,
+ 'agent': agent,
+ 'service': service,
+ 'blocks': blocks,
+ }
+
+# Based on Greg Maxwell's seed_filter.py
+def filterbyasn(ips, max_per_asn, max_total):
+ result = []
+ asn_count = {}
+ for ip in ips:
+ 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')
+ return result
+
+def main():
+ lines = sys.stdin.readlines()
+ ips = [parseline(line) for line in lines]
+
+ # Skip entries with valid IPv4 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)
+ # 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['ipnum']))
+
+ for ip in ips:
+ print ip['ip']
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/spendfrom/README.md b/contrib/spendfrom/README.md
new file mode 100644
index 0000000000..c0a9c9ccf9
--- /dev/null
+++ b/contrib/spendfrom/README.md
@@ -0,0 +1,35 @@
+### SpendFrom ###
+
+Use the raw transactions API to send coins received on a particular
+address (or addresses).
+
+### Usage: ###
+Depends on [jsonrpc](http://json-rpc.org/).
+
+ spendfrom.py --from=FROMADDRESS1[,FROMADDRESS2] --to=TOADDRESS --amount=amount \
+ --fee=fee --datadir=/path/to/.bitcoin --testnet --dry_run
+
+With no arguments, outputs a list of amounts associated with addresses.
+
+With arguments, sends coins received by the `FROMADDRESS` addresses to the `TOADDRESS`.
+
+### Notes ###
+
+- You may explicitly specify how much fee to pay (a fee more than 1% of the amount
+will fail, though, to prevent bitcoin-losing accidents). Spendfrom may fail if
+it thinks the transaction would never be confirmed (if the amount being sent is
+too small, or if the transaction is too many bytes for the fee).
+
+- If a change output needs to be created, the change will be sent to the last
+`FROMADDRESS` (if you specify just one `FROMADDRESS`, change will go back to it).
+
+- If `--datadir` is not specified, the default datadir is used.
+
+- The `--dry_run` option will just create and sign the transaction and print
+the transaction data (as hexadecimal), instead of broadcasting it.
+
+- If the transaction is created and broadcast successfully, a transaction id
+is printed.
+
+- If this was a tool for end-users and not programmers, it would have much friendlier
+error-handling.
diff --git a/contrib/spendfrom/setup.py b/contrib/spendfrom/setup.py
new file mode 100644
index 0000000000..01b9768a5b
--- /dev/null
+++ b/contrib/spendfrom/setup.py
@@ -0,0 +1,9 @@
+from distutils.core import setup
+setup(name='btcspendfrom',
+ version='1.0',
+ description='Command-line utility for bitcoin "coin control"',
+ author='Gavin Andresen',
+ author_email='gavin@bitcoinfoundation.org',
+ requires=['jsonrpc'],
+ scripts=['spendfrom.py'],
+ )
diff --git a/contrib/spendfrom/spendfrom.py b/contrib/spendfrom/spendfrom.py
new file mode 100755
index 0000000000..72ee0425eb
--- /dev/null
+++ b/contrib/spendfrom/spendfrom.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+#
+# Use the raw transactions API to spend bitcoins received on particular addresses,
+# and send any change back to that same address.
+#
+# Example usage:
+# spendfrom.py # Lists available funds
+# spendfrom.py --from=ADDRESS --to=ADDRESS --amount=11.00
+#
+# Assumes it will talk to a bitcoind or Bitcoin-Qt running
+# on localhost.
+#
+# Depends on jsonrpc
+#
+
+from decimal import *
+import getpass
+import math
+import os
+import os.path
+import platform
+import sys
+import time
+from jsonrpc import ServiceProxy, json
+
+BASE_FEE=Decimal("0.001")
+
+def check_json_precision():
+ """Make sure json library being used does not lose precision converting BTC values"""
+ n = Decimal("20000000.00000003")
+ satoshis = int(json.loads(json.dumps(float(n)))*1.0e8)
+ if satoshis != 2000000000000003:
+ raise RuntimeError("JSON encode/decode loses precision")
+
+def determine_db_dir():
+ """Return the default location of the bitcoin data directory"""
+ if platform.system() == "Darwin":
+ return os.path.expanduser("~/Library/Application Support/Bitcoin/")
+ elif platform.system() == "Windows":
+ return os.path.join(os.environ['APPDATA'], "Bitcoin")
+ return os.path.expanduser("~/.bitcoin")
+
+def read_bitcoin_config(dbdir):
+ """Read the bitcoin.conf file from dbdir, returns dictionary of settings"""
+ from ConfigParser import SafeConfigParser
+
+ class FakeSecHead(object):
+ def __init__(self, fp):
+ self.fp = fp
+ self.sechead = '[all]\n'
+ def readline(self):
+ if self.sechead:
+ try: return self.sechead
+ finally: self.sechead = None
+ else:
+ s = self.fp.readline()
+ if s.find('#') != -1:
+ s = s[0:s.find('#')].strip() +"\n"
+ return s
+
+ config_parser = SafeConfigParser()
+ config_parser.readfp(FakeSecHead(open(os.path.join(dbdir, "bitcoin.conf"))))
+ return dict(config_parser.items("all"))
+
+def connect_JSON(config):
+ """Connect to a bitcoin JSON-RPC server"""
+ testnet = config.get('testnet', '0')
+ testnet = (int(testnet) > 0) # 0/1 in config file, convert to True/False
+ if not 'rpcport' in config:
+ config['rpcport'] = 18332 if testnet else 8332
+ connect = "http://%s:%s@127.0.0.1:%s"%(config['rpcuser'], config['rpcpassword'], config['rpcport'])
+ try:
+ result = ServiceProxy(connect)
+ # ServiceProxy is lazy-connect, so send an RPC command mostly to catch connection errors,
+ # but also make sure the bitcoind we're talking to is/isn't testnet:
+ if result.getmininginfo()['testnet'] != testnet:
+ sys.stderr.write("RPC server at "+connect+" testnet setting mismatch\n")
+ sys.exit(1)
+ return result
+ except:
+ sys.stderr.write("Error connecting to RPC server at "+connect+"\n")
+ sys.exit(1)
+
+def unlock_wallet(bitcoind):
+ info = bitcoind.getinfo()
+ if 'unlocked_until' not in info:
+ return True # wallet is not encrypted
+ t = int(info['unlocked_until'])
+ if t <= time.time():
+ try:
+ passphrase = getpass.getpass("Wallet is locked; enter passphrase: ")
+ bitcoind.walletpassphrase(passphrase, 5)
+ except:
+ sys.stderr.write("Wrong passphrase\n")
+
+ info = bitcoind.getinfo()
+ return int(info['unlocked_until']) > time.time()
+
+def list_available(bitcoind):
+ address_summary = dict()
+
+ address_to_account = dict()
+ for info in bitcoind.listreceivedbyaddress(0):
+ address_to_account[info["address"]] = info["account"]
+
+ unspent = bitcoind.listunspent(0)
+ for output in unspent:
+ # listunspent doesn't give addresses, so:
+ rawtx = bitcoind.getrawtransaction(output['txid'], 1)
+ vout = rawtx["vout"][output['vout']]
+ pk = vout["scriptPubKey"]
+
+ # This code only deals with ordinary pay-to-bitcoin-address
+ # or pay-to-script-hash outputs right now; anything exotic is ignored.
+ if pk["type"] != "pubkeyhash" and pk["type"] != "scripthash":
+ continue
+
+ address = pk["addresses"][0]
+ if address in address_summary:
+ address_summary[address]["total"] += vout["value"]
+ address_summary[address]["outputs"].append(output)
+ else:
+ address_summary[address] = {
+ "total" : vout["value"],
+ "outputs" : [output],
+ "account" : address_to_account.get(address, "")
+ }
+
+ return address_summary
+
+def select_coins(needed, inputs):
+ # Feel free to improve this, this is good enough for my simple needs:
+ outputs = []
+ have = Decimal("0.0")
+ n = 0
+ while have < needed and n < len(inputs):
+ outputs.append({ "txid":inputs[n]["txid"], "vout":inputs[n]["vout"]})
+ have += inputs[n]["amount"]
+ n += 1
+ return (outputs, have-needed)
+
+def create_tx(bitcoind, fromaddresses, toaddress, amount, fee):
+ all_coins = list_available(bitcoind)
+
+ total_available = Decimal("0.0")
+ needed = amount+fee
+ potential_inputs = []
+ for addr in fromaddresses:
+ if addr not in all_coins:
+ continue
+ potential_inputs.extend(all_coins[addr]["outputs"])
+ total_available += all_coins[addr]["total"]
+
+ if total_available < needed:
+ sys.stderr.write("Error, only %f BTC available, need %f\n"%(total_available, needed));
+ sys.exit(1)
+
+ #
+ # Note:
+ # Python's json/jsonrpc modules have inconsistent support for Decimal numbers.
+ # Instead of wrestling with getting json.dumps() (used by jsonrpc) to encode
+ # Decimals, I'm casting amounts to float before sending them to bitcoind.
+ #
+ outputs = { toaddress : float(amount) }
+ (inputs, change_amount) = select_coins(needed, potential_inputs)
+ if change_amount > BASE_FEE: # don't bother with zero or tiny change
+ change_address = fromaddresses[-1]
+ if change_address in outputs:
+ outputs[change_address] += float(change_amount)
+ else:
+ outputs[change_address] = float(change_amount)
+
+ rawtx = bitcoind.createrawtransaction(inputs, outputs)
+ signed_rawtx = bitcoind.signrawtransaction(rawtx)
+ if not signed_rawtx["complete"]:
+ sys.stderr.write("signrawtransaction failed\n")
+ sys.exit(1)
+ txdata = signed_rawtx["hex"]
+
+ return txdata
+
+def compute_amount_in(bitcoind, txinfo):
+ result = Decimal("0.0")
+ for vin in txinfo['vin']:
+ in_info = bitcoind.getrawtransaction(vin['txid'], 1)
+ vout = in_info['vout'][vin['vout']]
+ result = result + vout['value']
+ return result
+
+def compute_amount_out(txinfo):
+ result = Decimal("0.0")
+ for vout in txinfo['vout']:
+ result = result + vout['value']
+ return result
+
+def sanity_test_fee(bitcoind, txdata_hex, max_fee):
+ class FeeError(RuntimeError):
+ pass
+ try:
+ txinfo = bitcoind.decoderawtransaction(txdata_hex)
+ total_in = compute_amount_in(bitcoind, txinfo)
+ total_out = compute_amount_out(txinfo)
+ if total_in-total_out > max_fee:
+ raise FeeError("Rejecting transaction, unreasonable fee of "+str(total_in-total_out))
+
+ tx_size = len(txdata_hex)/2
+ kb = tx_size/1000 # integer division rounds down
+ if kb > 1 and fee < BASE_FEE:
+ raise FeeError("Rejecting no-fee transaction, larger than 1000 bytes")
+ if total_in < 0.01 and fee < BASE_FEE:
+ raise FeeError("Rejecting no-fee, tiny-amount transaction")
+ # Exercise for the reader: compute transaction priority, and
+ # warn if this is a very-low-priority transaction
+
+ except FeeError as err:
+ sys.stderr.write((str(err)+"\n"))
+ sys.exit(1)
+
+def main():
+ import optparse
+
+ parser = optparse.OptionParser(usage="%prog [options]")
+ parser.add_option("--from", dest="fromaddresses", default=None,
+ help="addresses to get bitcoins from")
+ parser.add_option("--to", dest="to", default=None,
+ help="address to get send bitcoins to")
+ parser.add_option("--amount", dest="amount", default=None,
+ help="amount to send")
+ parser.add_option("--fee", dest="fee", default="0.0",
+ help="fee to include")
+ parser.add_option("--datadir", dest="datadir", default=determine_db_dir(),
+ help="location of bitcoin.conf file with RPC username/password (default: %default)")
+ parser.add_option("--testnet", dest="testnet", default=False, action="store_true",
+ help="Use the test network")
+ parser.add_option("--dry_run", dest="dry_run", default=False, action="store_true",
+ help="Don't broadcast the transaction, just create and print the transaction data")
+
+ (options, args) = parser.parse_args()
+
+ check_json_precision()
+ config = read_bitcoin_config(options.datadir)
+ if options.testnet: config['testnet'] = True
+ bitcoind = connect_JSON(config)
+
+ if options.amount is None:
+ address_summary = list_available(bitcoind)
+ for address,info in address_summary.iteritems():
+ n_transactions = len(info['outputs'])
+ if n_transactions > 1:
+ print("%s %.8f %s (%d transactions)"%(address, info['total'], info['account'], n_transactions))
+ else:
+ print("%s %.8f %s"%(address, info['total'], info['account']))
+ else:
+ fee = Decimal(options.fee)
+ amount = Decimal(options.amount)
+ while unlock_wallet(bitcoind) == False:
+ pass # Keep asking for passphrase until they get it right
+ txdata = create_tx(bitcoind, options.fromaddresses.split(","), options.to, amount, fee)
+ sanity_test_fee(bitcoind, txdata, amount*Decimal("0.01"))
+ if options.dry_run:
+ print(txdata)
+ else:
+ txid = bitcoind.sendrawtransaction(txdata)
+ print(txid)
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/test-patches/README.md b/contrib/test-patches/README.md
new file mode 100644
index 0000000000..def40b0d6c
--- /dev/null
+++ b/contrib/test-patches/README.md
@@ -0,0 +1,7 @@
+### 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
new file mode 100644
index 0000000000..1cd043d0d7
--- /dev/null
+++ b/contrib/test-patches/temp-revert-2.patch
@@ -0,0 +1,20 @@
+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/testgen/README.md b/contrib/testgen/README.md
new file mode 100644
index 0000000000..83624f443a
--- /dev/null
+++ b/contrib/testgen/README.md
@@ -0,0 +1,8 @@
+### TestGen ###
+
+Utilities to generate test vectors for the data-driven Bitcoin tests.
+
+Usage:
+
+ gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json
+ gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json \ No newline at end of file
diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py
new file mode 100644
index 0000000000..b716495145
--- /dev/null
+++ b/contrib/testgen/base58.py
@@ -0,0 +1,104 @@
+'''
+Bitcoin base58 encoding and decoding.
+
+Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain)
+'''
+import hashlib
+
+# for compatibility with following code...
+class SHA256:
+ new = hashlib.sha256
+
+if str != bytes:
+ # Python 3.x
+ def ord(c):
+ return c
+ def chr(n):
+ return bytes( (n,) )
+
+__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
+__b58base = len(__b58chars)
+b58chars = __b58chars
+
+def b58encode(v):
+ """ encode v, which is a string of bytes, to base58.
+ """
+ long_value = 0
+ for (i, c) in enumerate(v[::-1]):
+ long_value += (256**i) * ord(c)
+
+ result = ''
+ while long_value >= __b58base:
+ div, mod = divmod(long_value, __b58base)
+ result = __b58chars[mod] + result
+ long_value = div
+ result = __b58chars[long_value] + result
+
+ # Bitcoin does a little leading-zero-compression:
+ # leading 0-bytes in the input become leading-1s
+ nPad = 0
+ for c in v:
+ if c == '\0': nPad += 1
+ else: break
+
+ return (__b58chars[0]*nPad) + result
+
+def b58decode(v, length = None):
+ """ decode v into a string of len bytes
+ """
+ long_value = 0
+ for (i, c) in enumerate(v[::-1]):
+ long_value += __b58chars.find(c) * (__b58base**i)
+
+ result = bytes()
+ while long_value >= 256:
+ div, mod = divmod(long_value, 256)
+ result = chr(mod) + result
+ long_value = div
+ result = chr(long_value) + result
+
+ nPad = 0
+ for c in v:
+ if c == __b58chars[0]: nPad += 1
+ else: break
+
+ result = chr(0)*nPad + result
+ if length is not None and len(result) != length:
+ return None
+
+ return result
+
+def checksum(v):
+ """Return 32-bit checksum based on SHA256"""
+ return SHA256.new(SHA256.new(v).digest()).digest()[0:4]
+
+def b58encode_chk(v):
+ """b58encode a string, with 32-bit checksum"""
+ return b58encode(v + checksum(v))
+
+def b58decode_chk(v):
+ """decode a base58 string, check and remove checksum"""
+ result = b58decode(v)
+ if result is None:
+ return None
+ h3 = checksum(result[:-4])
+ if result[-4:] == checksum(result[:-4]):
+ return result[:-4]
+ else:
+ return None
+
+def get_bcaddress_version(strAddress):
+ """ Returns None if strAddress is invalid. Otherwise returns integer version of address. """
+ addr = b58decode_chk(strAddress)
+ if addr is None or len(addr)!=21: return None
+ version = addr[0]
+ return ord(version)
+
+if __name__ == '__main__':
+ # Test case (from http://gitorious.org/bitcoin/python-base58.git)
+ assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') is 0
+ _ohai = 'o hai'.encode('ascii')
+ _tmp = b58encode(_ohai)
+ assert _tmp == 'DYB3oMS'
+ assert b58decode(_tmp, 5) == _ohai
+ print("Tests passed")
diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py
new file mode 100755
index 0000000000..1813436953
--- /dev/null
+++ b/contrib/testgen/gen_base58_test_vectors.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+'''
+Generate valid and invalid base58 address and private key test vectors.
+
+Usage:
+ gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json
+ gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json
+'''
+# 2012 Wladimir J. van der Laan
+# Released under MIT License
+import os
+from itertools import islice
+from base58 import b58encode, b58decode, b58encode_chk, b58decode_chk, b58chars
+import random
+from binascii import b2a_hex
+
+# key types
+PUBKEY_ADDRESS = 0
+SCRIPT_ADDRESS = 5
+PUBKEY_ADDRESS_TEST = 111
+SCRIPT_ADDRESS_TEST = 196
+PRIVKEY = 128
+PRIVKEY_TEST = 239
+
+metadata_keys = ['isPrivkey', 'isTestnet', 'addrType', 'isCompressed']
+# templates for valid sequences
+templates = [
+ # prefix, payload_size, suffix, metadata
+ # None = N/A
+ ((PUBKEY_ADDRESS,), 20, (), (False, False, 'pubkey', None)),
+ ((SCRIPT_ADDRESS,), 20, (), (False, False, 'script', None)),
+ ((PUBKEY_ADDRESS_TEST,), 20, (), (False, True, 'pubkey', None)),
+ ((SCRIPT_ADDRESS_TEST,), 20, (), (False, True, 'script', None)),
+ ((PRIVKEY,), 32, (), (True, False, None, False)),
+ ((PRIVKEY,), 32, (1,), (True, False, None, True)),
+ ((PRIVKEY_TEST,), 32, (), (True, True, None, False)),
+ ((PRIVKEY_TEST,), 32, (1,), (True, True, None, True))
+]
+
+def is_valid(v):
+ '''Check vector v for validity'''
+ result = b58decode_chk(v)
+ if result is None:
+ return False
+ valid = False
+ for template in templates:
+ prefix = str(bytearray(template[0]))
+ suffix = str(bytearray(template[2]))
+ if result.startswith(prefix) and result.endswith(suffix):
+ if (len(result) - len(prefix) - len(suffix)) == template[1]:
+ return True
+ return False
+
+def gen_valid_vectors():
+ '''Generate valid test vectors'''
+ while True:
+ for template in templates:
+ prefix = str(bytearray(template[0]))
+ payload = os.urandom(template[1])
+ suffix = str(bytearray(template[2]))
+ rv = b58encode_chk(prefix + payload + suffix)
+ assert is_valid(rv)
+ metadata = dict([(x,y) for (x,y) in zip(metadata_keys,template[3]) if y is not None])
+ yield (rv, b2a_hex(payload), metadata)
+
+def gen_invalid_vector(template, corrupt_prefix, randomize_payload_size, corrupt_suffix):
+ '''Generate possibly invalid vector'''
+ if corrupt_prefix:
+ prefix = os.urandom(1)
+ else:
+ prefix = str(bytearray(template[0]))
+
+ if randomize_payload_size:
+ payload = os.urandom(max(int(random.expovariate(0.5)), 50))
+ else:
+ payload = os.urandom(template[1])
+
+ if corrupt_suffix:
+ suffix = os.urandom(len(template[2]))
+ else:
+ suffix = str(bytearray(template[2]))
+
+ return b58encode_chk(prefix + payload + suffix)
+
+def randbool(p = 0.5):
+ '''Return True with P(p)'''
+ return random.random() < p
+
+def gen_invalid_vectors():
+ '''Generate invalid test vectors'''
+ # start with some manual edge-cases
+ yield "",
+ yield "x",
+ while True:
+ # kinds of invalid vectors:
+ # invalid prefix
+ # invalid payload length
+ # invalid (randomized) suffix (add random data)
+ # corrupt checksum
+ for template in templates:
+ val = gen_invalid_vector(template, randbool(0.2), randbool(0.2), randbool(0.2))
+ if random.randint(0,10)<1: # line corruption
+ if randbool(): # add random character to end
+ val += random.choice(b58chars)
+ else: # replace random character in the middle
+ n = random.randint(0, len(val))
+ val = val[0:n] + random.choice(b58chars) + val[n+1:]
+ if not is_valid(val):
+ yield val,
+
+if __name__ == '__main__':
+ import sys, json
+ iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors}
+ try:
+ uiter = iters[sys.argv[1]]
+ except IndexError:
+ uiter = gen_valid_vectors
+ try:
+ count = int(sys.argv[2])
+ except IndexError:
+ count = 0
+
+ data = list(islice(uiter(), count))
+ json.dump(data, sys.stdout, sort_keys=True, indent=4)
+ sys.stdout.write('\n')
+
diff --git a/contrib/tidy_datadir.sh b/contrib/tidy_datadir.sh
new file mode 100755
index 0000000000..5d6d826444
--- /dev/null
+++ b/contrib/tidy_datadir.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+if [ -d "$1" ]; then
+ cd "$1"
+else
+ echo "Usage: $0 <datadir>" >&2
+ echo "Removes obsolete Bitcoin database files" >&2
+ exit 1
+fi
+
+LEVEL=0
+if [ -f wallet.dat -a -f addr.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=1; fi
+if [ -f wallet.dat -a -f peers.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=2; fi
+if [ -f wallet.dat -a -f peers.dat -a -f coins/CURRENT -a -f blktree/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=3; fi
+if [ -f wallet.dat -a -f peers.dat -a -f chainstate/CURRENT -a -f blocks/index/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=4; fi
+
+case $LEVEL in
+ 0)
+ echo "Error: no Bitcoin datadir detected."
+ exit 1
+ ;;
+ 1)
+ echo "Detected old Bitcoin datadir (before 0.7)."
+ echo "Nothing to do."
+ exit 0
+ ;;
+ 2)
+ echo "Detected Bitcoin 0.7 datadir."
+ ;;
+ 3)
+ echo "Detected Bitcoin pre-0.8 datadir."
+ ;;
+ 4)
+ echo "Detected Bitcoin 0.8 datadir."
+ ;;
+esac
+
+FILES=""
+DIRS=""
+
+if [ $LEVEL -ge 3 ]; then FILES=$(echo $FILES blk????.dat blkindex.dat); fi
+if [ $LEVEL -ge 2 ]; then FILES=$(echo $FILES addr.dat); fi
+if [ $LEVEL -ge 4 ]; then DIRS=$(echo $DIRS coins blktree); fi
+
+for FILE in $FILES; do
+ if [ -f $FILE ]; then
+ echo "Deleting: $FILE"
+ rm -f $FILE
+ fi
+done
+
+for DIR in $DIRS; do
+ if [ -d $DIR ]; then
+ echo "Deleting: $DIR/"
+ rm -rf $DIR
+ fi
+done
+
+echo "Done."
diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh
new file mode 100755
index 0000000000..6b5137e7b5
--- /dev/null
+++ b/contrib/verify-commits/gpg.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+INPUT=$(</dev/stdin)
+VALID=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
+ esac
+done
+if ! $VALID; then
+ exit 1
+fi
+echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh
new file mode 100755
index 0000000000..607c0cac45
--- /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..eb13f8762e
--- /dev/null
+++ b/contrib/verify-commits/trusted-git-root
@@ -0,0 +1 @@
+053038e5ba116cb319fb85f3cb3e062cf1b3df15
diff --git a/contrib/verify-commits/trusted-keys b/contrib/verify-commits/trusted-keys
new file mode 100644
index 0000000000..658ad0375b
--- /dev/null
+++ b/contrib/verify-commits/trusted-keys
@@ -0,0 +1,5 @@
+71A3B16735405025D447E8F274810B012346C9A6
+1F4410F6A89268CE3197A84C57896D2FF8F0B657
+01CDF4627A3B88AAE4A571C87588242FBE38D3A8
+AF8BE07C7049F3A26B239D5325B3083201782B2F
+81291FA67D2C379A006A053FEAB5AF94D9E9ABE7
diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh
new file mode 100755
index 0000000000..5841fa2077
--- /dev/null
+++ b/contrib/verify-commits/verify-commits.sh
@@ -0,0 +1,51 @@
+#!/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")
+
+HAVE_FAILED=false
+IS_SIGNED () {
+ if [ $1 = $VERIFIED_ROOT ]; then
+ return 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/README.md b/contrib/verifysfbinaries/README.md
new file mode 100644
index 0000000000..8c038865bd
--- /dev/null
+++ b/contrib/verifysfbinaries/README.md
@@ -0,0 +1,6 @@
+### Verify SF Binaries ###
+This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org.
+
+It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file.
+
+The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2. \ No newline at end of file
diff --git a/contrib/verifysfbinaries/verify.sh b/contrib/verifysfbinaries/verify.sh
new file mode 100755
index 0000000000..3eb4693883
--- /dev/null
+++ b/contrib/verifysfbinaries/verify.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org
+### It first checks if the signature passes, and then downloads the files specified in
+### the file, and checks if the hashes of these files match those that are specified
+### in the signature file.
+### The script returns 0 if everything passes the checks. It returns 1 if either the
+### signature check or the hash check doesn't pass. If an error occurs the return value is 2
+
+function clean_up {
+ for file in $*
+ do
+ rm "$file" 2> /dev/null
+ done
+}
+
+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-"
+RCVERSIONSTRING="rc"
+
+if [ ! -d "$WORKINGDIR" ]; then
+ mkdir "$WORKINGDIR"
+fi
+
+cd "$WORKINGDIR"
+
+#test if a version number has been passed as an argument
+if [ -n "$1" ]; then
+ #let's also check if the version number includes the prefix 'bitcoin-',
+ # and add this prefix if it doesn't
+ if [[ $1 == "$VERSIONPREFIX"* ]]; then
+ VERSION="$1"
+ else
+ VERSION="$VERSIONPREFIX$1"
+ fi
+
+ #now let's see if the version string contains "rc", and strip it off if it does
+ # and simultaneously add RCSUBDIR to BASEDIR, where we will look for SIGNATUREFILENAME
+ if [[ $VERSION == *"$RCVERSIONSTRING"* ]]; then
+ BASEDIR="$BASEDIR${VERSION/%-$RCVERSIONSTRING*}/"
+ BASEDIR="$BASEDIR$RCSUBDIR"
+ else
+ BASEDIR="$BASEDIR$VERSION/"
+ fi
+
+ SIGNATUREFILE="$BASEDIR$SIGNATUREFILENAME"
+else
+ BASEDIR="${SIGNATUREFILE%/*}/"
+fi
+
+#first we fetch the file containing the signature
+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 "wget output:"
+ echo "$WGETOUT"|sed 's/^/\t/g'
+ exit 2
+fi
+
+#then we check it
+GPGOUT=$(gpg --yes --decrypt --output "$TMPFILE" "$SIGNATUREFILENAME" 2>&1)
+
+#return value 0: good signature
+#return value 1: bad signature
+#return value 2: gpg error
+
+RET="$?"
+if [ $RET -ne 0 ]; then
+ if [ $RET -eq 1 ]; then
+ #and notify the user if it's bad
+ 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?"
+ fi
+
+ echo "gpg output:"
+ echo "$GPGOUT"|sed 's/^/\t/g'
+ clean_up $SIGNATUREFILENAME $TMPFILE
+ exit "$RET"
+fi
+
+#here we extract the filenames from the signature file
+FILES=$(awk '{print $2}' "$TMPFILE")
+
+#and download these one by one
+for file in in $FILES
+do
+ wget --quiet -N "$BASEDIR$file"
+done
+
+#check hashes
+DIFF=$(diff <(sha256sum $FILES) "$TMPFILE")
+
+if [ $? -eq 1 ]; then
+ echo "Hashes don't match."
+ echo "Offending files:"
+ echo "$DIFF"|grep "^<"|awk '{print "\t"$3}'
+ exit 1
+elif [ $? -gt 1 ]; then
+ echo "Error executing 'diff'"
+ exit 2
+fi
+
+#everything matches! clean up the mess
+clean_up $FILES $SIGNATUREFILENAME $TMPFILE
+
+exit 0
diff --git a/contrib/wallettools/walletchangepass.py b/contrib/wallettools/walletchangepass.py
deleted file mode 100644
index 30f3f5b26a..0000000000
--- a/contrib/wallettools/walletchangepass.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from jsonrpc import ServiceProxy
-access = ServiceProxy("http://127.0.0.1:8332")
-pwd = raw_input("Enter old wallet passphrase: ")
-pwd2 = raw_input("Enter new wallet passphrase: ")
-access.walletpassphrasechange(pwd, pwd2) \ No newline at end of file
diff --git a/contrib/wallettools/walletunlock.py b/contrib/wallettools/walletunlock.py
deleted file mode 100644
index f847c6fe61..0000000000
--- a/contrib/wallettools/walletunlock.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from jsonrpc import ServiceProxy
-access = ServiceProxy("http://127.0.0.1:8332")
-pwd = raw_input("Enter wallet passphrase: ")
-access.walletpassphrase(pwd, 60) \ No newline at end of file