diff options
Diffstat (limited to 'contrib')
40 files changed, 551 insertions, 178 deletions
diff --git a/contrib/bitcoin-cli.bash-completion b/contrib/bitcoin-cli.bash-completion index f4cac84182..ddea58a05c 100644 --- a/contrib/bitcoin-cli.bash-completion +++ b/contrib/bitcoin-cli.bash-completion @@ -1,5 +1,5 @@ # bash programmable completion for bitcoin-cli(1) -# Copyright (c) 2012-2016 The Bitcoin Core developers +# Copyright (c) 2012-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,13 +17,6 @@ _bitcoin_rpc() { $bitcoin_cli "${rpcargs[@]}" "$@" } -# Add wallet accounts to COMPREPLY -_bitcoin_accounts() { - local accounts - accounts=$(_bitcoin_rpc listaccounts | awk -F '"' '{ print $2 }') - COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) -} - _bitcoin_cli() { local cur prev words=() cword local bitcoin_cli @@ -60,10 +53,9 @@ _bitcoin_cli() { if ((cword > 3)); then case ${words[cword-3]} in addmultisigaddress) - _bitcoin_accounts return 0 ;; - getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaddress|listsinceblock) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; @@ -80,14 +72,10 @@ _bitcoin_cli() { COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) return 0 ;; - fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listreceivedbyaddress|sendrawtransaction) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; - move|setaccount) - _bitcoin_accounts - return 0 - ;; esac fi @@ -96,12 +84,11 @@ _bitcoin_cli() { _filedir return 0 ;; - getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + getaddednodeinfo|getrawmempool|lockunspent) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; - getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) - _bitcoin_accounts + getbalance|getnewaddress|listtransactions|sendmany) return 0 ;; esac diff --git a/contrib/bitcoind.bash-completion b/contrib/bitcoind.bash-completion index da869fa2c3..ec1d9512d4 100644 --- a/contrib/bitcoind.bash-completion +++ b/contrib/bitcoind.bash-completion @@ -1,5 +1,5 @@ # bash programmable completion for bitcoind(1) and bitcoin-qt(1) -# Copyright (c) 2012-2016 The Bitcoin Core developers +# Copyright (c) 2012-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 0eccbacb96..581fe712e9 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com> Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2019, Bitcoin Core Developers +Copyright: 2009-2020, Bitcoin Core Developers License: Expat Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org, as well as the numerous contributors to the project. diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 04fa02484f..515a0d8fc6 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -98,22 +98,26 @@ repository (requires pngcrush). security-check.py and test-security-check.py ============================================ -Perform basic ELF security checks on a series of executables. +Perform basic security checks on a series of executables. symbol-check.py =============== -A script to check that the (Linux) executables produced by gitian only contain -allowed gcc, glibc and libstdc++ version symbols. This makes sure they are -still compatible with the minimum supported Linux distribution versions. +A script to check that the executables produced by gitian only contain +certain symbols and are only linked against allowed libraries. + +For Linux this means checking for allowed gcc, glibc and libstdc++ version symbols. +This makes sure they are still compatible with the minimum supported distribution versions. + +For macOS we check that the executables are only linked against libraries we allow. Example usage after a gitian build: find ../gitian-builder/build -type f -executable | xargs python3 contrib/devtools/symbol-check.py -If only supported symbols are used the return value will be 0 and the output will be empty. +If no errors occur 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: +If there are any errors the return value will be 1 and output 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 diff --git a/contrib/devtools/circular-dependencies.py b/contrib/devtools/circular-dependencies.py index 2e4657f1dd..6afa4351e7 100755 --- a/contrib/devtools/circular-dependencies.py +++ b/contrib/devtools/circular-dependencies.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# 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. import sys import re diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index 5307b04197..1b71245aab 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -19,6 +19,8 @@ EXCLUDE = [ 'src/qt/bitcoinstrings.cpp', 'src/chainparamsseeds.h', # other external copyrights: + 'src/reverse_iterator.h', + 'src/test/fuzz/FuzzedDataProvider.h', 'src/tinyformat.h', 'test/functional/test_framework/bignum.py', # python init: @@ -455,14 +457,14 @@ CPP_HEADER = ''' def get_cpp_header_lines_to_insert(start_year, end_year): return reversed(get_header_lines(CPP_HEADER, start_year, end_year)) -PYTHON_HEADER = ''' +SCRIPT_HEADER = ''' # Copyright (c) %s The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -def get_python_header_lines_to_insert(start_year, end_year): - return reversed(get_header_lines(PYTHON_HEADER, start_year, end_year)) +def get_script_header_lines_to_insert(start_year, end_year): + return reversed(get_header_lines(SCRIPT_HEADER, start_year, end_year)) ################################################################################ # query git for year of last change @@ -491,17 +493,18 @@ def file_has_hashbang(file_lines): return False return file_lines[0][:2] == '#!' -def insert_python_header(filename, file_lines, start_year, end_year): +def insert_script_header(filename, file_lines, start_year, end_year): if file_has_hashbang(file_lines): insert_idx = 1 else: insert_idx = 0 - header_lines = get_python_header_lines_to_insert(start_year, end_year) + header_lines = get_script_header_lines_to_insert(start_year, end_year) for line in header_lines: file_lines.insert(insert_idx, line) write_file_lines(filename, file_lines) def insert_cpp_header(filename, file_lines, start_year, end_year): + file_lines.insert(0, '\n') header_lines = get_cpp_header_lines_to_insert(start_year, end_year) for line in header_lines: file_lines.insert(0, line) @@ -513,8 +516,8 @@ def exec_insert_header(filename, style): sys.exit('*** %s already has a copyright by The Bitcoin Core developers' % (filename)) start_year, end_year = get_git_change_year_range(filename) - if style == 'python': - insert_python_header(filename, file_lines, start_year, end_year) + if style in ['python', 'shell']: + insert_script_header(filename, file_lines, start_year, end_year) else: insert_cpp_header(filename, file_lines, start_year, end_year) @@ -555,11 +558,13 @@ def insert_cmd(argv): if not os.path.isfile(filename): sys.exit("*** bad filename: %s" % filename) _, extension = os.path.splitext(filename) - if extension not in ['.h', '.cpp', '.cc', '.c', '.py']: + if extension not in ['.h', '.cpp', '.cc', '.c', '.py', '.sh']: sys.exit("*** cannot insert for file extension %s" % extension) if extension == '.py': style = 'python' + elif extension == '.sh': + style = 'shell' else: style = 'cpp' exec_insert_header(filename, style) diff --git a/contrib/devtools/gen-manpages.sh b/contrib/devtools/gen-manpages.sh index dbdb622877..aa65953d83 100755 --- a/contrib/devtools/gen-manpages.sh +++ b/contrib/devtools/gen-manpages.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash +# Copyright (c) 2016-2019 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. export LC_ALL=C TOPDIR=${TOPDIR:-$(git rev-parse --show-toplevel)} diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index 44b7f6c7cc..21d64e893d 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2018 The Bitcoin Core developers +# Copyright (c) 2015-2020 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -Perform basic ELF security checks on a series of executables. +Perform basic security checks on a series of executables. 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). +Needs `readelf` (for ELF), `objdump` (for PE) and `otool` (for MACHO). ''' import subprocess import sys @@ -14,6 +14,7 @@ import os READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump') +OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool') NONFATAL = {} # checks which are non-fatal for now but only generate a warning def check_ELF_PIE(executable): @@ -162,6 +163,40 @@ def check_PE_NX(executable): (arch,bits) = get_PE_dll_characteristics(executable) return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT +def get_MACHO_executable_flags(executable): + p = subprocess.Popen([OTOOL_CMD, '-vh', 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') + + flags = [] + for line in stdout.splitlines(): + tokens = line.split() + # filter first two header lines + if 'magic' in tokens or 'Mach' in tokens: + continue + # filter ncmds and sizeofcmds values + flags += [t for t in tokens if not t.isdigit()] + return flags + +def check_MACHO_PIE(executable) -> bool: + ''' + Check for position independent executable (PIE), allowing for address space randomization. + ''' + flags = get_MACHO_executable_flags(executable) + if 'PIE' in flags: + return True + return False + +def check_MACHO_NOUNDEFS(executable) -> bool: + ''' + Check for no undefined references. + ''' + flags = get_MACHO_executable_flags(executable) + if 'NOUNDEFS' in flags: + return True + return False + CHECKS = { 'ELF': [ ('PIE', check_ELF_PIE), @@ -173,6 +208,10 @@ CHECKS = { ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('NX', check_PE_NX) +], +'MACHO': [ + ('PIE', check_MACHO_PIE), + ('NOUNDEFS', check_MACHO_NOUNDEFS), ] } @@ -183,6 +222,8 @@ def identify_executable(executable): return 'PE' elif magic.startswith(b'\x7fELF'): return 'ELF' + elif magic.startswith(b'\xcf\xfa'): + return 'MACHO' return None if __name__ == '__main__': diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index d8b684026c..f92d997621 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -4,8 +4,8 @@ # 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. +allowed gcc and glibc version symbols. This makes sure they are still compatible +with the minimum supported Linux distribution versions. Example usage: @@ -15,31 +15,32 @@ import subprocess import re import sys import os +from typing import List, Optional, Tuple -# Debian 6.0.9 (Squeeze) has: +# Debian 8 (Jessie) EOL: 2020. https://wiki.debian.org/DebianReleases#Production_Releases # -# - g++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=g%2B%2B) -# - libc version 2.11.3 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libc6) -# - libstdc++ version 4.4.5 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libstdc%2B%2B6) +# - g++ version 4.9.2 (https://packages.debian.org/search?suite=jessie&arch=any&searchon=names&keywords=g%2B%2B) +# - libc version 2.19 (https://packages.debian.org/search?suite=jessie&arch=any&searchon=names&keywords=libc6) # -# Ubuntu 10.04.4 (Lucid Lynx) has: +# Ubuntu 16.04 (Xenial) EOL: 2024. https://wiki.ubuntu.com/Releases # -# - g++ version 4.4.3 (http://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=lucid§ion=all) -# - libc version 2.11.1 (http://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=lucid§ion=all) -# - libstdc++ version 4.4.3 (http://packages.ubuntu.com/search?suite=lucid§ion=all&arch=any&keywords=libstdc%2B%2B&searchon=names) +# - g++ version 5.3.1 (https://packages.ubuntu.com/search?keywords=g%2B%2B&searchon=names&suite=xenial§ion=all) +# - libc version 2.23.0 (https://packages.ubuntu.com/search?keywords=libc6&searchon=names&suite=xenial§ion=all) +# +# CentOS 7 EOL: 2024. https://wiki.centos.org/FAQ/General +# +# - g++ version 4.8.5 (http://mirror.centos.org/centos/7/os/x86_64/Packages/) +# - libc version 2.17 (http://mirror.centos.org/centos/7/os/x86_64/Packages/) # # 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 +# According to GNU ABI document (https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: +# GCC 4.8.5: GCC_4.8.0 +# (glibc) GLIBC_2_17 # MAX_VERSIONS = { -'GCC': (4,4,0), -'CXXABI': (1,3,3), -'GLIBCXX': (3,4,13), -'GLIBC': (2,11), +'GCC': (4,8,0), +'GLIBC': (2,17), 'LIBATOMIC': (1,0) } # See here for a description of _IO_stdin_used: @@ -47,17 +48,19 @@ MAX_VERSIONS = { # Ignore symbols that are exported as part of every executable IGNORE_EXPORTS = { -'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr' +'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr', +'environ', '_environ', '__environ', } READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') +OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool') + # Allowed NEEDED libraries -ALLOWED_LIBRARIES = { +ELF_ALLOWED_LIBRARIES = { # bitcoind and bitcoin-qt 'libgcc_s.so.1', # GCC base support 'libc.so.6', # C library 'libpthread.so.0', # threading -'libanl.so.1', # DNS resolve 'libm.so.6', # math library 'librt.so.1', # real-time (clock) 'libatomic.so.1', @@ -79,6 +82,25 @@ ARCH_MIN_GLIBC_VER = { 'AArch64':(2,17), 'RISC-V': (2,27) } + +MACHO_ALLOWED_LIBRARIES = { +# bitcoind and bitcoin-qt +'libc++.1.dylib', # C++ Standard Library +'libSystem.B.dylib', # libc, libm, libpthread, libinfo +# bitcoin-qt only +'AppKit', # user interface +'ApplicationServices', # common application tasks. +'Carbon', # deprecated c back-compat API +'CoreFoundation', # low level func, data types +'CoreGraphics', # 2D rendering +'CoreServices', # operating system services +'CoreText', # interface for laying out text and handling fonts. +'Foundation', # base layer functionality for apps/frameworks +'ImageIO', # read and write image file formats. +'IOKit', # user-space access to hardware devices and drivers. +'libobjc.A.dylib', # Objective-C runtime library +} + class CPPFilt(object): ''' Demangle C++ symbol names. @@ -98,15 +120,15 @@ class CPPFilt(object): self.proc.stdout.close() self.proc.wait() -def read_symbols(executable, imports=True): +def read_symbols(executable, imports=True) -> List[Tuple[str, str, str]]: ''' - Parse an ELF executable and return a list of (symbol,version) tuples + Parse an ELF executable and return a list of (symbol,version, arch) tuples for dynamic, imported symbols. ''' p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', '-h', 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())) + raise IOError('Could not read symbols for {}: {}'.format(executable, stderr.strip())) syms = [] for line in stdout.splitlines(): line = line.split() @@ -121,7 +143,7 @@ def read_symbols(executable, imports=True): syms.append((sym, version, arch)) return syms -def check_version(max_versions, version, arch): +def check_version(max_versions, version, arch) -> bool: if '_' in version: (lib, _, ver) = version.rpartition('_') else: @@ -132,7 +154,7 @@ def check_version(max_versions, version, arch): return False return ver <= max_versions[lib] or lib == 'GLIBC' and ver <= ARCH_MIN_GLIBC_VER[arch] -def read_libraries(filename): +def elf_read_libraries(filename) -> List[str]: 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: @@ -148,26 +170,94 @@ def read_libraries(filename): raise ValueError('Unparseable (NEEDED) specification') return libraries -if __name__ == '__main__': +def check_imported_symbols(filename) -> bool: + cppfilt = CPPFilt() + ok = True + for sym, version, arch in read_symbols(filename, True): + if version and not check_version(MAX_VERSIONS, version, arch): + print('{}: symbol {} from unsupported version {}'.format(filename, cppfilt(sym), version)) + ok = False + return ok + +def check_exported_symbols(filename) -> bool: cppfilt = CPPFilt() + ok = True + for sym,version,arch in read_symbols(filename, False): + if arch == 'RISC-V' or sym in IGNORE_EXPORTS: + continue + print('{}: export of symbol {} not allowed'.format(filename, cppfilt(sym))) + ok = False + return ok + +def check_ELF_libraries(filename) -> bool: + ok = True + for library_name in elf_read_libraries(filename): + if library_name not in ELF_ALLOWED_LIBRARIES: + print('{}: NEEDED library {} is not allowed'.format(filename, library_name)) + ok = False + return ok + +def macho_read_libraries(filename) -> List[str]: + p = subprocess.Popen([OTOOL_CMD, '-L', 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.splitlines(): + tokens = line.split() + if len(tokens) == 1: # skip executable name + continue + libraries.append(tokens[0].split('/')[-1]) + return libraries + +def check_MACHO_libraries(filename) -> bool: + ok = True + for dylib in macho_read_libraries(filename): + if dylib not in MACHO_ALLOWED_LIBRARIES: + print('{} is not in ALLOWED_LIBRARIES!'.format(dylib)) + ok = False + return ok + +CHECKS = { +'ELF': [ + ('IMPORTED_SYMBOLS', check_imported_symbols), + ('EXPORTED_SYMBOLS', check_exported_symbols), + ('LIBRARY_DEPENDENCIES', check_ELF_libraries) +], +'MACHO': [ + ('DYNAMIC_LIBRARIES', check_MACHO_libraries) +] +} + +def identify_executable(executable) -> Optional[str]: + with open(filename, 'rb') as f: + magic = f.read(4) + if magic.startswith(b'MZ'): + return 'PE' + elif magic.startswith(b'\x7fELF'): + return 'ELF' + elif magic.startswith(b'\xcf\xfa'): + return 'MACHO' + return None + +if __name__ == '__main__': retval = 0 for filename in sys.argv[1:]: - # Check imported symbols - for sym,version,arch in read_symbols(filename, True): - if version and not check_version(MAX_VERSIONS, version, arch): - print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) - retval = 1 - # Check exported symbols - if arch != 'RISC-V': - for sym,version,arch in read_symbols(filename, False): - if sym in IGNORE_EXPORTS: - continue - print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) - retval = 1 - # Check dependency libraries - for library_name in read_libraries(filename): - if library_name not in ALLOWED_LIBRARIES: - print('%s: NEEDED library %s is not allowed' % (filename, library_name)) + try: + etype = identify_executable(filename) + if etype is None: + print('{}: unknown format'.format(filename)) retval = 1 + continue + failed = [] + for (name, func) in CHECKS[etype]: + if not func(filename): + failed.append(name) + if failed: + print('{}: failed {}'.format(filename, ' '.join(failed))) + retval = 1 + except IOError: + print('{}: cannot open'.format(filename)) + retval = 1 sys.exit(retval) diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index bb864bfc0c..438d5f6bf0 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2018 The Bitcoin Core developers +# Copyright (c) 2015-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' diff --git a/contrib/devtools/test_deterministic_coverage.sh b/contrib/devtools/test_deterministic_coverage.sh index 88ac850021..f5cd05a2c3 100755 --- a/contrib/devtools/test_deterministic_coverage.sh +++ b/contrib/devtools/test_deterministic_coverage.sh @@ -21,8 +21,8 @@ NON_DETERMINISTIC_TESTS=( "miner_tests/CreateNewBlock_validity" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) "scheduler_tests/manythreads" # scheduler.cpp: CScheduler::serviceQueue() "scheduler_tests/singlethreadedscheduler_ordered" # scheduler.cpp: CScheduler::serviceQueue() - "tx_validationcache_tests/checkinputs_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) - "tx_validationcache_tests/tx_mempool_block_doublespend" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "txvalidationcache_tests/checkinputs_test" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) + "txvalidationcache_tests/tx_mempool_block_doublespend" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) "txindex_tests/txindex_initial_sync" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) "txvalidation_tests/tx_mempool_reject_coinbase" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) "validation_block_tests/processnewblock_signals_ordering" # validation.cpp: if (GetMainSignals().CallbacksPending() > 10) diff --git a/contrib/devtools/utxo_snapshot.sh b/contrib/devtools/utxo_snapshot.sh new file mode 100755 index 0000000000..dee25ff67b --- /dev/null +++ b/contrib/devtools/utxo_snapshot.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2019 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +export LC_ALL=C + +set -ueo pipefail + +if (( $# < 3 )); then + echo 'Usage: utxo_snapshot.sh <generate-at-height> <snapshot-out-path> <bitcoin-cli-call ...>' + echo + echo " if <snapshot-out-path> is '-', don't produce a snapshot file but instead print the " + echo " expected assumeutxo hash" + echo + echo 'Examples:' + echo + echo " ./contrib/devtools/utxo_snapshot.sh 570000 utxo.dat ./src/bitcoin-cli -datadir=\$(pwd)/testdata" + echo ' ./contrib/devtools/utxo_snapshot.sh 570000 - ./src/bitcoin-cli' + exit 1 +fi + +GENERATE_AT_HEIGHT="${1}"; shift; +OUTPUT_PATH="${1}"; shift; +# Most of the calls we make take a while to run, so pad with a lengthy timeout. +BITCOIN_CLI_CALL="${*} -rpcclienttimeout=9999999" + +# Block we'll invalidate/reconsider to rewind/fast-forward the chain. +PIVOT_BLOCKHASH=$($BITCOIN_CLI_CALL getblockhash $(( GENERATE_AT_HEIGHT + 1 )) ) + +(>&2 echo "Rewinding chain back to height ${GENERATE_AT_HEIGHT} (by invalidating ${PIVOT_BLOCKHASH}); this may take a while") +${BITCOIN_CLI_CALL} invalidateblock "${PIVOT_BLOCKHASH}" + +if [[ "${OUTPUT_PATH}" = "-" ]]; then + (>&2 echo "Generating txoutset info...") + ${BITCOIN_CLI_CALL} gettxoutsetinfo | grep hash_serialized_2 | sed 's/^.*: "\(.\+\)\+",/\1/g' +else + (>&2 echo "Generating UTXO snapshot...") + ${BITCOIN_CLI_CALL} dumptxoutset "${OUTPUT_PATH}" +fi + +(>&2 echo "Restoring chain to original height; this may take a while") +${BITCOIN_CLI_CALL} reconsiderblock "${PIVOT_BLOCKHASH}" diff --git a/contrib/filter-lcov.py b/contrib/filter-lcov.py index df1db76e92..75034616f7 100755 --- a/contrib/filter-lcov.py +++ b/contrib/filter-lcov.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2017-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. import argparse diff --git a/contrib/gitian-build.py b/contrib/gitian-build.py index 570d4906cd..ade9e00d1b 100755 --- a/contrib/gitian-build.py +++ b/contrib/gitian-build.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# Copyright (c) 2018-2019 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. import argparse import os @@ -51,10 +54,8 @@ def build(): os.chdir('gitian-builder') os.makedirs('inputs', exist_ok=True) - subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz']) - subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch']) - subprocess.check_call(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True) - subprocess.check_call(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True) + subprocess.check_call(['wget', '-O', 'inputs/osslsigncode-2.0.tar.gz', 'https://github.com/mtrojnar/osslsigncode/archive/2.0.tar.gz']) + subprocess.check_call(["echo '5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f inputs/osslsigncode-2.0.tar.gz' | sha256sum -c"], shell=True) subprocess.check_call(['make', '-C', '../bitcoin/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common']) if args.linux: diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index e0b9f74397..257dd8ba30 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -46,12 +46,12 @@ script: | FAKETIME_PROGS="date ar ranlib nm" HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" - HOST_LDFLAGS=-static-libstdc++ + HOST_LDFLAGS_BASE="-static-libstdc++" export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" - export BUILD_DIR=`pwd` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -59,11 +59,12 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi + # Use $LIB in LD_PRELOAD to avoid hardcoding the dir (See `man ld.so`) function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} @@ -77,7 +78,7 @@ script: | then echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog}-8 | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} @@ -107,7 +108,7 @@ script: | rm -f ${WRAP_DIR}/${prog} cat << EOF > ${WRAP_DIR}/${prog} #!/usr/bin/env bash - REAL="`which -a ${prog}-8 | grep -v ${WRAP_DIR}/${prog} | head -1`" + REAL="$(which -a ${prog}-8 | grep -v ${WRAP_DIR}/${prog} | head -1)" for var in "\$@" do if [ "\$var" = "-m32" ]; then @@ -122,7 +123,7 @@ script: | done cd bitcoin - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" # Build dependencies for each host for i in $HOSTS; do EXTRA_INCLUDES="$EXTRA_INCLUDES_BASE/$i" @@ -141,10 +142,11 @@ script: | # Create the release tarball using (arbitrarily) the first host ./autogen.sh - CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ + CONFIG_SITE=${BASEPREFIX}/$(echo "${HOSTS}" | awk '{print $1;}')/share/config.site ./configure --prefix=/ make dist - SOURCEDIST=`echo bitcoin-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + SOURCEDIST=$(echo bitcoin-*.tar.gz) + DISTNAME=${SOURCEDIST/%.tar.gz} + # Correct tar file order mkdir -p temp pushd temp @@ -159,9 +161,16 @@ script: | # Extract the release tarball into a dir for each host and build for i in ${HOSTS}; do export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + if [ "${i}" = "riscv64-linux-gnu" ]; then + # Workaround for https://bugs.launchpad.net/ubuntu/+source/gcc-8-cross-ports/+bug/1853740 + # TODO: remove this when no longer needed + HOST_LDFLAGS="${HOST_LDFLAGS_BASE} -Wl,-z,noexecstack" + else + HOST_LDFLAGS="${HOST_LDFLAGS_BASE}" + fi mkdir -p distsrc-${i} cd distsrc-${i} - INSTALLPATH=`pwd`/installed/${DISTNAME} + INSTALLPATH="${PWD}/installed/${DISTNAME}" mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index 4cfca403b1..a4f3219c22 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -17,14 +17,14 @@ script: | WRAP_DIR=$HOME/wrapped mkdir -p ${WRAP_DIR} - export PATH=`pwd`:$PATH + export PATH="$PWD":$PATH FAKETIME_PROGS="dmg genisoimage" # Create global faketime wrappers for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export 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} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index a563bef778..7c5abb9018 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -37,7 +37,7 @@ script: | set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="x86_64-apple-darwin14" + HOSTS="x86_64-apple-darwin16" CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" @@ -45,7 +45,7 @@ script: | export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" - export BUILD_DIR=`pwd` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -55,11 +55,12 @@ script: | export ZERO_AR_DATE=1 + # Use $LIB in LD_PRELOAD to avoid hardcoding the dir (See `man ld.so`) function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} @@ -71,7 +72,7 @@ script: | for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} @@ -86,7 +87,7 @@ script: | export PATH=${WRAP_DIR}:${PATH} cd bitcoin - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" mkdir -p ${BASEPREFIX}/SDKs tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.11.sdk.tar.gz @@ -104,10 +105,10 @@ script: | # Create the release tarball using (arbitrarily) the first host ./autogen.sh - CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ + CONFIG_SITE=${BASEPREFIX}/$(echo "${HOSTS}" | awk '{print $1;}')/share/config.site ./configure --prefix=/ make dist - SOURCEDIST=`echo bitcoin-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + SOURCEDIST=$(echo bitcoin-*.tar.gz) + DISTNAME=${SOURCEDIST/%.tar.gz} # Correct tar file order mkdir -p temp @@ -125,7 +126,7 @@ script: | export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} - INSTALLPATH=`pwd`/installed/${DISTNAME} + INSTALLPATH="${PWD}/installed/${DISTNAME}" mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST @@ -136,6 +137,8 @@ script: | CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make ${MAKEOPTS} -C src check-symbols make install-strip DESTDIR=${INSTALLPATH} make osx_volname diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index 656c6d9b7a..9d96465742 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -6,37 +6,36 @@ suites: architectures: - "amd64" packages: -# Once osslsigncode supports openssl 1.1, we can change this back to libssl-dev -- "libssl1.0-dev" +- "libssl-dev" - "autoconf" +- "libtool" +- "pkg-config" remotes: - "url": "https://github.com/bitcoin-core/bitcoin-detached-sigs.git" "dir": "signature" files: -- "osslsigncode-1.7.1.tar.gz" -- "osslsigncode-Backports-to-1.7.1.patch" +- "osslsigncode-2.0.tar.gz" - "bitcoin-win-unsigned.tar.gz" script: | set -e -o pipefail - BUILD_DIR=`pwd` + BUILD_DIR="$PWD" SIGDIR=${BUILD_DIR}/signature/win UNSIGNED_DIR=${BUILD_DIR}/unsigned - echo "f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 osslsigncode-1.7.1.tar.gz" | sha256sum -c - echo "a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 osslsigncode-Backports-to-1.7.1.patch" | sha256sum -c + echo "5a60e0a4b3e0b4d655317b2f12a810211c50242138322b16e7e01c6fbb89d92f osslsigncode-2.0.tar.gz" | sha256sum -c mkdir -p ${UNSIGNED_DIR} tar -C ${UNSIGNED_DIR} -xf bitcoin-win-unsigned.tar.gz - tar xf osslsigncode-1.7.1.tar.gz - cd osslsigncode-1.7.1 - patch -p1 < ${BUILD_DIR}/osslsigncode-Backports-to-1.7.1.patch + tar xf osslsigncode-2.0.tar.gz + cd osslsigncode-2.0 + ./autogen.sh ./configure --without-gsf --without-curl --disable-dependency-tracking make find ${UNSIGNED_DIR} -name "*-unsigned.exe" | while read i; do - INFILE="`basename "${i}"`" - OUTFILE="`echo "${INFILE}" | sed s/-unsigned//`" + INFILE="$(basename "${i}")" + OUTFILE="${INFILE/-unsigned}" ./osslsigncode attach-signature -in "${i}" -out "${OUTDIR}/${OUTFILE}" -sigin "${SIGDIR}/${INFILE}.pem" done diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index d600af84fb..de2e45190a 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -40,7 +40,7 @@ script: | export QT_RCC_TEST=1 export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" - export BUILD_DIR=`pwd` + export BUILD_DIR="$PWD" mkdir -p ${WRAP_DIR} if test -n "$GBUILD_CACHE_ENABLED"; then export SOURCES_PATH=${GBUILD_COMMON_CACHE} @@ -48,11 +48,12 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi + # Use $LIB in LD_PRELOAD to avoid hardcoding the dir (See `man ld.so`) function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} echo "\$REAL \$@" >> $WRAP_DIR/${prog} chmod +x ${WRAP_DIR}/${prog} @@ -64,7 +65,7 @@ script: | for prog in ${FAKETIME_HOST_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} chmod +x ${WRAP_DIR}/${i}-${prog} @@ -79,7 +80,7 @@ script: | for prog in gcc g++; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} echo "REAL=\`which -a ${i}-${prog}-posix | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} - echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export LD_PRELOAD='/usr/\$LIB/faketime/libfaketime.so.1'" >> ${WRAP_DIR}/${i}-${prog} echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog} echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} @@ -96,7 +97,7 @@ script: | export PATH=${WRAP_DIR}:${PATH} cd bitcoin - BASEPREFIX=`pwd`/depends + BASEPREFIX="${PWD}/depends" # Build dependencies for each host for i in $HOSTS; do make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" @@ -111,10 +112,11 @@ script: | # Create the release tarball using (arbitrarily) the first host ./autogen.sh - CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ + CONFIG_SITE=${BASEPREFIX}/$(echo "${HOSTS}" | awk '{print $1;}')/share/config.site ./configure --prefix=/ make dist - SOURCEDIST=`echo bitcoin-*.tar.gz` - DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + SOURCEDIST=$(echo bitcoin-*.tar.gz) + DISTNAME=${SOURCEDIST/%.tar.gz} + # Correct tar file order mkdir -p temp pushd temp @@ -131,7 +133,7 @@ script: | export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} mkdir -p distsrc-${i} cd distsrc-${i} - INSTALLPATH=`pwd`/installed/${DISTNAME} + INSTALLPATH="${PWD}/installed/${DISTNAME}" mkdir -p ${INSTALLPATH} tar --strip-components=1 -xf ../$SOURCEDIST @@ -145,10 +147,7 @@ script: | make ${MAKEOPTS} -C src check-security make deploy make install DESTDIR=${INSTALLPATH} - ( - SETUP_EXE="$(basename "$(echo ./*-setup.exe)")" - cp -f "$SETUP_EXE" "${OUTDIR}/${SETUP_EXE/%-setup.exe/-setup-unsigned.exe}" - ) + cp -f --target-directory="${OUTDIR}" ./bitcoin-*-setup-unsigned.exe cd installed mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ find . -name "lib*.la" -delete diff --git a/contrib/gitian-keys/keys.txt b/contrib/gitian-keys/keys.txt index 9222a40b17..ba3036a89f 100644 --- a/contrib/gitian-keys/keys.txt +++ b/contrib/gitian-keys/keys.txt @@ -27,6 +27,7 @@ D62A803E27E7F43486035ADBBCD04D8E9CCCAC2A Paul Rabahy 37EC7D7B0A217CDB4B4E007E7FAB114267E4FA04 Peter Todd D762373D24904A3E42F33B08B9A408E71DAAC974 Pieter Wuille (Location: Leuven, Belgium) 133EAC179436F14A5CF1B794860FEB804E669320 Pieter Wuille +A8FC55F3B04BA3146F3492E79303B33A305224CB Sebastian Kung (TheCharlatan) ED9BDF7AD6A55E232E84524257FF9BDBCC301009 Sjors Provoost AEC1884398647C47413C1C3FB1179EB7347DC10D Warren Togami 79D00BAC68B56D422F945A8F8E3A8F3247DBCBBF Willy Ko diff --git a/contrib/guix/README.md b/contrib/guix/README.md index 4dfa1729a5..46d755886c 100644 --- a/contrib/guix/README.md +++ b/contrib/guix/README.md @@ -62,15 +62,16 @@ Likewise, to perform a bootstrapped build (takes even longer): export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--bootstrap --no-substitutes' ``` -### Using the right Guix +### Using a version of Guix with `guix time-machine` capabilities -Once Guix is installed, deploy our patched version into your current Guix -profile. The changes there are slowly being upstreamed. +> Note: This entire section can be skipped if you are already using a version of +> Guix that has [the `guix time-machine` command][guix/time-machine]. + +Once Guix is installed, if it doesn't have the `guix time-machine` command, pull +the latest `guix`. ```sh -guix pull --url=https://github.com/dongcarl/guix.git \ - --commit=82c77e52b8b46e0a3aad2cb12307c2e30547deec \ - --max-jobs=4 # change accordingly +guix pull --max-jobs=4 # change number of jobs accordingly ``` Make sure that you are using your current profile. (You are prompted to do this @@ -80,9 +81,6 @@ at the end of the `guix pull`) export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH" ``` -> Note: There is ongoing work to eliminate this entire section using Guix -> [inferiors][guix/inferiors] and [channels][guix/channels]. - ## Usage ### As a Development Environment @@ -224,6 +222,7 @@ repository and will likely put one up soon. [guix/substitute-server-auth]: https://www.gnu.org/software/guix/manual/en/html_node/Substitute-Server-Authorization.html [guix/inferiors]: https://www.gnu.org/software/guix/manual/en/html_node/Inferiors.html [guix/channels]: https://www.gnu.org/software/guix/manual/en/html_node/Channels.html +[guix/time-machine]: https://guix.gnu.org/manual/en/html_node/Invoking-guix-time_002dmachine.html [debian/guix-package]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850644 [fanquake/guix-docker]: https://github.com/fanquake/core-review/tree/master/guix diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh index f8ba8c7ed2..5e0c681f29 100755 --- a/contrib/guix/guix-build.sh +++ b/contrib/guix/guix-build.sh @@ -13,6 +13,12 @@ make -C "${PWD}/depends" -j"$MAX_JOBS" download ${V:+V=1} ${SOURCES_PATH:+SOURCE # Determine the reference time used for determinism (overridable by environment) SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" +time-machine() { + guix time-machine --url=https://github.com/dongcarl/guix.git \ + --commit=b3a7c72c8b2425f8ddb0fc6e3b1caeed40f86dee \ + -- "$@" +} + # Deterministically build Bitcoin Core for HOSTs (overriable by environment) for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu}; do @@ -22,18 +28,18 @@ for host in ${HOSTS=i686-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64- # Run the build script 'contrib/guix/libexec/build.sh' in the build # container specified by 'contrib/guix/manifest.scm' # shellcheck disable=SC2086 - guix environment --manifest="${PWD}/contrib/guix/manifest.scm" \ - --container \ - --pure \ - --no-cwd \ - --share="$PWD"=/bitcoin \ - ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ - ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ - -- env HOST="$host" \ - MAX_JOBS="$MAX_JOBS" \ - SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ - ${V:+V=1} \ - ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ - bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh" + time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ + --container \ + --pure \ + --no-cwd \ + --share="$PWD"=/bitcoin \ + ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ + ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ + -- env HOST="$host" \ + MAX_JOBS="$MAX_JOBS" \ + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ + ${V:+V=1} \ + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ + bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh" done diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index ca11d7a0f0..23b656cad7 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -106,7 +106,7 @@ chain for " target " development.")) (base-libc glibc-2.27) (base-gcc (make-gcc-rpath-link (make-ssp-fixed-gcc gcc-9)))) - "Convienience wrapper around MAKE-CROSS-TOOLCHAIN with default values + "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building Bitcoin Core release binaries." (make-cross-toolchain target base-gcc-for-libc diff --git a/contrib/install_db4.sh b/contrib/install_db4.sh index 4b848dda99..e9130a21de 100755 --- a/contrib/install_db4.sh +++ b/contrib/install_db4.sh @@ -1,4 +1,7 @@ #!/bin/sh +# Copyright (c) 2017-2019 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. # Install libdb4.8 (Berkeley DB). diff --git a/contrib/linearize/example-linearize.cfg b/contrib/linearize/example-linearize.cfg index 2315898bf1..5990b9307a 100644 --- a/contrib/linearize/example-linearize.cfg +++ b/contrib/linearize/example-linearize.cfg @@ -28,6 +28,11 @@ input=/home/example/.bitcoin/blocks #genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 #input=/home/example/.bitcoin/testnet3/blocks +# regtest +#netmagic=fabfb5da +#genesis=0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206 +#input=/home/example/.bitcoin/regtest/blocks + # "output" option causes blockchain files to be written to the given location, # with "output_file" ignored. If not used, "output_file" is used instead. # output=/home/example/blockchain_directory diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 9ad7a03941..bcca3b7cea 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -2,7 +2,7 @@ # # linearize-data.py: Construct a linear, no-fork version of the chain. # -# Copyright (c) 2013-2018 The Bitcoin Core developers +# Copyright (c) 2013-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py index 02c96d2a75..fed6e665b8 100755 --- a/contrib/linearize/linearize-hashes.py +++ b/contrib/linearize/linearize-hashes.py @@ -2,7 +2,7 @@ # # linearize-hashes.py: List blocks in a linear, no-fork version of the chain. # -# Copyright (c) 2013-2018 The Bitcoin Core developers +# Copyright (c) 2013-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # diff --git a/contrib/macdeploy/detached-sig-apply.sh b/contrib/macdeploy/detached-sig-apply.sh index af2b11fa0d..5c5a85d3fe 100755 --- a/contrib/macdeploy/detached-sig-apply.sh +++ b/contrib/macdeploy/detached-sig-apply.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitcoin Core developers +# Copyright (c) 2014-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh index 938bcd1638..31a97f0a24 100755 --- a/contrib/macdeploy/detached-sig-create.sh +++ b/contrib/macdeploy/detached-sig-create.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitcoin Core developers +# Copyright (c) 2014-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/macdeploy/extract-osx-sdk.sh b/contrib/macdeploy/extract-osx-sdk.sh index 4c175156f4..21243ada04 100755 --- a/contrib/macdeploy/extract-osx-sdk.sh +++ b/contrib/macdeploy/extract-osx-sdk.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/qos/tc.sh b/contrib/qos/tc.sh index ccb0f4f895..8408545a21 100644 --- a/contrib/qos/tc.sh +++ b/contrib/qos/tc.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (c) 2017 The Bitcoin Core developers +# Copyright (c) 2017-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py index ec589d4c02..d516ca10c1 100755 --- a/contrib/seeds/makeseeds.py +++ b/contrib/seeds/makeseeds.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2013-2018 The Bitcoin Core developers +# Copyright (c) 2013-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -19,13 +19,9 @@ MIN_BLOCKS = 337600 # These are hosts that have been observed to be behaving strangely (e.g. # aggressively connecting to every node). -SUSPICIOUS_HOSTS = { - "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" -} +with open("suspicious_hosts.txt", mode="r", encoding="utf-8") as f: + SUSPICIOUS_HOSTS = {s.strip() for s in f if s.strip()} + PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$") PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$") diff --git a/contrib/seeds/suspicious_hosts.txt b/contrib/seeds/suspicious_hosts.txt new file mode 100644 index 0000000000..13385cc816 --- /dev/null +++ b/contrib/seeds/suspicious_hosts.txt @@ -0,0 +1,16 @@ +130.211.129.106 +148.251.238.178 +176.9.46.6 +178.63.107.226 +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 +83.81.130.26 +88.198.17.7
\ No newline at end of file diff --git a/contrib/valgrind.supp b/contrib/valgrind.supp index 0f6d993fd2..744b8ee70f 100644 --- a/contrib/valgrind.supp +++ b/contrib/valgrind.supp @@ -6,7 +6,14 @@ # Example use: # $ valgrind --suppressions=contrib/valgrind.supp src/test/test_bitcoin # $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ -# --show-leak-kinds=all src/test/test_bitcoin --log_level=test_suite +# --show-leak-kinds=all src/test/test_bitcoin +# +# To create suppressions for found issues, use the --gen-suppressions=all option: +# $ valgrind --suppressions=contrib/valgrind.supp --leak-check=full \ +# --show-leak-kinds=all --gen-suppressions=all --show-reachable=yes \ +# --error-limit=no src/test/test_bitcoin +# +# Note that suppressions may depend on OS and/or library versions. { Suppress libstdc++ warning - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65434 Memcheck:Leak @@ -23,8 +30,57 @@ Memcheck:Cond obj:*/libdb_cxx-*.so fun:__log_put +} +{ + Suppress libdb warning + Memcheck:Param + pwrite64(buf) + fun:pwrite + fun:__os_io +} +{ + Suppress libdb warning + Memcheck:Cond + fun:__log_putr.isra.1 +} +{ + Suppress libdb warning + Memcheck:Param + pwrite64(buf) + fun:pwrite + fun:__os_io + obj:*/libdb_cxx-*.so +} +{ + Suppress uninitialized bytes warning in compat code + Memcheck:Param + ioctl(TCSET{S,SW,SF}) + fun:tcsetattr +} +{ + Suppress libdb warning + Memcheck:Leak + fun:malloc + ... obj:*/libdb_cxx-*.so - fun:__log_put_record +} +{ + Suppress leaks on init + Memcheck:Leak + ... + fun:_Z11AppInitMainR11NodeContext +} +{ + Suppress leaks on shutdown + Memcheck:Leak + ... + fun:_Z8ShutdownR11NodeContext +} +{ + Ignore GUI warning + Memcheck:Leak + ... + obj:/usr/lib64/libgdk-3.so.0.2404.7 } { Suppress leveldb warning (leveldb::InitModule()) - https://github.com/google/leveldb/issues/113 @@ -41,3 +97,103 @@ ... fun:_ZN7leveldbL14InitDefaultEnvEv } +{ + Suppress leveldb leak + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_ZN7leveldb6DBImpl14BackgroundCallEv +} +{ + Suppress leveldb leak + Memcheck:Leak + fun:_Znwm + ... + fun:GetCoin +} +{ + Suppress wcsnrtombs glibc SSE4 warning (could be related: https://stroika.atlassian.net/browse/STK-626) + Memcheck:Addr16 + fun:__wcsnlen_sse4_1 + fun:wcsnrtombs +} +{ + Suppress wcsnrtombs warning (remove after removing boost::fs) + Memcheck:Cond + ... + fun:_ZN5boost10filesystem6detail11unique_pathERKNS0_4pathEPNS_6system10error_codeE + fun:unique_path +} +{ + Suppress boost warning + Memcheck:Leak + fun:_Znwm + ... + fun:_ZN5boost9unit_test9framework5state17execute_test_treeEmjPKNS2_23random_generator_helperE + fun:_ZN5boost9unit_test9framework3runEmb + fun:_ZN5boost9unit_test14unit_test_mainEPFbvEiPPc + fun:main +} +{ + Suppress boost::filesystem warning (fixed in boost 1.70: https://github.com/boostorg/filesystem/commit/bbe9d1771e5d679b3f10c42a58fc81f7e8c024a9) + Memcheck:Cond + fun:_ZN5boost10filesystem6detail28directory_iterator_incrementERNS0_18directory_iteratorEPNS_6system10error_codeE + ... + obj:*/libboost_filesystem.so.* +} +{ + Suppress boost::filesystem warning (could be related: https://stackoverflow.com/questions/9830182/function-boostfilesystemcomplete-being-reported-as-possible-memory-leak-by-v) + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_ZN5boost10filesystem8absoluteERKNS0_4pathES3_ +} +{ + Suppress boost still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + ... + fun:_M_construct_aux<char*> + fun:_M_construct<char*> + fun:basic_string + fun:path +} +{ + Suppress LogInstance still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:_Znwm + fun:_Z11LogInstancev +} +{ + Suppress secp256k1_context_create still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:secp256k1_context_create +} +{ + Suppress BCLog::Logger::StartLogging() still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:_ZN5BCLog6Logger12StartLoggingEv +} +{ + Suppress BCLog::Logger::StartLogging() still reachable memory warning + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:_ZN5BCLog6Logger12StartLoggingEv +} +{ + Suppress rest_blockhash_by_height Conditional jump or move depends on uninitialised value(s) + Memcheck:Cond + fun:_ZL24rest_blockhash_by_heightP11HTTPRequestRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE +} diff --git a/contrib/verify-commits/README.md b/contrib/verify-commits/README.md index 1215962a16..e95a57586f 100644 --- a/contrib/verify-commits/README.md +++ b/contrib/verify-commits/README.md @@ -40,7 +40,7 @@ Import trusted keys In order to check the commit signatures, you must add the trusted PGP keys to your machine. [GnuPG](https://gnupg.org/) may be used to import the trusted keys by running the following command: ```sh -gpg --recv-keys $(<contrib/verify-commits/trusted-keys) +gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys $(<contrib/verify-commits/trusted-keys) ``` Key expiry/revocation diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh index 288e4ccacb..db5bfce208 100755 --- a/contrib/verify-commits/gpg.sh +++ b/contrib/verify-commits/gpg.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2016 The Bitcoin Core developers +# Copyright (c) 2014-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/verify-commits/pre-push-hook.sh b/contrib/verify-commits/pre-push-hook.sh index 4db4a90853..a26791f0d1 100755 --- a/contrib/verify-commits/pre-push-hook.sh +++ b/contrib/verify-commits/pre-push-hook.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2014-2015 The Bitcoin Core developers +# Copyright (c) 2014-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py index 9ec8663fba..7e46c6fd47 100755 --- a/contrib/verify-commits/verify-commits.py +++ b/contrib/verify-commits/verify-commits.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2018 The Bitcoin Core developers +# Copyright (c) 2018-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Verify commits against a trusted keys list.""" diff --git a/contrib/verifybinaries/verify.sh b/contrib/verifybinaries/verify.sh index bfe74aa4fa..4296998631 100755 --- a/contrib/verifybinaries/verify.sh +++ b/contrib/verifybinaries/verify.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/windeploy/detached-sig-create.sh b/contrib/windeploy/detached-sig-create.sh index cc42422b23..31720e72e7 100755 --- a/contrib/windeploy/detached-sig-create.sh +++ b/contrib/windeploy/detached-sig-create.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2014-2015 The Bitcoin Core developers +# Copyright (c) 2014-2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. |