aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rwxr-xr-xcontrib/devtools/check-doc.py46
-rwxr-xr-xcontrib/devtools/clang-format-diff.py20
-rwxr-xr-xcontrib/devtools/github-merge.py18
-rwxr-xr-xcontrib/devtools/lint-python.sh3
-rwxr-xr-xcontrib/devtools/lint-tests.sh19
-rwxr-xr-xcontrib/devtools/optimize-pngs.py30
-rwxr-xr-xcontrib/devtools/security-check.py47
-rwxr-xr-xcontrib/devtools/symbol-check.py69
-rwxr-xr-xcontrib/devtools/update-translations.py3
-rwxr-xr-xcontrib/macdeploy/custom_dsstore.py3
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus27
-rw-r--r--contrib/testgen/base58.py20
-rwxr-xr-xcontrib/testgen/gen_base58_test_vectors.py25
-rw-r--r--contrib/verify-commits/README.md21
-rw-r--r--contrib/verify-commits/allow-revsig-commits400
-rw-r--r--contrib/verify-commits/trusted-git-root2
16 files changed, 592 insertions, 161 deletions
diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py
index f164ea9322..0c2e1a24be 100755
--- a/contrib/devtools/check-doc.py
+++ b/contrib/devtools/check-doc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2015-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -16,31 +16,33 @@ import sys
FOLDER_GREP = 'src'
FOLDER_TEST = 'src/test/'
-CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/%s' % FOLDER_GREP
-CMD_GREP_ARGS = r"egrep -r -I '(map(Multi)?Args(\.count\(|\[)|Get(Bool)?Arg\()\"\-[^\"]+?\"' %s | grep -v '%s'" % (CMD_ROOT_DIR, FOLDER_TEST)
-CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_ROOT_DIR)
-REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"')
-REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
+REGEX_ARG = '(?:ForceSet|SoftSet|Get|Is)(?:Bool)?Args?(?:Set)?\("(-[^"]+)"'
+REGEX_DOC = 'HelpMessageOpt\("(-[^"=]+?)(?:=|")'
+CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/{}'.format(FOLDER_GREP)
+CMD_GREP_ARGS = r"git grep --perl-regexp '{}' -- {} ':(exclude){}'".format(REGEX_ARG, CMD_ROOT_DIR, FOLDER_TEST)
+CMD_GREP_DOCS = r"git grep --perl-regexp '{}' {}".format(REGEX_DOC, CMD_ROOT_DIR)
# list unsupported, deprecated and duplicate args as they need no documentation
SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-prematurewitness', '-walletprematurewitness', '-promiscuousmempoolflags', '-blockminsize', '-dbcrashratio', '-forcecompactdb', '-usehd'])
+
def main():
- used = check_output(CMD_GREP_ARGS, shell=True)
- docd = check_output(CMD_GREP_DOCS, shell=True)
-
- args_used = set(re.findall(REGEX_ARG,used))
- args_docd = set(re.findall(REGEX_DOC,docd)).union(SET_DOC_OPTIONAL)
- args_need_doc = args_used.difference(args_docd)
- args_unknown = args_docd.difference(args_used)
-
- print "Args used : %s" % len(args_used)
- print "Args documented : %s" % len(args_docd)
- print "Args undocumented: %s" % len(args_need_doc)
- print args_need_doc
- print "Args unknown : %s" % len(args_unknown)
- print args_unknown
-
- sys.exit(len(args_need_doc))
+ used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True)
+ docd = check_output(CMD_GREP_DOCS, shell=True, universal_newlines=True)
+
+ args_used = set(re.findall(re.compile(REGEX_ARG), used))
+ args_docd = set(re.findall(re.compile(REGEX_DOC), docd)).union(SET_DOC_OPTIONAL)
+ args_need_doc = args_used.difference(args_docd)
+ args_unknown = args_docd.difference(args_used)
+
+ print("Args used : {}".format(len(args_used)))
+ print("Args documented : {}".format(len(args_docd)))
+ print("Args undocumented: {}".format(len(args_need_doc)))
+ print(args_need_doc)
+ print("Args unknown : {}".format(len(args_unknown)))
+ print(args_unknown)
+
+ sys.exit(len(args_need_doc))
+
if __name__ == "__main__":
main()
diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py
index 7ea49b65e1..5402870fba 100755
--- a/contrib/devtools/clang-format-diff.py
+++ b/contrib/devtools/clang-format-diff.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
@@ -69,10 +69,9 @@ Example usage for git/svn users:
import argparse
import difflib
+import io
import re
-import string
import subprocess
-import StringIO
import sys
@@ -133,9 +132,9 @@ def main():
['-lines', str(start_line) + ':' + str(end_line)])
# Reformat files containing changes in place.
- for filename, lines in lines_by_file.iteritems():
+ for filename, lines in lines_by_file.items():
if args.i and args.verbose:
- print 'Formatting', filename
+ print('Formatting {}'.format(filename))
command = [binary, filename]
if args.i:
command.append('-i')
@@ -143,8 +142,11 @@ def main():
command.append('-sort-includes')
command.extend(lines)
command.extend(['-style=file', '-fallback-style=none'])
- p = subprocess.Popen(command, stdout=subprocess.PIPE,
- stderr=None, stdin=subprocess.PIPE)
+ p = subprocess.Popen(command,
+ stdout=subprocess.PIPE,
+ stderr=None,
+ stdin=subprocess.PIPE,
+ universal_newlines=True)
stdout, stderr = p.communicate()
if p.returncode != 0:
sys.exit(p.returncode)
@@ -152,11 +154,11 @@ def main():
if not args.i:
with open(filename) as f:
code = f.readlines()
- formatted_code = StringIO.StringIO(stdout).readlines()
+ formatted_code = io.StringIO(stdout).readlines()
diff = difflib.unified_diff(code, formatted_code,
filename, filename,
'(before formatting)', '(after formatting)')
- diff_string = string.join(diff, '')
+ diff_string = ''.join(diff)
if len(diff_string) > 0:
sys.stdout.write(diff_string)
diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py
index 2941d2cb6d..9c666673cf 100755
--- a/contrib/devtools/github-merge.py
+++ b/contrib/devtools/github-merge.py
@@ -46,7 +46,7 @@ def git_config_get(option, default=None):
'''
try:
return subprocess.check_output([GIT,'config','--get',option]).rstrip().decode('utf-8')
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
return default
def retrieve_pr_info(repo,pull):
@@ -193,23 +193,23 @@ def main():
devnull = open(os.devnull,'w')
try:
subprocess.check_call([GIT,'checkout','-q',branch])
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Cannot check out branch %s." % (branch), file=stderr)
sys.exit(3)
try:
subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*',
'+refs/heads/'+branch+':refs/heads/'+base_branch])
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Cannot find pull request #%s or branch %s on %s." % (pull,branch,host_repo), file=stderr)
sys.exit(3)
try:
subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout)
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Cannot find head of pull request #%s on %s." % (pull,host_repo), file=stderr)
sys.exit(3)
try:
subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+merge_branch], stdout=devnull, stderr=stdout)
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Cannot find merge of pull request #%s on %s." % (pull,host_repo), file=stderr)
sys.exit(3)
subprocess.check_call([GIT,'checkout','-q',base_branch])
@@ -230,7 +230,7 @@ def main():
message += '\n\nPull request description:\n\n ' + body.replace('\n', '\n ') + '\n'
try:
subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message.encode('utf-8'),head_branch])
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Cannot be merged cleanly.",file=stderr)
subprocess.check_call([GIT,'merge','--abort'])
sys.exit(4)
@@ -249,12 +249,12 @@ def main():
try:
first_sha512 = tree_sha512sum()
message += '\n\nTree-SHA512: ' + first_sha512
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Unable to compute tree hash")
sys.exit(4)
try:
subprocess.check_call([GIT,'commit','--amend','-m',message.encode('utf-8')])
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("ERROR: Cannot update message.", file=stderr)
sys.exit(4)
@@ -299,7 +299,7 @@ def main():
try:
subprocess.check_call([GIT,'commit','-q','--gpg-sign','--amend','--no-edit'])
break
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
print("Error while signing, asking again.",file=stderr)
elif reply == 'x':
print("Not signing off on merge, exiting.",file=stderr)
diff --git a/contrib/devtools/lint-python.sh b/contrib/devtools/lint-python.sh
index e2c9d775a6..1469ce1640 100755
--- a/contrib/devtools/lint-python.sh
+++ b/contrib/devtools/lint-python.sh
@@ -52,6 +52,7 @@
# F822 undefined name name in __all__
# F823 local variable name … referenced before assignment
# F831 duplicate argument name in function definition
+# F841 local variable 'foo' is assigned to but never used
# W292 no newline at end of file
# W504 line break after binary operator
# W601 .has_key() is deprecated, use "in"
@@ -60,4 +61,4 @@
# W604 backticks are deprecated, use "repr()"
# W605 invalid escape sequence "x"
-flake8 --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E271,E272,E273,E274,E275,E304,E306,E502,E702,E703,E714,E721,E741,E742,E743,F401,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F822,F823,F831,W292,W504,W601,W602,W603,W604,W605 .
+flake8 --ignore=B,C,E,F,I,N,W --select=E112,E113,E115,E116,E125,E131,E133,E223,E224,E271,E272,E273,E274,E275,E304,E306,E502,E702,E703,E714,E721,E741,E742,E743,F401,F402,F404,F406,F407,F601,F602,F621,F622,F631,F701,F702,F703,F704,F705,F706,F707,F811,F812,F822,F823,F831,F841,W292,W504,W601,W602,W603,W604,W605 .
diff --git a/contrib/devtools/lint-tests.sh b/contrib/devtools/lint-tests.sh
new file mode 100755
index 0000000000..dd1a3ebdc4
--- /dev/null
+++ b/contrib/devtools/lint-tests.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Copyright (c) 2018 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#
+# Check the test suite naming convention
+
+NAMING_INCONSISTENCIES=$(git grep -E '^BOOST_FIXTURE_TEST_SUITE\(' -- \
+ "src/test/**.cpp" "src/wallet/test/**.cpp" | \
+ grep -vE '/(.*?)\.cpp:BOOST_FIXTURE_TEST_SUITE\(\1, .*\)$')
+if [[ ${NAMING_INCONSISTENCIES} != "" ]]; then
+ echo "The test suite in file src/test/foo_tests.cpp should be named"
+ echo "\"foo_tests\". Please make sure the following test suites follow"
+ echo "that convention:"
+ echo
+ echo "${NAMING_INCONSISTENCIES}"
+ exit 1
+fi
diff --git a/contrib/devtools/optimize-pngs.py b/contrib/devtools/optimize-pngs.py
index 5cb3bb6f75..565b199125 100755
--- a/contrib/devtools/optimize-pngs.py
+++ b/contrib/devtools/optimize-pngs.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2014-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,7 +10,7 @@ import os
import sys
import subprocess
import hashlib
-from PIL import Image
+from PIL import Image # pip3 install Pillow
def file_hash(filename):
'''Return hash of raw file contents'''
@@ -27,7 +27,7 @@ def content_hash(filename):
pngcrush = 'pngcrush'
git = 'git'
folders = ["src/qt/res/movies", "src/qt/res/icons", "share/pixmaps"]
-basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
+basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel'], universal_newlines=True).rstrip('\n')
totalSaveBytes = 0
noHashChange = True
@@ -37,42 +37,40 @@ for folder in folders:
for file in os.listdir(absFolder):
extension = os.path.splitext(file)[1]
if extension.lower() == '.png':
- print("optimizing "+file+"..."),
+ print("optimizing {}...".format(file), end =' ')
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')
+ subprocess.call([pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path],
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except:
- print "pngcrush is not installed, aborting..."
+ 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"
+ if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT, universal_newlines=True):
+ 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"
+ print("Image contents of PNG file {} before and after crushing don't match".format(file))
sys.exit(1)
fileMetaMap['psize'] = os.path.getsize(file_path)
outputArray.append(fileMetaMap)
- print("done\n"),
+ print("done")
-print "summary:\n+++++++++++++++++"
+print("summary:\n+++++++++++++++++")
for fileDict in outputArray:
oldHash = fileDict['sha256Old']
newHash = fileDict['sha256New']
totalSaveBytes += fileDict['osize'] - fileDict['psize']
noHashChange = noHashChange and (oldHash == newHash)
- print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n"
+ print(fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n")
-print "completed. Checksum stable: "+str(noHashChange)+". Total reduction: "+str(totalSaveBytes)+" bytes"
+print("completed. Checksum stable: "+str(noHashChange)+". Total reduction: "+str(totalSaveBytes)+" bytes")
diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py
index 1613f704df..0f2099953f 100755
--- a/contrib/devtools/security-check.py
+++ b/contrib/devtools/security-check.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2015-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -8,7 +8,6 @@ Exit status will be 0 if successful, and the program will be silent.
Otherwise the exit status will be 1 and it will log which executables failed which checks.
Needs `readelf` (for ELF) and `objdump` (for PE).
'''
-from __future__ import division,print_function,unicode_literals
import subprocess
import sys
import os
@@ -21,38 +20,38 @@ def check_ELF_PIE(executable):
'''
Check for position independent executable (PIE), allowing for address space randomization.
'''
- p = subprocess.Popen([READELF_CMD, '-h', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ p = subprocess.Popen([READELF_CMD, '-h', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
ok = False
- for line in stdout.split(b'\n'):
+ for line in stdout.splitlines():
line = line.split()
- if len(line)>=2 and line[0] == b'Type:' and line[1] == b'DYN':
+ if len(line)>=2 and line[0] == 'Type:' and line[1] == 'DYN':
ok = True
return ok
def get_ELF_program_headers(executable):
'''Return type and flags for ELF program headers'''
- p = subprocess.Popen([READELF_CMD, '-l', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ p = subprocess.Popen([READELF_CMD, '-l', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
in_headers = False
count = 0
headers = []
- for line in stdout.split(b'\n'):
- if line.startswith(b'Program Headers:'):
+ for line in stdout.splitlines():
+ if line.startswith('Program Headers:'):
in_headers = True
- if line == b'':
+ if line == '':
in_headers = False
if in_headers:
if count == 1: # header line
- ofs_typ = line.find(b'Type')
- ofs_offset = line.find(b'Offset')
- ofs_flags = line.find(b'Flg')
- ofs_align = line.find(b'Align')
+ ofs_typ = line.find('Type')
+ ofs_offset = line.find('Offset')
+ ofs_flags = line.find('Flg')
+ ofs_align = line.find('Align')
if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1:
raise ValueError('Cannot parse elfread -lW output')
elif count > 1:
@@ -69,9 +68,9 @@ def check_ELF_NX(executable):
have_wx = False
have_gnu_stack = False
for (typ, flags) in get_ELF_program_headers(executable):
- if typ == b'GNU_STACK':
+ if typ == 'GNU_STACK':
have_gnu_stack = True
- if b'W' in flags and b'E' in flags: # section is both writable and executable
+ if 'W' in flags and 'E' in flags: # section is both writable and executable
have_wx = True
return have_gnu_stack and not have_wx
@@ -88,17 +87,17 @@ def check_ELF_RELRO(executable):
# However, the dynamic linker need to write to this area so these are RW.
# Glibc itself takes care of mprotecting this area R after relocations are finished.
# See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347
- if typ == b'GNU_RELRO':
+ if typ == 'GNU_RELRO':
have_gnu_relro = True
have_bindnow = False
- p = subprocess.Popen([READELF_CMD, '-d', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ p = subprocess.Popen([READELF_CMD, '-d', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
- for line in stdout.split(b'\n'):
+ for line in stdout.splitlines():
tokens = line.split()
- if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2]):
+ if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2]):
have_bindnow = True
return have_gnu_relro and have_bindnow
@@ -106,13 +105,13 @@ def check_ELF_Canary(executable):
'''
Check for use of stack canary
'''
- p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
ok = False
- for line in stdout.split(b'\n'):
- if b'__stack_chk_fail' in line:
+ for line in stdout.splitlines():
+ if '__stack_chk_fail' in line:
ok = True
return ok
@@ -122,13 +121,13 @@ def get_PE_dll_characteristics(executable):
Returns a tuple (arch,bits) where arch is 'i386:x86-64' or 'i386'
and bits is the DllCharacteristics value.
'''
- p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
arch = ''
bits = 0
- for line in stdout.split('\n'):
+ for line in stdout.splitlines():
tokens = line.split()
if len(tokens)>=2 and tokens[0] == 'architecture:':
arch = tokens[1].rstrip(',')
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index 98daa1bd76..3a67319eaa 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# 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.
@@ -11,7 +11,6 @@ Example usage:
find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py
'''
-from __future__ import division, print_function, unicode_literals
import subprocess
import re
import sys
@@ -47,28 +46,28 @@ MAX_VERSIONS = {
# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
-b'_edata', b'_end', b'_init', b'__bss_start', b'_fini', b'_IO_stdin_used'
+'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used'
}
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
# Allowed NEEDED libraries
ALLOWED_LIBRARIES = {
# bitcoind and bitcoin-qt
-b'libgcc_s.so.1', # GCC base support
-b'libc.so.6', # C library
-b'libpthread.so.0', # threading
-b'libanl.so.1', # DNS resolve
-b'libm.so.6', # math library
-b'librt.so.1', # real-time (clock)
-b'ld-linux-x86-64.so.2', # 64-bit dynamic linker
-b'ld-linux.so.2', # 32-bit dynamic linker
+'libgcc_s.so.1', # GCC base support
+'libc.so.6', # C library
+'libpthread.so.0', # threading
+'libanl.so.1', # DNS resolve
+'libm.so.6', # math library
+'librt.so.1', # real-time (clock)
+'ld-linux-x86-64.so.2', # 64-bit dynamic linker
+'ld-linux.so.2', # 32-bit dynamic linker
# bitcoin-qt only
-b'libX11-xcb.so.1', # part of X11
-b'libX11.so.6', # part of X11
-b'libxcb.so.1', # part of X11
-b'libfontconfig.so.1', # font support
-b'libfreetype.so.6', # font parsing
-b'libdl.so.2' # programming interface to dynamic linker
+'libX11-xcb.so.1', # part of X11
+'libX11.so.6', # part of X11
+'libxcb.so.1', # part of X11
+'libfontconfig.so.1', # font support
+'libfreetype.so.6', # font parsing
+'libdl.so.2' # programming interface to dynamic linker
}
class CPPFilt(object):
@@ -78,10 +77,10 @@ class CPPFilt(object):
Use a pipe to the 'c++filt' command.
'''
def __init__(self):
- self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
def __call__(self, mangled):
- self.proc.stdin.write(mangled + b'\n')
+ self.proc.stdin.write(mangled + '\n')
self.proc.stdin.flush()
return self.proc.stdout.readline().rstrip()
@@ -95,43 +94,43 @@ 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)
+ p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(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(b'\n'):
+ for line in stdout.splitlines():
line = line.split()
- if len(line)>7 and re.match(b'[0-9]+:$', line[0]):
- (sym, _, version) = line[7].partition(b'@')
- is_import = line[6] == b'UND'
- if version.startswith(b'@'):
+ 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 b'_' in version:
- (lib, _, ver) = version.rpartition(b'_')
+ if '_' in version:
+ (lib, _, ver) = version.rpartition('_')
else:
lib = version
ver = '0'
- ver = tuple([int(x) for x in ver.split(b'.')])
+ ver = tuple([int(x) for x in ver.split('.')])
if not lib in max_versions:
return False
return ver <= max_versions[lib]
def read_libraries(filename):
- p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
+ p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
libraries = []
- for line in stdout.split(b'\n'):
+ for line in stdout.splitlines():
tokens = line.split()
- if len(tokens)>2 and tokens[1] == b'(NEEDED)':
- match = re.match(b'^Shared library: \[(.*)\]$', b' '.join(tokens[2:]))
+ if len(tokens)>2 and tokens[1] == '(NEEDED)':
+ match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:]))
if match:
libraries.append(match.group(1))
else:
@@ -145,18 +144,18 @@ if __name__ == '__main__':
# 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).decode('utf-8'), version.decode('utf-8')))
+ 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).decode('utf-8')))
+ print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym)))
retval = 1
# Check dependency libraries
for library_name in read_libraries(filename):
if library_name not in ALLOWED_LIBRARIES:
- print('%s: NEEDED library %s is not allowed' % (filename, library_name.decode('utf-8')))
+ print('%s: NEEDED library %s is not allowed' % (filename, library_name))
retval = 1
sys.exit(retval)
diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py
index e1924749d2..b36e6968bf 100755
--- a/contrib/devtools/update-translations.py
+++ b/contrib/devtools/update-translations.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# 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.
@@ -15,7 +15,6 @@ It will do the following automatically:
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
diff --git a/contrib/macdeploy/custom_dsstore.py b/contrib/macdeploy/custom_dsstore.py
index e6ecabace1..b29fc71765 100755
--- a/contrib/macdeploy/custom_dsstore.py
+++ b/contrib/macdeploy/custom_dsstore.py
@@ -1,8 +1,7 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2013-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.
-from __future__ import division,print_function,unicode_literals
import biplist
from ds_store import DSStore
from mac_alias import Alias
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
index 23a568ad13..17ce6c44f9 100755
--- a/contrib/macdeploy/macdeployqtplus
+++ b/contrib/macdeploy/macdeployqtplus
@@ -1,5 +1,4 @@
-#!/usr/bin/env python
-from __future__ import division, print_function, unicode_literals
+#!/usr/bin/env python3
#
# Copyright (C) 2011 Patrick "p2k" Schneider <me@p2k-network.org>
#
@@ -203,7 +202,7 @@ def getFrameworks(binaryPath, verbose):
if verbose >= 3:
print("Inspecting with otool: " + binaryPath)
otoolbin=os.getenv("OTOOL", "otool")
- otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ otool = subprocess.Popen([otoolbin, "-L", binaryPath], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
o_stdout, o_stderr = otool.communicate()
if otool.returncode != 0:
if verbose >= 1:
@@ -211,7 +210,7 @@ def getFrameworks(binaryPath, verbose):
sys.stderr.flush()
raise RuntimeError("otool failed with return code %d" % otool.returncode)
- otoolLines = o_stdout.decode().split("\n")
+ otoolLines = o_stdout.split("\n")
otoolLines.pop(0) # First line is the inspected binary
if ".framework" in binaryPath or binaryPath.endswith(".dylib"):
otoolLines.pop(0) # Frameworks and dylibs list themselves as a dependency.
@@ -714,22 +713,6 @@ elif config.sign:
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 "capture_stdout" in kwargs:
@@ -747,7 +730,7 @@ if config.dmg is not None:
if not value is True:
hdiutil_args.append(str(value))
- return run(hdiutil_args)
+ return run(hdiutil_args, universal_newlines=True)
if verbose >= 2:
if fancy is None:
@@ -789,7 +772,7 @@ if config.dmg is not None:
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
- m = re.search("/Volumes/(.+$)", output.decode())
+ m = re.search("/Volumes/(.+$)", output)
disk_root = m.group(0)
disk_name = m.group(1)
diff --git a/contrib/testgen/base58.py b/contrib/testgen/base58.py
index 816d40b49c..0dbb79a707 100644
--- a/contrib/testgen/base58.py
+++ b/contrib/testgen/base58.py
@@ -28,7 +28,9 @@ def b58encode(v):
"""
long_value = 0
for (i, c) in enumerate(v[::-1]):
- long_value += (256**i) * ord(c)
+ if isinstance(c, str):
+ c = ord(c)
+ long_value += (256**i) * c
result = ''
while long_value >= __b58base:
@@ -41,7 +43,7 @@ def b58encode(v):
# leading 0-bytes in the input become leading-1s
nPad = 0
for c in v:
- if c == '\0': nPad += 1
+ if c == 0: nPad += 1
else: break
return (__b58chars[0]*nPad) + result
@@ -50,8 +52,10 @@ 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)
+ for i, c in enumerate(v[::-1]):
+ pos = __b58chars.find(c)
+ assert pos != -1
+ long_value += pos * (__b58base**i)
result = bytes()
while long_value >= 256:
@@ -62,10 +66,12 @@ def b58decode(v, length = None):
nPad = 0
for c in v:
- if c == __b58chars[0]: nPad += 1
- else: break
+ if c == __b58chars[0]:
+ nPad += 1
+ continue
+ break
- result = chr(0)*nPad + result
+ result = bytes(nPad) + result
if length is not None and len(result) != length:
return None
diff --git a/contrib/testgen/gen_base58_test_vectors.py b/contrib/testgen/gen_base58_test_vectors.py
index 8e6a5d5819..4351605786 100755
--- a/contrib/testgen/gen_base58_test_vectors.py
+++ b/contrib/testgen/gen_base58_test_vectors.py
@@ -1,11 +1,11 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2012-2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
Generate valid and invalid base58 address and private key test vectors.
-Usage:
+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
'''
@@ -46,8 +46,8 @@ def is_valid(v):
if result is None:
return False
for template in templates:
- prefix = str(bytearray(template[0]))
- suffix = str(bytearray(template[2]))
+ prefix = bytearray(template[0])
+ suffix = bytearray(template[2])
if result.startswith(prefix) and result.endswith(suffix):
if (len(result) - len(prefix) - len(suffix)) == template[1]:
return True
@@ -57,20 +57,23 @@ 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]))
+ prefix = bytearray(template[0])
+ payload = bytearray(os.urandom(template[1]))
+ suffix = 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)
+ metadata = {x: y for x, y in zip(metadata_keys,template[3]) if y is not None}
+ hexrepr = b2a_hex(payload)
+ if isinstance(hexrepr, bytes):
+ hexrepr = hexrepr.decode('utf8')
+ yield (rv, hexrepr, 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]))
+ prefix = bytearray(template[0])
if randomize_payload_size:
payload = os.urandom(max(int(random.expovariate(0.5)), 50))
@@ -80,7 +83,7 @@ def gen_invalid_vector(template, corrupt_prefix, randomize_payload_size, corrupt
if corrupt_suffix:
suffix = os.urandom(len(template[2]))
else:
- suffix = str(bytearray(template[2]))
+ suffix = bytearray(template[2])
return b58encode_chk(prefix + payload + suffix)
diff --git a/contrib/verify-commits/README.md b/contrib/verify-commits/README.md
index e9e3f65da2..fa492fdd27 100644
--- a/contrib/verify-commits/README.md
+++ b/contrib/verify-commits/README.md
@@ -24,3 +24,24 @@ keys:
Note that the above isn't a good UI/UX yet, and needs significant improvements
to make it more convenient and reduce the chance of errors; pull-reqs
improving this process would be much appreciated.
+
+Configuration files
+-------------------
+
+* `trusted-git-root`: This file should contain a single git commit hash which is the first unsigned git commit (hence it is the "root of trust").
+* `trusted-sha512-root-commit`: This file should contain a single git commit hash which is the first commit without a SHA512 root commitment.
+* `trusted-keys`: This file should contain a \n-delimited list of all PGP fingerprints of authorized commit signers (primary, not subkeys).
+* `allow-revsig-commits`: This file should contain a \n-delimited list of git commit hashes. See next section for more info.
+
+Key expiry/revocation
+---------------------
+
+When a key (or subkey) which has signed old commits expires or is revoked,
+verify-commits will start failing to verify all commits which were signed by
+said key. In order to avoid bumping the root-of-trust `trusted-git-root`
+file, individual commits which were signed by such a key can be added to the
+`allow-revsig-commits` file. That way, the PGP signatures are still verified
+but no new commits can be signed by any expired/revoked key. To easily build a
+list of commits which need to be added, verify-commits.sh can be edited to test
+each commit with BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG set to both 1 and 0, and
+those which need it set to 1 printed.
diff --git a/contrib/verify-commits/allow-revsig-commits b/contrib/verify-commits/allow-revsig-commits
index f0088cdca4..3abf82e529 100644
--- a/contrib/verify-commits/allow-revsig-commits
+++ b/contrib/verify-commits/allow-revsig-commits
@@ -102,3 +102,403 @@ bafd075c5e6a1088ef0f1aa0b0b224e026a3d3e0
c8d2473e6cb042e7275a10c49d3f6a4a91bf0166
386f4385ab04b0b2c3d47bddc0dc0f2de7354964
9f33dba05c01ecc5c56eb1284ab7d64d42f55171
+7466a26cab5d66665991433947964a638f5b957e
+b43aba89e356ff95b706e80d4802f60fc46a569a
+02b7e8319aef2a870264ad4fa2e3bb18664dcc36
+f686002a8eba820a40ac2f34a6e8f57b2b5cc54c
+2b1c50b9352ab1dc40b0f877db23c1fa4048fae3
+2405ce1df043f778b8efb9205009500cbc17313a
+4ad3b3c72c73d61e0a0cab541dca20acf651320d
+4ba3d4f4393d81148422d24d222fe7ed00130194
+8ee5c7b747171e335793c74cd9d2f7491da58164
+872c921c0a208b04bd0713758e52fcab5b7c1684
+00d1680498c5550e7db1f359202d3433a092fafd
+585db41e9ab7a6fb262c8bad7f427cdbdc497188
+18462960c0f13bd07d8f52b61e7d7bc17e991eea
+0630974647dacaf25e7fcb7f9cbb785bb078ede6
+0f58d7f3d62f012f2584f5e781fc73de4763dd9e
+3d16f581538b0974853e820508e8b3093269d2fd
+66e91420ab233cf1dac64504e0dc129019bf8c0d
+d8d9162f5bad39b2720dd2b2da237c6159e4755f
+29fad97c320c892ab6a480c81e2078ec22ab354b
+791c3ea61b4e49fd46a1a71b84ca99ddf69d2ff7
+a312e201ba56742499a5480b5f2115f01505c217
+ce56fdd2e8cdf94fd0ab76d71adbfa755e23ce7d
+480f42630cbd598c04fa59ee0e406f56904ecffb
+6012f1caf744ac9b53383d7d10a8f1b70ca2c0e1
+ded6a2afa549f693dcabb430ce0862f8631360c8
+07090c5339436f856e79a8036d1c85deeb453803
+0e265916d1c6a63e4a3821dab9db597b5ec64b46
+e4ffcacc2187d3419c8ea12b82fb06d82d8751d2
+e117cfe45eee9169409e74a44ef4a866be25bc35
+dcfe218626b05204e9fbc95ba5d95ca0eb72ec9b
+23481fa50301201ef5a60675ef899aa6ce94ca03
+27c59dc502f29cf1d76290556c21e366145e3b2e
+4a62ddd01873d18dbca96c81d756be1020249b45
+a233fb4f1d037e68ff70eef3a9f5b7bf1d631918
+b2089c51cc4af2f7e1c0ec75be9449ee222b1d69
+c997f8808256521397f1c003bb1e9896fee6eaa0
+5dc00f68c49c46a380a98d06233f90528b8e2557
+fe53d5f3636aed064823bc220d828c7ff08d1d52
+935eb8de039dec65669a96a1c3b86f4b03a1b86c
+0277173b1defb63216d40a8d8805ae6d5d563c26
+2a30e67d20f76bbcd9a7d445f616f005316e0a1a
+d32528e733f2711b34dbc41fbb2bb0f153bf7e9a
+4cad91663df381d0dff8526f3b4aa74569dfb626
+1b06ed136f17b526360617a70026aed5ded5746c
+895fbd768f0c89cea3f78acac58b233d4e3a145e
+f0295becbf3ef1fb78095306408789253fe0c114
+8d573198638e52e2dbd9abc609861430f9d2bcc3
+9d9c4185fadaf243bb97c226e2fef16b65299699
+eebe4580bc8d6484d79ecb24dd87412221cf2ea7
+9cf6393a4f82b9c81d3b4b468a17a89db10531a2
+598a9c4e4dcd03c6d80fba005de729a6a3aeba7e
+6970b30c6f1d2be7947295fe18f2390649b17a4b
+f359afcc410432ed5d30001acda0c66741ee8935
+126000ba9e7ff16271be2f4eef3df99ade8d624f
+b5e4b9b5100ec15217d43edb5f4149439f4b20a5
+b987ca4ee495a7fff82f0ac14ef0753bfb7586e2
+b03013396cb2f4bf25746388b3982a2c3616e16b
+9a97f39afaa890caa7987c6bc001b9a66e3e74e8
+cad504bf4c302f7a72e0a0e191f3fdbafda7340f
+45cf8a03cb57b8639a8d47323bde46ba22d9eeaf
+b7450cdbd89a1c862f4d4d8bf093f8a0b5448f9c
+0910cbe4ef31eb95fd76c7c2f820419fe64a3150
+92a810d04b906722c9efe60e3997243c71ff3d4c
+45173fa6fca9537abb0a0554f731d14b9f89c456
+fd4ca17360e6fc0c9bb76bf6b5b07c9102c12728
+ddff3447f29b62d79a33f728791f42fa9436216e
+36a5a4404836da323c755523fbd27563a8e84f94
+c991b304dee368f506cfee27ddaa333f1f82c518
+d38d1a3e75aa97ffa8755ddd431754a6d0942964
+a332a7d5a15214015f9553fdb2bcf80a1a4b8dc0
+604e08c83cf58ca7e7cda2ab284c1ace7bb12977
+18a1bbad98bd4321f15e7921d9aec91661499d90
+8049241e226c16bd07b029c0cb4b62ac40f0c923
+797441ee995aac59f55d59a93ecb55e8ecbe7dbc
+62fdf9b07087b80d2142799bdd2324f61483359d
+f60b4ad57912b78a96af08046a503f7905610a8c
+13e31dd6548d64a5992f439e74bb424bf88aca04
+fbce66a982679b5409a295be5c99a2eef429cabf
+9f2c2dba21855b8cb9b193b1819be73fa4a23a99
+a89221873a3ee2451c73b41bbe2d99d36f439d31
+3d6ad407770e13958e157bf026cae0bfb9254899
+901ba3e3819405306414628306746552b0aa1d28
+7a43fbb959c38e025e558e472ad57de357539894
+0d89fa0877930c6c8a539a656c1009ad8ab6755b
+54aedc013744c86b11157423fa3cffc9a51eef02
+f0c1f8abb0182da557d07372b938f3a0a4bb906f
+4ed818060ecf4a38a02c8cb48f6cbc78d2ee7708
+3bdf242fc68a8d767932c6214455d4d413effbc9
+5e468994fbb349e8eefc996954a31a67a34aaa15
+41aa9c4a801a01eca1fad22a7095372d23dace60
+2adbddb03840ad71e843c6c4a207a13e871cd1d4
+13e352dc53dec0127c5f94a60055d0ca829420dc
+95e14dc81dd30ee0d396ad08dca9a6980d16eee1
+61fb80660f73e5aa5b69302ecc7ac33da206ba5a
+05a761932edd05cf94ffe938908baf058f38632a
+ee92243e66f2df03b3a759a8ffb75dc06f0cea0d
+22cdf93c062eeaa0f8f9d6220f01b67240073dfb
+76b33491596736ca804e3a29bd8398d7a1516ab7
+6e4e98ee8ce2da3cca2e2fd210e9e8dbc9b1c936
+c838283ecdfb9490425bb071b7c22e542de46c7c
+5e3f5e4f25b65b583d3bfefac9e1148035781089
+f7388e93d3dd91a90239aedac4ec58404f103a2e
+0a2f46b0158b6fc7244a585913b0925c0acf707f
+dd561667cb7ccbbfed3134b05a565971ef6f5873
+6f01dcf63873a5e42798635ab4026c9a5f9fa213
+70fec9e36bcd1a3d93df019be084aaf89cecd7d7
+f9b74ef3fc74fd7d2aa94560820341f03cda8e12
+998c3046fab2b52bc9f141cfb588a18c05506a86
+89cc4f905e30b913ca20e4192d538cc5cbe2c38d
+87d90efd69b64f769116956a5db89e536e9e3714
+5aeaa9ccd1568a77e075dbe2bd2435bd60c87c91
+bfb270acfa30713dc8c968bb9ee40cf5a2360359
+1b8c88451b0554502435d3883c528ad0aad1b09b
+57ee73990f1ce29916adfd99f93eae1ccea1a43b
+808c84f89d0edcef9ddaab0b849a382719f6ec9e
+14b860bf64020451ced823b859da8cb912278ab9
+c63364610f4a041df1c1bd81d01b1f6856160749
+92eadc395071876d77f3babddc056b4325bdbabc
+e93fff1463ae906fc986bf98c3b118c82f171546
+9ccafb1d7bdd172a9b963444072a844da379c4f7
+b4a509a3f817121c3df98ddfd96b2769e18a3e5a
+dbc4ae03963014ab4b7957d62ba59dbd8f938c33
+8ddf60db7ad636b6a31b590251c671ded635fa1d
+f199b8a33d9443a258a1f49a1a29674cd9ee9a20
+e542728cde676f218c552d841d0af29b92f9800b
+763231051596b8e3455b839911ad6a3a1f1c3c74
+ff4cd6075b12fb32b9a906deea3ed033e3f9560a
+9c3c9cdae3e20b5bdea91a0631edac5116bbc89f
+93d20a734d2ee873832bed8ca5c05cf8e539c53c
+ef8340d25f7c5dd5682bdecea97ce84cfce1493c
+69c7ecef405d168f658a9cc7996da84c17f61e66
+4ce2f3d0d33346e9f0e96851689ee6550b2a72e3
+44e1fd926cfb0df0fbd8c41de8cd65ed8d5d6e18
+d6d2c8503c4039b682196d83a67dc28359c10c5c
+ae233c4ec3d14a97c6195059f52873cdba2b4755
+0f399a9ff227896265cafab9b2e9fab6cdb9b5b9
+f4ed44ab4a8f9a87ba678d5fd1449fbf636103dc
+7fcd61b2613c211bb042a82a889655178be6a212
+42973f834445d7735738bdba8847812ba3c34d95
+8df48b36ed3201d938b9974ecbee455d7dc2fb84
+96ac26e56627f0c24213fcd3a1cce9fc95f1f661
+cce94c518a46b7b0006f984bbe4d69e8749182d2
+801dd40666d1e6009920ad3ff755c7bb993b2a62
+ce829855cfca103dde55661fa1524e66b139d063
+b148803b181e30213e8a7f3bd89c8239e9dcb866
+c377feaad87f8109f85da6caf62602b30c20effc
+b37cab65c63e051ebc5b491da9bd687581df94df
+16e41844e7d6c5876d2caaeef6010656950c6ec5
+ee50c9e48786dea0d9df2e45805c25565c100fe3
+11dacc6154c42bc6fe3ba94c1823f8a46e4fe81a
+791a0e6ddade27d1b69f4861a6640de60b9553cf
+638e6c59da4fad987c437592174b188510193b2e
+52f8877525d5238f3440e73710507be889d14127
+2a56baf395bf11835d784c4f8634f4525deed6a1
+bc561b4b7d6a3f71649d37d5eb9047c29efa2b13
+31809d6f8514c4a8d5677e947e3f1ebb0db210b9
+a31e9ad4f027955d43c04a05517244647e250161
+777519bd96f68c18150a0f5942f8f97a91937f5e
+4eb1f39d421024d9666cec61deaf96715ffae4c6
+50fae68d416b4b8ec4ca192923dfd5ae9ea42773
+ce665863b137ac4a7470cf006a92aa7694faca71
+81f8c0378b2ab5ea0d7b65635cb529bd3c69127c
+108222b9c323a05cc9339368f10ddd0859f62b43
+28f788e47e58f2b462351d6989348a4e1a241b2b
+d81dccf191a48a6b59c3747d7b4ccbe3535dde40
+a90e6d2bffc422ddcdb771c53aac0bceb970a2c4
+91e49c51f1aecc9e1d75457f4920d52a4b0a133c
+60dd9cc470584960431de425e2a9ffbed0e8034a
+ede386c2193fc31351e193b3a8cf30030d6be62c
+a084767b40c0d3ba8fa8f8d60f1e8d99a9dc3457
+3f726c99f819f97f2ab21b94d34c6b3129cd883a
+77fc469fc78cdd87c29f398d46ac58dbb9ef62c0
+4ae6d0fbef60ccbecf8f23bb482e201b3678f7a3
+8858b6ddd3bce9daa08da6e05de3ca863a399c15
+22e301a3d56dc9e6878380ee92c7d19ca43119d2
+c484ec6c9b85ca4e331e395c564ae232fd0681dd
+a46a671e253528e450bd57645c400bf761da07ab
+655970d9c60ae6850daf452457e14e21047c0e1b
+b6a48914c50631914192aa11b19205436a9c664d
+7db65c363a0cc6ca7cdb04de9a973ab70013baad
+6366941275344dac7e2130b0c972e90117d37ed0
+4fb2586661471a1572c2df2a5a091011d45eb7c4
+d7be7b39fa1021ec4518186afe145ee948e12a94
+85aec87b11ec41295558175c63f1f5a849460fdf
+aeb31756276034dd506fdf97c8aaade0e7e584f5
+ac016e17d20253129a0287cee7e1d06b7ef15966
+bf74d377fb8e20140da6eac1407414928384bcea
+2c811e08db651a4aed6ea0f7c1972d60de6de8ab
+e5d26e47c7a482c072a7fe47bb84c56854734184
+96a63a3e0cefe920819bd42add0041837b1214a1
+e526ca6284b9e13be1b912b80dd73a34e739b539
+ecd21357f16106e541e9c2854ead2a906659b938
+4b5a7ce0c301ad971f383eb60f61bf9b4026efda
+929fd7276c0f0c30b9416f61a6f5f35d763d81e4
+fa8a0639f7b0ce04030b72b4d5be4f0aa36fc5cb
+f1f1605c22a6283bbfd757055fcf2b584a857709
+0c173a15ca1bf20999f74987988985508c9de463
+df0793f324e33066cc746c0cb1d053d35733d626
+2b0179d8a9b75397937126b36114df0dddeab40c
+bf0a08be281dc42241e7f264c2a20515eb4781bb
+3895e25a77363ae8b49358fb793f50fa8b271e2d
+1fc783fc08bc078239537535f174ab8a489772c0
+1d4805ce04645f3203b0cfd3d66ea710e7433eb4
+d3b58704d1d325875fc605580c1c02b825c1bbcc
+ed88e3194c4bc43aeafef929da7b419d03dea1ad
+dd07f47b79628668e29cc0143b21e790100ee445
+65cc7aacfbfc7b747926375280a1d839e88d576b
+080ec5209172ac9605f1434559dbb3c1e012b10a
+416af3edf5b5ab265acf95568f2bc9eabd3d96de
+e0a7801223fd573863939e76cb633f1dcc2d22c4
+4bc853b50fd9127687eb9e4f3b679dd261a4fa96
+c68a9a69278aa194fed96bd9733d32af3690a11e
+c38f540298f0e188df5ed68fd56c623b9ac8331b
+643fa0b22d70e459d7f7ec3d728ae4811dc5158f
+e053e05c130549f43953f1d70e724dc9ce3e1b85
+75e898c094eea533d1dfaf141c6afccc3072c49f
+2805d606bc46bf5589093a1b92d3542c13ce50c2
+32751807c9c06011eb689cba56b401a6302699c0
+30853e16d332816752dafcfca92147c7ffef5b54
+bea5b00cfe95cd37832305c0f93c339a22a7d79d
+c871f323b418fac27bf834843ca26985010df53f
+329fc1dce7a1c372c8b10c2f2f8732b2c60daff0
+1aefc94dd78d6e0c9209cb09fc16f53dedf42108
+8e5725666b519b61fcdc3141da5c6a57c1959909
+a4ca0b042365061020627a8c045cddacea3312ec
+8bd16ee12fc8ef6723e0572c29b979c15b92b4f4
+87abe20fc118721cc5efdbd94a8462468cd1da2b
+4b766fcdd4ca16399075d1e081a321b3b05ce516
+f6241b3e420e19f3f0507cbbc872fe9218916a02
+7ee523604851af62c0a47c07ee023a8710ef32f7
+776ba233e939fe41a74c6b2632b93a0679a32c71
+6a796b2b53fe542e0f340f250f4f20d69efed8d0
+23d78c4dd01bc74ba35db3e3df95280f6f1b2e22
+f4b15e2de97c4f8cdbb40bef4c9d0ab2807974d9
+fff72de5bf8ac7b70208e655f237b80e70e18851
+170bc2c381f86a523de2fc8b71d62ade66303c0d
+314ebdfcb38d4b4c977579f787d5e1a20d068c94
+e9274839bf316b1972d80d28e45759f898edbf86
+75171f099e82e3527d7c3469b15891bd92227ec2
+3c5e6c94caf40395e031fbde44a0cca46fdd76ec
+dc8fc0c73bebbc1c48ac5540026030c9cc00ec23
+492d22f92919d8d9d59568318c26c1e2ac4890cc
+80c3a734298e824f9321c4efdd446086a3baad89
+47535d7c3ec79c5978cdcc03a5351ddbbb22538d
+1b25b6df0f08f7474228c5b6ed13b58682e1e440
+c530c15180631cea95e9c292cf7fabde9dca9db3
+2723bcdce3248417e98e6c43207bef74d34076c1
+ed22eb4a62bd8d5369aaec87d4cbdc03c9f16368
+9111df9673beb6d6616d491a5478f09b5f14d040
+d86bb075bf6d1e78c1e4f3dd38b0ea828ef5ecfe
+50a1cc0f0aef1514b917a5a3f4476967170b429d
+6ce733747e160ca699711f2c47e686284ca9aa07
+b44adf92342ad4f9c343ba29c081a91687932936
+88799ea1b1c08f4bc1a487c9e3c2effd5e1650ae
+080d7c700fc3291560d79fc590e05b8e2bad984f
+12af74b289f8cdc6caf850dc6c802f9936b1e8b3
+8e4f7e72410df3ba430082c7cf385f26fd75b033
+8ac80412867118172dc4172494304e19969e9489
+f2734c2828f69d9cfd535e5eab0592a7674b2b61
+0b9fb682890b8fe10cec54072b809a5efe57d33d
+5b029aaedb5fcf7cadd249607dd28eb3f233ab8c
+79af9fbd8c3c0e54702a9c92b171f134bd4466c8
+c412fd805ddf3282dc2e1f28e30f51ffcb1f1da2
+111849345bb5140f86b48e730ceab4bff45fa2e9
+a0b1e57b20a17177ed5a9a54e4a8aab597a546b4
+ca209230c8e73745cf8cfc79f500c9c46e103306
+a230b0588788dbe1ac84622aea169c577b381241
+dfef6b6af08097f0676a2323085558fbbd3c48c6
+3192e5278abca7c1f3b4a2a7f77a0ce941c73985
+7c7ddd9ead99a8b5033a1a5d4698032c9e2b3a92
+10b930dde8f14e9cb661810e97a33bbf144fc55c
+9225de2cf652fe2bf6e50636824cdb641546f57d
+598ef9c44b3ea2cc142c175f077b493f39f5ba22
+c49355c7170a64bdd7864cc3ba9a64916b67fe7c
+857d1e171e051b254a617f27b39f6a551054cee2
+21833f9456f6ad5bc06321ad6d9590f42ce0195c
+8910b4717e5bb946ee6988f7fe9fd461f53a5935
+5703dff0939f05c7457cebd6fc61d88ab13afe41
+8bfa13b15b84cb372950fb7b25a1080173060b6a
+ac23a7c1f19b3d8c326ffe75c8e13edf285f90fe
+19be26afe3d04783a92d032b55bf3fb1e2ae63cc
+f7ec7cfd38b543ba81ac7bed5b77f9a19739460b
+36afd4db4442c45d4078b1a7ad16a1872b5bee0d
+88c2ae3ed2bb5d367dd408c9255cd8f1e7a36c7d
+a13a417cdcfdfd1f1b3bf997bb6ffe6e69b096b9
+d6064a89ac97dc0d2ce9da3982e1a4e25afaeda8
+7146d96de3e15a80cafbab2af48ff6f65d8e41bb
+5628c70f2a44567695e5331fe2293c5b7f35b629
+7ff4a538a8682cdf02a4bcd6f15499c841001b73
+aa5fa642b0e7ce2ea55e2298886f212f11a8894e
+8efd1c820b9a782d8608d54d924658536178295c
+50a226563cd8d7c0a5e8448e87fede0eb72a8354
+b860915f8b0dae98e57a254d11575ea41f5c5a79
+d304fef3746039183f51b3ac8f4774dcf3a64f59
+53ab12d9318d5d195ccc77028b0e3ae66dc6e1fd
+668de70be039a4f1ffcf20aeae2a22ee71fc55a8
+0fea960ca917b73aff853fe88476174c8a313863
+f89502306dcf6393a2c7b0efbb0fa728fc582137
+ff58b1c3bdff5e5f687f10f9e40ce495ca49674e
+0b96abc35f1a9d46a27eeddd7df418d107c29c57
+b0b57a17306a7e963a4fe463f84e2b150a00a859
+4105cb6fd964ad13099ca83b1fdf3d35f3961f74
+23281a4dc3afc42a001346caec4dbb8193f0bb53
+8daf103fa138f9a184448ebf1c2e03b9dbd96f21
+02e5308c1b9f3771bbe49bc5036215fa2bd66aa9
+a65ced1a66575c652baf5084644b8647f531be8c
+2456a835f0bc7796d9ff71f64837fa6790e2b7cc
+9ec1330b455c1ab2eb6b89f8a2ab885677d4ae8a
+0b738075bd43fbd4410e30a51e0498cbfd2b7513
+98c80e374b84e5a9c2d5c36889a0b1ebed5b814b
+25720fc394e27a951bcad26095fb5a711bfacb8f
+4cfd57d2e38207d78722ce8c9274ba8dd700d1cc
+0fc1c31a878e93d938c67db3f958e82e3c39659f
+df1ab5b4d67b46b5e9e840b1fbe0ff02520831f9
+5bc3b6cede8dabdf3f4f27ddb03723cbb7cde51a
+c2ea1e6561caba3abffce361abc800822b9e0efe
+caa2f106d704ec3ade63498031dd58d34510bc76
+dce853ef76ef90c46d84294225088d595467d08c
+dbc8a8c86ae50059fddb2d6834fa5f0c9bbf9b71
+0f921e6a0492c4e9f037a9ed91f474885032d68c
+041331e1da23e4136fd046ed870cdcc177464176
+e6ba5068f107ac234576e77cedbd748b665369c2
+76fcd9d5034143a5b041766552670d19f926097d
+72bf1b3d0962304850a3ef5fe375db4bff1d0a39
+919db037f1f5cc73cdcaef92dd9cb0e7f5c8dec3
+c36229b0b2e9d4554053f5c9fc451ac29a493b1f
+9e4bb312e6958d2baa309ba670e5eed1523c6f47
+d7ba4a233bd5a6f8fadee681c68a995e23fe36d7
+98514988a3d3e8b7dbf0463884a5c38f5ed5562d
+5412c08c3cf13577566064edd04da021c37b7cbe
+31bcc667863f368157efa1143a78623a5db8f0d1
+7bd1aa566fb4a4fe194f209085649f2c722b0cff
+c4522e71c7e1d8ecfd70112e9375b9d00d6733a8
+e22f409f18881b63a8e747036584a71217f40e6e
+97ec6e5c9098a1240655cfcab05b6cd5eedb6cd1
+bc121b0eb19713ec72002b5be03ba5ac35903a17
+c98f6b3d93a2cc1b49a6db425ea2b661089d0f9e
+0de7fd36de57a68e543b4c1f184fba192c398c73
+e662d281b837c25b2b70525aa8fe8af894339823
+44adf683ad232db8ce0cb89b3e236a1f5944cfb0
+cb2ed300a89ebf9f0654da869ced665ed8b2abe7
+0a6d48d9ed60b0b02177059ab116f8f46d2cbed3
+b42291334651fff46dbfe5947a726f65cb9d7dfe
+e5364991daecb73aca3bb5ac37f2619d7a89211b
+4a2b170c075ce703cbdc82519a48016a9ee3f99c
+924de0bd75a7f75df65d7d15f9d1587a2e794abf
+1253f8692fc3a11be9430685cd405236a68df6c3
+2b799ae9e1e0a540f9a5971ddf27d83254668279
+c9bdf9a75f9fde8cd011e4aa94be4ed4347078a3
+3d69ecb4edeb80003a1a41442e320898a30dbd9c
+f08222e882b18c1f279308636e03beceece2dbf1
+23e03f8d26d7bd03273a5dcbdcfe3905dfb49ffb
+03dd707dc027fbf6f24120213f8eb66571600374
+d0754799698de2c032abcb8198ee5d5401063213
+072116fceb2294b97d1c40f79305f2e3ff71812b
+e66cc1d58e16bf1650dd6479fed64ecaca8c6098
+f137753a2dcd8229f89d1d1ac28039364e5850b4
+61d191fbf953700ba8aeadc9c8cf4c195efbd10c
+76f3c02fb01a6df98fbd8c16ac21d159d4649d37
+6013c73b3312e11b447ed387426749014716f820
+6faffb8a83db3f209a303a4464dbdd597faad5a4
+cc9e8aca5f950c78dcfeff63c441ba993c1fe12f
+8ca69a2a88a77eb06149fa049ab1a7e6de38b321
+2f71490d21796594ca6f55e375558944de9db5a0
+08cc5fd666456cb476467473ed1880c90c92dedb
+e31a43c725ebe641d7c219c3886eee18eebf0bb8
+52b5a8785de760a204b2b0aab19dfaf79c2c3ff0
+483e8e4f4875a1a621ec9e9df2880d3037d95ed7
+1e5799c52535a3fc20e885916f1e7ed33ecc7f46
+a82e5d8220bbc8b5d786bed99b0876f530b9b7cc
+7fe6c5c993706e8395cdaf7977bee793c06f48f3
+2a0836f6d5e7c1d7e97bedb0e0ea33dcaf981f77
+ddc308068d69c6c9aa629ee3c4ce75e1d1cf08b5
+ec139a5621a9c9f03e1988391a3c7c6c5d849776
+c01a6c48b982d625fd9f4f69005878781d3d56fa
+95a983d56dbda457e3bf8766d59bac74c7aa5699
+760741a00833876976389ed7a6b73f36ee5b4c13
+6e5e5abba6f8bbbe61c22795df440dfafcfdc378
+cf2cecb18779ce83de9adebf382dff1c19b12840
+af9b7a9f2f73b1a2f9728106774dd13e8d1cdd8d
+115735d547fdeade822f547eb3e8c8f9961a9b07
+c2c69edf37b5c02aafa01d0407dadbf5ef8751b5
+a072d1a83787e786d074a4b5871b0b961781f7c6
+ed2cd59e258f756b2eaed7909a60956ade6ef7ee
+ae5575ba41c8a782805afb1c08730343cfc22397
+6ff2c8d29f6b5a5c2ce63f0a16f3bb0dbd049451
+a80de15113166354cdf208e3d8b6e25f4511a591
+06bd4f637f15e769f088d9051a5af94bbb0217a3
+6700cc993cc07fb0f5b8b577ff8c4afcf0b18274
+37f9a1f627c0995d89b62923e75cd092600894f9
+8844ef15ded02d5ed86fb95aaf251235fcef2396
+1b87e5b5b184a0a6c683eda23b36393822b57f03
+e2bf830bb6c1bfa038c943dd6f5d92a406bd723f
+423ca302a3ee87000530da3c105f269b8fabece7
+4e14afe42fdd468d5de11df8cc13defdcb8e83f8
+3e90fe6534206412ea22beaa445cf20d28fbe718
+88b77c7da0a672c89e24df37ea6e9085b4e2a05c
+0ad104190465d8d65c2344bbe10dcf3df025d86c
+5c7df7022bcd360e6af00b9458b1a3fd54e1cc9a
+59ad56851a342d2c62f6b38bf15002b23ab439e1
diff --git a/contrib/verify-commits/trusted-git-root b/contrib/verify-commits/trusted-git-root
index e560b98d02..c60f8ab695 100644
--- a/contrib/verify-commits/trusted-git-root
+++ b/contrib/verify-commits/trusted-git-root
@@ -1 +1 @@
-11049f4fe62606d1b0380a9ef800ac130f0fbadf
+82bcf405f6db1d55b684a1f63a4aabad376cdad7