aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rwxr-xr-xcontrib/devtools/github-merge.py46
-rw-r--r--contrib/verify-commits/allow-revsig-commits104
-rwxr-xr-xcontrib/zmq/zmq_sub.py97
-rwxr-xr-xcontrib/zmq/zmq_sub3.4.py89
4 files changed, 305 insertions, 31 deletions
diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py
index 0cee0921b1..bb6ffb0253 100755
--- a/contrib/devtools/github-merge.py
+++ b/contrib/devtools/github-merge.py
@@ -18,6 +18,7 @@ from __future__ import division,print_function,unicode_literals
import os
from sys import stdin,stdout,stderr
import argparse
+import hashlib
import subprocess
import json,codecs
try:
@@ -69,6 +70,27 @@ def ask_prompt(text):
print("",file=stderr)
return reply
+def tree_sha512sum():
+ files = sorted(subprocess.check_output([GIT, 'ls-tree', '--full-tree', '-r', '--name-only', 'HEAD']).splitlines())
+ overall = hashlib.sha512()
+ for f in files:
+ intern = hashlib.sha512()
+ fi = open(f, 'rb')
+ while True:
+ piece = fi.read(65536)
+ if piece:
+ intern.update(piece)
+ else:
+ break
+ fi.close()
+ dig = intern.hexdigest()
+ overall.update(dig.encode("utf-8"))
+ overall.update(" ".encode("utf-8"))
+ overall.update(f)
+ overall.update("\n".encode("utf-8"))
+ return overall.hexdigest()
+
+
def parse_arguments():
epilog = '''
In addition, you can set the following git configuration variables:
@@ -157,6 +179,9 @@ def main():
subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch])
try:
+ # Go up to the repository's root.
+ toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip()
+ os.chdir(toplevel)
# Create unsigned merge commit.
if title:
firstline = 'Merge #%s: %s' % (pull,title)
@@ -175,14 +200,29 @@ def main():
print("ERROR: Creating merge failed (already merged?).",file=stderr)
exit(4)
+ # Put tree SHA512 into the message
+ try:
+ first_sha512 = tree_sha512sum()
+ message += '\n\nTree-SHA512: ' + first_sha512
+ except subprocess.CalledProcessError as e:
+ printf("ERROR: Unable to compute tree hash")
+ exit(4)
+ try:
+ subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')])
+ except subprocess.CalledProcessError as e:
+ printf("ERROR: Cannot update message.",file=stderr)
+ exit(4)
+ second_sha512 = tree_sha512sum()
+ if first_sha512 != second_sha512:
+ print("ERROR: Tree hash changed unexpectedly",file=stderr)
+ exit(4)
+
print('%s#%s%s %s %sinto %s%s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title,ATTR_RESET+ATTR_PR,branch,ATTR_RESET))
subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch])
print()
+
# Run test command if configured.
if testcmd:
- # Go up to the repository's root.
- toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip()
- os.chdir(toplevel)
if subprocess.call(testcmd,shell=True):
print("ERROR: Running %s failed." % testcmd,file=stderr)
exit(5)
diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits
index e69de29bb2..f0088cdca4 100644
--- a/contrib/verify-commits/allow-revsig-commits
+++ b/contrib/verify-commits/allow-revsig-commits
@@ -0,0 +1,104 @@
+a06ede9a138d0fb86b0de17c42b936d9fe6e2158
+923dc447eaa8e017985b2afbbb12dd1283fbea0e
+71148b8947fe8b4d756822420a7f31c380159425
+6696b4635ceb9b47aaa63244bff9032fa7b08354
+812714fd80e96e28cd288c553c83838cecbfc2d9
+8a445c5651edb9a1f51497055b7ddf4402be9188
+e126d0c12ca66278d9e7b12187c5ff4fc02a7e6c
+3908fc4728059719bed0e1c7b1c8b388c2d4a8da
+8b66bf74e2a349e71eaa183af81fa63eaee76ad2
+05950427d310654774031764a7141a1a4fd9c6e4
+07fd147b9f12e9205afd66a624edce357977d615
+12e31127948fa4bb01c3bddc1b8c85b432f7465b
+8c87f175d335e9d9e93f987d871ae9f05f6a10a7
+46b249e578e8a3dfbe85bc7253a12e82ef4b658b
+a55716abe5662ec74c2f8af93023f1e7cca901fc
+f646275b90b1de93bc62b4c4d045d75ac0b96eee
+c252685aa5867631e9a5ef07ccae7c7c25cae8ff
+a7d55c93385359952d85decd5037843ac70ba3d4
+7dac1e5e9e887f5f6ff146e812a05bd3bf281eae
+2a524b8e8fe69ef487fd8ea1b4f7a03f473ed201
+ce5c1f4acae43477989cdf9a82ed33703919cda2
+2db4cbcc437f51f5dac82cc4de46f383b92e6f11
+7aa700424cbda387536373d8dfec88aee43f950e
+b99a093afed880f23fb279c443cc6ae5e379cc43
+b83264d9c7a8ddb79f64bd9540caddc8632ef31f
+57e337d40e94ba33d8cd265c134d6ef857b32b59
+a1dcf2e1087beaf3981739fd2bb74f35ecad630a
+d38b0d7a6b6056cba26999b702815775e2437d87
+815640ec6af9a38d6a2da4a4400056e2f4105080
+09c4fd157c5b88df2d97fad4826c79b094db90c9
+2efcfa5acfacb958973d9e8125e1d81f102e2dfd
+dc6dee41f7cf2ba93fcd0fea7c157e4b2775d439
+ad826b3df9f763b49f1e3e3d50c4efdd438c7547
+c1a52276848d8caa9a9789dff176408c1aa6b1ed
+3bf06e9bac57b5b5a746677b75e297a7b154bdbd
+72ae6f8cf0224370e8121d6769b21e612ca15d6f
+a143b88dbd4971ecfdd1d39a494489c8f2db0344
+76fec09d878d6dbf214bdb6228d480bd9195db4c
+93566e0c37c5ae104095474fea89f00dcb40f551
+407d9232ef5cb1ebf6cff21f3d13e07ea4158eeb
+9346f8429957e356d21c665bab59fe45bcf1f74e
+6eeac6e30d65f9a972067c1ea8c49978c8e631ac
+dc6b9406bdfab2af8c86cb080cb3e6cf8f2385d8
+9f554e03ebe5701c1b75ff03b3d6152095c0cad3
+05009935f9ac070197113954d680bc2c9150b9b3
+508404de98a8a5435f52916cef8f328e82651961
+ed0cc50afed146c27f6d8129c683c225fb940093
+6429cfa8a70308241c576aeb92ffe3db5203b2ef
+6898213409811b140843c3d89af43328c3b22fad
+5b2ea29cf4fd298346437bb16a54407f8c1f9dca
+e2a1a1ee895149c544d4ae295466611f0cec3094
+e82fb872ff5cc8fd22d43327c1ee3e755f61c562
+19b0f33de0efd9da788e8e4f3fdc2a9e159abdb1
+89de1538ce1f8c00f80e8d11f43e1b77e24d7dea
+de07fdcf77e97b8613091285e4d0a734f5de7492
+01680195f8aa586c55c44767397380def3a23b54
+05e1c85fb687c82ae477c72d4a7e2d6b0c692167
+c072b8fd95cd4fa84f08189a0cd8b173ea2dbb8e
+9a0ed08b40b15ae2b791aa8549b53e69934b4ea7
+53f8f226bd1d627c4a6dec5862a1d4ea5a933e45
+9d0f43b7ca7241d8a018fd35dd3bc01555235ec6
+f12d2b5a8ac397e4bcaefcc19898f8ff5705dea5
+8250de13587ed05ca45df3e12c5dc9bcb1500e2c
+d727f77e390426e9e463336bda08d50c451c7086
+484312bda2d43e3ea60047be076332299463adf8
+c7e05b35ab0a791c7a8e2d863e716fdec6f3f671
+b9c1cd81848da9de1baf9c2f29c19c50e549de13
+8ea7d31e384975019733b5778feabbd9955c79d8
+f798b891bcecea9548eedacae70eeb9906c1ddbf
+ebefe7a00b46579cdd1e033a8c7fd8ce9aa578e4
+ad087638ee4864d6244ec9381ff764bfa6ee5086
+66db2d62d59817320c9182fc18e75a93b76828ea
+7ce9ac5c83b1844a518ef2e12e87aae3cacdfe58
+4286f43025149cf44207c3ad98e4a1f068520ada
+cd0c5135ab2291aaa5410ac919bad3fc87249a4a
+66ed450d771a8fc01c159a8402648ebd1c35eb4c
+a82f03393a32842d49236e8666ee57805ca701f8
+f972b04d63eb8af79ff3cec1dc561ed13dfa6053
+ec45cc5e27668171b55271b0c735194c70e7da41
+715e9fd7454f7a48d7adba7d42f662c20a3e3367
+2e0a99037dcc35bc63ba0d54371bc678af737c8e
+7fa8d758598407f3bf0beb0118dc122ea5340736
+6a22373771edbc3c7513cacb9355f880c73c2cbf
+b89ef131147f71a96152a7b5c4374266cdf539b2
+01d8359983e2f77b5118fede3ffa947072c666c8
+58f0c929a3d70a4bff79cc200f1c186f71ef1675
+950be19727a581970591d8f8138dfe4725750382
+425278d17bd0edf8a3a7cc81e55016f7fd8e7726
+c028c7b7557da2baff7af8840108e8be4db8e0c6
+47a7cfb0aa2498f6801026d258a59f9de48f60b0
+f6b7df3155ddb4cedfbcf5d3eb3383d4614b3a85
+d72098038f3b55a714ed8adb34fab547b15eb0d5
+c49c825bd9f4764536b45df5a684d97173673fc7
+33799afe83eec4200ff140e9bf5eae83701a4d7f
+5c3f8ddcaa1164079105c452429fccf8127b01b6
+1f01443567b03ac75a91c810f1733f5c21b5699d
+b3e42b6d02e8d19658a9135e427ebceab5367779
+69b3a6dd9d9a0adf5506c8b9fde42187356bd4a8
+bafd075c5e6a1088ef0f1aa0b0b224e026a3d3e0
+7daa3adb242d9c8728fdb15c6af6596aaad5502f
+514993554c370f4cf30a109ac28d5d64893dbf0a
+c8d2473e6cb042e7275a10c49d3f6a4a91bf0166
+386f4385ab04b0b2c3d47bddc0dc0f2de7354964
+9f33dba05c01ecc5c56eb1284ab7d64d42f55171
diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py
index 5707188f23..ea398a27ea 100755
--- a/contrib/zmq/zmq_sub.py
+++ b/contrib/zmq/zmq_sub.py
@@ -1,43 +1,84 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""
+ ZMQ example using python3's asyncio
+
+ Bitcoin should be started with the command line arguments:
+ bitcoind -testnet -daemon \
+ -zmqpubhashblock=tcp://127.0.0.1:28332 \
+ -zmqpubrawtx=tcp://127.0.0.1:28332 \
+ -zmqpubhashtx=tcp://127.0.0.1:28332 \
+ -zmqpubhashblock=tcp://127.0.0.1:28332
+
+ We use the asyncio library here. `self.handle()` installs itself as a
+ future at the end of the function. Since it never returns with the event
+ loop having an empty stack of futures, this creates an infinite loop. An
+ alternative is to wrap the contents of `handle` inside `while True`.
+
+ A blocking example using python 2.7 can be obtained from the git history:
+ https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
+"""
+
import binascii
+import asyncio
import zmq
+import zmq.asyncio
+import signal
import struct
+import sys
+
+if not (sys.version_info.major >= 3 and sys.version_info.minor >= 5):
+ print("This example only works with Python 3.5 and greater")
+ exit(1)
port = 28332
-zmqContext = zmq.Context()
-zmqSubSocket = zmqContext.socket(zmq.SUB)
-zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock")
-zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx")
-zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock")
-zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx")
-zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
-
-try:
- while True:
- msg = zmqSubSocket.recv_multipart()
- topic = str(msg[0])
+class ZMQHandler():
+ def __init__(self):
+ self.loop = zmq.asyncio.install()
+ self.zmqContext = zmq.asyncio.Context()
+
+ self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock")
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx")
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock")
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx")
+ self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
+
+ async def handle(self) :
+ msg = await self.zmqSubSocket.recv_multipart()
+ topic = msg[0]
body = msg[1]
sequence = "Unknown"
if len(msg[-1]) == 4:
msgSequence = struct.unpack('<I', msg[-1])[-1]
sequence = str(msgSequence)
- if topic == "hashblock":
- print '- HASH BLOCK ('+sequence+') -'
- print binascii.hexlify(body)
- elif topic == "hashtx":
- print '- HASH TX ('+sequence+') -'
- print binascii.hexlify(body)
- elif topic == "rawblock":
- print '- RAW BLOCK HEADER ('+sequence+') -'
- print binascii.hexlify(body[:80])
- elif topic == "rawtx":
- print '- RAW TX ('+sequence+') -'
- print binascii.hexlify(body)
-
-except KeyboardInterrupt:
- zmqContext.destroy()
+ if topic == b"hashblock":
+ print('- HASH BLOCK ('+sequence+') -')
+ print(binascii.hexlify(body))
+ elif topic == b"hashtx":
+ print('- HASH TX ('+sequence+') -')
+ print(binascii.hexlify(body))
+ elif topic == b"rawblock":
+ print('- RAW BLOCK HEADER ('+sequence+') -')
+ print(binascii.hexlify(body[:80]))
+ elif topic == b"rawtx":
+ print('- RAW TX ('+sequence+') -')
+ print(binascii.hexlify(body))
+ # schedule ourselves to receive the next message
+ asyncio.ensure_future(self.handle())
+
+ def start(self):
+ self.loop.add_signal_handler(signal.SIGINT, self.stop)
+ self.loop.create_task(self.handle())
+ self.loop.run_forever()
+
+ def stop(self):
+ self.loop.stop()
+ self.zmqContext.destroy()
+
+daemon = ZMQHandler()
+daemon.start()
diff --git a/contrib/zmq/zmq_sub3.4.py b/contrib/zmq/zmq_sub3.4.py
new file mode 100755
index 0000000000..a2ff64b29b
--- /dev/null
+++ b/contrib/zmq/zmq_sub3.4.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+# Copyright (c) 2014-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+"""
+ ZMQ example using python3's asyncio
+
+ Bitcoin should be started with the command line arguments:
+ bitcoind -testnet -daemon \
+ -zmqpubhashblock=tcp://127.0.0.1:28332 \
+ -zmqpubrawtx=tcp://127.0.0.1:28332 \
+ -zmqpubhashtx=tcp://127.0.0.1:28332 \
+ -zmqpubhashblock=tcp://127.0.0.1:28332
+
+ We use the asyncio library here. `self.handle()` installs itself as a
+ future at the end of the function. Since it never returns with the event
+ loop having an empty stack of futures, this creates an infinite loop. An
+ alternative is to wrap the contents of `handle` inside `while True`.
+
+ The `@asyncio.coroutine` decorator and the `yield from` syntax found here
+ was introduced in python 3.4 and has been deprecated in favor of the `async`
+ and `await` keywords respectively.
+
+ A blocking example using python 2.7 can be obtained from the git history:
+ https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
+"""
+
+import binascii
+import asyncio
+import zmq
+import zmq.asyncio
+import signal
+import struct
+import sys
+
+if not (sys.version_info.major >= 3 and sys.version_info.minor >= 4):
+ print("This example only works with Python 3.4 and greater")
+ exit(1)
+
+port = 28332
+
+class ZMQHandler():
+ def __init__(self):
+ self.loop = zmq.asyncio.install()
+ self.zmqContext = zmq.asyncio.Context()
+
+ self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock")
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashtx")
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawblock")
+ self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "rawtx")
+ self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % port)
+
+ @asyncio.coroutine
+ def handle(self) :
+ msg = yield from self.zmqSubSocket.recv_multipart()
+ topic = msg[0]
+ body = msg[1]
+ sequence = "Unknown";
+ if len(msg[-1]) == 4:
+ msgSequence = struct.unpack('<I', msg[-1])[-1]
+ sequence = str(msgSequence)
+ if topic == b"hashblock":
+ print('- HASH BLOCK ('+sequence+') -')
+ print(binascii.hexlify(body))
+ elif topic == b"hashtx":
+ print('- HASH TX ('+sequence+') -')
+ print(binascii.hexlify(body))
+ elif topic == b"rawblock":
+ print('- RAW BLOCK HEADER ('+sequence+') -')
+ print(binascii.hexlify(body[:80]))
+ elif topic == b"rawtx":
+ print('- RAW TX ('+sequence+') -')
+ print(binascii.hexlify(body))
+ # schedule ourselves to receive the next message
+ asyncio.ensure_future(self.handle())
+
+ def start(self):
+ self.loop.add_signal_handler(signal.SIGINT, self.stop)
+ self.loop.create_task(self.handle())
+ self.loop.run_forever()
+
+ def stop(self):
+ self.loop.stop()
+ self.zmqContext.destroy()
+
+daemon = ZMQHandler()
+daemon.start()