aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am13
-rwxr-xr-xci/test/00_setup_env.sh2
-rwxr-xr-xci/test/00_setup_env_native_multiprocess.sh1
-rwxr-xr-xci/test/04_install.sh12
-rw-r--r--configure.ac14
-rwxr-xr-xcontrib/devtools/symbol-check.py12
-rwxr-xr-xcontrib/devtools/test-security-check.py31
-rwxr-xr-xcontrib/devtools/test-symbol-check.py45
-rwxr-xr-xcontrib/devtools/utils.py22
-rwxr-xr-xcontrib/guix/libexec/build.sh18
-rwxr-xr-xcontrib/guix/libexec/codesign.sh1
-rw-r--r--contrib/guix/manifest.scm49
-rw-r--r--contrib/guix/patches/binutils-mingw-w64-disable-flags.patch171
-rw-r--r--contrib/guix/patches/gcc-8-sort-libtool-find-output.patch8
-rw-r--r--contrib/guix/patches/glibc-2.24-elfm-loadaddr-dynamic-rewrite.patch62
-rw-r--r--contrib/guix/patches/glibc-2.24-no-build-time-cxx-header-run.patch100
-rw-r--r--contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include__-to-include-asm-syscalls.h.patch72
-rw-r--r--contrib/guix/patches/glibc-ldd-x86_64.patch10
-rw-r--r--contrib/guix/patches/glibc-versioned-locpath.patch240
-rw-r--r--contrib/guix/patches/nsis-SConstruct-sde-support.patch3
-rw-r--r--depends/README.md8
-rw-r--r--doc/README.md7
-rw-r--r--doc/benchmarking.md27
-rw-r--r--doc/dependencies.md4
-rw-r--r--doc/developer-notes.md2
-rw-r--r--doc/release-process.md23
-rw-r--r--src/Makefile.am16
-rw-r--r--src/addrman.cpp32
-rw-r--r--src/addrman.h5
-rw-r--r--src/bench/bench.h18
-rw-r--r--src/bench/bench_bitcoin.cpp8
-rw-r--r--src/bitcoin-cli.cpp6
-rw-r--r--src/chainparams.cpp2
-rw-r--r--src/consensus/params.h34
-rw-r--r--src/consensus/tx_verify.cpp9
-rw-r--r--src/deploymentinfo.cpp36
-rw-r--r--src/deploymentinfo.h29
-rw-r--r--src/deploymentstatus.cpp17
-rw-r--r--src/deploymentstatus.h55
-rw-r--r--src/httpserver.cpp26
-rw-r--r--src/init.cpp13
-rw-r--r--src/miner.cpp7
-rw-r--r--src/net_processing.cpp13
-rw-r--r--src/netaddress.cpp2
-rw-r--r--src/node/blockstorage.cpp9
-rw-r--r--src/node/interfaces.cpp3
-rw-r--r--src/outputtype.cpp23
-rw-r--r--src/outputtype.h5
-rw-r--r--src/qt/bitcoingui.cpp6
-rw-r--r--src/qt/bitcoinstrings.cpp10
-rw-r--r--src/qt/coincontroldialog.cpp4
-rw-r--r--src/qt/guiutil.cpp3
-rw-r--r--src/qt/locale/bitcoin_en.ts374
-rw-r--r--src/qt/locale/bitcoin_en.xlf3038
-rw-r--r--src/qt/overviewpage.cpp23
-rw-r--r--src/qt/peertablemodel.cpp4
-rw-r--r--src/qt/peertablemodel.h3
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/sendcoinsentry.cpp4
-rw-r--r--src/qt/signverifymessagedialog.cpp4
-rw-r--r--src/qt/test/wallettests.cpp2
-rw-r--r--src/qt/transactionview.cpp4
-rw-r--r--src/rpc/blockchain.cpp51
-rw-r--r--src/rpc/mining.cpp11
-rw-r--r--src/rpc/misc.cpp3
-rw-r--r--src/script/descriptor.cpp199
-rw-r--r--src/script/descriptor.h23
-rw-r--r--src/script/interpreter.cpp6
-rw-r--r--src/script/standard.cpp8
-rw-r--r--src/test/addrman_tests.cpp40
-rw-r--r--src/test/descriptor_tests.cpp8
-rw-r--r--src/test/fuzz/banman.cpp22
-rw-r--r--src/test/fuzz/integer.cpp16
-rw-r--r--src/test/fuzz/key_io.cpp11
-rw-r--r--src/test/fuzz/load_external_block_file.cpp2
-rw-r--r--src/test/fuzz/netaddress.cpp2
-rw-r--r--src/test/fuzz/script.cpp40
-rw-r--r--src/test/fuzz/util.cpp39
-rw-r--r--src/test/fuzz/util.h34
-rw-r--r--src/test/interfaces_tests.cpp2
-rw-r--r--src/test/serfloat_tests.cpp8
-rw-r--r--src/test/streams_tests.cpp2
-rw-r--r--src/test/system_tests.cpp5
-rw-r--r--src/test/util/setup_common.cpp4
-rw-r--r--src/test/validation_chainstatemanager_tests.cpp9
-rw-r--r--src/test/versionbits_tests.cpp45
-rw-r--r--src/util/system.cpp5
-rw-r--r--src/validation.cpp316
-rw-r--r--src/validation.h54
-rw-r--r--src/versionbits.cpp33
-rw-r--r--src/versionbits.h36
-rw-r--r--src/versionbitsinfo.cpp18
-rw-r--r--src/versionbitsinfo.h17
-rw-r--r--src/wallet/external_signer_scriptpubkeyman.h4
-rw-r--r--src/wallet/interfaces.cpp6
-rw-r--r--src/wallet/rpcdump.cpp26
-rw-r--r--src/wallet/rpcwallet.cpp11
-rw-r--r--src/wallet/scriptpubkeyman.cpp155
-rw-r--r--src/wallet/scriptpubkeyman.h38
-rw-r--r--src/wallet/spend.cpp5
-rw-r--r--src/wallet/wallet.cpp147
-rw-r--r--src/wallet/wallet.h26
-rw-r--r--src/wallet/walletdb.cpp55
-rw-r--r--src/wallet/walletdb.h3
-rw-r--r--src/wallet/walletutil.h3
-rw-r--r--test/functional/data/invalid_txs.py48
-rwxr-xr-xtest/functional/feature_block.py9
-rwxr-xr-xtest/functional/feature_fee_estimation.py10
-rwxr-xr-xtest/functional/feature_rbf.py12
-rwxr-xr-xtest/functional/feature_segwit.py52
-rwxr-xr-xtest/functional/feature_taproot.py18
-rwxr-xr-xtest/functional/mempool_accept.py16
-rwxr-xr-xtest/functional/mempool_accept_wtxid.py116
-rwxr-xr-xtest/functional/p2p_segwit.py109
-rwxr-xr-xtest/functional/rpc_createmultisig.py7
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py2
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py5
-rw-r--r--test/functional/test_framework/blocktools.py13
-rwxr-xr-xtest/functional/test_framework/wallet_util.py38
-rwxr-xr-xtest/functional/test_runner.py1
-rwxr-xr-xtest/functional/wallet_address_types.py10
-rwxr-xr-xtest/functional/wallet_basic.py3
-rwxr-xr-xtest/functional/wallet_importdescriptors.py159
-rwxr-xr-xtest/functional/wallet_importmulti.py21
-rwxr-xr-xtest/functional/wallet_keypool.py2
-rwxr-xr-xtest/functional/wallet_labels.py52
-rwxr-xr-xtest/functional/wallet_listdescriptors.py4
-rwxr-xr-xtest/functional/wallet_taproot.py6
-rwxr-xr-xtest/lint/lint-python.sh2
-rwxr-xr-xtest/lint/lint-spelling.sh2
-rw-r--r--test/sanitizer_suppressions/ubsan3
131 files changed, 4435 insertions, 2646 deletions
diff --git a/Makefile.am b/Makefile.am
index d84dab1842..3ac698b96f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,7 @@ DIST_SHARE = \
BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \
$(top_srcdir)/contrib/devtools/security-check.py \
+ $(top_srcdir)/contrib/devtools/utils.py \
$(top_srcdir)/contrib/devtools/pixie.py
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
@@ -366,14 +367,14 @@ clean-local: clean-docs
test-security-check:
if TARGET_DARWIN
- $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO
- $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO
+ $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO
+ $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO
endif
if TARGET_WINDOWS
- $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE
- $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE
+ $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE
+ $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE
endif
if TARGET_LINUX
- $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF
- $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF
+ $(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF
+ $(AM_V_at) CC='$(CC)' CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF
endif
diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh
index fa4d0410fa..8a9d808f5d 100755
--- a/ci/test/00_setup_env.sh
+++ b/ci/test/00_setup_env.sh
@@ -47,7 +47,7 @@ export RUN_FUZZ_TESTS=${RUN_FUZZ_TESTS:-false}
export EXPECTED_TESTS_DURATION_IN_SECONDS=${EXPECTED_TESTS_DURATION_IN_SECONDS:-1000}
export CONTAINER_NAME=${CONTAINER_NAME:-ci_unnamed}
-export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:18.04}
+export DOCKER_NAME_TAG=${DOCKER_NAME_TAG:-ubuntu:20.04}
# Randomize test order.
# See https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/random.html
export BOOST_TEST_RANDOM=${BOOST_TEST_RANDOM:-1}
diff --git a/ci/test/00_setup_env_native_multiprocess.sh b/ci/test/00_setup_env_native_multiprocess.sh
index 1418dfbc51..8869b2a083 100755
--- a/ci/test/00_setup_env_native_multiprocess.sh
+++ b/ci/test/00_setup_env_native_multiprocess.sh
@@ -13,5 +13,4 @@ export DEP_OPTS="DEBUG=1 MULTIPROCESS=1"
export GOAL="install"
export BITCOIN_CONFIG="--enable-debug CC=clang CXX=clang++" # Use clang to avoid OOM
export TEST_RUNNER_ENV="BITCOIND=bitcoin-node"
-export RUN_SECURITY_TESTS="true"
export PIP_PACKAGES="lief"
diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh
index 01dbfe221b..2079d2ed2b 100755
--- a/ci/test/04_install.sh
+++ b/ci/test/04_install.sh
@@ -11,6 +11,7 @@ if [[ $QEMU_USER_CMD == qemu-s390* ]]; then
fi
if [ "$CI_OS_NAME" == "macos" ]; then
+ sudo -H pip3 install --upgrade pip
IN_GETOPT_BIN="/usr/local/opt/gnu-getopt/bin/getopt" ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES
fi
@@ -83,11 +84,14 @@ fi
DOCKER_EXEC echo "Free disk space:"
DOCKER_EXEC df -h
-if [ ! -d ${DIR_QA_ASSETS} ]; then
- DOCKER_EXEC git clone --depth=1 https://github.com/bitcoin-core/qa-assets ${DIR_QA_ASSETS}
+if [ "$RUN_FUZZ_TESTS" = "true" ] || [ "$RUN_UNIT_TESTS" = "true" ] || [ "$RUN_UNIT_TESTS_SEQUENTIAL" = "true" ]; then
+ if [ ! -d ${DIR_QA_ASSETS} ]; then
+ DOCKER_EXEC git clone --depth=1 https://github.com/bitcoin-core/qa-assets ${DIR_QA_ASSETS}
+ fi
+
+ export DIR_FUZZ_IN=${DIR_QA_ASSETS}/fuzz_seed_corpus/
+ export DIR_UNIT_TEST_DATA=${DIR_QA_ASSETS}/unit_test_data/
fi
-export DIR_FUZZ_IN=${DIR_QA_ASSETS}/fuzz_seed_corpus/
-export DIR_UNIT_TEST_DATA=${DIR_QA_ASSETS}/unit_test_data/
DOCKER_EXEC mkdir -p "${BASE_SCRATCH_DIR}/sanitizer-output/"
diff --git a/configure.ac b/configure.ac
index 88f91004af..6f78e8dec4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -318,13 +318,6 @@ AC_ARG_ENABLE([gprof],
[enable_gprof=$enableval],
[enable_gprof=no])
-dnl Pass compiler & linker flags that make builds deterministic
-AC_ARG_ENABLE([determinism],
- [AS_HELP_STRING([--enable-determinism],
- [Enable compilation flags that make builds deterministic (default is no)])],
- [enable_determinism=$enableval],
- [enable_determinism=no])
-
dnl Turn warnings into errors
AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-werror],
@@ -907,6 +900,7 @@ if test x$use_hardening != xno; then
])
fi
+ AX_CHECK_LINK_FLAG([[-Wl,--enable-reloc-section]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--enable-reloc-section"],, [[$LDFLAG_WERROR]])
AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"],, [[$LDFLAG_WERROR]])
AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"],, [[$LDFLAG_WERROR]])
AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"],, [[$LDFLAG_WERROR]])
@@ -931,12 +925,6 @@ if test x$TARGET_OS = xdarwin; then
AX_CHECK_LINK_FLAG([[-Wl,-bind_at_load]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-bind_at_load"],, [[$LDFLAG_WERROR]])
fi
-if test x$enable_determinism = xyes; then
- if test x$TARGET_OS = xwindows; then
- AX_CHECK_LINK_FLAG([[-Wl,--no-insert-timestamp]], [LDFLAGS="$LDFLAGS -Wl,--no-insert-timestamp"],, [[$LDFLAG_WERROR]])
- fi
-fi
-
AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h sys/sysctl.h vm/vm_param.h sys/vmmeter.h sys/resources.h])
AC_CHECK_DECLS([getifaddrs, freeifaddrs],[CHECK_SOCKET],,
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index 56e4313d78..61f727fa63 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -3,21 +3,22 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
-A script to check that the executables produced by gitian only contain
-certain symbols and are only linked against allowed libraries.
+A script to check that release executables only contain certain symbols
+and are only linked against allowed libraries.
Example usage:
- find ../gitian-builder/build -type f -executable | xargs python3 contrib/devtools/symbol-check.py
+ find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py
'''
import subprocess
import sys
-import os
from typing import List, Optional
import lief
import pixie
+from utils import determine_wellknown_cmd
+
# Debian 8 (Jessie) EOL: 2020. https://wiki.debian.org/DebianReleases#Production_Releases
#
# - g++ version 4.9.2 (https://packages.debian.org/search?suite=jessie&arch=any&searchon=names&keywords=g%2B%2B)
@@ -60,7 +61,6 @@ IGNORE_EXPORTS = {
'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr',
'environ', '_environ', '__environ',
}
-CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
# Allowed NEEDED libraries
ELF_ALLOWED_LIBRARIES = {
@@ -140,7 +140,7 @@ 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, universal_newlines=True)
+ self.proc = subprocess.Popen(determine_wellknown_cmd('CPPFILT', 'c++filt'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
def __call__(self, mangled):
self.proc.stdin.write(mangled + '\n')
diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py
index c079fe5b4d..14058e2cc8 100755
--- a/contrib/devtools/test-security-check.py
+++ b/contrib/devtools/test-security-check.py
@@ -9,6 +9,8 @@ import os
import subprocess
import unittest
+from utils import determine_wellknown_cmd
+
def write_testcode(filename):
with open(filename, 'w', encoding="utf8") as f:
f.write('''
@@ -25,7 +27,7 @@ def clean_files(source, executable):
os.remove(executable)
def call_security_check(cc, source, executable, options):
- subprocess.run([cc,source,'-o',executable] + options, check=True)
+ subprocess.run([*cc,source,'-o',executable] + options, check=True)
p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
return (p.returncode, p.stdout.rstrip())
@@ -33,7 +35,7 @@ class TestSecurityChecks(unittest.TestCase):
def test_ELF(self):
source = 'test1.c'
executable = 'test1'
- cc = 'gcc'
+ cc = determine_wellknown_cmd('CC', 'gcc')
write_testcode(source)
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
@@ -54,18 +56,20 @@ class TestSecurityChecks(unittest.TestCase):
def test_PE(self):
source = 'test1.c'
executable = 'test1.exe'
- cc = 'x86_64-w64-mingw32-gcc'
+ cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
write_testcode(source)
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
- (1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
- (1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
- (1, executable+': failed HIGH_ENTROPY_VA RELOC_SECTION'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va','-no-pie','-fno-PIE']),
- (1, executable+': failed RELOC_SECTION'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--disable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
+ (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--disable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
+ (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
+ (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-pie','-fPIE']),
+ (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA')) # -pie -fPIE does nothing unless --dynamicbase is also supplied
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--no-high-entropy-va','-pie','-fPIE']),
+ (1, executable+': failed HIGH_ENTROPY_VA'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']),
(0, ''))
clean_files(source, executable)
@@ -73,7 +77,7 @@ class TestSecurityChecks(unittest.TestCase):
def test_MACHO(self):
source = 'test1.c'
executable = 'test1'
- cc = 'clang'
+ cc = determine_wellknown_cmd('CC', 'clang')
write_testcode(source)
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']),
@@ -95,4 +99,3 @@ class TestSecurityChecks(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py
index 6ce2fa3560..7d83c5f751 100755
--- a/contrib/devtools/test-symbol-check.py
+++ b/contrib/devtools/test-symbol-check.py
@@ -7,41 +7,51 @@ Test script for symbol-check.py
'''
import os
import subprocess
+from typing import List
import unittest
-def call_symbol_check(cc, source, executable, options):
- subprocess.run([cc,source,'-o',executable] + options, check=True)
+from utils import determine_wellknown_cmd
+
+def call_symbol_check(cc: List[str], source, executable, options):
+ subprocess.run([*cc,source,'-o',executable] + options, check=True)
p = subprocess.run(['./contrib/devtools/symbol-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
os.remove(source)
os.remove(executable)
return (p.returncode, p.stdout.rstrip())
+def get_machine(cc: List[str]):
+ p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, universal_newlines=True)
+ return p.stdout.rstrip()
+
class TestSymbolChecks(unittest.TestCase):
def test_ELF(self):
source = 'test1.c'
executable = 'test1'
- cc = 'gcc'
+ cc = determine_wellknown_cmd('CC', 'gcc')
+
+ # there's no way to do this test for RISC-V at the moment; we build for
+ # RISC-V in a glibc 2.27 envinonment and we allow all symbols from 2.27.
+ if 'riscv' in get_machine(cc):
+ self.skipTest("test not available for RISC-V")
- # renameat2 was introduced in GLIBC 2.28, so is newer than the upper limit
- # of glibc for all platforms
+ # nextup was introduced in GLIBC 2.24, so is newer than our supported
+ # glibc (2.17), and available in our release build environment (2.24).
with open(source, 'w', encoding="utf8") as f:
f.write('''
#define _GNU_SOURCE
- #include <stdio.h>
- #include <linux/fs.h>
+ #include <math.h>
- int renameat2(int olddirfd, const char *oldpath,
- int newdirfd, const char *newpath, unsigned int flags);
+ double nextup(double x);
int main()
{
- renameat2(0, "test", 0, "test_", RENAME_EXCHANGE);
+ nextup(3.14);
return 0;
}
''')
- self.assertEqual(call_symbol_check(cc, source, executable, []),
- (1, executable + ': symbol renameat2 from unsupported version GLIBC_2.28\n' +
+ self.assertEqual(call_symbol_check(cc, source, executable, ['-lm']),
+ (1, executable + ': symbol nextup from unsupported version GLIBC_2.24\n' +
executable + ': failed IMPORTED_SYMBOLS'))
# -lutil is part of the libc6 package so a safe bet that it's installed
@@ -82,7 +92,7 @@ class TestSymbolChecks(unittest.TestCase):
def test_MACHO(self):
source = 'test1.c'
executable = 'test1'
- cc = 'clang'
+ cc = determine_wellknown_cmd('CC', 'clang')
with open(source, 'w', encoding="utf8") as f:
f.write('''
@@ -96,7 +106,7 @@ class TestSymbolChecks(unittest.TestCase):
''')
- self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat']),
+ self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']),
(1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' +
f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK'))
@@ -113,7 +123,7 @@ class TestSymbolChecks(unittest.TestCase):
}
''')
- self.assertEqual(call_symbol_check(cc, source, executable, ['-framework', 'CoreGraphics']),
+ self.assertEqual(call_symbol_check(cc, source, executable, ['-framework', 'CoreGraphics', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']),
(1, f'{executable}: failed MIN_OS SDK'))
source = 'test3.c'
@@ -126,13 +136,13 @@ class TestSymbolChecks(unittest.TestCase):
}
''')
- self.assertEqual(call_symbol_check(cc, source, executable, ['-mmacosx-version-min=10.14']),
+ self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,10.14', '-Wl,11.4']),
(1, f'{executable}: failed SDK'))
def test_PE(self):
source = 'test1.c'
executable = 'test1.exe'
- cc = 'x86_64-w64-mingw32-gcc'
+ cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
with open(source, 'w', encoding="utf8") as f:
f.write('''
@@ -182,4 +192,3 @@ class TestSymbolChecks(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/contrib/devtools/utils.py b/contrib/devtools/utils.py
new file mode 100755
index 0000000000..68ad1c3aba
--- /dev/null
+++ b/contrib/devtools/utils.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python3
+# Copyright (c) 2021 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+'''
+Common utility functions
+'''
+import shutil
+import sys
+import os
+from typing import List
+
+
+def determine_wellknown_cmd(envvar, progname) -> List[str]:
+ maybe_env = os.getenv(envvar)
+ maybe_which = shutil.which(progname)
+ if maybe_env:
+ return maybe_env.split(' ') # Well-known vars are often meant to be word-split
+ elif maybe_which:
+ return [ maybe_which ]
+ else:
+ sys.exit(f"{progname} not found")
diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
index 6741328473..0b96949a6b 100755
--- a/contrib/guix/libexec/build.sh
+++ b/contrib/guix/libexec/build.sh
@@ -214,6 +214,7 @@ make -C depends --jobs="$JOBS" HOST="$HOST" \
x86_64_linux_NM=x86_64-linux-gnu-nm \
x86_64_linux_STRIP=x86_64-linux-gnu-strip \
qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' \
+ qt_config_opts_x86_64_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' \
FORCE_USE_SYSTEM_CLANG=1
@@ -239,7 +240,7 @@ mkdir -p "$OUTDIR"
# CONFIGFLAGS
CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests --disable-fuzz-binary"
case "$HOST" in
- *linux*) CONFIGFLAGS+=" --enable-glibc-back-compat" ;;
+ *linux*) CONFIGFLAGS+=" --disable-threadlocal" ;;
esac
# CFLAGS
@@ -259,6 +260,13 @@ case "$HOST" in
*mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;;
esac
+# Using --no-tls-get-addr-optimize retains compatibility with glibc 2.17, by
+# avoiding a PowerPC64 optimisation available in glibc 2.22 and later.
+# https://sourceware.org/binutils/docs-2.35/ld/PowerPC64-ELF64.html
+case "$HOST" in
+ *powerpc64*) HOST_LDFLAGS="${HOST_LDFLAGS} -Wl,--no-tls-get-addr-optimize" ;;
+esac
+
case "$HOST" in
powerpc64-linux-*|riscv64-linux-*) HOST_LDFLAGS="${HOST_LDFLAGS} -Wl,-z,noexecstack" ;;
esac
@@ -291,10 +299,11 @@ mkdir -p "$DISTSRC"
# Build Bitcoin Core
make --jobs="$JOBS" ${V:+V=1}
- # Perform basic ELF security checks on a series of executables.
+ # Check that symbol/security checks tools are sane.
+ make test-security-check ${V:+V=1}
+ # Perform basic security checks on a series of executables.
make -C src --jobs=1 check-security ${V:+V=1}
- # Check that executables only contain allowed gcc, glibc and libstdc++
- # version symbols for Linux distro back-compatibility.
+ # Check that executables only contain allowed version symbols.
make -C src --jobs=1 check-symbols ${V:+V=1}
mkdir -p "$OUTDIR"
@@ -445,5 +454,6 @@ mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
find "$ACTUAL_OUTDIR" -type f
} | xargs realpath --relative-base="$PWD" \
| xargs sha256sum \
+ | sort -k2 \
| sponge "$ACTUAL_OUTDIR"/SHA256SUMS.part
)
diff --git a/contrib/guix/libexec/codesign.sh b/contrib/guix/libexec/codesign.sh
index b1eec686ec..f484ac5774 100755
--- a/contrib/guix/libexec/codesign.sh
+++ b/contrib/guix/libexec/codesign.sh
@@ -108,5 +108,6 @@ mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \
find "$ACTUAL_OUTDIR" -type f
} | xargs realpath --relative-base="$PWD" \
| xargs sha256sum \
+ | sort -k2 \
| sponge "$ACTUAL_OUTDIR"/SHA256SUMS.part
)
diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm
index ba168a2a4a..e71cf52533 100644
--- a/contrib/guix/manifest.scm
+++ b/contrib/guix/manifest.scm
@@ -80,6 +80,10 @@ http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html"
(("-rpath=") "-rpath-link="))
#t))))))))
+(define (make-binutils-with-mingw-w64-disable-flags xbinutils)
+ (package-with-extra-patches xbinutils
+ (search-our-patches "binutils-mingw-w64-disable-flags.patch")))
+
(define (make-cross-toolchain target
base-gcc-for-libc
base-kernel-headers
@@ -135,11 +139,25 @@ chain for " target " development."))
(package-with-extra-patches gcc-8
(search-our-patches "gcc-8-sort-libtool-find-output.patch")))
+;; Building glibc with stack smashing protector first landed in glibc 2.25, use
+;; this function to disable for older glibcs
+;;
+;; From glibc 2.25 changelog:
+;;
+;; * Most of glibc can now be built with the stack smashing protector enabled.
+;; It is recommended to build glibc with --enable-stack-protector=strong.
+;; Implemented by Nick Alcock (Oracle).
+(define (make-glibc-without-ssp xglibc)
+ (package-with-extra-configure-variable
+ (package-with-extra-configure-variable
+ xglibc "libc_cv_ssp" "no")
+ "libc_cv_ssp_strong" "no"))
+
(define* (make-bitcoin-cross-toolchain target
#:key
(base-gcc-for-libc gcc-7)
(base-kernel-headers linux-libre-headers-5.4)
- (base-libc glibc) ; glibc 2.31
+ (base-libc (make-glibc-without-ssp glibc-2.24))
(base-gcc (make-gcc-rpath-link base-gcc)))
"Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values
desirable for building Bitcoin Core release binaries."
@@ -154,7 +172,7 @@ desirable for building Bitcoin Core release binaries."
(define (make-mingw-pthreads-cross-toolchain target)
"Create a cross-compilation toolchain package for TARGET"
- (let* ((xbinutils (cross-binutils target))
+ (let* ((xbinutils (make-binutils-with-mingw-w64-disable-flags (cross-binutils target)))
(pthreads-xlibc mingw-w64-x86_64-winpthreads)
(pthreads-xgcc (make-gcc-with-pthreads
(cross-gcc target
@@ -557,6 +575,28 @@ and endian independent.")
inspecting signatures in Mach-O binaries.")
(license license:expat))))
+(define-public glibc-2.24
+ (package
+ (inherit glibc)
+ (version "2.24")
+ (source (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://sourceware.org/git/glibc.git")
+ (commit "0d7f1ed30969886c8dde62fbf7d2c79967d4bace")))
+ (file-name (git-file-name "glibc" "0d7f1ed30969886c8dde62fbf7d2c79967d4bace"))
+ (sha256
+ (base32
+ "0g5hryia5v1k0qx97qffgwzrz4lr4jw3s5kj04yllhswsxyjbic3"))
+ (patches (search-our-patches "glibc-ldd-x86_64.patch"
+ "glibc-versioned-locpath.patch"
+ "glibc-2.24-elfm-loadaddr-dynamic-rewrite.patch"
+ "glibc-2.24-no-build-time-cxx-header-run.patch"))))))
+
+(define glibc-2.27/bitcoin-patched
+ (package-with-extra-patches glibc-2.27
+ (search-our-patches "glibc-2.27-riscv64-Use-__has_include__-to-include-asm-syscalls.h.patch")))
+
(packages->manifest
(append
(list ;; The Basics
@@ -606,7 +646,10 @@ inspecting signatures in Mach-O binaries.")
(make-nsis-with-sde-support nsis-x86_64)
osslsigncode))
((string-contains target "-linux-")
- (list (make-bitcoin-cross-toolchain target)))
+ (list (cond ((string-contains target "riscv64-")
+ (make-bitcoin-cross-toolchain target #:base-libc glibc-2.27/bitcoin-patched))
+ (else
+ (make-bitcoin-cross-toolchain target)))))
((string-contains target "darwin")
(list clang-toolchain-10 binutils imagemagick libtiff librsvg font-tuffy cmake xorriso python-signapple))
(else '())))))
diff --git a/contrib/guix/patches/binutils-mingw-w64-disable-flags.patch b/contrib/guix/patches/binutils-mingw-w64-disable-flags.patch
new file mode 100644
index 0000000000..8f88eb9dfd
--- /dev/null
+++ b/contrib/guix/patches/binutils-mingw-w64-disable-flags.patch
@@ -0,0 +1,171 @@
+Description: Add disable opposites to the security-related flags
+Author: Stephen Kitt <skitt@debian.org>
+
+This patch adds "no-" variants to disable the various security flags:
+"no-dynamicbase", "no-nxcompat", "no-high-entropy-va", "disable-reloc-section".
+
+--- a/ld/emultempl/pe.em
++++ b/ld/emultempl/pe.em
+@@ -259,9 +261,11 @@
+ (OPTION_ENABLE_LONG_SECTION_NAMES + 1)
+ /* DLLCharacteristics flags. */
+ #define OPTION_DYNAMIC_BASE (OPTION_DISABLE_LONG_SECTION_NAMES + 1)
+-#define OPTION_FORCE_INTEGRITY (OPTION_DYNAMIC_BASE + 1)
++#define OPTION_NO_DYNAMIC_BASE (OPTION_DYNAMIC_BASE + 1)
++#define OPTION_FORCE_INTEGRITY (OPTION_NO_DYNAMIC_BASE + 1)
+ #define OPTION_NX_COMPAT (OPTION_FORCE_INTEGRITY + 1)
+-#define OPTION_NO_ISOLATION (OPTION_NX_COMPAT + 1)
++#define OPTION_NO_NX_COMPAT (OPTION_NX_COMPAT + 1)
++#define OPTION_NO_ISOLATION (OPTION_NO_NX_COMPAT + 1)
+ #define OPTION_NO_SEH (OPTION_NO_ISOLATION + 1)
+ #define OPTION_NO_BIND (OPTION_NO_SEH + 1)
+ #define OPTION_WDM_DRIVER (OPTION_NO_BIND + 1)
+@@ -271,6 +275,7 @@
+ #define OPTION_NO_INSERT_TIMESTAMP (OPTION_INSERT_TIMESTAMP + 1)
+ #define OPTION_BUILD_ID (OPTION_NO_INSERT_TIMESTAMP + 1)
+ #define OPTION_ENABLE_RELOC_SECTION (OPTION_BUILD_ID + 1)
++#define OPTION_DISABLE_RELOC_SECTION (OPTION_ENABLE_RELOC_SECTION + 1)
+
+ static void
+ gld${EMULATION_NAME}_add_options
+@@ -342,8 +347,10 @@
+ {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
+ {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+ {"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
++ {"no-dynamicbase", no_argument, NULL, OPTION_NO_DYNAMIC_BASE},
+ {"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
+ {"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
++ {"no-nxcompat", no_argument, NULL, OPTION_NO_NX_COMPAT},
+ {"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
+ {"no-seh", no_argument, NULL, OPTION_NO_SEH},
+ {"no-bind", no_argument, NULL, OPTION_NO_BIND},
+@@ -351,6 +358,7 @@
+ {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
+ {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+ {"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION},
++ {"disable-reloc-section", no_argument, NULL, OPTION_DISABLE_RELOC_SECTION},
+ {NULL, no_argument, NULL, 0}
+ };
+
+@@ -485,9 +494,12 @@
+ in object files\n"));
+ fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
+ address space layout randomization (ASLR)\n"));
++ fprintf (file, _(" --no-dynamicbase Image base address may not be relocated\n"));
+ fprintf (file, _(" --enable-reloc-section Create the base relocation table\n"));
++ fprintf (file, _(" --disable-reloc-section Disable the base relocation table\n"));
+ fprintf (file, _(" --forceinteg Code integrity checks are enforced\n"));
+ fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n"));
++ fprintf (file, _(" --no-nxcompat Image is not compatible with data execution prevention\n"));
+ fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n"));
+ fprintf (file, _(" --no-seh Image does not use SEH. No SE handler may\n\
+ be called in this image\n"));
+@@ -862,12 +874,21 @@
+ case OPTION_ENABLE_RELOC_SECTION:
+ pe_dll_enable_reloc_section = 1;
+ break;
++ case OPTION_DISABLE_RELOC_SECTION:
++ pe_dll_enable_reloc_section = 0;
++ /* fall through */
++ case OPTION_NO_DYNAMIC_BASE:
++ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
++ break;
+ case OPTION_FORCE_INTEGRITY:
+ pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+ break;
+ case OPTION_NX_COMPAT:
+ pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+ break;
++ case OPTION_NO_NX_COMPAT:
++ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
++ break;
+ case OPTION_NO_ISOLATION:
+ pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+ break;
+--- a/ld/emultempl/pep.em
++++ b/ld/emultempl/pep.em
+@@ -237,9 +240,12 @@
+ OPTION_ENABLE_LONG_SECTION_NAMES,
+ OPTION_DISABLE_LONG_SECTION_NAMES,
+ OPTION_HIGH_ENTROPY_VA,
++ OPTION_NO_HIGH_ENTROPY_VA,
+ OPTION_DYNAMIC_BASE,
++ OPTION_NO_DYNAMIC_BASE,
+ OPTION_FORCE_INTEGRITY,
+ OPTION_NX_COMPAT,
++ OPTION_NO_NX_COMPAT,
+ OPTION_NO_ISOLATION,
+ OPTION_NO_SEH,
+ OPTION_NO_BIND,
+@@ -248,7 +254,8 @@
+ OPTION_NO_INSERT_TIMESTAMP,
+ OPTION_TERMINAL_SERVER_AWARE,
+ OPTION_BUILD_ID,
+- OPTION_ENABLE_RELOC_SECTION
++ OPTION_ENABLE_RELOC_SECTION,
++ OPTION_DISABLE_RELOC_SECTION
+ };
+
+ static void
+@@ -315,9 +322,12 @@
+ {"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
+ {"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
+ {"high-entropy-va", no_argument, NULL, OPTION_HIGH_ENTROPY_VA},
++ {"no-high-entropy-va", no_argument, NULL, OPTION_NO_HIGH_ENTROPY_VA},
+ {"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
++ {"no-dynamicbase", no_argument, NULL, OPTION_NO_DYNAMIC_BASE},
+ {"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
+ {"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
++ {"no-nxcompat", no_argument, NULL, OPTION_NO_NX_COMPAT},
+ {"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
+ {"no-seh", no_argument, NULL, OPTION_NO_SEH},
+ {"no-bind", no_argument, NULL, OPTION_NO_BIND},
+@@ -327,6 +337,7 @@
+ {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
+ {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+ {"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION},
++ {"disable-reloc-section", no_argument, NULL, OPTION_DISABLE_RELOC_SECTION},
+ {NULL, no_argument, NULL, 0}
+ };
+
+@@ -448,11 +461,15 @@
+ in object files\n"));
+ fprintf (file, _(" --high-entropy-va Image is compatible with 64-bit address space\n\
+ layout randomization (ASLR)\n"));
++ fprintf (file, _(" --no-high-entropy-va Image is not compatible with 64-bit ASLR\n"));
+ fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
+ address space layout randomization (ASLR)\n"));
++ fprintf (file, _(" --no-dynamicbase Image base address may not be relocated\n"));
+ fprintf (file, _(" --enable-reloc-section Create the base relocation table\n"));
++ fprintf (file, _(" --disable-reloc-section Disable the base relocation table\n"));
+ fprintf (file, _(" --forceinteg Code integrity checks are enforced\n"));
+ fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n"));
++ fprintf (file, _(" --no-nxcompat Image is not compatible with data execution prevention\n"));
+ fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n"));
+ fprintf (file, _(" --no-seh Image does not use SEH; no SE handler may\n\
+ be called in this image\n"));
+@@ -809,12 +826,24 @@
+ case OPTION_ENABLE_RELOC_SECTION:
+ pep_dll_enable_reloc_section = 1;
+ break;
++ case OPTION_DISABLE_RELOC_SECTION:
++ pep_dll_enable_reloc_section = 0;
++ /* fall through */
++ case OPTION_NO_DYNAMIC_BASE:
++ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
++ /* fall through */
++ case OPTION_NO_HIGH_ENTROPY_VA:
++ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
++ break;
+ case OPTION_FORCE_INTEGRITY:
+ pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
+ break;
+ case OPTION_NX_COMPAT:
+ pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
+ break;
++ case OPTION_NO_NX_COMPAT:
++ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
++ break;
+ case OPTION_NO_ISOLATION:
+ pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
+ break;
diff --git a/contrib/guix/patches/gcc-8-sort-libtool-find-output.patch b/contrib/guix/patches/gcc-8-sort-libtool-find-output.patch
index 1dfe3ba132..f327c464f3 100644
--- a/contrib/guix/patches/gcc-8-sort-libtool-find-output.patch
+++ b/contrib/guix/patches/gcc-8-sort-libtool-find-output.patch
@@ -1,3 +1,11 @@
+guix: repro: Sort find output in libtool for gcc-8
+
+Otherwise the resulting .a static libraries (e.g. libstdc++.a) will not
+be reproducible and end up making the Bitcoin binaries non-reproducible
+as well.
+
+See: https://reproducible-builds.org/docs/archives/#gnu-libtool
+
diff --git a/gcc/configure b/gcc/configure
index 97ba7d7d69c..e37a96f0c0c 100755
--- a/gcc/configure
diff --git a/contrib/guix/patches/glibc-2.24-elfm-loadaddr-dynamic-rewrite.patch b/contrib/guix/patches/glibc-2.24-elfm-loadaddr-dynamic-rewrite.patch
new file mode 100644
index 0000000000..5c4d0c6ebe
--- /dev/null
+++ b/contrib/guix/patches/glibc-2.24-elfm-loadaddr-dynamic-rewrite.patch
@@ -0,0 +1,62 @@
+https://sourceware.org/git/?p=glibc.git;a=commit;h=a68ba2f3cd3cbe32c1f31e13c20ed13487727b32
+
+commit 6b02af31e9a721bb15a11380cd22d53b621711f8
+Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date: Wed Oct 18 17:26:23 2017 +0100
+
+ [AARCH64] Rewrite elf_machine_load_address using _DYNAMIC symbol
+
+ This patch rewrites aarch64 elf_machine_load_address to use special _DYNAMIC
+ symbol instead of _dl_start.
+
+ The static address of _DYNAMIC symbol is stored in the first GOT entry.
+ Here is the change which makes this solution work (part of binutils 2.24):
+ https://sourceware.org/ml/binutils/2013-06/msg00248.html
+
+ i386, x86_64 targets use the same method to do this as well.
+
+ The original implementation relies on a trick that R_AARCH64_ABS32 relocation
+ being resolved at link time and the static address fits in the 32bits.
+ However, in LP64, normally, the address is defined to be 64 bit.
+
+ Here is the C version one which should be portable in all cases.
+
+ * sysdeps/aarch64/dl-machine.h (elf_machine_load_address): Use
+ _DYNAMIC symbol to calculate load address.
+
+diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
+index e86d8b5b63..5a5b8a5de5 100644
+--- a/sysdeps/aarch64/dl-machine.h
++++ b/sysdeps/aarch64/dl-machine.h
+@@ -49,26 +49,11 @@ elf_machine_load_address (void)
+ /* To figure out the load address we use the definition that for any symbol:
+ dynamic_addr(symbol) = static_addr(symbol) + load_addr
+
+- The choice of symbol is arbitrary. The static address we obtain
+- by constructing a non GOT reference to the symbol, the dynamic
+- address of the symbol we compute using adrp/add to compute the
+- symbol's address relative to the PC.
+- This depends on 32bit relocations being resolved at link time
+- and that the static address fits in the 32bits. */
+-
+- ElfW(Addr) static_addr;
+- ElfW(Addr) dynamic_addr;
+-
+- asm (" \n"
+-" adrp %1, _dl_start; \n"
+-" add %1, %1, #:lo12:_dl_start \n"
+-" ldr %w0, 1f \n"
+-" b 2f \n"
+-"1: \n"
+-" .word _dl_start \n"
+-"2: \n"
+- : "=r" (static_addr), "=r" (dynamic_addr));
+- return dynamic_addr - static_addr;
++ _DYNAMIC sysmbol is used here as its link-time address stored in
++ the special unrelocated first GOT entry. */
++
++ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
++ return (ElfW(Addr)) &_DYNAMIC - elf_machine_dynamic ();
+ }
+
+ /* Set up the loaded object described by L so its unrelocated PLT
diff --git a/contrib/guix/patches/glibc-2.24-no-build-time-cxx-header-run.patch b/contrib/guix/patches/glibc-2.24-no-build-time-cxx-header-run.patch
new file mode 100644
index 0000000000..11fe7fdc99
--- /dev/null
+++ b/contrib/guix/patches/glibc-2.24-no-build-time-cxx-header-run.patch
@@ -0,0 +1,100 @@
+https://sourceware.org/git/?p=glibc.git;a=commit;h=fc3e1337be1c6935ab58bd13520f97a535cf70cc
+
+commit dc23a45db566095e83ff0b7a57afc87fb5ca89a1
+Author: Florian Weimer <fweimer@redhat.com>
+Date: Wed Sep 21 10:45:32 2016 +0200
+
+ Avoid running $(CXX) during build to obtain header file paths
+
+ This reduces the build time somewhat and is particularly noticeable
+ during rebuilds with few code changes.
+
+diff --git a/Makerules b/Makerules
+index 7e4077ee50..c338850de5 100644
+--- a/Makerules
++++ b/Makerules
+@@ -121,14 +121,10 @@ ifneq (,$(CXX))
+ # will be used instead of /usr/include/stdlib.h and /usr/include/math.h.
+ before-compile := $(common-objpfx)cstdlib $(common-objpfx)cmath \
+ $(before-compile)
+-cstdlib=$(shell echo "\#include <cstdlib>" | $(CXX) -M -MP -x c++ - \
+- | sed -n "/cstdlib:/{s/:$$//;p}")
+-$(common-objpfx)cstdlib: $(cstdlib)
++$(common-objpfx)cstdlib: $(c++-cstdlib-header)
+ $(INSTALL_DATA) $< $@T
+ $(move-if-change) $@T $@
+-cmath=$(shell echo "\#include <cmath>" | $(CXX) -M -MP -x c++ - \
+- | sed -n "/cmath:/{s/:$$//;p}")
+-$(common-objpfx)cmath: $(cmath)
++$(common-objpfx)cmath: $(c++-cmath-header)
+ $(INSTALL_DATA) $< $@T
+ $(move-if-change) $@T $@
+ endif
+diff --git a/config.make.in b/config.make.in
+index 95c6f36876..04a8b3ed7f 100644
+--- a/config.make.in
++++ b/config.make.in
+@@ -45,6 +45,8 @@ defines = @DEFINES@
+ sysheaders = @sysheaders@
+ sysincludes = @SYSINCLUDES@
+ c++-sysincludes = @CXX_SYSINCLUDES@
++c++-cstdlib-header = @CXX_CSTDLIB_HEADER@
++c++-cmath-header = @CXX_CMATH_HEADER@
+ all-warnings = @all_warnings@
+ enable-werror = @enable_werror@
+
+diff --git a/configure b/configure
+index 17625e1041..6ff252744b 100755
+--- a/configure
++++ b/configure
+@@ -635,6 +635,8 @@ BISON
+ INSTALL_INFO
+ PERL
+ BASH_SHELL
++CXX_CMATH_HEADER
++CXX_CSTDLIB_HEADER
+ CXX_SYSINCLUDES
+ SYSINCLUDES
+ AUTOCONF
+@@ -5054,6 +5056,18 @@ fi
+
+
+
++# Obtain some C++ header file paths. This is used to make a local
++# copy of those headers in Makerules.
++if test -n "$CXX"; then
++ find_cxx_header () {
++ echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}"
++ }
++ CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)"
++ CXX_CMATH_HEADER="$(find_cxx_header cmath)"
++fi
++
++
++
+ # Test if LD_LIBRARY_PATH contains the notation for the current directory
+ # since this would lead to problems installing/building glibc.
+ # LD_LIBRARY_PATH contains the current directory if one of the following
+diff --git a/configure.ac b/configure.ac
+index 33bcd62180..9938ab0dc2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1039,6 +1039,18 @@ fi
+ AC_SUBST(SYSINCLUDES)
+ AC_SUBST(CXX_SYSINCLUDES)
+
++# Obtain some C++ header file paths. This is used to make a local
++# copy of those headers in Makerules.
++if test -n "$CXX"; then
++ find_cxx_header () {
++ echo "#include <$1>" | $CXX -M -MP -x c++ - | sed -n "/$1:/{s/:\$//;p}"
++ }
++ CXX_CSTDLIB_HEADER="$(find_cxx_header cstdlib)"
++ CXX_CMATH_HEADER="$(find_cxx_header cmath)"
++fi
++AC_SUBST(CXX_CSTDLIB_HEADER)
++AC_SUBST(CXX_CMATH_HEADER)
++
+ # Test if LD_LIBRARY_PATH contains the notation for the current directory
+ # since this would lead to problems installing/building glibc.
+ # LD_LIBRARY_PATH contains the current directory if one of the following
diff --git a/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include__-to-include-asm-syscalls.h.patch b/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include__-to-include-asm-syscalls.h.patch
new file mode 100644
index 0000000000..d6217157ee
--- /dev/null
+++ b/contrib/guix/patches/glibc-2.27-riscv64-Use-__has_include__-to-include-asm-syscalls.h.patch
@@ -0,0 +1,72 @@
+https://sourceware.org/git/?p=glibc.git;a=commit;h=0b9c84906f653978fb8768c7ebd0ee14a47e662e
+
+From 562c52cc81a4e456a62e6455feb32732049e9070 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Mon, 31 Dec 2018 09:26:42 -0800
+Subject: [PATCH] riscv: Use __has_include__ to include <asm/syscalls.h> [BZ
+ #24022]
+
+<asm/syscalls.h> has been removed by
+
+commit 27f8899d6002e11a6e2d995e29b8deab5aa9cc25
+Author: David Abdurachmanov <david.abdurachmanov@gmail.com>
+Date: Thu Nov 8 20:02:39 2018 +0100
+
+ riscv: add asm/unistd.h UAPI header
+
+ Marcin Juszkiewicz reported issues while generating syscall table for riscv
+ using 4.20-rc1. The patch refactors our unistd.h files to match some other
+ architectures.
+
+ - Add asm/unistd.h UAPI header, which has __ARCH_WANT_NEW_STAT only for 64-bit
+ - Remove asm/syscalls.h UAPI header and merge to asm/unistd.h
+ - Adjust kernel asm/unistd.h
+
+ So now asm/unistd.h UAPI header should show all syscalls for riscv.
+
+<asm/syscalls.h> may be restored by
+
+Subject: [PATCH] riscv: restore asm/syscalls.h UAPI header
+Date: Tue, 11 Dec 2018 09:09:35 +0100
+
+UAPI header asm/syscalls.h was merged into UAPI asm/unistd.h header,
+which did resolve issue with missing syscalls macros resulting in
+glibc (2.28) build failure. It also broke glibc in a different way:
+asm/syscalls.h is being used by glibc. I noticed this while doing
+Fedora 30/Rawhide mass rebuild.
+
+The patch returns asm/syscalls.h header and incl. it into asm/unistd.h.
+I plan to send a patch to glibc to use asm/unistd.h instead of
+asm/syscalls.h
+
+In the meantime, we use __has_include__, which was added to GCC 5, to
+check if <asm/syscalls.h> exists before including it. Tested with
+build-many-glibcs.py for riscv against kernel 4.19.12 and 4.20-rc7.
+
+ [BZ #24022]
+ * sysdeps/unix/sysv/linux/riscv/flush-icache.c: Check if
+ <asm/syscalls.h> exists with __has_include__ before including it.
+---
+ sysdeps/unix/sysv/linux/riscv/flush-icache.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/unix/sysv/linux/riscv/flush-icache.c b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
+index d612ef4c6c..0b2042620b 100644
+--- a/sysdeps/unix/sysv/linux/riscv/flush-icache.c
++++ b/sysdeps/unix/sysv/linux/riscv/flush-icache.c
+@@ -21,7 +21,11 @@
+ #include <stdlib.h>
+ #include <atomic.h>
+ #include <sys/cachectl.h>
+-#include <asm/syscalls.h>
++#if __has_include__ (<asm/syscalls.h>)
++# include <asm/syscalls.h>
++#else
++# include <asm/unistd.h>
++#endif
+
+ typedef int (*func_type) (void *, void *, unsigned long int);
+
+--
+2.31.1
+
diff --git a/contrib/guix/patches/glibc-ldd-x86_64.patch b/contrib/guix/patches/glibc-ldd-x86_64.patch
new file mode 100644
index 0000000000..b1b6d5a548
--- /dev/null
+++ b/contrib/guix/patches/glibc-ldd-x86_64.patch
@@ -0,0 +1,10 @@
+By default, 'RTDLLIST' in 'ldd' refers to 'lib64/ld-linux-x86-64.so', whereas
+it's in 'lib/' for us. This patch fixes that.
+
+--- glibc-2.17/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed 2012-12-25 04:02:13.000000000 +0100
++++ glibc-2.17/sysdeps/unix/sysv/linux/x86_64/ldd-rewrite.sed 2013-09-15 23:08:03.000000000 +0200
+@@ -1,3 +1,3 @@
+ /LD_TRACE_LOADED_OBJECTS=1/a\
+ add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
+-s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \264\4-x86-64\6 \2x32\4-x32\6"_
++s_^\(RTLDLIST=\)\(.*lib\)\(\|64\|x32\)\(/[^/]*\)\(-x86-64\|-x32\)\(\.so\.[0-9.]*\)[ ]*$_\1"\2\4\6 \2\4-x86-64\6 \2x32\4-x32\6"_
diff --git a/contrib/guix/patches/glibc-versioned-locpath.patch b/contrib/guix/patches/glibc-versioned-locpath.patch
new file mode 100644
index 0000000000..bc7652127f
--- /dev/null
+++ b/contrib/guix/patches/glibc-versioned-locpath.patch
@@ -0,0 +1,240 @@
+The format of locale data can be incompatible between libc versions, and
+loading incompatible data can lead to 'setlocale' returning EINVAL at best
+or triggering an assertion failure at worst. See
+https://lists.gnu.org/archive/html/guix-devel/2015-09/msg00717.html
+for background information.
+
+To address that, this patch changes libc to honor a new 'GUIX_LOCPATH'
+variable, and to look for locale data in version-specific sub-directories of
+that variable. So, if GUIX_LOCPATH=/foo:/bar, locale data is searched for in
+/foo/X.Y and /bar/X.Y, where X.Y is the libc version number.
+
+That way, a single 'GUIX_LOCPATH' setting can work even if different libc
+versions coexist on the system.
+
+--- a/locale/newlocale.c
++++ b/locale/newlocale.c
+@@ -30,6 +30,7 @@
+ /* Lock for protecting global data. */
+ __libc_rwlock_define (extern , __libc_setlocale_lock attribute_hidden)
+
++extern error_t compute_locale_search_path (char **, size_t *);
+
+ /* Use this when we come along an error. */
+ #define ERROR_RETURN \
+@@ -48,7 +49,6 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
+ __locale_t result_ptr;
+ char *locale_path;
+ size_t locale_path_len;
+- const char *locpath_var;
+ int cnt;
+ size_t names_len;
+
+@@ -102,17 +102,8 @@ __newlocale (int category_mask, const char *locale, __locale_t base)
+ locale_path = NULL;
+ locale_path_len = 0;
+
+- locpath_var = getenv ("LOCPATH");
+- if (locpath_var != NULL && locpath_var[0] != '\0')
+- {
+- if (__argz_create_sep (locpath_var, ':',
+- &locale_path, &locale_path_len) != 0)
+- return NULL;
+-
+- if (__argz_add_sep (&locale_path, &locale_path_len,
+- _nl_default_locale_path, ':') != 0)
+- return NULL;
+- }
++ if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
++ return NULL;
+
+ /* Get the names for the locales we are interested in. We either
+ allow a composite name or a single name. */
+diff --git a/locale/setlocale.c b/locale/setlocale.c
+index ead030d..0c0e314 100644
+--- a/locale/setlocale.c
++++ b/locale/setlocale.c
+@@ -215,12 +215,65 @@ setdata (int category, struct __locale_data *data)
+ }
+ }
+
++/* Return in *LOCALE_PATH and *LOCALE_PATH_LEN the locale data search path as
++ a colon-separated list. Return ENOMEN on error, zero otherwise. */
++error_t
++compute_locale_search_path (char **locale_path, size_t *locale_path_len)
++{
++ char* guix_locpath_var = getenv ("GUIX_LOCPATH");
++ char *locpath_var = getenv ("LOCPATH");
++
++ if (guix_locpath_var != NULL && guix_locpath_var[0] != '\0')
++ {
++ /* Entries in 'GUIX_LOCPATH' take precedence over 'LOCPATH'. These
++ entries are systematically prefixed with "/X.Y" where "X.Y" is the
++ libc version. */
++ if (__argz_create_sep (guix_locpath_var, ':',
++ locale_path, locale_path_len) != 0
++ || __argz_suffix_entries (locale_path, locale_path_len,
++ "/" VERSION) != 0)
++ goto bail_out;
++ }
++
++ if (locpath_var != NULL && locpath_var[0] != '\0')
++ {
++ char *reg_locale_path = NULL;
++ size_t reg_locale_path_len = 0;
++
++ if (__argz_create_sep (locpath_var, ':',
++ &reg_locale_path, &reg_locale_path_len) != 0)
++ goto bail_out;
++
++ if (__argz_append (locale_path, locale_path_len,
++ reg_locale_path, reg_locale_path_len) != 0)
++ goto bail_out;
++
++ free (reg_locale_path);
++ }
++
++ if (*locale_path != NULL)
++ {
++ /* Append the system default locale directory. */
++ if (__argz_add_sep (locale_path, locale_path_len,
++ _nl_default_locale_path, ':') != 0)
++ goto bail_out;
++ }
++
++ return 0;
++
++ bail_out:
++ free (*locale_path);
++ *locale_path = NULL;
++ *locale_path_len = 0;
++
++ return ENOMEM;
++}
++
+ char *
+ setlocale (int category, const char *locale)
+ {
+ char *locale_path;
+ size_t locale_path_len;
+- const char *locpath_var;
+ char *composite;
+
+ /* Sanity check for CATEGORY argument. */
+@@ -251,17 +304,10 @@ setlocale (int category, const char *locale)
+ locale_path = NULL;
+ locale_path_len = 0;
+
+- locpath_var = getenv ("LOCPATH");
+- if (locpath_var != NULL && locpath_var[0] != '\0')
++ if (compute_locale_search_path (&locale_path, &locale_path_len) != 0)
+ {
+- if (__argz_create_sep (locpath_var, ':',
+- &locale_path, &locale_path_len) != 0
+- || __argz_add_sep (&locale_path, &locale_path_len,
+- _nl_default_locale_path, ':') != 0)
+- {
+- __libc_rwlock_unlock (__libc_setlocale_lock);
+- return NULL;
+- }
++ __libc_rwlock_unlock (__libc_setlocale_lock);
++ return NULL;
+ }
+
+ if (category == LC_ALL)
+diff --git a/string/Makefile b/string/Makefile
+index 8424a61..f925503 100644
+--- a/string/Makefile
++++ b/string/Makefile
+@@ -38,7 +38,7 @@ routines := strcat strchr strcmp strcoll strcpy strcspn \
+ swab strfry memfrob memmem rawmemchr strchrnul \
+ $(addprefix argz-,append count create ctsep next \
+ delete extract insert stringify \
+- addsep replace) \
++ addsep replace suffix) \
+ envz basename \
+ strcoll_l strxfrm_l string-inlines memrchr \
+ xpg-strerror strerror_l
+diff --git a/string/argz-suffix.c b/string/argz-suffix.c
+new file mode 100644
+index 0000000..505b0f2
+--- /dev/null
++++ b/string/argz-suffix.c
+@@ -0,0 +1,56 @@
++/* Copyright (C) 2015 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ludovic Courtès <ludo@gnu.org>.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <http://www.gnu.org/licenses/>. */
++
++#include <argz.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <string.h>
++
++
++error_t
++__argz_suffix_entries (char **argz, size_t *argz_len, const char *suffix)
++
++{
++ size_t suffix_len = strlen (suffix);
++ size_t count = __argz_count (*argz, *argz_len);
++ size_t new_argz_len = *argz_len + count * suffix_len;
++ char *new_argz = malloc (new_argz_len);
++
++ if (new_argz)
++ {
++ char *p = new_argz, *entry;
++
++ for (entry = *argz;
++ entry != NULL;
++ entry = argz_next (*argz, *argz_len, entry))
++ {
++ p = stpcpy (p, entry);
++ p = stpcpy (p, suffix);
++ p++;
++ }
++
++ free (*argz);
++ *argz = new_argz;
++ *argz_len = new_argz_len;
++
++ return 0;
++ }
++ else
++ return ENOMEM;
++}
++weak_alias (__argz_suffix_entries, argz_suffix_entries)
+diff --git a/string/argz.h b/string/argz.h
+index bb62a31..d276a35 100644
+--- a/string/argz.h
++++ b/string/argz.h
+@@ -134,6 +134,16 @@ extern error_t argz_replace (char **__restrict __argz,
+ const char *__restrict __str,
+ const char *__restrict __with,
+ unsigned int *__restrict __replace_count);
++
++/* Suffix each entry of ARGZ & ARGZ_LEN with SUFFIX. Return 0 on success,
++ and ENOMEN if memory cannot be allocated. */
++extern error_t __argz_suffix_entries (char **__restrict __argz,
++ size_t *__restrict __argz_len,
++ const char *__restrict __suffix);
++extern error_t argz_suffix_entries (char **__restrict __argz,
++ size_t *__restrict __argz_len,
++ const char *__restrict __suffix);
++
+
+ /* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
+ are no more. If entry is NULL, then the first entry is returned. This
diff --git a/contrib/guix/patches/nsis-SConstruct-sde-support.patch b/contrib/guix/patches/nsis-SConstruct-sde-support.patch
index 5edf1b7c8e..f58406a7a0 100644
--- a/contrib/guix/patches/nsis-SConstruct-sde-support.patch
+++ b/contrib/guix/patches/nsis-SConstruct-sde-support.patch
@@ -1,3 +1,6 @@
+https://github.com/kichik/nsis/pull/13
+https://sourceforge.net/p/nsis/code/7248/
+
diff --git a/SConstruct b/SConstruct
index e8252c9..41786f2 100755
--- a/SConstruct
diff --git a/depends/README.md b/depends/README.md
index 50e1a32c70..4f3b6df487 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -87,6 +87,14 @@ For linux S390X cross compilation:
sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu
+### Install the required dependencies: M1-based macOS
+
+To be able to build the `qt` package, ensure that Rosetta 2 is installed:
+
+```
+softwareupdate --install-rosetta
+```
+
### Dependency Options
The following can be set when running make: `make FOO=bar`
diff --git a/doc/README.md b/doc/README.md
index 45e7983038..38f6b1d327 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -30,8 +30,8 @@ Drag Bitcoin Core to your applications folder, and then run Bitcoin Core.
* See the documentation at the [Bitcoin Wiki](https://en.bitcoin.it/wiki/Main_Page)
for help and more information.
-* Ask for help on the [Bitcoin StackExchange](https://bitcoin.stackexchange.com)
-* Ask for help on [#bitcoin](https://webchat.freenode.net/#bitcoin) on Freenode. If you don't have an IRC client, use [webchat here](https://webchat.freenode.net/#bitcoin).
+* Ask for help on [Bitcoin StackExchange](https://bitcoin.stackexchange.com).
+* Ask for help on #bitcoin on Libera Chat. If you don't have an IRC client, you can use [web.libera.chat](https://web.libera.chat/#bitcoin).
* Ask for help on the [BitcoinTalk](https://bitcointalk.org/) forums, in the [Technical Support board](https://bitcointalk.org/index.php?board=4.0).
Building
@@ -68,8 +68,7 @@ The Bitcoin repo's [root README](/README.md) contains relevant information on th
### Resources
* Discuss on the [BitcoinTalk](https://bitcointalk.org/) forums, in the [Development & Technical Discussion board](https://bitcointalk.org/index.php?board=6.0).
-* Discuss project-specific development on #bitcoin-core-dev on Libera Chat. If you don't have an IRC client, use [webchat here](https://web.libera.chat/#bitcoin-core-dev).
-* Discuss general Bitcoin development on #bitcoin-dev on Freenode. If you don't have an IRC client, use [webchat here](https://webchat.freenode.net/#bitcoin-dev).
+* Discuss project-specific development on #bitcoin-core-dev on Libera Chat. If you don't have an IRC client, you can use [web.libera.chat](https://web.libera.chat/#bitcoin-core-dev).
### Miscellaneous
- [Assets Attribution](assets-attribution.md)
diff --git a/doc/benchmarking.md b/doc/benchmarking.md
index b6cd86eafe..84d5f2c444 100644
--- a/doc/benchmarking.md
+++ b/doc/benchmarking.md
@@ -8,8 +8,10 @@ thread queue, wallet balance.
Running
---------------------
-For benchmarks purposes you only need to compile `bitcoin_bench`. Beware of configuring without `--enable-debug` as this would impact
-benchmarking by unlatching log printers and lock analysis.
+For benchmarking, you only need to compile `bitcoin_bench`. The bench runner
+warns if you configure with `--enable-debug`, but consider if building without
+it will impact the benchmark(s) you are interested in by unlatching log printers
+and lock analysis.
make -C src bitcoin_bench
@@ -19,19 +21,28 @@ After compiling bitcoin-core, the benchmarks can be run with:
The output will look similar to:
```
-| ns/byte | byte/s | error % | benchmark
-|--------------------:|--------------------:|--------:|:----------------------------------------------
-| 64.13 | 15,592,356.01 | 0.1% | `Base58CheckEncode`
-| 24.56 | 40,722,672.68 | 0.2% | `Base58Decode`
+| ns/op | op/s | err% | total | benchmark
+|--------------------:|--------------------:|--------:|----------:|:----------
+| 57,927,463.00 | 17.26 | 3.6% | 0.66 | `AddrManAdd`
+| 677,816.00 | 1,475.33 | 4.9% | 0.01 | `AddrManGetAddr`
+
+...
+
+| ns/byte | byte/s | err% | total | benchmark
+|--------------------:|--------------------:|--------:|----------:|:----------
+| 127.32 | 7,854,302.69 | 0.3% | 0.00 | `Base58CheckEncode`
+| 31.95 | 31,303,226.99 | 0.2% | 0.00 | `Base58Decode`
+
...
```
Help
---------------------
- src/bench/bench_bitcoin --help
+ src/bench/bench_bitcoin -?
-To print options like scaling factor or per-benchmark filter.
+To print the various options, like listing the benchmarks without running them
+or using a regex filter to only run certain benchmarks.
Notes
---------------------
diff --git a/doc/dependencies.md b/doc/dependencies.md
index a467759418..66c5a76b3b 100644
--- a/doc/dependencies.md
+++ b/doc/dependencies.md
@@ -7,7 +7,7 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct
| --- | --- | --- | --- | --- | --- |
| Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | |
| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.64.0](https://github.com/bitcoin/bitcoin/pull/22320) | No | | |
-| Clang | | [5.0+](https://releases.llvm.org/download.html) (C++17 support) | | | |
+| Clang<sup>[ \* ](#note1)</sup> | | [5.0+](https://releases.llvm.org/download.html) (C++17 support) | | | |
| Expat | [2.2.7](https://libexpat.github.io/) | | No | Yes | |
| fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | |
| FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) (Android only) |
@@ -28,6 +28,8 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct
| ZeroMQ | [4.3.1](https://github.com/zeromq/libzmq/releases) | 4.0.0 | No | | |
| zlib | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) |
+<a name="note1">Note \*</a> : When compiling with `-stdlib=libc++`, the minimum supported libc++ version is 7.0.
+
Controlling dependencies
------------------------
Some dependencies are not needed in all configurations. The following are some factors that affect the dependency list.
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index c3a63b3523..583c50a763 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -88,7 +88,7 @@ code.
separate words (snake_case).
- Class member variables have a `m_` prefix.
- Global variables have a `g_` prefix.
- - Compile-time constant names are all uppercase, and use `_` to separate words.
+ - Constant names are all uppercase, and use `_` to separate words.
- Class names, function names, and method names are UpperCamelCase
(PascalCase). Do not prefix class names with `C`.
- Test suite naming convention: The Boost test suite in file
diff --git a/doc/release-process.md b/doc/release-process.md
index 3ead1181b9..546169df8d 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -278,7 +278,7 @@ The `*-debug*` files generated by the gitian build contain debug symbols
for troubleshooting by developers. It is assumed that anyone that is interested
in debugging can run gitian to generate the files for themselves. To avoid
end-user confusion about which file to pick, as well as save storage
-space *do not upload these to the bitcoin.org server, nor put them in the torrent*.
+space *do not upload these to the bitcoincore.org server, nor put them in the torrent*.
- GPG-sign it, delete the unsigned file:
```
@@ -288,7 +288,7 @@ rm SHA256SUMS
(the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files)
Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry.
-- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server
+- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoincore.org server
into `/var/www/bin/bitcoin-core-${VERSION}`
- A `.torrent` will appear in the directory after a few minutes. Optionally help seed this torrent. To get the `magnet:` URI use:
@@ -296,24 +296,9 @@ Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spur
transmission-show -m <torrent file>
```
Insert the magnet URI into the announcement sent to mailing lists. This permits
-people without access to `bitcoin.org` to download the binary distribution.
+people without access to `bitcoincore.org` to download the binary distribution.
Also put it into the `optional_magnetlink:` slot in the YAML file for
-bitcoin.org (see below for bitcoin.org update instructions).
-
-- Update bitcoin.org version
-
- - First, check to see if the Bitcoin.org maintainers have prepared a
- release: https://github.com/bitcoin-dot-org/bitcoin.org/labels/Core
-
- - If they have, it will have previously failed their CI
- checks because the final release files weren't uploaded.
- Trigger a CI rebuild---if it passes, merge.
-
- - If they have not prepared a release, follow the Bitcoin.org release
- instructions: https://github.com/bitcoin-dot-org/bitcoin.org/blob/master/docs/adding-events-release-notes-and-alerts.md#release-notes
-
- - After the pull request is merged, the website will automatically show the newest version within 15 minutes, as well
- as update the OS download links.
+bitcoincore.org.
- Update other repositories and websites for new version
diff --git a/src/Makefile.am b/src/Makefile.am
index e2ed70556d..7de5fb36ed 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -145,6 +145,8 @@ BITCOIN_CORE_H = \
core_memusage.h \
cuckoocache.h \
dbwrapper.h \
+ deploymentinfo.h \
+ deploymentstatus.h \
external_signer.h \
flatfile.h \
fs.h \
@@ -272,7 +274,6 @@ BITCOIN_CORE_H = \
validation.h \
validationinterface.h \
versionbits.h \
- versionbitsinfo.h \
wallet/bdb.h \
wallet/coincontrol.h \
wallet/coinselection.h \
@@ -328,6 +329,7 @@ libbitcoin_server_a_SOURCES = \
chain.cpp \
consensus/tx_verify.cpp \
dbwrapper.cpp \
+ deploymentstatus.cpp \
flatfile.cpp \
httprpc.cpp \
httpserver.cpp \
@@ -540,6 +542,7 @@ libbitcoin_common_a_SOURCES = \
compressor.cpp \
core_read.cpp \
core_write.cpp \
+ deploymentinfo.cpp \
external_signer.cpp \
init/common.cpp \
key.cpp \
@@ -561,7 +564,6 @@ libbitcoin_common_a_SOURCES = \
script/sign.cpp \
script/signingprovider.cpp \
script/standard.cpp \
- versionbitsinfo.cpp \
warnings.cpp \
$(BITCOIN_CORE_H)
@@ -812,23 +814,23 @@ clean-local:
check-symbols: $(bin_PROGRAMS)
if TARGET_DARWIN
@echo "Checking macOS dynamic libraries..."
- $(AM_V_at) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
+ $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
endif
if TARGET_WINDOWS
@echo "Checking Windows dynamic libraries..."
- $(AM_V_at) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
+ $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
endif
-if GLIBC_BACK_COMPAT
+if TARGET_LINUX
@echo "Checking glibc back compat..."
- $(AM_V_at) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
+ $(AM_V_at) CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
endif
check-security: $(bin_PROGRAMS)
if HARDEN
@echo "Checking binary security..."
- $(AM_V_at) OBJDUMP=$(OBJDUMP) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS)
+ $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS)
endif
libbitcoin_ipc_mpgen_input = \
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 8f702b5a8c..8192b4eba6 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -77,6 +77,38 @@ double CAddrInfo::GetChance(int64_t nNow) const
return fChance;
}
+void CAddrMan::RemoveInvalid()
+{
+ for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; ++bucket) {
+ for (size_t i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
+ const auto id = vvNew[bucket][i];
+ if (id != -1 && !mapInfo[id].IsValid()) {
+ ClearNew(bucket, i);
+ }
+ }
+ }
+
+ for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; ++bucket) {
+ for (size_t i = 0; i < ADDRMAN_BUCKET_SIZE; ++i) {
+ const auto id = vvTried[bucket][i];
+ if (id == -1) {
+ continue;
+ }
+ const auto& addr_info = mapInfo[id];
+ if (addr_info.IsValid()) {
+ continue;
+ }
+ vvTried[bucket][i] = -1;
+ --nTried;
+ SwapRandom(addr_info.nRandomPos, vRandom.size() - 1);
+ vRandom.pop_back();
+ mapAddr.erase(addr_info);
+ mapInfo.erase(id);
+ m_tried_collisions.erase(id);
+ }
+ }
+}
+
CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId)
{
AssertLockHeld(cs);
diff --git a/src/addrman.h b/src/addrman.h
index 665e253192..c2f425f2fa 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -450,6 +450,8 @@ public:
LogPrint(BCLog::ADDRMAN, "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
}
+ RemoveInvalid();
+
Check();
}
@@ -762,6 +764,9 @@ private:
//! Update an entry's service bits.
void SetServices_(const CService &addr, ServiceFlags nServices) EXCLUSIVE_LOCKS_REQUIRED(cs);
+ //! Remove invalid addresses.
+ void RemoveInvalid() EXCLUSIVE_LOCKS_REQUIRED(cs);
+
friend class CAddrManTest;
};
diff --git a/src/bench/bench.h b/src/bench/bench.h
index 22f06d8cb8..c4fcd80e33 100644
--- a/src/bench/bench.h
+++ b/src/bench/bench.h
@@ -18,16 +18,19 @@
/*
* Usage:
-static void CODE_TO_TIME(benchmark::Bench& bench)
+static void NameOfYourBenchmarkFunction(benchmark::Bench& bench)
{
- ... do any setup needed...
- nanobench::Config().run([&] {
- ... do stuff you want to time...
+ ...do any setup needed...
+
+ bench.run([&] {
+ ...do stuff you want to time; refer to src/bench/nanobench.h
+ for more information and the options that can be passed here...
});
- ... do any cleanup needed...
+
+ ...do any cleanup needed...
}
-BENCHMARK(CODE_TO_TIME);
+BENCHMARK(NameOfYourBenchmarkFunction);
*/
@@ -55,7 +58,8 @@ public:
static void RunAll(const Args& args);
};
-}
+} // namespace benchmark
+
// BENCHMARK(foo) expands to: benchmark::BenchRunner bench_11foo("foo", foo);
#define BENCHMARK(n) \
benchmark::BenchRunner PASTE2(bench_, PASTE2(__LINE__, n))(STRINGIZE(n), n);
diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp
index 135659f87f..aab777cac1 100644
--- a/src/bench/bench_bitcoin.cpp
+++ b/src/bench/bench_bitcoin.cpp
@@ -16,11 +16,11 @@ static void SetupBenchArgs(ArgsManager& argsman)
{
SetupHelpOptions(argsman);
- argsman.AddArg("-list", "List benchmarks without executing them", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ argsman.AddArg("-asymptote=n1,n2,n3,...", "Test asymptotic growth of the runtime of an algorithm, if supported by the benchmark", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-filter=<regex>", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
- argsman.AddArg("-asymptote=n1,n2,n3,...", strprintf("Test asymptotic growth of the runtime of an algorithm, if supported by the benchmark"), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
- argsman.AddArg("-output_csv=<output.csv>", "Generate CSV file with the most important benchmark results.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
- argsman.AddArg("-output_json=<output.json>", "Generate JSON file with all benchmark results.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ argsman.AddArg("-list", "List benchmarks without executing them", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ argsman.AddArg("-output_csv=<output.csv>", "Generate CSV file with the most important benchmark results", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ argsman.AddArg("-output_json=<output.json>", "Generate JSON file with all benchmark results", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
}
// parses a comma separated list like "10,20,30,50"
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index adc485983f..7a5f945511 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -797,7 +797,7 @@ static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& str
// Execute and handle connection failures with -rpcwait.
const bool fWait = gArgs.GetBoolArg("-rpcwait", false);
const int timeout = gArgs.GetArg("-rpcwaittimeout", DEFAULT_WAIT_CLIENT_TIMEOUT);
- const int64_t deadline = GetTime<std::chrono::seconds>().count() + timeout;
+ const auto deadline{GetTime<std::chrono::microseconds>() + 1s * timeout};
do {
try {
@@ -810,9 +810,9 @@ static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& str
}
break; // Connection succeeded, no need to retry.
} catch (const CConnectionFailed& e) {
- const int64_t now = GetTime<std::chrono::seconds>().count();
+ const auto now{GetTime<std::chrono::microseconds>()};
if (fWait && (timeout <= 0 || now < deadline)) {
- UninterruptibleSleep(std::chrono::seconds{1});
+ UninterruptibleSleep(1s);
} else {
throw CConnectionFailed(strprintf("timeout on transient error: %s", e.what()));
}
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index fdaadeed4a..58a27e053b 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -7,9 +7,9 @@
#include <chainparamsseeds.h>
#include <consensus/merkle.h>
+#include <deploymentinfo.h>
#include <hash.h> // for signet block challenge hash
#include <util/system.h>
-#include <versionbitsinfo.h>
#include <assert.h>
diff --git a/src/consensus/params.h b/src/consensus/params.h
index 28c95e0884..174f4677fa 100644
--- a/src/consensus/params.h
+++ b/src/consensus/params.h
@@ -11,13 +11,25 @@
namespace Consensus {
-enum DeploymentPos
+enum BuriedDeployment : int16_t
+{
+ // buried deployments get negative values to avoid overlap with DeploymentPos
+ DEPLOYMENT_HEIGHTINCB = std::numeric_limits<int16_t>::min(),
+ DEPLOYMENT_CLTV,
+ DEPLOYMENT_DERSIG,
+ DEPLOYMENT_CSV,
+ DEPLOYMENT_SEGWIT,
+};
+constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_SEGWIT; }
+
+enum DeploymentPos : uint16_t
{
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
- // NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
+ // NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
+constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_TAPROOT; }
/**
* Struct for each individual consensus rule change using BIP9.
@@ -100,7 +112,25 @@ struct Params {
*/
bool signet_blocks{false};
std::vector<uint8_t> signet_challenge;
+
+ int DeploymentHeight(BuriedDeployment dep) const
+ {
+ switch (dep) {
+ case DEPLOYMENT_HEIGHTINCB:
+ return BIP34Height;
+ case DEPLOYMENT_CLTV:
+ return BIP65Height;
+ case DEPLOYMENT_DERSIG:
+ return BIP66Height;
+ case DEPLOYMENT_CSV:
+ return CSVHeight;
+ case DEPLOYMENT_SEGWIT:
+ return SegwitHeight;
+ } // no default case, so the compiler can warn about missing cases
+ return std::numeric_limits<int>::max();
+ }
};
+
} // namespace Consensus
#endif // BITCOIN_CONSENSUS_PARAMS_H
diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
index f595f16eab..88d8da6ed5 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -20,6 +20,15 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
return true;
if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
return true;
+
+ // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a
+ // transaction is still considered final if all inputs' nSequence ==
+ // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored.
+ //
+ // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will
+ // also check that the spending input's nSequence != SEQUENCE_FINAL,
+ // ensuring that an unsatisfied nLockTime value will actually cause
+ // IsFinalTx() to return false here:
for (const auto& txin : tx.vin) {
if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
return false;
diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp
new file mode 100644
index 0000000000..030a7806de
--- /dev/null
+++ b/src/deploymentinfo.cpp
@@ -0,0 +1,36 @@
+// Copyright (c) 2016-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.
+
+#include <deploymentinfo.h>
+
+#include <consensus/params.h>
+
+const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
+ {
+ /*.name =*/ "testdummy",
+ /*.gbt_force =*/ true,
+ },
+ {
+ /*.name =*/ "taproot",
+ /*.gbt_force =*/ true,
+ },
+};
+
+std::string DeploymentName(Consensus::BuriedDeployment dep)
+{
+ assert(ValidDeployment(dep));
+ switch (dep) {
+ case Consensus::DEPLOYMENT_HEIGHTINCB:
+ return "bip34";
+ case Consensus::DEPLOYMENT_CLTV:
+ return "bip65";
+ case Consensus::DEPLOYMENT_DERSIG:
+ return "bip66";
+ case Consensus::DEPLOYMENT_CSV:
+ return "csv";
+ case Consensus::DEPLOYMENT_SEGWIT:
+ return "segwit";
+ } // no default case, so the compiler can warn about missing cases
+ return "";
+}
diff --git a/src/deploymentinfo.h b/src/deploymentinfo.h
new file mode 100644
index 0000000000..63d58a7da2
--- /dev/null
+++ b/src/deploymentinfo.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2016-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.
+
+#ifndef BITCOIN_DEPLOYMENTINFO_H
+#define BITCOIN_DEPLOYMENTINFO_H
+
+#include <consensus/params.h>
+
+#include <string>
+
+struct VBDeploymentInfo {
+ /** Deployment name */
+ const char *name;
+ /** Whether GBT clients can safely ignore this rule in simplified usage */
+ bool gbt_force;
+};
+
+extern const VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS];
+
+std::string DeploymentName(Consensus::BuriedDeployment dep);
+
+inline std::string DeploymentName(Consensus::DeploymentPos pos)
+{
+ assert(Consensus::ValidDeployment(pos));
+ return VersionBitsDeploymentInfo[pos].name;
+}
+
+#endif // BITCOIN_DEPLOYMENTINFO_H
diff --git a/src/deploymentstatus.cpp b/src/deploymentstatus.cpp
new file mode 100644
index 0000000000..9007800421
--- /dev/null
+++ b/src/deploymentstatus.cpp
@@ -0,0 +1,17 @@
+// Copyright (c) 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.
+
+#include <deploymentstatus.h>
+
+#include <consensus/params.h>
+#include <versionbits.h>
+
+VersionBitsCache g_versionbitscache;
+
+/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
+ * ValidDeployment check */
+
+static_assert(ValidDeployment(Consensus::DEPLOYMENT_TESTDUMMY), "sanity check of DeploymentPos failed (TESTDUMMY not valid)");
+static_assert(!ValidDeployment(Consensus::MAX_VERSION_BITS_DEPLOYMENTS), "sanity check of DeploymentPos failed (MAX value considered valid)");
+static_assert(!ValidDeployment(static_cast<Consensus::BuriedDeployment>(Consensus::DEPLOYMENT_TESTDUMMY)), "sanity check of BuriedDeployment failed (overlaps with DeploymentPos)");
diff --git a/src/deploymentstatus.h b/src/deploymentstatus.h
new file mode 100644
index 0000000000..84c5e54698
--- /dev/null
+++ b/src/deploymentstatus.h
@@ -0,0 +1,55 @@
+// Copyright (c) 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.
+
+#ifndef BITCOIN_DEPLOYMENTSTATUS_H
+#define BITCOIN_DEPLOYMENTSTATUS_H
+
+#include <chain.h>
+#include <versionbits.h>
+
+#include <limits>
+
+/** Global cache for versionbits deployment status */
+extern VersionBitsCache g_versionbitscache;
+
+/** Determine if a deployment is active for the next block */
+inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep)
+{
+ assert(Consensus::ValidDeployment(dep));
+ return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
+}
+
+inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep)
+{
+ assert(Consensus::ValidDeployment(dep));
+ return ThresholdState::ACTIVE == g_versionbitscache.State(pindexPrev, params, dep);
+}
+
+/** Determine if a deployment is active for this block */
+inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep)
+{
+ assert(Consensus::ValidDeployment(dep));
+ return index.nHeight >= params.DeploymentHeight(dep);
+}
+
+inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep)
+{
+ assert(Consensus::ValidDeployment(dep));
+ return DeploymentActiveAfter(index.pprev, params, dep);
+}
+
+/** Determine if a deployment is enabled (can ever be active) */
+inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::BuriedDeployment dep)
+{
+ assert(Consensus::ValidDeployment(dep));
+ return params.DeploymentHeight(dep) != std::numeric_limits<int>::max();
+}
+
+inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::DeploymentPos dep)
+{
+ assert(Consensus::ValidDeployment(dep));
+ return params.vDeployments[dep].nTimeout != 0;
+}
+
+#endif // BITCOIN_DEPLOYMENTSTATUS_H
diff --git a/src/httpserver.cpp b/src/httpserver.cpp
index b3984a43bb..8741ad9b86 100644
--- a/src/httpserver.cpp
+++ b/src/httpserver.cpp
@@ -136,7 +136,7 @@ static struct evhttp* eventHTTP = nullptr;
//! List of subnets to allow RPC connections from
static std::vector<CSubNet> rpc_allow_subnets;
//! Work queue for handling longer requests off the event loop thread
-static WorkQueue<HTTPClosure>* workQueue = nullptr;
+static std::unique_ptr<WorkQueue<HTTPClosure>> g_work_queue{nullptr};
//! Handlers for (sub)paths
static std::vector<HTTPPathHandler> pathHandlers;
//! Bound listening sockets
@@ -256,10 +256,10 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
// Dispatch to worker thread
if (i != iend) {
std::unique_ptr<HTTPWorkItem> item(new HTTPWorkItem(std::move(hreq), path, i->handler));
- assert(workQueue);
- if (workQueue->Enqueue(item.get()))
+ assert(g_work_queue);
+ if (g_work_queue->Enqueue(item.get())) {
item.release(); /* if true, queue took ownership */
- else {
+ } else {
LogPrintf("WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n");
item->req->WriteReply(HTTP_SERVICE_UNAVAILABLE, "Work queue depth exceeded");
}
@@ -392,7 +392,7 @@ bool InitHTTPServer()
int workQueueDepth = std::max((long)gArgs.GetArg("-rpcworkqueue", DEFAULT_HTTP_WORKQUEUE), 1L);
LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth);
- workQueue = new WorkQueue<HTTPClosure>(workQueueDepth);
+ g_work_queue = std::make_unique<WorkQueue<HTTPClosure>>(workQueueDepth);
// transfer ownership to eventBase/HTTP via .release()
eventBase = base_ctr.release();
eventHTTP = http_ctr.release();
@@ -424,7 +424,7 @@ void StartHTTPServer()
g_thread_http = std::thread(ThreadHTTP, eventBase);
for (int i = 0; i < rpcThreads; i++) {
- g_thread_http_workers.emplace_back(HTTPWorkQueueRun, workQueue, i);
+ g_thread_http_workers.emplace_back(HTTPWorkQueueRun, g_work_queue.get(), i);
}
}
@@ -435,16 +435,17 @@ void InterruptHTTPServer()
// Reject requests on current connections
evhttp_set_gencb(eventHTTP, http_reject_request_cb, nullptr);
}
- if (workQueue)
- workQueue->Interrupt();
+ if (g_work_queue) {
+ g_work_queue->Interrupt();
+ }
}
void StopHTTPServer()
{
LogPrint(BCLog::HTTP, "Stopping HTTP server\n");
- if (workQueue) {
+ if (g_work_queue) {
LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n");
- for (auto& thread: g_thread_http_workers) {
+ for (auto& thread : g_thread_http_workers) {
thread.join();
}
g_thread_http_workers.clear();
@@ -467,10 +468,7 @@ void StopHTTPServer()
event_base_free(eventBase);
eventBase = nullptr;
}
- if (workQueue) {
- delete workQueue;
- workQueue = nullptr;
- }
+ g_work_queue.reset();
LogPrint(BCLog::HTTP, "Stopped HTTP server\n");
}
diff --git a/src/init.cpp b/src/init.cpp
index da0447ca79..ae96f510bc 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -16,6 +16,7 @@
#include <chain.h>
#include <chainparams.h>
#include <compat/sanity.h>
+#include <deploymentstatus.h>
#include <fs.h>
#include <hash.h>
#include <httprpc.h>
@@ -1372,7 +1373,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// block file from disk.
// Note that it also sets fReindex based on the disk flag!
// From here on out fReindex and fReset mean something different!
- if (!chainman.LoadBlockIndex(chainparams)) {
+ if (!chainman.LoadBlockIndex()) {
if (ShutdownRequested()) break;
strLoadError = _("Error loading block database");
break;
@@ -1396,7 +1397,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// If we're not mid-reindex (based on disk + args), add a genesis block on disk
// (otherwise we use the one already on disk).
// This is called again in ThreadImport after the reindex completes.
- if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock(chainparams)) {
+ if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock()) {
strLoadError = _("Error initializing block database");
break;
}
@@ -1427,7 +1428,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
- if (!chainstate->ReplayBlocks(chainparams)) {
+ if (!chainstate->ReplayBlocks()) {
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
failed_chainstate_init = true;
break;
@@ -1439,7 +1440,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (!is_coinsview_empty(chainstate)) {
// LoadChainTip initializes the chain based on CoinsTip()'s best block
- if (!chainstate->LoadChainTip(chainparams)) {
+ if (!chainstate->LoadChainTip()) {
strLoadError = _("Error initializing block database");
failed_chainstate_init = true;
break; // out of the per-chainstate loop
@@ -1461,7 +1462,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
LOCK(cs_main);
auto chainstates{chainman.GetAll()};
if (std::any_of(chainstates.begin(), chainstates.end(),
- [&chainparams](const CChainState* cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(chainparams); })) {
+ [](const CChainState* cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(); })) {
strLoadError = strprintf(_("Witness data for blocks after height %d requires validation. Please restart with -reindex."),
chainparams.GetConsensus().SegwitHeight);
break;
@@ -1587,7 +1588,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}
}
- if (chainparams.GetConsensus().SegwitHeight != std::numeric_limits<int>::max()) {
+ if (DeploymentEnabled(chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
// Advertise witness capabilities.
// The option to not set NODE_WITNESS is only used in the tests and should be removed.
nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS);
diff --git a/src/miner.cpp b/src/miner.cpp
index 0cf303eb3c..d9186a5d6d 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -13,6 +13,7 @@
#include <consensus/merkle.h>
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
+#include <deploymentstatus.h>
#include <policy/feerate.h>
#include <policy/policy.h>
#include <pow.h>
@@ -120,7 +121,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
assert(pindexPrev != nullptr);
nHeight = pindexPrev->nHeight + 1;
- pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
+ pblock->nVersion = g_versionbitscache.ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
if (chainparams.MineBlocksOnDemand())
@@ -137,12 +138,12 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
// This is only needed in case the witness softfork activation is reverted
// (which would require a very deep reorganization).
// Note that the mempool would accept transactions with witness data before
- // IsWitnessEnabled, but we would only ever mine blocks after IsWitnessEnabled
+ // the deployment is active, but we would only ever mine blocks after activation
// unless there is a massive block reorganization with the witness softfork
// not activated.
// TODO: replace this with a call to main to assess validity of a mempool
// transaction (which in most cases can be a no-op).
- fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
+ fIncludeWitness = DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
int nPackagesSelected = 0;
int nDescendantsUpdated = 0;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 2175b76d16..315d2ac5cd 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -11,6 +11,7 @@
#include <blockfilter.h>
#include <chainparams.h>
#include <consensus/validation.h>
+#include <deploymentstatus.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <merkleblock.h>
@@ -997,7 +998,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
// We consider the chain that this peer is on invalid.
return;
}
- if (!State(nodeid)->fHaveWitness && IsWitnessEnabled(pindex->pprev, consensusParams)) {
+ if (!State(nodeid)->fHaveWitness && DeploymentActiveAt(*pindex, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
// We wouldn't download this block or its descendants from this peer.
return;
}
@@ -1467,7 +1468,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
return;
nHighestFastAnnounce = pindex->nHeight;
- bool fWitnessEnabled = IsWitnessEnabled(pindex->pprev, m_chainparams.GetConsensus());
+ bool fWitnessEnabled = DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT);
uint256 hashBlock(pblock->GetHash());
{
@@ -1709,7 +1710,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
} // release cs_main before calling ActivateBestChain
if (need_activate_chain) {
BlockValidationState state;
- if (!m_chainman.ActiveChainstate().ActivateBestChain(state, m_chainparams, a_recent_block)) {
+ if (!m_chainman.ActiveChainstate().ActivateBestChain(state, a_recent_block)) {
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
}
}
@@ -2082,7 +2083,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
!IsBlockRequested(pindexWalk->GetBlockHash()) &&
- (!IsWitnessEnabled(pindexWalk->pprev, m_chainparams.GetConsensus()) || State(pfrom.GetId())->fHaveWitness)) {
+ (!DeploymentActiveAt(*pindexWalk, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) || State(pfrom.GetId())->fHaveWitness)) {
// We don't have this block, and it's not yet in flight.
vToFetch.push_back(pindexWalk);
}
@@ -2935,7 +2936,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
a_recent_block = most_recent_block;
}
BlockValidationState state;
- if (!m_chainman.ActiveChainstate().ActivateBestChain(state, m_chainparams, a_recent_block)) {
+ if (!m_chainman.ActiveChainstate().ActivateBestChain(state, a_recent_block)) {
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
}
}
@@ -3397,7 +3398,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
return;
}
- if (IsWitnessEnabled(pindex->pprev, m_chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
+ if (DeploymentActiveAt(*pindex, m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT) && !nodestate->fSupportsDesiredCmpctVersion) {
// Don't bother trying to process compact blocks from v1 peers
// after segwit activates.
return;
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 1ea3969978..e7b3377475 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -489,7 +489,7 @@ bool CNetAddr::IsValid() const
*/
bool CNetAddr::IsRoutable() const
{
- return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsRFC7343() || IsLocal() || IsInternal());
+ return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || IsRFC4193() || IsRFC4843() || IsRFC7343() || IsLocal() || IsInternal());
}
/**
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 013d61282b..0083b74b33 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -493,7 +493,6 @@ struct CImportingNow {
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
{
- const CChainParams& chainparams = Params();
ScheduleBatchPriority();
{
@@ -512,7 +511,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
break; // This error is logged in OpenBlockFile
}
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
- chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file, &pos);
+ chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos);
if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exit %s\n", __func__);
return;
@@ -523,7 +522,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
fReindex = false;
LogPrintf("Reindexing finished\n");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
- chainman.ActiveChainstate().LoadGenesisBlock(chainparams);
+ chainman.ActiveChainstate().LoadGenesisBlock();
}
// -loadblock=
@@ -531,7 +530,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
FILE* file = fsbridge::fopen(path, "rb");
if (file) {
LogPrintf("Importing blocks file %s...\n", path.string());
- chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file);
+ chainman.ActiveChainstate().LoadExternalBlockFile(file);
if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exit %s\n", __func__);
return;
@@ -548,7 +547,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
// the relevant pointers before the ABC call.
for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
BlockValidationState state;
- if (!chainstate->ActivateBestChain(state, chainparams, nullptr)) {
+ if (!chainstate->ActivateBestChain(state, nullptr)) {
LogPrintf("Failed to connect best block (%s)\n", state.ToString());
StartShutdown();
return;
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 807b0143a6..183b5a5d91 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -6,6 +6,7 @@
#include <banman.h>
#include <chain.h>
#include <chainparams.h>
+#include <deploymentstatus.h>
#include <external_signer.h>
#include <init.h>
#include <interfaces/chain.h>
@@ -692,7 +693,7 @@ public:
{
LOCK(::cs_main);
const CBlockIndex* tip = Assert(m_node.chainman)->ActiveChain().Tip();
- return VersionBitsState(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE;
+ return DeploymentActiveAfter(tip, Params().GetConsensus(), Consensus::DEPLOYMENT_TAPROOT);
}
NodeContext& m_node;
};
diff --git a/src/outputtype.cpp b/src/outputtype.cpp
index d96fb282c5..8ede7b9974 100644
--- a/src/outputtype.cpp
+++ b/src/outputtype.cpp
@@ -18,6 +18,7 @@
static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";
static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
+static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
bool ParseOutputType(const std::string& type, OutputType& output_type)
{
@@ -30,6 +31,9 @@ bool ParseOutputType(const std::string& type, OutputType& output_type)
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
output_type = OutputType::BECH32;
return true;
+ } else if (type == OUTPUT_TYPE_STRING_BECH32M) {
+ output_type = OutputType::BECH32M;
+ return true;
}
return false;
}
@@ -40,6 +44,7 @@ const std::string& FormatOutputType(OutputType type)
case OutputType::LEGACY: return OUTPUT_TYPE_STRING_LEGACY;
case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT;
case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32;
+ case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M;
} // no default case, so the compiler can warn about missing cases
assert(false);
}
@@ -59,6 +64,7 @@ CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type)
return witdest;
}
}
+ case OutputType::BECH32M: {} // This function should never be used with BECH32M, so let it assert
} // no default case, so the compiler can warn about missing cases
assert(false);
}
@@ -98,6 +104,23 @@ CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore,
return ScriptHash(witprog);
}
}
+ case OutputType::BECH32M: {} // This function should not be used for BECH32M, so let it assert
} // no default case, so the compiler can warn about missing cases
assert(false);
}
+
+std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest) {
+ if (std::holds_alternative<PKHash>(dest) ||
+ std::holds_alternative<ScriptHash>(dest)) {
+ return OutputType::LEGACY;
+ }
+ if (std::holds_alternative<WitnessV0KeyHash>(dest) ||
+ std::holds_alternative<WitnessV0ScriptHash>(dest)) {
+ return OutputType::BECH32;
+ }
+ if (std::holds_alternative<WitnessV1Taproot>(dest) ||
+ std::holds_alternative<WitnessUnknown>(dest)) {
+ return OutputType::BECH32M;
+ }
+ return std::nullopt;
+}
diff --git a/src/outputtype.h b/src/outputtype.h
index 88422e5824..2b83235cd0 100644
--- a/src/outputtype.h
+++ b/src/outputtype.h
@@ -18,12 +18,14 @@ enum class OutputType {
LEGACY,
P2SH_SEGWIT,
BECH32,
+ BECH32M,
};
static constexpr auto OUTPUT_TYPES = std::array{
OutputType::LEGACY,
OutputType::P2SH_SEGWIT,
OutputType::BECH32,
+ OutputType::BECH32M,
};
[[nodiscard]] bool ParseOutputType(const std::string& str, OutputType& output_type);
@@ -45,4 +47,7 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key);
*/
CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, const CScript& script, OutputType);
+/** Get the OutputType for a CTxDestination */
+std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest);
+
#endif // BITCOIN_OUTPUTTYPE_H
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 3d632ec702..f8aeb01659 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -1173,14 +1173,12 @@ void BitcoinGUI::message(const QString& title, QString message, unsigned int sty
void BitcoinGUI::changeEvent(QEvent *e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
overviewAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/overview")));
sendCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/send")));
receiveCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/receiving_addresses")));
historyAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/history")));
}
-#endif
QMainWindow::changeEvent(e);
@@ -1511,14 +1509,14 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
void UnitDisplayStatusBarControl::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
QString style = QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name());
if (style != styleSheet()) {
setStyleSheet(style);
}
}
-#endif
+
+ QLabel::changeEvent(e);
}
/** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index bff253e58a..d2d4079ea9 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -42,6 +42,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Dumpfile version is not supported. This version of bitcoin-wallet "
"only supports version 1 dumpfiles. Got dumpfile with version %s"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and "
+"\"bech32\" address types"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: Listening for incoming connections failed (listen returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -"
@@ -103,9 +106,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Total length of network version string (%i) exceeds maximum length (%i). "
"Reduce the number or size of uacomments."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Transaction needs a change address, but we can't generate it. Please call "
-"keypoolrefill first."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Unable to replay blocks. You will need to rebuild the database using -"
"reindex-chainstate."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -160,6 +160,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error: Got key that was not hex: %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Got value that was not hex: %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Keypool ran out, please call keypoolrefill first"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Missing checksum"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: No %s addresses available."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unable to parse version %u as a uint32_t"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unable to write record to new wallet"),
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
@@ -216,6 +217,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must not be negative"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction has too long of a mempool chain"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction must have at least one recipient"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Transaction needs a change address, but we can't generate it. %s"),
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer. %s is probably already running."),
@@ -228,6 +230,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Unknown -blockfilterindex value %s."),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown address type '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown change type '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unknown new rules activated (versionbit %i)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Unsupported logging category %s=%s."),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrading UTXO database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrading txindex database"),
@@ -235,5 +238,4 @@ QT_TRANSLATE_NOOP("bitcoin-core", "User Agent comment (%s) contains unsafe chara
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying blocks…"),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet(s)…"),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart %s to complete"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Warning: unknown new rules activated (versionbit %i)"),
};
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 2360fa9b37..d2a9365890 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -564,11 +564,11 @@ void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *
void CoinControlDialog::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
updateView();
}
-#endif
+
+ QDialog::changeEvent(e);
}
void CoinControlDialog::updateView()
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 393dca8ccd..ecdfce2f5a 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -809,11 +809,10 @@ void ThemedLabel::setThemedPixmap(const QString& image_filename, int width, int
void ThemedLabel::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
updateThemedPixmap();
}
-#endif
+
QLabel::changeEvent(e);
}
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index b146489ba8..7026f49c01 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -55,11 +55,12 @@
</message>
<message>
<location line="-30"/>
+ <location filename="../addressbookpage.cpp" line="+122"/>
<source>&amp;Delete</source>
<translation>&amp;Delete</translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="+84"/>
+ <location filename="../addressbookpage.cpp" line="-38"/>
<source>Choose the address to send coins to</source>
<translation type="unfinished"></translation>
</message>
@@ -96,26 +97,21 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</message>
<message>
<location line="+8"/>
- <source>Copy Address</source>
+ <source>&amp;Copy Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy Label</source>
+ <source>Copy &amp;Label</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Edit</source>
+ <source>&amp;Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+3"/>
- <source>Delete</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+161"/>
+ <location line="+164"/>
<source>Export Address List</source>
<translation type="unfinished"></translation>
</message>
@@ -317,7 +313,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context>
<name>BitcoinApplication</name>
<message>
- <location filename="../bitcoin.cpp" line="+420"/>
+ <location filename="../bitcoin.cpp" line="+421"/>
<source>Runaway exception</source>
<translation type="unfinished"></translation>
</message>
@@ -405,18 +401,18 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+358"/>
+ <location line="+373"/>
<source>Network activity disabled.</source>
<extracomment>A substring of the tooltip.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+426"/>
+ <location line="+424"/>
<source>Proxy is &lt;b&gt;enabled&lt;/b&gt;: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1096"/>
+ <location line="-1109"/>
<source>Send coins to a Bitcoin address</source>
<translation>Send coins to a Bitcoin address</translation>
</message>
@@ -546,7 +542,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>Tabs toolbar</translation>
</message>
<message>
- <location line="+422"/>
+ <location line="+437"/>
<source>Syncing Headers (%1%)…</source>
<translation type="unfinished"></translation>
</message>
@@ -576,7 +572,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-766"/>
+ <location line="-781"/>
<source>Request payments (generates QR codes and bitcoin: URIs)</source>
<translation type="unfinished"></translation>
</message>
@@ -596,7 +592,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+678"/>
+ <location line="+693"/>
<source>Processed %n block(s) of transaction history.</source>
<translation>
<numerusform>Processed %n block of transaction history.</numerusform>
@@ -644,7 +640,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>Up to date</translation>
</message>
<message>
- <location line="-715"/>
+ <location line="-730"/>
<source>Load Partially Signed Bitcoin Transaction</source>
<translation type="unfinished"></translation>
</message>
@@ -744,7 +740,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+248"/>
+ <location line="+263"/>
<source>%1 client</source>
<translation type="unfinished"></translation>
</message>
@@ -792,7 +788,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+110"/>
+ <location line="+108"/>
<source>Date: %1
</source>
<translation type="unfinished"></translation>
@@ -956,34 +952,38 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished">Confirmed</translation>
</message>
<message>
- <location filename="../coincontroldialog.cpp" line="+55"/>
- <source>Copy address</source>
+ <location filename="../coincontroldialog.cpp" line="+66"/>
+ <source>Copy amount</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-11"/>
+ <source>&amp;Copy address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy label</source>
+ <source>Copy &amp;label</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <location line="+9"/>
- <source>Copy amount</source>
+ <source>Copy &amp;amount</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-8"/>
- <source>Copy transaction ID</source>
+ <location line="+1"/>
+ <source>Copy transaction &amp;ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+2"/>
- <source>Lock unspent</source>
+ <source>L&amp;ock unspent</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Unlock unspent</source>
+ <source>&amp;Unlock unspent</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1061,12 +1061,12 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context>
<name>CreateWalletActivity</name>
<message>
- <location filename="../walletcontroller.cpp" line="+253"/>
+ <location filename="../walletcontroller.cpp" line="+254"/>
<source>Creating Wallet &lt;b&gt;%1&lt;/b&gt;…</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+28"/>
+ <location line="+31"/>
<source>Create wallet failed</source>
<translation type="unfinished"></translation>
</message>
@@ -1075,6 +1075,11 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<source>Create wallet warning</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location line="+16"/>
+ <source>Can&apos;t list signers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CreateWalletDialog</name>
@@ -1139,15 +1144,31 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../createwalletdialog.cpp" line="+21"/>
+ <location line="+7"/>
+ <source>Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>External signer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../createwalletdialog.cpp" line="+22"/>
<source>Create</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+42"/>
+ <location line="+68"/>
<source>Compiled without sqlite support (required for descriptor wallets)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location line="+14"/>
+ <source>Compiled without external signing support (required for external signing)</source>
+ <extracomment>&quot;External signing&quot; means using devices such as hardware wallets.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>EditAddressDialog</name>
@@ -1472,7 +1493,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context>
<name>OpenWalletActivity</name>
<message>
- <location filename="../walletcontroller.cpp" line="+39"/>
+ <location filename="../walletcontroller.cpp" line="+32"/>
<source>Open wallet failed</source>
<translation type="unfinished"></translation>
</message>
@@ -1530,7 +1551,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+171"/>
+ <location line="+201"/>
<location line="+187"/>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation type="unfinished"></translation>
@@ -1579,7 +1600,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>&amp;Network</translation>
</message>
<message>
- <location line="-188"/>
+ <location line="-218"/>
<source>Prune &amp;block storage to</source>
<translation type="unfinished"></translation>
</message>
@@ -1629,7 +1650,22 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+30"/>
+ <location line="+10"/>
+ <source>External Signer (e.g. hardware wallet)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>&amp;External signer script path</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Full path to a Bitcoin Core compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+32"/>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<translation>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</translation>
</message>
@@ -1762,12 +1798,12 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation>
</message>
<message>
- <location line="-463"/>
+ <location line="-493"/>
<source>Whether to show coin control features or not.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+260"/>
+ <location line="+290"/>
<source>Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services.</source>
<translation type="unfinished"></translation>
</message>
@@ -1812,7 +1848,13 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation>&amp;Cancel</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+104"/>
+ <location filename="../optionsdialog.cpp" line="+97"/>
+ <source>Compiled without external signing support (required for external signing)</source>
+ <extracomment>&quot;External signing&quot; means using devices such as hardware wallets.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+12"/>
<source>default</source>
<translation>default</translation>
</message>
@@ -1822,7 +1864,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+91"/>
+ <location line="+93"/>
<source>Confirm options reset</source>
<translation>Confirm options reset</translation>
</message>
@@ -1962,7 +2004,7 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../overviewpage.cpp" line="+193"/>
+ <location filename="../overviewpage.cpp" line="+188"/>
<source>Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings-&gt;Mask values.</source>
<translation type="unfinished"></translation>
</message>
@@ -2168,7 +2210,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<context>
<name>PeerTableModel</name>
<message>
- <location filename="../peertablemodel.h" line="+101"/>
+ <location filename="../peertablemodel.h" line="+107"/>
<source>User Agent</source>
<extracomment>Title of Peers Table column which contains the peer&apos;s User Agent string.</extracomment>
<translation type="unfinished"></translation>
@@ -2384,7 +2426,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoin.cpp" line="+111"/>
+ <location filename="../bitcoin.cpp" line="+112"/>
<source>Error: Specified data directory &quot;%1&quot; does not exist.</source>
<translation type="unfinished"></translation>
</message>
@@ -2418,12 +2460,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<name>QRImageWidget</name>
<message>
<location filename="../qrimagewidget.cpp" line="+30"/>
- <source>Save Image…</source>
+ <source>&amp;Save Image…</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy Image</source>
+ <source>&amp;Copy Image</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2467,7 +2509,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<location line="+23"/>
<location line="+36"/>
<location line="+23"/>
- <location line="+722"/>
+ <location line="+692"/>
<location line="+26"/>
<location line="+26"/>
<location line="+23"/>
@@ -2490,12 +2532,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<location line="+23"/>
<location line="+23"/>
<location line="+26"/>
- <location filename="../rpcconsole.h" line="+138"/>
+ <location filename="../rpcconsole.h" line="+139"/>
<source>N/A</source>
<translation>N/A</translation>
</message>
<message>
- <location line="-1549"/>
+ <location line="-1519"/>
<source>Client version</source>
<translation>Client version</translation>
</message>
@@ -2536,12 +2578,12 @@ If you are receiving this error you should request the merchant provide a BIP21
</message>
<message>
<location line="+29"/>
- <location line="+922"/>
+ <location line="+892"/>
<source>Network</source>
<translation>Network</translation>
</message>
<message>
- <location line="-915"/>
+ <location line="-885"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
@@ -2581,7 +2623,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+241"/>
+ <location line="+211"/>
<source>&amp;Reset</source>
<translation type="unfinished"></translation>
</message>
@@ -2609,7 +2651,7 @@ If you are receiving this error you should request the merchant provide a BIP21
</message>
<message>
<location line="+68"/>
- <location filename="../rpcconsole.cpp" line="+1091"/>
+ <location filename="../rpcconsole.cpp" line="+1124"/>
<source>Select a peer to view detailed information.</source>
<translation type="unfinished"></translation>
</message>
@@ -2644,13 +2686,13 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1516"/>
- <location line="+1081"/>
+ <location line="-1486"/>
+ <location line="+1051"/>
<source>User Agent</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1155"/>
+ <location line="-1125"/>
<source>Node window</source>
<translation type="unfinished"></translation>
</message>
@@ -2665,17 +2707,17 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+84"/>
+ <location line="+78"/>
<source>Decrease font size</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+32"/>
+ <location line="+20"/>
<source>Increase font size</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+558"/>
+ <location line="+546"/>
<source>Permissions</source>
<translation type="unfinished"></translation>
</message>
@@ -2780,7 +2822,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-1288"/>
+ <location line="-1258"/>
<source>Last block time</source>
<translation>Last block time</translation>
</message>
@@ -2795,7 +2837,7 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation>&amp;Console</translation>
</message>
<message>
- <location line="+217"/>
+ <location line="+187"/>
<source>&amp;Network Traffic</source>
<translation type="unfinished"></translation>
</message>
@@ -2815,12 +2857,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/debugwindow.ui" line="-321"/>
+ <location filename="../forms/debugwindow.ui" line="-291"/>
<source>Debug log file</source>
<translation>Debug log file</translation>
</message>
<message>
- <location line="+155"/>
+ <location line="+125"/>
<source>Clear console</source>
<translation>Clear console</translation>
</message>
@@ -2850,12 +2892,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+38"/>
+ <location line="+40"/>
<source>Never</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../rpcconsole.cpp" line="-417"/>
+ <location filename="../rpcconsole.cpp" line="-429"/>
<source>Inbound: initiated by peer</source>
<translation type="unfinished"></translation>
</message>
@@ -2924,52 +2966,52 @@ If you are receiving this error you should request the merchant provide a BIP21
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+385"/>
- <source>Network activity disabled</source>
+ <location line="+150"/>
+ <source>&amp;Disconnect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+77"/>
- <source>Executing command without any wallet</source>
+ <location line="+1"/>
+ <source>1 &amp;hour</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-2"/>
- <source>Executing command using &quot;%1&quot; wallet</source>
+ <location line="+1"/>
+ <source>1 d&amp;ay</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-319"/>
- <source>Disconnect</source>
+ <location line="+1"/>
+ <source>1 &amp;week</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>1 hour</source>
+ <source>1 &amp;year</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>1 day</source>
+ <location line="+22"/>
+ <source>&amp;Unban</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>1 week</source>
+ <location line="+221"/>
+ <source>Network activity disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>1 year</source>
+ <location line="+77"/>
+ <source>Executing command without any wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+19"/>
- <source>Unban</source>
+ <location line="-2"/>
+ <source>Executing command using &quot;%1&quot; wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+150"/>
+ <location line="-146"/>
<source>Welcome to the %1 RPC console.
Use up and down arrows to navigate history, and %2 to clear screen.
Use %3 and %4 to increase or decrease the font size.
@@ -2997,7 +3039,7 @@ For more information on using this console, type %6.
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../rpcconsole.h" line="-38"/>
+ <location filename="../rpcconsole.h" line="-40"/>
<source>Unknown</source>
<translation type="unfinished"></translation>
</message>
@@ -3102,27 +3144,27 @@ For more information on using this console, type %6.
</message>
<message>
<location filename="../receivecoinsdialog.cpp" line="+47"/>
- <source>Copy URI</source>
+ <source>Copy &amp;URI</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy address</source>
+ <source>&amp;Copy address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy label</source>
+ <source>Copy &amp;label</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy message</source>
+ <source>Copy &amp;message</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy amount</source>
+ <source>Copy &amp;amount</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3180,6 +3222,16 @@ For more information on using this console, type %6.
</message>
<message>
<location line="+10"/>
+ <source>&amp;Verify</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Verify this address on e.g. a hardware wallet screen</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
<source>&amp;Save Image…</source>
<translation type="unfinished"></translation>
</message>
@@ -3189,7 +3241,7 @@ For more information on using this console, type %6.
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/receiverequestdialog.ui" line="-221"/>
+ <location filename="../forms/receiverequestdialog.ui" line="-234"/>
<source>Payment information</source>
<translation type="unfinished"></translation>
</message>
@@ -3197,7 +3249,7 @@ For more information on using this console, type %6.
<context>
<name>RecentRequestsTableModel</name>
<message>
- <location filename="../recentrequeststablemodel.cpp" line="+30"/>
+ <location filename="../recentrequeststablemodel.cpp" line="+32"/>
<source>Date</source>
<translation type="unfinished">Date</translation>
</message>
@@ -3236,7 +3288,7 @@ For more information on using this console, type %6.
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="+14"/>
- <location filename="../sendcoinsdialog.cpp" line="+674"/>
+ <location filename="../sendcoinsdialog.cpp" line="+738"/>
<source>Send Coins</source>
<translation>Send Coins</translation>
</message>
@@ -3423,7 +3475,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation>S&amp;end</translation>
</message>
<message>
- <location filename="../sendcoinsdialog.cpp" line="-582"/>
+ <location filename="../sendcoinsdialog.cpp" line="-646"/>
<source>Copy quantity</source>
<translation type="unfinished"></translation>
</message>
@@ -3463,7 +3515,24 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+29"/>
+ <location line="+30"/>
+ <source>Sign on device</source>
+ <extracomment>&quot;device&quot; usually means a hardware wallet</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Connect your hardware wallet first.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Set external signer script path in Options -&gt; Wallet</source>
+ <extracomment>&quot;External signer&quot; means using devices such as hardware wallets.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Cr&amp;eate Unsigned</source>
<translation type="unfinished"></translation>
</message>
@@ -3508,7 +3577,29 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+44"/>
+ <location line="+0"/>
+ <source>Sign and send</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Sign failed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>External signer not found</source>
+ <extracomment>&quot;External signer&quot; means using devices such as hardware wallets.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>External signer failure</source>
+ <extracomment>&quot;External signer&quot; means using devices such as hardware wallets.</extracomment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+58"/>
<source>Save Transaction Data</source>
<translation type="unfinished"></translation>
</message>
@@ -3524,7 +3615,12 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-76"/>
+ <location line="+175"/>
+ <source>External balance:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-302"/>
<source>or</source>
<translation type="unfinished"></translation>
</message>
@@ -3569,12 +3665,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+1"/>
- <source>Send</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+229"/>
+ <location line="+283"/>
<source>Watch-only balance:</source>
<translation type="unfinished"></translation>
</message>
@@ -4434,62 +4525,62 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+75"/>
- <source>Abandon transaction</source>
+ <location line="-26"/>
+ <source>Range…</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-3"/>
- <source>Increase transaction fee</source>
+ <location line="+90"/>
+ <source>&amp;Copy address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-8"/>
- <source>Copy address</source>
+ <location line="+1"/>
+ <source>Copy &amp;label</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy label</source>
+ <source>Copy &amp;amount</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy amount</source>
+ <source>Copy transaction &amp;ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy transaction ID</source>
+ <source>Copy &amp;raw transaction</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy raw transaction</source>
+ <source>Copy full transaction &amp;details</source>
<translation type="unfinished"></translation>
</message>
<message>
<location line="+1"/>
- <source>Copy full transaction details</source>
+ <source>&amp;Show transaction details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
- <source>Edit address label</source>
+ <location line="+2"/>
+ <source>Increase transaction &amp;fee</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-6"/>
- <source>Show transaction details</source>
+ <location line="+3"/>
+ <source>A&amp;bandon transaction</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-96"/>
- <source>Range…</source>
+ <location line="+1"/>
+ <source>&amp;Edit address label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+276"/>
+ <location line="+174"/>
<source>Export Transaction History</source>
<translation type="unfinished"></translation>
</message>
@@ -4576,7 +4667,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<context>
<name>WalletController</name>
<message>
- <location filename="../walletcontroller.cpp" line="-250"/>
+ <location filename="../walletcontroller.cpp" line="-262"/>
<source>Close wallet</source>
<translation type="unfinished"></translation>
</message>
@@ -4604,7 +4695,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<context>
<name>WalletFrame</name>
<message>
- <location filename="../walletframe.cpp" line="+39"/>
+ <location filename="../walletframe.cpp" line="+35"/>
<source>No wallet has been loaded.
Go to File &gt; Open Wallet to load a wallet.
- OR -</source>
@@ -4624,7 +4715,7 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished">Send Coins</translation>
</message>
<message>
- <location line="+279"/>
+ <location line="+260"/>
<location line="+52"/>
<location line="+13"/>
<location line="+5"/>
@@ -4692,7 +4783,12 @@ Go to File &gt; Open Wallet to load a wallet.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+20"/>
+ <location line="+14"/>
+ <source>Can&apos;t display address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+18"/>
<source>default wallet</source>
<translation type="unfinished"></translation>
</message>
@@ -4842,6 +4938,11 @@ Go to File &gt; Open Wallet to load a wallet.
</message>
<message>
<location line="+3"/>
+ <source>Error: Legacy wallets only support the &quot;legacy&quot;, &quot;p2sh-segwit&quot;, and &quot;bech32&quot; address types</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation type="unfinished"></translation>
</message>
@@ -4947,11 +5048,6 @@ Go to File &gt; Open Wallet to load a wallet.
</message>
<message>
<location line="+3"/>
- <source>Transaction needs a change address, but we can&apos;t generate it. Please call keypoolrefill first.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location line="+3"/>
<source>Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.</source>
<translation type="unfinished"></translation>
</message>
@@ -5162,6 +5258,11 @@ Go to File &gt; Open Wallet to load a wallet.
</message>
<message>
<location line="+1"/>
+ <source>Error: No %s addresses available.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error: Unable to parse version %u as a uint32_t</source>
<translation type="unfinished"></translation>
</message>
@@ -5442,6 +5543,11 @@ Go to File &gt; Open Wallet to load a wallet.
</message>
<message>
<location line="+1"/>
+ <source>Transaction needs a change address, but we can&apos;t generate it. %s</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Transaction too large</source>
<translation type="unfinished"></translation>
</message>
@@ -5502,6 +5608,11 @@ Go to File &gt; Open Wallet to load a wallet.
</message>
<message>
<location line="+1"/>
+ <source>Unknown new rules activated (versionbit %i)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Unsupported logging category %s=%s.</source>
<translation type="unfinished"></translation>
</message>
@@ -5535,10 +5646,5 @@ Go to File &gt; Open Wallet to load a wallet.
<source>Wallet needed to be rewritten: restart %s to complete</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location line="+1"/>
- <source>Warning: unknown new rules activated (versionbit %i)</source>
- <translation type="unfinished"></translation>
- </message>
</context>
</TS>
diff --git a/src/qt/locale/bitcoin_en.xlf b/src/qt/locale/bitcoin_en.xlf
index ffe7812738..caefddc663 100644
--- a/src/qt/locale/bitcoin_en.xlf
+++ b/src/qt/locale/bitcoin_en.xlf
@@ -56,6 +56,7 @@
<source xml:space="preserve">&amp;Delete</source>
<target xml:space="preserve">&amp;Delete</target>
<context-group purpose="location"><context context-type="linenumber">101</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../addressbookpage.cpp</context><context context-type="linenumber">122</context></context-group>
</trans-unit>
</group>
</body></file>
@@ -98,43 +99,38 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context-group purpose="location"><context context-type="linenumber">109</context></context-group>
</trans-unit>
<trans-unit id="_msg19">
- <source xml:space="preserve">Copy Address</source>
+ <source xml:space="preserve">&amp;Copy Address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">117</context></context-group>
</trans-unit>
<trans-unit id="_msg20">
- <source xml:space="preserve">Copy Label</source>
+ <source xml:space="preserve">Copy &amp;Label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">118</context></context-group>
</trans-unit>
<trans-unit id="_msg21">
- <source xml:space="preserve">Edit</source>
+ <source xml:space="preserve">&amp;Edit</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">119</context></context-group>
</trans-unit>
<trans-unit id="_msg22">
- <source xml:space="preserve">Delete</source>
- <target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">122</context></context-group>
- </trans-unit>
- <trans-unit id="_msg23">
<source xml:space="preserve">Export Address List</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">283</context></context-group>
</trans-unit>
- <trans-unit id="_msg24">
+ <trans-unit id="_msg23">
<source xml:space="preserve">Comma separated file</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">286</context></context-group>
<note annotates="source" from="developer">Expanded name of the CSV file format. See https://en.wikipedia.org/wiki/Comma-separated_values</note>
</trans-unit>
- <trans-unit id="_msg25">
+ <trans-unit id="_msg24">
<source xml:space="preserve">There was an error trying to save the address list to %1. Please try again.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">302</context></context-group>
<note annotates="source" from="developer">An error message. %1 is a stand-in argument for the name of the file we attempted to save to.</note>
</trans-unit>
- <trans-unit id="_msg26">
+ <trans-unit id="_msg25">
<source xml:space="preserve">Exporting Failed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
@@ -143,17 +139,17 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../addresstablemodel.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="AddressTableModel">
- <trans-unit id="_msg27">
+ <trans-unit id="_msg26">
<source xml:space="preserve">Label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">168</context></context-group>
</trans-unit>
- <trans-unit id="_msg28">
+ <trans-unit id="_msg27">
<source xml:space="preserve">Address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">168</context></context-group>
</trans-unit>
- <trans-unit id="_msg29">
+ <trans-unit id="_msg28">
<source xml:space="preserve">(no label)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
@@ -162,27 +158,27 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/askpassphrasedialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="AskPassphraseDialog">
- <trans-unit id="_msg30" approved="yes">
+ <trans-unit id="_msg29" approved="yes">
<source xml:space="preserve">Passphrase Dialog</source>
<target xml:space="preserve">Passphrase Dialog</target>
<context-group purpose="location"><context context-type="linenumber">26</context></context-group>
</trans-unit>
- <trans-unit id="_msg31" approved="yes">
+ <trans-unit id="_msg30" approved="yes">
<source xml:space="preserve">Enter passphrase</source>
<target xml:space="preserve">Enter passphrase</target>
<context-group purpose="location"><context context-type="linenumber">56</context></context-group>
</trans-unit>
- <trans-unit id="_msg32" approved="yes">
+ <trans-unit id="_msg31" approved="yes">
<source xml:space="preserve">New passphrase</source>
<target xml:space="preserve">New passphrase</target>
<context-group purpose="location"><context context-type="linenumber">70</context></context-group>
</trans-unit>
- <trans-unit id="_msg33" approved="yes">
+ <trans-unit id="_msg32" approved="yes">
<source xml:space="preserve">Repeat new passphrase</source>
<target xml:space="preserve">Repeat new passphrase</target>
<context-group purpose="location"><context context-type="linenumber">84</context></context-group>
</trans-unit>
- <trans-unit id="_msg34">
+ <trans-unit id="_msg33">
<source xml:space="preserve">Show passphrase</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
@@ -191,83 +187,83 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../askpassphrasedialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="AskPassphraseDialog">
- <trans-unit id="_msg35">
+ <trans-unit id="_msg34">
<source xml:space="preserve">Encrypt wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg36">
+ <trans-unit id="_msg35">
<source xml:space="preserve">This operation needs your wallet passphrase to unlock the wallet.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">54</context></context-group>
</trans-unit>
- <trans-unit id="_msg37">
+ <trans-unit id="_msg36">
<source xml:space="preserve">Unlock wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">59</context></context-group>
</trans-unit>
- <trans-unit id="_msg38">
+ <trans-unit id="_msg37">
<source xml:space="preserve">Change passphrase</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">62</context></context-group>
</trans-unit>
- <trans-unit id="_msg39">
+ <trans-unit id="_msg38">
<source xml:space="preserve">Confirm wallet encryption</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">110</context></context-group>
</trans-unit>
- <trans-unit id="_msg40">
+ <trans-unit id="_msg39">
<source xml:space="preserve">Warning: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg41">
+ <trans-unit id="_msg40">
<source xml:space="preserve">Are you sure you wish to encrypt your wallet?</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg42">
+ <trans-unit id="_msg41">
<source xml:space="preserve">Wallet encrypted</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">129</context></context-group>
<context-group purpose="location"><context context-type="linenumber">173</context></context-group>
</trans-unit>
- <trans-unit id="_msg43">
+ <trans-unit id="_msg42">
<source xml:space="preserve">Enter the new passphrase for the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;ten or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">48</context></context-group>
</trans-unit>
- <trans-unit id="_msg44">
+ <trans-unit id="_msg43">
<source xml:space="preserve">Enter the old passphrase and new passphrase for the wallet.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">63</context></context-group>
</trans-unit>
- <trans-unit id="_msg45">
+ <trans-unit id="_msg44">
<source xml:space="preserve">Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">118</context></context-group>
</trans-unit>
- <trans-unit id="_msg46">
+ <trans-unit id="_msg45">
<source xml:space="preserve">Wallet to be encrypted</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg47">
+ <trans-unit id="_msg46">
<source xml:space="preserve">Your wallet is about to be encrypted. </source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">124</context></context-group>
</trans-unit>
- <trans-unit id="_msg48">
+ <trans-unit id="_msg47">
<source xml:space="preserve">Your wallet is now encrypted. </source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">131</context></context-group>
</trans-unit>
- <trans-unit id="_msg49">
+ <trans-unit id="_msg48">
<source xml:space="preserve">IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">133</context></context-group>
</trans-unit>
- <trans-unit id="_msg50">
+ <trans-unit id="_msg49">
<source xml:space="preserve">Wallet encryption failed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
@@ -275,35 +271,35 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context-group purpose="location"><context context-type="linenumber">179</context></context-group>
<context-group purpose="location"><context context-type="linenumber">185</context></context-group>
</trans-unit>
- <trans-unit id="_msg51">
+ <trans-unit id="_msg50">
<source xml:space="preserve">Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">140</context></context-group>
</trans-unit>
- <trans-unit id="_msg52">
+ <trans-unit id="_msg51">
<source xml:space="preserve">The supplied passphrases do not match.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">148</context></context-group>
<context-group purpose="location"><context context-type="linenumber">186</context></context-group>
</trans-unit>
- <trans-unit id="_msg53">
+ <trans-unit id="_msg52">
<source xml:space="preserve">Wallet unlock failed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">159</context></context-group>
<context-group purpose="location"><context context-type="linenumber">165</context></context-group>
</trans-unit>
- <trans-unit id="_msg54">
+ <trans-unit id="_msg53">
<source xml:space="preserve">The passphrase entered for the wallet decryption was incorrect.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">160</context></context-group>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg55">
+ <trans-unit id="_msg54">
<source xml:space="preserve">Wallet passphrase was successfully changed.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
</trans-unit>
- <trans-unit id="_msg56">
+ <trans-unit id="_msg55">
<source xml:space="preserve">Warning: The Caps Lock key is on!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">220</context></context-group>
@@ -313,12 +309,12 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../bantablemodel.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="BanTableModel">
- <trans-unit id="_msg57">
+ <trans-unit id="_msg56">
<source xml:space="preserve">IP/Netmask</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">85</context></context-group>
</trans-unit>
- <trans-unit id="_msg58">
+ <trans-unit id="_msg57">
<source xml:space="preserve">Banned Until</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">85</context></context-group>
@@ -327,683 +323,683 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../bitcoin.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="BitcoinApplication">
- <trans-unit id="_msg59">
+ <trans-unit id="_msg58">
<source xml:space="preserve">Runaway exception</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">420</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">421</context></context-group>
</trans-unit>
- <trans-unit id="_msg60">
+ <trans-unit id="_msg59">
<source xml:space="preserve">A fatal error occurred. %1 can no longer continue safely and will quit.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">421</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">422</context></context-group>
</trans-unit>
- <trans-unit id="_msg61">
+ <trans-unit id="_msg60">
<source xml:space="preserve">Internal error</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">430</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">431</context></context-group>
</trans-unit>
- <trans-unit id="_msg62">
+ <trans-unit id="_msg61">
<source xml:space="preserve">An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">431</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">432</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg63">
+ <trans-unit id="_msg62">
<source xml:space="preserve">Error: Specified data directory &quot;%1&quot; does not exist.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">542</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">544</context></context-group>
</trans-unit>
- <trans-unit id="_msg64">
+ <trans-unit id="_msg63">
<source xml:space="preserve">Error: Cannot parse configuration file: %1.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">548</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">550</context></context-group>
</trans-unit>
- <trans-unit id="_msg65">
+ <trans-unit id="_msg64">
<source xml:space="preserve">Error: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">563</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">565</context></context-group>
</trans-unit>
- <trans-unit id="_msg66">
+ <trans-unit id="_msg65">
<source xml:space="preserve">Error initializing settings: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">572</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">574</context></context-group>
</trans-unit>
- <trans-unit id="_msg67">
+ <trans-unit id="_msg66">
<source xml:space="preserve">%1 didn&apos;t yet exit safely…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">635</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">637</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../bitcoingui.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="BitcoinGUI">
- <trans-unit id="_msg68" approved="yes">
+ <trans-unit id="_msg67" approved="yes">
<source xml:space="preserve">&amp;Overview</source>
<target xml:space="preserve">&amp;Overview</target>
<context-group purpose="location"><context context-type="linenumber">245</context></context-group>
</trans-unit>
- <trans-unit id="_msg69" approved="yes">
+ <trans-unit id="_msg68" approved="yes">
<source xml:space="preserve">Show general overview of wallet</source>
<target xml:space="preserve">Show general overview of wallet</target>
<context-group purpose="location"><context context-type="linenumber">246</context></context-group>
</trans-unit>
- <trans-unit id="_msg70" approved="yes">
+ <trans-unit id="_msg69" approved="yes">
<source xml:space="preserve">&amp;Transactions</source>
<target xml:space="preserve">&amp;Transactions</target>
<context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg71" approved="yes">
+ <trans-unit id="_msg70" approved="yes">
<source xml:space="preserve">Browse transaction history</source>
<target xml:space="preserve">Browse transaction history</target>
<context-group purpose="location"><context context-type="linenumber">275</context></context-group>
</trans-unit>
- <trans-unit id="_msg72" approved="yes">
+ <trans-unit id="_msg71" approved="yes">
<source xml:space="preserve">E&amp;xit</source>
<target xml:space="preserve">E&amp;xit</target>
<context-group purpose="location"><context context-type="linenumber">298</context></context-group>
</trans-unit>
- <trans-unit id="_msg73" approved="yes">
+ <trans-unit id="_msg72" approved="yes">
<source xml:space="preserve">Quit application</source>
<target xml:space="preserve">Quit application</target>
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
</trans-unit>
- <trans-unit id="_msg74">
+ <trans-unit id="_msg73">
<source xml:space="preserve">&amp;About %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">302</context></context-group>
</trans-unit>
- <trans-unit id="_msg75">
+ <trans-unit id="_msg74">
<source xml:space="preserve">Show information about %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">303</context></context-group>
</trans-unit>
- <trans-unit id="_msg76" approved="yes">
+ <trans-unit id="_msg75" approved="yes">
<source xml:space="preserve">About &amp;Qt</source>
<target xml:space="preserve">About &amp;Qt</target>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
</trans-unit>
- <trans-unit id="_msg77" approved="yes">
+ <trans-unit id="_msg76" approved="yes">
<source xml:space="preserve">Show information about Qt</source>
<target xml:space="preserve">Show information about Qt</target>
<context-group purpose="location"><context context-type="linenumber">307</context></context-group>
</trans-unit>
- <trans-unit id="_msg78">
+ <trans-unit id="_msg77">
<source xml:space="preserve">Modify configuration options for %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">310</context></context-group>
</trans-unit>
- <trans-unit id="_msg79">
+ <trans-unit id="_msg78">
<source xml:space="preserve">Create a new wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">356</context></context-group>
</trans-unit>
- <trans-unit id="_msg80">
+ <trans-unit id="_msg79">
<source xml:space="preserve">Wallet:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">565</context></context-group>
</trans-unit>
- <trans-unit id="_msg81">
+ <trans-unit id="_msg80">
<source xml:space="preserve">Network activity disabled.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">923</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">938</context></context-group>
<note annotates="source" from="developer">A substring of the tooltip.</note>
</trans-unit>
- <trans-unit id="_msg82">
+ <trans-unit id="_msg81">
<source xml:space="preserve">Proxy is &lt;b&gt;enabled&lt;/b&gt;: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1349</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1362</context></context-group>
</trans-unit>
- <trans-unit id="_msg83" approved="yes">
+ <trans-unit id="_msg82" approved="yes">
<source xml:space="preserve">Send coins to a Bitcoin address</source>
<target xml:space="preserve">Send coins to a Bitcoin address</target>
<context-group purpose="location"><context context-type="linenumber">253</context></context-group>
</trans-unit>
- <trans-unit id="_msg84" approved="yes">
+ <trans-unit id="_msg83" approved="yes">
<source xml:space="preserve">Backup wallet to another location</source>
<target xml:space="preserve">Backup wallet to another location</target>
<context-group purpose="location"><context context-type="linenumber">320</context></context-group>
</trans-unit>
- <trans-unit id="_msg85" approved="yes">
+ <trans-unit id="_msg84" approved="yes">
<source xml:space="preserve">Change the passphrase used for wallet encryption</source>
<target xml:space="preserve">Change the passphrase used for wallet encryption</target>
<context-group purpose="location"><context context-type="linenumber">322</context></context-group>
</trans-unit>
- <trans-unit id="_msg86" approved="yes">
+ <trans-unit id="_msg85" approved="yes">
<source xml:space="preserve">&amp;Send</source>
<target xml:space="preserve">&amp;Send</target>
<context-group purpose="location"><context context-type="linenumber">252</context></context-group>
</trans-unit>
- <trans-unit id="_msg87" approved="yes">
+ <trans-unit id="_msg86" approved="yes">
<source xml:space="preserve">&amp;Receive</source>
<target xml:space="preserve">&amp;Receive</target>
<context-group purpose="location"><context context-type="linenumber">263</context></context-group>
</trans-unit>
- <trans-unit id="_msg88">
+ <trans-unit id="_msg87">
<source xml:space="preserve">&amp;Options…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">309</context></context-group>
</trans-unit>
- <trans-unit id="_msg89" approved="yes">
+ <trans-unit id="_msg88" approved="yes">
<source xml:space="preserve">&amp;Show / Hide</source>
<target xml:space="preserve">&amp;Show / Hide</target>
<context-group purpose="location"><context context-type="linenumber">313</context></context-group>
</trans-unit>
- <trans-unit id="_msg90" approved="yes">
+ <trans-unit id="_msg89" approved="yes">
<source xml:space="preserve">Show or hide the main Window</source>
<target xml:space="preserve">Show or hide the main Window</target>
<context-group purpose="location"><context context-type="linenumber">314</context></context-group>
</trans-unit>
- <trans-unit id="_msg91">
+ <trans-unit id="_msg90">
<source xml:space="preserve">&amp;Encrypt Wallet…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">316</context></context-group>
</trans-unit>
- <trans-unit id="_msg92" approved="yes">
+ <trans-unit id="_msg91" approved="yes">
<source xml:space="preserve">Encrypt the private keys that belong to your wallet</source>
<target xml:space="preserve">Encrypt the private keys that belong to your wallet</target>
<context-group purpose="location"><context context-type="linenumber">317</context></context-group>
</trans-unit>
- <trans-unit id="_msg93">
+ <trans-unit id="_msg92">
<source xml:space="preserve">&amp;Backup Wallet…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">319</context></context-group>
</trans-unit>
- <trans-unit id="_msg94">
+ <trans-unit id="_msg93">
<source xml:space="preserve">&amp;Change Passphrase…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg95">
+ <trans-unit id="_msg94">
<source xml:space="preserve">Sign &amp;message…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg96" approved="yes">
+ <trans-unit id="_msg95" approved="yes">
<source xml:space="preserve">Sign messages with your Bitcoin addresses to prove you own them</source>
<target xml:space="preserve">Sign messages with your Bitcoin addresses to prove you own them</target>
<context-group purpose="location"><context context-type="linenumber">324</context></context-group>
</trans-unit>
- <trans-unit id="_msg97">
+ <trans-unit id="_msg96">
<source xml:space="preserve">&amp;Verify message…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">325</context></context-group>
</trans-unit>
- <trans-unit id="_msg98" approved="yes">
+ <trans-unit id="_msg97" approved="yes">
<source xml:space="preserve">Verify messages to ensure they were signed with specified Bitcoin addresses</source>
<target xml:space="preserve">Verify messages to ensure they were signed with specified Bitcoin addresses</target>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg99">
+ <trans-unit id="_msg98">
<source xml:space="preserve">&amp;Load PSBT from file…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">327</context></context-group>
</trans-unit>
- <trans-unit id="_msg100">
+ <trans-unit id="_msg99">
<source xml:space="preserve">Load PSBT from clipboard…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">329</context></context-group>
</trans-unit>
- <trans-unit id="_msg101">
+ <trans-unit id="_msg100">
<source xml:space="preserve">Open &amp;URI…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">343</context></context-group>
</trans-unit>
- <trans-unit id="_msg102">
+ <trans-unit id="_msg101">
<source xml:space="preserve">Close Wallet…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">351</context></context-group>
</trans-unit>
- <trans-unit id="_msg103">
+ <trans-unit id="_msg102">
<source xml:space="preserve">Create Wallet…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">354</context></context-group>
</trans-unit>
- <trans-unit id="_msg104">
+ <trans-unit id="_msg103">
<source xml:space="preserve">Close All Wallets…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">358</context></context-group>
</trans-unit>
- <trans-unit id="_msg105" approved="yes">
+ <trans-unit id="_msg104" approved="yes">
<source xml:space="preserve">&amp;File</source>
<target xml:space="preserve">&amp;File</target>
<context-group purpose="location"><context context-type="linenumber">455</context></context-group>
</trans-unit>
- <trans-unit id="_msg106" approved="yes">
+ <trans-unit id="_msg105" approved="yes">
<source xml:space="preserve">&amp;Settings</source>
<target xml:space="preserve">&amp;Settings</target>
<context-group purpose="location"><context context-type="linenumber">473</context></context-group>
</trans-unit>
- <trans-unit id="_msg107" approved="yes">
+ <trans-unit id="_msg106" approved="yes">
<source xml:space="preserve">&amp;Help</source>
<target xml:space="preserve">&amp;Help</target>
<context-group purpose="location"><context context-type="linenumber">534</context></context-group>
</trans-unit>
- <trans-unit id="_msg108" approved="yes">
+ <trans-unit id="_msg107" approved="yes">
<source xml:space="preserve">Tabs toolbar</source>
<target xml:space="preserve">Tabs toolbar</target>
<context-group purpose="location"><context context-type="linenumber">545</context></context-group>
</trans-unit>
- <trans-unit id="_msg109">
+ <trans-unit id="_msg108">
<source xml:space="preserve">Syncing Headers (%1%)…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">967</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">982</context></context-group>
</trans-unit>
- <trans-unit id="_msg110">
+ <trans-unit id="_msg109">
<source xml:space="preserve">Synchronizing with network…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1013</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1028</context></context-group>
</trans-unit>
- <trans-unit id="_msg111">
+ <trans-unit id="_msg110">
<source xml:space="preserve">Indexing blocks on disk…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1018</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1033</context></context-group>
</trans-unit>
- <trans-unit id="_msg112">
+ <trans-unit id="_msg111">
<source xml:space="preserve">Processing blocks on disk…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1020</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1035</context></context-group>
</trans-unit>
- <trans-unit id="_msg113">
+ <trans-unit id="_msg112">
<source xml:space="preserve">Reindexing blocks on disk…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1024</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1039</context></context-group>
</trans-unit>
- <trans-unit id="_msg114">
+ <trans-unit id="_msg113">
<source xml:space="preserve">Connecting to peers…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1030</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1045</context></context-group>
</trans-unit>
- <trans-unit id="_msg115">
+ <trans-unit id="_msg114">
<source xml:space="preserve">Request payments (generates QR codes and bitcoin: URIs)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">264</context></context-group>
</trans-unit>
- <trans-unit id="_msg116">
+ <trans-unit id="_msg115">
<source xml:space="preserve">Show the list of used sending addresses and labels</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">339</context></context-group>
</trans-unit>
- <trans-unit id="_msg117">
+ <trans-unit id="_msg116">
<source xml:space="preserve">Show the list of used receiving addresses and labels</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">341</context></context-group>
</trans-unit>
- <trans-unit id="_msg118">
+ <trans-unit id="_msg117">
<source xml:space="preserve">&amp;Command-line options</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">361</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">1039</context></context-group>
- <trans-unit id="_msg119[0]" approved="yes">
+ <context-group purpose="location"><context context-type="linenumber">1054</context></context-group>
+ <trans-unit id="_msg118[0]" approved="yes">
<source xml:space="preserve">Processed %n block(s) of transaction history.</source>
<target xml:space="preserve">Processed %n block of transaction history.</target>
</trans-unit>
- <trans-unit id="_msg119[1]" approved="yes">
+ <trans-unit id="_msg118[1]" approved="yes">
<source xml:space="preserve">Processed %n block(s) of transaction history.</source>
<target xml:space="preserve">Processed %n blocks of transaction history.</target>
</trans-unit>
</group>
- <trans-unit id="_msg120" approved="yes">
+ <trans-unit id="_msg119" approved="yes">
<source xml:space="preserve">%1 behind</source>
<target xml:space="preserve">%1 behind</target>
- <context-group purpose="location"><context context-type="linenumber">1062</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1077</context></context-group>
</trans-unit>
- <trans-unit id="_msg121">
+ <trans-unit id="_msg120">
<source xml:space="preserve">Catching up…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1067</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1082</context></context-group>
</trans-unit>
- <trans-unit id="_msg122" approved="yes">
+ <trans-unit id="_msg121" approved="yes">
<source xml:space="preserve">Last received block was generated %1 ago.</source>
<target xml:space="preserve">Last received block was generated %1 ago.</target>
- <context-group purpose="location"><context context-type="linenumber">1086</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1101</context></context-group>
</trans-unit>
- <trans-unit id="_msg123" approved="yes">
+ <trans-unit id="_msg122" approved="yes">
<source xml:space="preserve">Transactions after this will not yet be visible.</source>
<target xml:space="preserve">Transactions after this will not yet be visible.</target>
- <context-group purpose="location"><context context-type="linenumber">1088</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1103</context></context-group>
</trans-unit>
- <trans-unit id="_msg124" approved="yes">
+ <trans-unit id="_msg123" approved="yes">
<source xml:space="preserve">Error</source>
<target xml:space="preserve">Error</target>
- <context-group purpose="location"><context context-type="linenumber">1113</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1128</context></context-group>
</trans-unit>
- <trans-unit id="_msg125" approved="yes">
+ <trans-unit id="_msg124" approved="yes">
<source xml:space="preserve">Warning</source>
<target xml:space="preserve">Warning</target>
- <context-group purpose="location"><context context-type="linenumber">1117</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1132</context></context-group>
</trans-unit>
- <trans-unit id="_msg126" approved="yes">
+ <trans-unit id="_msg125" approved="yes">
<source xml:space="preserve">Information</source>
<target xml:space="preserve">Information</target>
- <context-group purpose="location"><context context-type="linenumber">1121</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1136</context></context-group>
</trans-unit>
- <trans-unit id="_msg127" approved="yes">
+ <trans-unit id="_msg126" approved="yes">
<source xml:space="preserve">Up to date</source>
<target xml:space="preserve">Up to date</target>
- <context-group purpose="location"><context context-type="linenumber">1043</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1058</context></context-group>
</trans-unit>
- <trans-unit id="_msg128">
+ <trans-unit id="_msg127">
<source xml:space="preserve">Load Partially Signed Bitcoin Transaction</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">328</context></context-group>
</trans-unit>
- <trans-unit id="_msg129">
+ <trans-unit id="_msg128">
<source xml:space="preserve">Load Partially Signed Bitcoin Transaction from clipboard</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">330</context></context-group>
</trans-unit>
- <trans-unit id="_msg130">
+ <trans-unit id="_msg129">
<source xml:space="preserve">Node window</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">332</context></context-group>
</trans-unit>
- <trans-unit id="_msg131">
+ <trans-unit id="_msg130">
<source xml:space="preserve">Open node debugging and diagnostic console</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">333</context></context-group>
</trans-unit>
- <trans-unit id="_msg132">
+ <trans-unit id="_msg131">
<source xml:space="preserve">&amp;Sending addresses</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">338</context></context-group>
</trans-unit>
- <trans-unit id="_msg133">
+ <trans-unit id="_msg132">
<source xml:space="preserve">&amp;Receiving addresses</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">340</context></context-group>
</trans-unit>
- <trans-unit id="_msg134">
+ <trans-unit id="_msg133">
<source xml:space="preserve">Open a bitcoin: URI</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">344</context></context-group>
</trans-unit>
- <trans-unit id="_msg135">
+ <trans-unit id="_msg134">
<source xml:space="preserve">Open Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">346</context></context-group>
</trans-unit>
- <trans-unit id="_msg136">
+ <trans-unit id="_msg135">
<source xml:space="preserve">Open a wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">348</context></context-group>
</trans-unit>
- <trans-unit id="_msg137">
+ <trans-unit id="_msg136">
<source xml:space="preserve">Close wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">352</context></context-group>
</trans-unit>
- <trans-unit id="_msg138">
+ <trans-unit id="_msg137">
<source xml:space="preserve">Close all wallets</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">359</context></context-group>
</trans-unit>
- <trans-unit id="_msg139">
+ <trans-unit id="_msg138">
<source xml:space="preserve">Show the %1 help message to get a list with possible Bitcoin command-line options</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">363</context></context-group>
</trans-unit>
- <trans-unit id="_msg140">
+ <trans-unit id="_msg139">
<source xml:space="preserve">&amp;Mask values</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">365</context></context-group>
</trans-unit>
- <trans-unit id="_msg141">
+ <trans-unit id="_msg140">
<source xml:space="preserve">Mask the values in the Overview tab</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">367</context></context-group>
</trans-unit>
- <trans-unit id="_msg142">
+ <trans-unit id="_msg141">
<source xml:space="preserve">default wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">399</context></context-group>
</trans-unit>
- <trans-unit id="_msg143">
+ <trans-unit id="_msg142">
<source xml:space="preserve">No wallets available</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">420</context></context-group>
</trans-unit>
- <trans-unit id="_msg144">
+ <trans-unit id="_msg143">
<source xml:space="preserve">&amp;Window</source>
<target xml:space="preserve" state="needs-review-translation">&amp;Window</target>
<context-group purpose="location"><context context-type="linenumber">484</context></context-group>
</trans-unit>
- <trans-unit id="_msg145">
+ <trans-unit id="_msg144">
<source xml:space="preserve">Minimize</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">486</context></context-group>
</trans-unit>
- <trans-unit id="_msg146">
+ <trans-unit id="_msg145">
<source xml:space="preserve">Zoom</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">496</context></context-group>
</trans-unit>
- <trans-unit id="_msg147">
+ <trans-unit id="_msg146">
<source xml:space="preserve">Main Window</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">514</context></context-group>
</trans-unit>
- <trans-unit id="_msg148">
+ <trans-unit id="_msg147">
<source xml:space="preserve">%1 client</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">762</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">777</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">920</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">935</context></context-group>
<note annotates="source" from="developer">A substring of the tooltip.</note>
- <trans-unit id="_msg149[0]">
+ <trans-unit id="_msg148[0]">
<source xml:space="preserve">%n active connection(s) to Bitcoin network.</source>
<target xml:space="preserve"></target>
</trans-unit>
- <trans-unit id="_msg149[1]">
+ <trans-unit id="_msg148[1]">
<source xml:space="preserve">%n active connection(s) to Bitcoin network.</source>
<target xml:space="preserve"></target>
</trans-unit>
</group>
- <trans-unit id="_msg150">
+ <trans-unit id="_msg149">
<source xml:space="preserve">Click for more actions.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">930</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">945</context></context-group>
<note annotates="source" from="developer">A substring of the tooltip. &quot;More actions&quot; are available via the context menu.</note>
</trans-unit>
- <trans-unit id="_msg151">
+ <trans-unit id="_msg150">
<source xml:space="preserve">Show Peers tab</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">947</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">962</context></context-group>
<note annotates="source" from="developer">A context menu item. The &quot;Peers tab&quot; is an element of the &quot;Node window&quot;.</note>
</trans-unit>
- <trans-unit id="_msg152">
+ <trans-unit id="_msg151">
<source xml:space="preserve">Disable network activity</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">955</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">970</context></context-group>
<note annotates="source" from="developer">A context menu item.</note>
</trans-unit>
- <trans-unit id="_msg153">
+ <trans-unit id="_msg152">
<source xml:space="preserve">Enable network activity</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">957</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">972</context></context-group>
<note annotates="source" from="developer">A context menu item. The network activity was disabled previously.</note>
</trans-unit>
- <trans-unit id="_msg154">
+ <trans-unit id="_msg153">
<source xml:space="preserve">Error: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1114</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1129</context></context-group>
</trans-unit>
- <trans-unit id="_msg155">
+ <trans-unit id="_msg154">
<source xml:space="preserve">Warning: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1118</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1133</context></context-group>
</trans-unit>
- <trans-unit id="_msg156">
+ <trans-unit id="_msg155">
<source xml:space="preserve">Date: %1
</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1228</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1241</context></context-group>
</trans-unit>
- <trans-unit id="_msg157">
+ <trans-unit id="_msg156">
<source xml:space="preserve">Amount: %1
</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1229</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1242</context></context-group>
</trans-unit>
- <trans-unit id="_msg158">
+ <trans-unit id="_msg157">
<source xml:space="preserve">Wallet: %1
</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1231</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1244</context></context-group>
</trans-unit>
- <trans-unit id="_msg159">
+ <trans-unit id="_msg158">
<source xml:space="preserve">Type: %1
</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1233</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1246</context></context-group>
</trans-unit>
- <trans-unit id="_msg160">
+ <trans-unit id="_msg159">
<source xml:space="preserve">Label: %1
</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1235</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1248</context></context-group>
</trans-unit>
- <trans-unit id="_msg161">
+ <trans-unit id="_msg160">
<source xml:space="preserve">Address: %1
</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1237</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1250</context></context-group>
</trans-unit>
- <trans-unit id="_msg162" approved="yes">
+ <trans-unit id="_msg161" approved="yes">
<source xml:space="preserve">Sent transaction</source>
<target xml:space="preserve">Sent transaction</target>
- <context-group purpose="location"><context context-type="linenumber">1238</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1251</context></context-group>
</trans-unit>
- <trans-unit id="_msg163" approved="yes">
+ <trans-unit id="_msg162" approved="yes">
<source xml:space="preserve">Incoming transaction</source>
<target xml:space="preserve">Incoming transaction</target>
- <context-group purpose="location"><context context-type="linenumber">1238</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1251</context></context-group>
</trans-unit>
- <trans-unit id="_msg164">
+ <trans-unit id="_msg163">
<source xml:space="preserve">HD key generation is &lt;b&gt;enabled&lt;/b&gt;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1290</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1303</context></context-group>
</trans-unit>
- <trans-unit id="_msg165">
+ <trans-unit id="_msg164">
<source xml:space="preserve">HD key generation is &lt;b&gt;disabled&lt;/b&gt;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1290</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1303</context></context-group>
</trans-unit>
- <trans-unit id="_msg166">
+ <trans-unit id="_msg165">
<source xml:space="preserve">Private key &lt;b&gt;disabled&lt;/b&gt;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1290</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1303</context></context-group>
</trans-unit>
- <trans-unit id="_msg167" approved="yes">
+ <trans-unit id="_msg166" approved="yes">
<source xml:space="preserve">Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
<target xml:space="preserve">Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</target>
- <context-group purpose="location"><context context-type="linenumber">1309</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1322</context></context-group>
</trans-unit>
- <trans-unit id="_msg168" approved="yes">
+ <trans-unit id="_msg167" approved="yes">
<source xml:space="preserve">Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
<target xml:space="preserve">Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</target>
- <context-group purpose="location"><context context-type="linenumber">1317</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1330</context></context-group>
</trans-unit>
- <trans-unit id="_msg169">
+ <trans-unit id="_msg168">
<source xml:space="preserve">Original message:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1437</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1450</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="UnitDisplayStatusBarControl">
- <trans-unit id="_msg170">
+ <trans-unit id="_msg169">
<source xml:space="preserve">Unit to show amounts in. Click to select another unit.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1478</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1491</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/coincontroldialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CoinControlDialog">
- <trans-unit id="_msg171">
+ <trans-unit id="_msg170">
<source xml:space="preserve">Coin Selection</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg172">
+ <trans-unit id="_msg171">
<source xml:space="preserve">Quantity:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">48</context></context-group>
</trans-unit>
- <trans-unit id="_msg173">
+ <trans-unit id="_msg172">
<source xml:space="preserve">Bytes:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">77</context></context-group>
</trans-unit>
- <trans-unit id="_msg174">
+ <trans-unit id="_msg173">
<source xml:space="preserve">Amount:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg175">
+ <trans-unit id="_msg174">
<source xml:space="preserve">Fee:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">202</context></context-group>
</trans-unit>
- <trans-unit id="_msg176">
+ <trans-unit id="_msg175">
<source xml:space="preserve">Dust:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">154</context></context-group>
</trans-unit>
- <trans-unit id="_msg177">
+ <trans-unit id="_msg176">
<source xml:space="preserve">After Fee:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">247</context></context-group>
</trans-unit>
- <trans-unit id="_msg178">
+ <trans-unit id="_msg177">
<source xml:space="preserve">Change:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">279</context></context-group>
</trans-unit>
- <trans-unit id="_msg179">
+ <trans-unit id="_msg178">
<source xml:space="preserve">(un)select all</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg180">
+ <trans-unit id="_msg179">
<source xml:space="preserve">Tree mode</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">351</context></context-group>
</trans-unit>
- <trans-unit id="_msg181">
+ <trans-unit id="_msg180">
<source xml:space="preserve">List mode</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">364</context></context-group>
</trans-unit>
- <trans-unit id="_msg182">
+ <trans-unit id="_msg181">
<source xml:space="preserve">Amount</source>
<target xml:space="preserve" state="needs-review-translation">Amount</target>
<context-group purpose="location"><context context-type="linenumber">420</context></context-group>
</trans-unit>
- <trans-unit id="_msg183">
+ <trans-unit id="_msg182">
<source xml:space="preserve">Received with label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">425</context></context-group>
</trans-unit>
- <trans-unit id="_msg184">
+ <trans-unit id="_msg183">
<source xml:space="preserve">Received with address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">430</context></context-group>
</trans-unit>
- <trans-unit id="_msg185">
+ <trans-unit id="_msg184">
<source xml:space="preserve">Date</source>
<target xml:space="preserve" state="needs-review-translation">Date</target>
<context-group purpose="location"><context context-type="linenumber">435</context></context-group>
</trans-unit>
- <trans-unit id="_msg186">
+ <trans-unit id="_msg185">
<source xml:space="preserve">Confirmations</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">440</context></context-group>
</trans-unit>
- <trans-unit id="_msg187">
+ <trans-unit id="_msg186">
<source xml:space="preserve">Confirmed</source>
<target xml:space="preserve" state="needs-review-translation">Confirmed</target>
<context-group purpose="location"><context context-type="linenumber">443</context></context-group>
@@ -1012,34 +1008,38 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../coincontroldialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CoinControlDialog">
+ <trans-unit id="_msg187">
+ <source xml:space="preserve">Copy amount</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">66</context></context-group>
+ </trans-unit>
<trans-unit id="_msg188">
- <source xml:space="preserve">Copy address</source>
+ <source xml:space="preserve">&amp;Copy address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">55</context></context-group>
</trans-unit>
<trans-unit id="_msg189">
- <source xml:space="preserve">Copy label</source>
+ <source xml:space="preserve">Copy &amp;label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">56</context></context-group>
</trans-unit>
<trans-unit id="_msg190">
- <source xml:space="preserve">Copy amount</source>
+ <source xml:space="preserve">Copy &amp;amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">57</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">66</context></context-group>
</trans-unit>
<trans-unit id="_msg191">
- <source xml:space="preserve">Copy transaction ID</source>
+ <source xml:space="preserve">Copy transaction &amp;ID</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
<trans-unit id="_msg192">
- <source xml:space="preserve">Lock unspent</source>
+ <source xml:space="preserve">L&amp;ock unspent</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
<trans-unit id="_msg193">
- <source xml:space="preserve">Unlock unspent</source>
+ <source xml:space="preserve">&amp;Unlock unspent</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">61</context></context-group>
</trans-unit>
@@ -1121,170 +1121,191 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<trans-unit id="_msg208">
<source xml:space="preserve">Creating Wallet &lt;b&gt;%1&lt;/b&gt;…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">253</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">254</context></context-group>
</trans-unit>
<trans-unit id="_msg209">
<source xml:space="preserve">Create wallet failed</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">281</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">285</context></context-group>
</trans-unit>
<trans-unit id="_msg210">
<source xml:space="preserve">Create wallet warning</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">283</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">287</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg211">
+ <source xml:space="preserve">Can&apos;t list signers</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">303</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="OpenWalletActivity">
- <trans-unit id="_msg211">
+ <trans-unit id="_msg212">
<source xml:space="preserve">Open wallet failed</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">322</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg212">
+ <trans-unit id="_msg213">
<source xml:space="preserve">Open wallet warning</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">324</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">337</context></context-group>
</trans-unit>
- <trans-unit id="_msg213">
+ <trans-unit id="_msg214">
<source xml:space="preserve">default wallet</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">334</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">347</context></context-group>
</trans-unit>
- <trans-unit id="_msg214">
+ <trans-unit id="_msg215">
<source xml:space="preserve">Opening Wallet &lt;b&gt;%1&lt;/b&gt;…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">336</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">349</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="WalletController">
- <trans-unit id="_msg215">
- <source xml:space="preserve">Close wallet</source>
- <target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">86</context></context-group>
- </trans-unit>
<trans-unit id="_msg216">
- <source xml:space="preserve">Are you sure you wish to close the wallet &lt;i&gt;%1&lt;/i&gt;?</source>
+ <source xml:space="preserve">Close wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">87</context></context-group>
</trans-unit>
<trans-unit id="_msg217">
- <source xml:space="preserve">Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled.</source>
+ <source xml:space="preserve">Are you sure you wish to close the wallet &lt;i&gt;%1&lt;/i&gt;?</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
</trans-unit>
<trans-unit id="_msg218">
- <source xml:space="preserve">Close all wallets</source>
+ <source xml:space="preserve">Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">101</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">89</context></context-group>
</trans-unit>
<trans-unit id="_msg219">
- <source xml:space="preserve">Are you sure you wish to close all wallets?</source>
+ <source xml:space="preserve">Close all wallets</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">102</context></context-group>
</trans-unit>
+ <trans-unit id="_msg220">
+ <source xml:space="preserve">Are you sure you wish to close all wallets?</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">103</context></context-group>
+ </trans-unit>
</group>
</body></file>
<file original="../forms/createwalletdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CreateWalletDialog">
- <trans-unit id="_msg220">
+ <trans-unit id="_msg221">
<source xml:space="preserve">Create Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg221">
+ <trans-unit id="_msg222">
<source xml:space="preserve">Wallet Name</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">25</context></context-group>
</trans-unit>
- <trans-unit id="_msg222">
+ <trans-unit id="_msg223">
<source xml:space="preserve">Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">38</context></context-group>
</trans-unit>
- <trans-unit id="_msg223">
+ <trans-unit id="_msg224">
<source xml:space="preserve">Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg224">
+ <trans-unit id="_msg225">
<source xml:space="preserve">Encrypt Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg225">
+ <trans-unit id="_msg226">
<source xml:space="preserve">Advanced Options</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">76</context></context-group>
</trans-unit>
- <trans-unit id="_msg226">
+ <trans-unit id="_msg227">
<source xml:space="preserve">Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">85</context></context-group>
</trans-unit>
- <trans-unit id="_msg227">
+ <trans-unit id="_msg228">
<source xml:space="preserve">Disable Private Keys</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
</trans-unit>
- <trans-unit id="_msg228">
+ <trans-unit id="_msg229">
<source xml:space="preserve">Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg229">
+ <trans-unit id="_msg230">
<source xml:space="preserve">Make Blank Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg230">
+ <trans-unit id="_msg231">
<source xml:space="preserve">Use descriptors for scriptPubKey management</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">105</context></context-group>
</trans-unit>
- <trans-unit id="_msg231">
+ <trans-unit id="_msg232">
<source xml:space="preserve">Descriptor Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
</trans-unit>
+ <trans-unit id="_msg233">
+ <source xml:space="preserve">Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first.</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">115</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg234">
+ <source xml:space="preserve">External signer</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">118</context></context-group>
+ </trans-unit>
</group>
</body></file>
<file original="../createwalletdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="CreateWalletDialog">
- <trans-unit id="_msg232">
+ <trans-unit id="_msg235">
<source xml:space="preserve">Create</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">21</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">22</context></context-group>
</trans-unit>
- <trans-unit id="_msg233">
+ <trans-unit id="_msg236">
<source xml:space="preserve">Compiled without sqlite support (required for descriptor wallets)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">63</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">90</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg237">
+ <source xml:space="preserve">Compiled without external signing support (required for external signing)</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">104</context></context-group>
+ <note annotates="source" from="developer">&quot;External signing&quot; means using devices such as hardware wallets.</note>
</trans-unit>
</group>
</body></file>
<file original="../forms/editaddressdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="EditAddressDialog">
- <trans-unit id="_msg234" approved="yes">
+ <trans-unit id="_msg238" approved="yes">
<source xml:space="preserve">Edit Address</source>
<target xml:space="preserve">Edit Address</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg235" approved="yes">
+ <trans-unit id="_msg239" approved="yes">
<source xml:space="preserve">&amp;Label</source>
<target xml:space="preserve">&amp;Label</target>
<context-group purpose="location"><context context-type="linenumber">25</context></context-group>
</trans-unit>
- <trans-unit id="_msg236">
+ <trans-unit id="_msg240">
<source xml:space="preserve">The label associated with this address list entry</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">35</context></context-group>
</trans-unit>
- <trans-unit id="_msg237">
+ <trans-unit id="_msg241">
<source xml:space="preserve">The address associated with this address list entry. This can only be modified for sending addresses.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">52</context></context-group>
</trans-unit>
- <trans-unit id="_msg238" approved="yes">
+ <trans-unit id="_msg242" approved="yes">
<source xml:space="preserve">&amp;Address</source>
<target xml:space="preserve">&amp;Address</target>
<context-group purpose="location"><context context-type="linenumber">42</context></context-group>
@@ -1293,42 +1314,42 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../editaddressdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="EditAddressDialog">
- <trans-unit id="_msg239">
+ <trans-unit id="_msg243">
<source xml:space="preserve">New sending address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">29</context></context-group>
</trans-unit>
- <trans-unit id="_msg240">
+ <trans-unit id="_msg244">
<source xml:space="preserve">Edit receiving address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg241">
+ <trans-unit id="_msg245">
<source xml:space="preserve">Edit sending address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">36</context></context-group>
</trans-unit>
- <trans-unit id="_msg242">
+ <trans-unit id="_msg246">
<source xml:space="preserve">The entered address &quot;%1&quot; is not a valid Bitcoin address.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">113</context></context-group>
</trans-unit>
- <trans-unit id="_msg243">
+ <trans-unit id="_msg247">
<source xml:space="preserve">Address &quot;%1&quot; already exists as a receiving address with label &quot;%2&quot; and so cannot be added as a sending address.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">146</context></context-group>
</trans-unit>
- <trans-unit id="_msg244">
+ <trans-unit id="_msg248">
<source xml:space="preserve">The entered address &quot;%1&quot; is already in the address book with label &quot;%2&quot;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">151</context></context-group>
</trans-unit>
- <trans-unit id="_msg245">
+ <trans-unit id="_msg249">
<source xml:space="preserve">Could not unlock wallet.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">123</context></context-group>
</trans-unit>
- <trans-unit id="_msg246">
+ <trans-unit id="_msg250">
<source xml:space="preserve">New key generation failed.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">128</context></context-group>
@@ -1337,59 +1358,59 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../intro.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="FreespaceChecker">
- <trans-unit id="_msg247" approved="yes">
+ <trans-unit id="_msg251" approved="yes">
<source xml:space="preserve">A new data directory will be created.</source>
<target xml:space="preserve">A new data directory will be created.</target>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg248" approved="yes">
+ <trans-unit id="_msg252" approved="yes">
<source xml:space="preserve">name</source>
<target xml:space="preserve">name</target>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg249" approved="yes">
+ <trans-unit id="_msg253" approved="yes">
<source xml:space="preserve">Directory already exists. Add %1 if you intend to create a new directory here.</source>
<target xml:space="preserve">Directory already exists. Add %1 if you intend to create a new directory here.</target>
<context-group purpose="location"><context context-type="linenumber">97</context></context-group>
</trans-unit>
- <trans-unit id="_msg250" approved="yes">
+ <trans-unit id="_msg254" approved="yes">
<source xml:space="preserve">Path already exists, and is not a directory.</source>
<target xml:space="preserve">Path already exists, and is not a directory.</target>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
</trans-unit>
- <trans-unit id="_msg251" approved="yes">
+ <trans-unit id="_msg255" approved="yes">
<source xml:space="preserve">Cannot create data directory here.</source>
<target xml:space="preserve">Cannot create data directory here.</target>
<context-group purpose="location"><context context-type="linenumber">107</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="Intro">
- <trans-unit id="_msg252">
+ <trans-unit id="_msg256">
<source xml:space="preserve">Bitcoin</source>
<target xml:space="preserve" state="needs-review-translation">Bitcoin</target>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg253">
+ <trans-unit id="_msg257">
<source xml:space="preserve">%1 GB of free space available</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">301</context></context-group>
</trans-unit>
- <trans-unit id="_msg254">
+ <trans-unit id="_msg258">
<source xml:space="preserve">(of %1 GB needed)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">303</context></context-group>
</trans-unit>
- <trans-unit id="_msg255">
+ <trans-unit id="_msg259">
<source xml:space="preserve">(%1 GB needed for full chain)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
</trans-unit>
- <trans-unit id="_msg256">
+ <trans-unit id="_msg260">
<source xml:space="preserve">At least %1 GB of data will be stored in this directory, and it will grow over time.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">378</context></context-group>
</trans-unit>
- <trans-unit id="_msg257">
+ <trans-unit id="_msg261">
<source xml:space="preserve">Approximately %1 GB of data will be stored in this directory.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">381</context></context-group>
@@ -1397,31 +1418,31 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">390</context></context-group>
<note annotates="source" from="developer">Explanatory text on the capability of the current prune target.</note>
- <trans-unit id="_msg258[0]">
+ <trans-unit id="_msg262[0]">
<source xml:space="preserve">(sufficient to restore backups %n day(s) old)</source>
<target xml:space="preserve"></target>
</trans-unit>
- <trans-unit id="_msg258[1]">
+ <trans-unit id="_msg262[1]">
<source xml:space="preserve">(sufficient to restore backups %n day(s) old)</source>
<target xml:space="preserve"></target>
</trans-unit>
</group>
- <trans-unit id="_msg259">
+ <trans-unit id="_msg263">
<source xml:space="preserve">%1 will download and store a copy of the Bitcoin block chain.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">392</context></context-group>
</trans-unit>
- <trans-unit id="_msg260">
+ <trans-unit id="_msg264">
<source xml:space="preserve">The wallet will also be stored in this directory.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">394</context></context-group>
</trans-unit>
- <trans-unit id="_msg261">
+ <trans-unit id="_msg265">
<source xml:space="preserve">Error: Specified data directory &quot;%1&quot; cannot be created.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">250</context></context-group>
</trans-unit>
- <trans-unit id="_msg262" approved="yes">
+ <trans-unit id="_msg266" approved="yes">
<source xml:space="preserve">Error</source>
<target xml:space="preserve">Error</target>
<context-group purpose="location"><context context-type="linenumber">280</context></context-group>
@@ -1430,29 +1451,29 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../utilitydialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="HelpMessageDialog">
- <trans-unit id="_msg263">
+ <trans-unit id="_msg267">
<source xml:space="preserve">version</source>
<target xml:space="preserve" state="needs-review-translation">version</target>
<context-group purpose="location"><context context-type="linenumber">37</context></context-group>
</trans-unit>
- <trans-unit id="_msg264">
+ <trans-unit id="_msg268">
<source xml:space="preserve">About %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">41</context></context-group>
</trans-unit>
- <trans-unit id="_msg265">
+ <trans-unit id="_msg269">
<source xml:space="preserve">Command-line options</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="ShutdownWindow">
- <trans-unit id="_msg266">
+ <trans-unit id="_msg270">
<source xml:space="preserve">%1 is shutting down…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">145</context></context-group>
</trans-unit>
- <trans-unit id="_msg267">
+ <trans-unit id="_msg271">
<source xml:space="preserve">Do not shut down the computer until this window disappears.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">146</context></context-group>
@@ -1461,57 +1482,57 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/intro.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="Intro">
- <trans-unit id="_msg268" approved="yes">
+ <trans-unit id="_msg272" approved="yes">
<source xml:space="preserve">Welcome</source>
<target xml:space="preserve">Welcome</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg269">
+ <trans-unit id="_msg273">
<source xml:space="preserve">Welcome to %1.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">23</context></context-group>
</trans-unit>
- <trans-unit id="_msg270">
+ <trans-unit id="_msg274">
<source xml:space="preserve">As this is the first time the program is launched, you can choose where %1 will store its data.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg271">
+ <trans-unit id="_msg275">
<source xml:space="preserve">When you click OK, %1 will begin to download and process the full %4 block chain (%2GB) starting with the earliest transactions in %3 when %4 initially launched.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
</trans-unit>
- <trans-unit id="_msg272">
+ <trans-unit id="_msg276">
<source xml:space="preserve">Limit block chain storage to</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">238</context></context-group>
</trans-unit>
- <trans-unit id="_msg273">
+ <trans-unit id="_msg277">
<source xml:space="preserve">Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">241</context></context-group>
</trans-unit>
- <trans-unit id="_msg274">
+ <trans-unit id="_msg278">
<source xml:space="preserve"> GB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">248</context></context-group>
</trans-unit>
- <trans-unit id="_msg275">
+ <trans-unit id="_msg279">
<source xml:space="preserve">This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">216</context></context-group>
</trans-unit>
- <trans-unit id="_msg276">
+ <trans-unit id="_msg280">
<source xml:space="preserve">If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg277" approved="yes">
+ <trans-unit id="_msg281" approved="yes">
<source xml:space="preserve">Use the default data directory</source>
<target xml:space="preserve">Use the default data directory</target>
<context-group purpose="location"><context context-type="linenumber">66</context></context-group>
</trans-unit>
- <trans-unit id="_msg278" approved="yes">
+ <trans-unit id="_msg282" approved="yes">
<source xml:space="preserve">Use a custom data directory:</source>
<target xml:space="preserve">Use a custom data directory:</target>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
@@ -1520,65 +1541,65 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/modaloverlay.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ModalOverlay">
- <trans-unit id="_msg279">
+ <trans-unit id="_msg283">
<source xml:space="preserve">Form</source>
<target xml:space="preserve" state="needs-review-translation">Form</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg280">
+ <trans-unit id="_msg284">
<source xml:space="preserve">Recent transactions may not yet be visible, and therefore your wallet&apos;s balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">133</context></context-group>
</trans-unit>
- <trans-unit id="_msg281">
+ <trans-unit id="_msg285">
<source xml:space="preserve">Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg282">
+ <trans-unit id="_msg286">
<source xml:space="preserve">Number of blocks left</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg283">
+ <trans-unit id="_msg287">
<source xml:space="preserve">Unknown…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
<context-group purpose="location"><context context-type="linenumber">248</context></context-group>
<context-group purpose="location"><context context-type="sourcefile">../modaloverlay.cpp</context><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg284">
+ <trans-unit id="_msg288">
<source xml:space="preserve">calculating…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">292</context></context-group>
<context-group purpose="location"><context context-type="linenumber">312</context></context-group>
</trans-unit>
- <trans-unit id="_msg285">
+ <trans-unit id="_msg289">
<source xml:space="preserve">Last block time</source>
<target xml:space="preserve" state="needs-review-translation">Last block time</target>
<context-group purpose="location"><context context-type="linenumber">235</context></context-group>
</trans-unit>
- <trans-unit id="_msg286">
+ <trans-unit id="_msg290">
<source xml:space="preserve">Progress</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">261</context></context-group>
</trans-unit>
- <trans-unit id="_msg287">
+ <trans-unit id="_msg291">
<source xml:space="preserve">Progress increase per hour</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">285</context></context-group>
</trans-unit>
- <trans-unit id="_msg288">
+ <trans-unit id="_msg292">
<source xml:space="preserve">Estimated time left until synced</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg289">
+ <trans-unit id="_msg293">
<source xml:space="preserve">Hide</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">342</context></context-group>
</trans-unit>
- <trans-unit id="_msg290">
+ <trans-unit id="_msg294">
<source xml:space="preserve">Esc</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">345</context></context-group>
@@ -1587,19 +1608,19 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../modaloverlay.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ModalOverlay">
- <trans-unit id="_msg291">
+ <trans-unit id="_msg295">
<source xml:space="preserve">%1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">34</context></context-group>
</trans-unit>
- <trans-unit id="_msg292">
+ <trans-unit id="_msg296">
<source xml:space="preserve">Unknown. Syncing Headers (%1, %2%)…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
</group>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg293">
+ <trans-unit id="_msg297">
<source xml:space="preserve">unknown</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">123</context></context-group>
@@ -1608,12 +1629,12 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/openuridialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OpenURIDialog">
- <trans-unit id="_msg294">
+ <trans-unit id="_msg298">
<source xml:space="preserve">Open bitcoin URI</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg295">
+ <trans-unit id="_msg299">
<source xml:space="preserve">URI:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">22</context></context-group>
@@ -1622,474 +1643,495 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../forms/optionsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OptionsDialog">
- <trans-unit id="_msg296" approved="yes">
+ <trans-unit id="_msg300" approved="yes">
<source xml:space="preserve">Options</source>
<target xml:space="preserve">Options</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg297" approved="yes">
+ <trans-unit id="_msg301" approved="yes">
<source xml:space="preserve">&amp;Main</source>
<target xml:space="preserve">&amp;Main</target>
<context-group purpose="location"><context context-type="linenumber">27</context></context-group>
</trans-unit>
- <trans-unit id="_msg298">
+ <trans-unit id="_msg302">
<source xml:space="preserve">Automatically start %1 after logging in to the system.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">33</context></context-group>
</trans-unit>
- <trans-unit id="_msg299">
+ <trans-unit id="_msg303">
<source xml:space="preserve">&amp;Start %1 on system login</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">36</context></context-group>
</trans-unit>
- <trans-unit id="_msg300">
+ <trans-unit id="_msg304">
<source xml:space="preserve">Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
- <trans-unit id="_msg301">
+ <trans-unit id="_msg305">
<source xml:space="preserve">Size of &amp;database cache</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
</trans-unit>
- <trans-unit id="_msg302">
+ <trans-unit id="_msg306">
<source xml:space="preserve">Number of script &amp;verification threads</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">151</context></context-group>
</trans-unit>
- <trans-unit id="_msg303">
+ <trans-unit id="_msg307">
<source xml:space="preserve">IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">322</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">509</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">352</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">539</context></context-group>
</trans-unit>
- <trans-unit id="_msg304">
+ <trans-unit id="_msg308">
<source xml:space="preserve">Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">391</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">414</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">437</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">421</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">444</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">467</context></context-group>
</trans-unit>
- <trans-unit id="_msg305">
+ <trans-unit id="_msg309">
<source xml:space="preserve">Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">606</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">636</context></context-group>
</trans-unit>
- <trans-unit id="_msg306">
+ <trans-unit id="_msg310">
<source xml:space="preserve">Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">686</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">699</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">716</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">729</context></context-group>
</trans-unit>
- <trans-unit id="_msg307">
+ <trans-unit id="_msg311">
<source xml:space="preserve">Open the %1 configuration file from the working directory.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">878</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">908</context></context-group>
</trans-unit>
- <trans-unit id="_msg308">
+ <trans-unit id="_msg312">
<source xml:space="preserve">Open Configuration File</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">881</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">911</context></context-group>
</trans-unit>
- <trans-unit id="_msg309" approved="yes">
+ <trans-unit id="_msg313" approved="yes">
<source xml:space="preserve">Reset all client options to default.</source>
<target xml:space="preserve">Reset all client options to default.</target>
- <context-group purpose="location"><context context-type="linenumber">891</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">921</context></context-group>
</trans-unit>
- <trans-unit id="_msg310" approved="yes">
+ <trans-unit id="_msg314" approved="yes">
<source xml:space="preserve">&amp;Reset Options</source>
<target xml:space="preserve">&amp;Reset Options</target>
- <context-group purpose="location"><context context-type="linenumber">894</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">924</context></context-group>
</trans-unit>
- <trans-unit id="_msg311" approved="yes">
+ <trans-unit id="_msg315" approved="yes">
<source xml:space="preserve">&amp;Network</source>
<target xml:space="preserve">&amp;Network</target>
- <context-group purpose="location"><context context-type="linenumber">249</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">279</context></context-group>
</trans-unit>
- <trans-unit id="_msg312">
+ <trans-unit id="_msg316">
<source xml:space="preserve">Prune &amp;block storage to</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">61</context></context-group>
</trans-unit>
- <trans-unit id="_msg313">
+ <trans-unit id="_msg317">
<source xml:space="preserve">GB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">71</context></context-group>
</trans-unit>
- <trans-unit id="_msg314">
+ <trans-unit id="_msg318">
<source xml:space="preserve">Reverting this setting requires re-downloading the entire blockchain.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg315">
+ <trans-unit id="_msg319">
<source xml:space="preserve">MiB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">124</context></context-group>
</trans-unit>
- <trans-unit id="_msg316">
+ <trans-unit id="_msg320">
<source xml:space="preserve">(0 = auto, &lt;0 = leave that many cores free)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">164</context></context-group>
</trans-unit>
- <trans-unit id="_msg317">
+ <trans-unit id="_msg321">
<source xml:space="preserve">W&amp;allet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">200</context></context-group>
</trans-unit>
- <trans-unit id="_msg318">
+ <trans-unit id="_msg322">
<source xml:space="preserve">Expert</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
</trans-unit>
- <trans-unit id="_msg319">
+ <trans-unit id="_msg323">
<source xml:space="preserve">Enable coin &amp;control features</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg320">
+ <trans-unit id="_msg324">
<source xml:space="preserve">If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
</trans-unit>
- <trans-unit id="_msg321">
+ <trans-unit id="_msg325">
<source xml:space="preserve">&amp;Spend unconfirmed change</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">225</context></context-group>
</trans-unit>
- <trans-unit id="_msg322" approved="yes">
+ <trans-unit id="_msg326">
+ <source xml:space="preserve">External Signer (e.g. hardware wallet)</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">235</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg327">
+ <source xml:space="preserve">&amp;External signer script path</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">243</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg328">
+ <source xml:space="preserve">Full path to a Bitcoin Core compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins!</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">253</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg329" approved="yes">
<source xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<target xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</target>
- <context-group purpose="location"><context context-type="linenumber">255</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">285</context></context-group>
</trans-unit>
- <trans-unit id="_msg323" approved="yes">
+ <trans-unit id="_msg330" approved="yes">
<source xml:space="preserve">Map port using &amp;UPnP</source>
<target xml:space="preserve">Map port using &amp;UPnP</target>
- <context-group purpose="location"><context context-type="linenumber">258</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">288</context></context-group>
</trans-unit>
- <trans-unit id="_msg324">
+ <trans-unit id="_msg331">
<source xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports NAT-PMP and it is enabled. The external port could be random.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">265</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">295</context></context-group>
</trans-unit>
- <trans-unit id="_msg325">
+ <trans-unit id="_msg332">
<source xml:space="preserve">Map port using NA&amp;T-PMP</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">268</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">298</context></context-group>
</trans-unit>
- <trans-unit id="_msg326">
+ <trans-unit id="_msg333">
<source xml:space="preserve">Accept connections from outside.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">275</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg327">
+ <trans-unit id="_msg334">
<source xml:space="preserve">Allow incomin&amp;g connections</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">278</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">308</context></context-group>
</trans-unit>
- <trans-unit id="_msg328">
+ <trans-unit id="_msg335">
<source xml:space="preserve">Connect to the Bitcoin network through a SOCKS5 proxy.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">285</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">315</context></context-group>
</trans-unit>
- <trans-unit id="_msg329">
+ <trans-unit id="_msg336">
<source xml:space="preserve">&amp;Connect through SOCKS5 proxy (default proxy):</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">288</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">318</context></context-group>
</trans-unit>
- <trans-unit id="_msg330" approved="yes">
+ <trans-unit id="_msg337" approved="yes">
<source xml:space="preserve">Proxy &amp;IP:</source>
<target xml:space="preserve">Proxy &amp;IP:</target>
- <context-group purpose="location"><context context-type="linenumber">297</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">484</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">327</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">514</context></context-group>
</trans-unit>
- <trans-unit id="_msg331" approved="yes">
+ <trans-unit id="_msg338" approved="yes">
<source xml:space="preserve">&amp;Port:</source>
<target xml:space="preserve">&amp;Port:</target>
- <context-group purpose="location"><context context-type="linenumber">329</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">516</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">359</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">546</context></context-group>
</trans-unit>
- <trans-unit id="_msg332" approved="yes">
+ <trans-unit id="_msg339" approved="yes">
<source xml:space="preserve">Port of the proxy (e.g. 9050)</source>
<target xml:space="preserve">Port of the proxy (e.g. 9050)</target>
- <context-group purpose="location"><context context-type="linenumber">354</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">541</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">384</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">571</context></context-group>
</trans-unit>
- <trans-unit id="_msg333">
+ <trans-unit id="_msg340">
<source xml:space="preserve">Used for reaching peers via:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">378</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">408</context></context-group>
</trans-unit>
- <trans-unit id="_msg334">
+ <trans-unit id="_msg341">
<source xml:space="preserve">IPv4</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">401</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">431</context></context-group>
</trans-unit>
- <trans-unit id="_msg335">
+ <trans-unit id="_msg342">
<source xml:space="preserve">IPv6</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">424</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">454</context></context-group>
</trans-unit>
- <trans-unit id="_msg336">
+ <trans-unit id="_msg343">
<source xml:space="preserve">Tor</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">447</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">477</context></context-group>
</trans-unit>
- <trans-unit id="_msg337" approved="yes">
+ <trans-unit id="_msg344" approved="yes">
<source xml:space="preserve">&amp;Window</source>
<target xml:space="preserve">&amp;Window</target>
- <context-group purpose="location"><context context-type="linenumber">577</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">607</context></context-group>
</trans-unit>
- <trans-unit id="_msg338">
+ <trans-unit id="_msg345">
<source xml:space="preserve">Show the icon in the system tray.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">583</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">613</context></context-group>
</trans-unit>
- <trans-unit id="_msg339">
+ <trans-unit id="_msg346">
<source xml:space="preserve">&amp;Show tray icon</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">586</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">616</context></context-group>
</trans-unit>
- <trans-unit id="_msg340" approved="yes">
+ <trans-unit id="_msg347" approved="yes">
<source xml:space="preserve">Show only a tray icon after minimizing the window.</source>
<target xml:space="preserve">Show only a tray icon after minimizing the window.</target>
- <context-group purpose="location"><context context-type="linenumber">596</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">626</context></context-group>
</trans-unit>
- <trans-unit id="_msg341" approved="yes">
+ <trans-unit id="_msg348" approved="yes">
<source xml:space="preserve">&amp;Minimize to the tray instead of the taskbar</source>
<target xml:space="preserve">&amp;Minimize to the tray instead of the taskbar</target>
- <context-group purpose="location"><context context-type="linenumber">599</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">629</context></context-group>
</trans-unit>
- <trans-unit id="_msg342" approved="yes">
+ <trans-unit id="_msg349" approved="yes">
<source xml:space="preserve">M&amp;inimize on close</source>
<target xml:space="preserve">M&amp;inimize on close</target>
- <context-group purpose="location"><context context-type="linenumber">609</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">639</context></context-group>
</trans-unit>
- <trans-unit id="_msg343" approved="yes">
+ <trans-unit id="_msg350" approved="yes">
<source xml:space="preserve">&amp;Display</source>
<target xml:space="preserve">&amp;Display</target>
- <context-group purpose="location"><context context-type="linenumber">630</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">660</context></context-group>
</trans-unit>
- <trans-unit id="_msg344" approved="yes">
+ <trans-unit id="_msg351" approved="yes">
<source xml:space="preserve">User Interface &amp;language:</source>
<target xml:space="preserve">User Interface &amp;language:</target>
- <context-group purpose="location"><context context-type="linenumber">638</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">668</context></context-group>
</trans-unit>
- <trans-unit id="_msg345">
+ <trans-unit id="_msg352">
<source xml:space="preserve">The user interface language can be set here. This setting will take effect after restarting %1.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">651</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">681</context></context-group>
</trans-unit>
- <trans-unit id="_msg346" approved="yes">
+ <trans-unit id="_msg353" approved="yes">
<source xml:space="preserve">&amp;Unit to show amounts in:</source>
<target xml:space="preserve">&amp;Unit to show amounts in:</target>
- <context-group purpose="location"><context context-type="linenumber">662</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">692</context></context-group>
</trans-unit>
- <trans-unit id="_msg347" approved="yes">
+ <trans-unit id="_msg354" approved="yes">
<source xml:space="preserve">Choose the default subdivision unit to show in the interface and when sending coins.</source>
<target xml:space="preserve">Choose the default subdivision unit to show in the interface and when sending coins.</target>
- <context-group purpose="location"><context context-type="linenumber">675</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">705</context></context-group>
</trans-unit>
- <trans-unit id="_msg348">
+ <trans-unit id="_msg355">
<source xml:space="preserve">Whether to show coin control features or not.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">212</context></context-group>
</trans-unit>
- <trans-unit id="_msg349">
+ <trans-unit id="_msg356">
<source xml:space="preserve">Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">472</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">502</context></context-group>
</trans-unit>
- <trans-unit id="_msg350">
+ <trans-unit id="_msg357">
<source xml:space="preserve">Use separate SOCKS&amp;5 proxy to reach peers via Tor onion services:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">475</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">505</context></context-group>
</trans-unit>
- <trans-unit id="_msg351">
+ <trans-unit id="_msg358">
<source xml:space="preserve">&amp;Third party transaction URLs</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">689</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">719</context></context-group>
</trans-unit>
- <trans-unit id="_msg352">
+ <trans-unit id="_msg359">
<source xml:space="preserve">Monospaced font in the Overview tab:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">711</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">741</context></context-group>
</trans-unit>
- <trans-unit id="_msg353">
+ <trans-unit id="_msg360">
<source xml:space="preserve">embedded &quot;%1&quot;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">719</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">749</context></context-group>
</trans-unit>
- <trans-unit id="_msg354">
+ <trans-unit id="_msg361">
<source xml:space="preserve">closest matching &quot;%1&quot;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">768</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">798</context></context-group>
</trans-unit>
- <trans-unit id="_msg355">
+ <trans-unit id="_msg362">
<source xml:space="preserve">Options set in this dialog are overridden by the command line or in the configuration file:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">833</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">863</context></context-group>
</trans-unit>
- <trans-unit id="_msg356" approved="yes">
+ <trans-unit id="_msg363" approved="yes">
<source xml:space="preserve">&amp;OK</source>
<target xml:space="preserve">&amp;OK</target>
- <context-group purpose="location"><context context-type="linenumber">974</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1004</context></context-group>
</trans-unit>
- <trans-unit id="_msg357" approved="yes">
+ <trans-unit id="_msg364" approved="yes">
<source xml:space="preserve">&amp;Cancel</source>
<target xml:space="preserve">&amp;Cancel</target>
- <context-group purpose="location"><context context-type="linenumber">987</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1017</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../optionsdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OptionsDialog">
- <trans-unit id="_msg358" approved="yes">
+ <trans-unit id="_msg365">
+ <source xml:space="preserve">Compiled without external signing support (required for external signing)</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">97</context></context-group>
+ <note annotates="source" from="developer">&quot;External signing&quot; means using devices such as hardware wallets.</note>
+ </trans-unit>
+ <trans-unit id="_msg366" approved="yes">
<source xml:space="preserve">default</source>
<target xml:space="preserve">default</target>
- <context-group purpose="location"><context context-type="linenumber">104</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">109</context></context-group>
</trans-unit>
- <trans-unit id="_msg359">
+ <trans-unit id="_msg367">
<source xml:space="preserve">none</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">185</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">190</context></context-group>
</trans-unit>
- <trans-unit id="_msg360" approved="yes">
+ <trans-unit id="_msg368" approved="yes">
<source xml:space="preserve">Confirm options reset</source>
<target xml:space="preserve">Confirm options reset</target>
- <context-group purpose="location"><context context-type="linenumber">276</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">283</context></context-group>
</trans-unit>
- <trans-unit id="_msg361">
+ <trans-unit id="_msg369">
<source xml:space="preserve">Client restart required to activate changes.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">277</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">334</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">284</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">341</context></context-group>
</trans-unit>
- <trans-unit id="_msg362">
+ <trans-unit id="_msg370">
<source xml:space="preserve">Client will be shut down. Do you want to proceed?</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">277</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg363">
+ <trans-unit id="_msg371">
<source xml:space="preserve">Configuration options</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">292</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">299</context></context-group>
</trans-unit>
- <trans-unit id="_msg364">
+ <trans-unit id="_msg372">
<source xml:space="preserve">The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">293</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">300</context></context-group>
</trans-unit>
- <trans-unit id="_msg365">
+ <trans-unit id="_msg373">
<source xml:space="preserve">Error</source>
<target xml:space="preserve" state="needs-review-translation">Error</target>
- <context-group purpose="location"><context context-type="linenumber">298</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg366">
+ <trans-unit id="_msg374">
<source xml:space="preserve">The configuration file could not be opened.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">298</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg367">
+ <trans-unit id="_msg375">
<source xml:space="preserve">This change would require a client restart.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">338</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">345</context></context-group>
</trans-unit>
- <trans-unit id="_msg368" approved="yes">
+ <trans-unit id="_msg376" approved="yes">
<source xml:space="preserve">The supplied proxy address is invalid.</source>
<target xml:space="preserve">The supplied proxy address is invalid.</target>
- <context-group purpose="location"><context context-type="linenumber">366</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">373</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/overviewpage.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OverviewPage">
- <trans-unit id="_msg369" approved="yes">
+ <trans-unit id="_msg377" approved="yes">
<source xml:space="preserve">Form</source>
<target xml:space="preserve">Form</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg370" approved="yes">
+ <trans-unit id="_msg378" approved="yes">
<source xml:space="preserve">The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
<target xml:space="preserve">The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</target>
<context-group purpose="location"><context context-type="linenumber">76</context></context-group>
<context-group purpose="location"><context context-type="linenumber">411</context></context-group>
</trans-unit>
- <trans-unit id="_msg371">
+ <trans-unit id="_msg379">
<source xml:space="preserve">Watch-only:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg372">
+ <trans-unit id="_msg380">
<source xml:space="preserve">Available:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">294</context></context-group>
</trans-unit>
- <trans-unit id="_msg373" approved="yes">
+ <trans-unit id="_msg381" approved="yes">
<source xml:space="preserve">Your current spendable balance</source>
<target xml:space="preserve">Your current spendable balance</target>
<context-group purpose="location"><context context-type="linenumber">304</context></context-group>
</trans-unit>
- <trans-unit id="_msg374">
+ <trans-unit id="_msg382">
<source xml:space="preserve">Pending:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">339</context></context-group>
</trans-unit>
- <trans-unit id="_msg375" approved="yes">
+ <trans-unit id="_msg383" approved="yes">
<source xml:space="preserve">Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
<target xml:space="preserve">Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</target>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg376" approved="yes">
+ <trans-unit id="_msg384" approved="yes">
<source xml:space="preserve">Immature:</source>
<target xml:space="preserve">Immature:</target>
<context-group purpose="location"><context context-type="linenumber">239</context></context-group>
</trans-unit>
- <trans-unit id="_msg377" approved="yes">
+ <trans-unit id="_msg385" approved="yes">
<source xml:space="preserve">Mined balance that has not yet matured</source>
<target xml:space="preserve">Mined balance that has not yet matured</target>
<context-group purpose="location"><context context-type="linenumber">210</context></context-group>
</trans-unit>
- <trans-unit id="_msg378">
+ <trans-unit id="_msg386">
<source xml:space="preserve">Balances</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">60</context></context-group>
</trans-unit>
- <trans-unit id="_msg379" approved="yes">
+ <trans-unit id="_msg387" approved="yes">
<source xml:space="preserve">Total:</source>
<target xml:space="preserve">Total:</target>
<context-group purpose="location"><context context-type="linenumber">200</context></context-group>
</trans-unit>
- <trans-unit id="_msg380" approved="yes">
+ <trans-unit id="_msg388" approved="yes">
<source xml:space="preserve">Your current total balance</source>
<target xml:space="preserve">Your current total balance</target>
<context-group purpose="location"><context context-type="linenumber">249</context></context-group>
</trans-unit>
- <trans-unit id="_msg381">
+ <trans-unit id="_msg389">
<source xml:space="preserve">Your current balance in watch-only addresses</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg382">
+ <trans-unit id="_msg390">
<source xml:space="preserve">Spendable:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">346</context></context-group>
</trans-unit>
- <trans-unit id="_msg383">
+ <trans-unit id="_msg391">
<source xml:space="preserve">Recent transactions</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">395</context></context-group>
</trans-unit>
- <trans-unit id="_msg384">
+ <trans-unit id="_msg392">
<source xml:space="preserve">Unconfirmed transactions to watch-only addresses</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg385">
+ <trans-unit id="_msg393">
<source xml:space="preserve">Mined balance in watch-only addresses that has not yet matured</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
- <trans-unit id="_msg386">
+ <trans-unit id="_msg394">
<source xml:space="preserve">Current total balance in watch-only addresses</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">268</context></context-group>
@@ -2098,41 +2140,41 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../overviewpage.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="OverviewPage">
- <trans-unit id="_msg387">
+ <trans-unit id="_msg395">
<source xml:space="preserve">Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings-&gt;Mask values.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">193</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">188</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/psbtoperationsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PSBTOperationsDialog">
- <trans-unit id="_msg388">
+ <trans-unit id="_msg396">
<source xml:space="preserve">Dialog</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg389">
+ <trans-unit id="_msg397">
<source xml:space="preserve">Sign Tx</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">86</context></context-group>
</trans-unit>
- <trans-unit id="_msg390">
+ <trans-unit id="_msg398">
<source xml:space="preserve">Broadcast Tx</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">102</context></context-group>
</trans-unit>
- <trans-unit id="_msg391">
+ <trans-unit id="_msg399">
<source xml:space="preserve">Copy to Clipboard</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg392">
+ <trans-unit id="_msg400">
<source xml:space="preserve">Save…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">129</context></context-group>
</trans-unit>
- <trans-unit id="_msg393">
+ <trans-unit id="_msg401">
<source xml:space="preserve">Close</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">136</context></context-group>
@@ -2141,123 +2183,123 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../psbtoperationsdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PSBTOperationsDialog">
- <trans-unit id="_msg394">
+ <trans-unit id="_msg402">
<source xml:space="preserve">Failed to load transaction: %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">55</context></context-group>
</trans-unit>
- <trans-unit id="_msg395">
+ <trans-unit id="_msg403">
<source xml:space="preserve">Failed to sign transaction: %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg396">
+ <trans-unit id="_msg404">
<source xml:space="preserve">Could not sign any more inputs.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">81</context></context-group>
</trans-unit>
- <trans-unit id="_msg397">
+ <trans-unit id="_msg405">
<source xml:space="preserve">Signed %1 inputs, but more signatures are still required.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">83</context></context-group>
</trans-unit>
- <trans-unit id="_msg398">
+ <trans-unit id="_msg406">
<source xml:space="preserve">Signed transaction successfully. Transaction is ready to broadcast.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">86</context></context-group>
</trans-unit>
- <trans-unit id="_msg399">
+ <trans-unit id="_msg407">
<source xml:space="preserve">Unknown error processing transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg400">
+ <trans-unit id="_msg408">
<source xml:space="preserve">Transaction broadcast successfully! Transaction ID: %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
</trans-unit>
- <trans-unit id="_msg401">
+ <trans-unit id="_msg409">
<source xml:space="preserve">Transaction broadcast failed: %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg402">
+ <trans-unit id="_msg410">
<source xml:space="preserve">PSBT copied to clipboard.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg403">
+ <trans-unit id="_msg411">
<source xml:space="preserve">Save Transaction Data</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">143</context></context-group>
</trans-unit>
- <trans-unit id="_msg404">
+ <trans-unit id="_msg412">
<source xml:space="preserve">Partially Signed Transaction (Binary)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">145</context></context-group>
<note annotates="source" from="developer">Expanded name of the binary PSBT file format. See: BIP 174.</note>
</trans-unit>
- <trans-unit id="_msg405">
+ <trans-unit id="_msg413">
<source xml:space="preserve">PSBT saved to disk.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg406">
+ <trans-unit id="_msg414">
<source xml:space="preserve"> * Sends %1 to %2</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">168</context></context-group>
</trans-unit>
- <trans-unit id="_msg407">
+ <trans-unit id="_msg415">
<source xml:space="preserve">Unable to calculate transaction fee or total transaction amount.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">178</context></context-group>
</trans-unit>
- <trans-unit id="_msg408">
+ <trans-unit id="_msg416">
<source xml:space="preserve">Pays transaction fee: </source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg409">
+ <trans-unit id="_msg417">
<source xml:space="preserve">Total Amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">192</context></context-group>
</trans-unit>
- <trans-unit id="_msg410">
+ <trans-unit id="_msg418">
<source xml:space="preserve">or</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">195</context></context-group>
</trans-unit>
- <trans-unit id="_msg411">
+ <trans-unit id="_msg419">
<source xml:space="preserve">Transaction has %1 unsigned inputs.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">201</context></context-group>
</trans-unit>
- <trans-unit id="_msg412">
+ <trans-unit id="_msg420">
<source xml:space="preserve">Transaction is missing some information about inputs.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">243</context></context-group>
</trans-unit>
- <trans-unit id="_msg413">
+ <trans-unit id="_msg421">
<source xml:space="preserve">Transaction still needs signature(s).</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">247</context></context-group>
</trans-unit>
- <trans-unit id="_msg414">
+ <trans-unit id="_msg422">
<source xml:space="preserve">(But this wallet cannot sign transactions.)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">250</context></context-group>
</trans-unit>
- <trans-unit id="_msg415">
+ <trans-unit id="_msg423">
<source xml:space="preserve">(But this wallet does not have the right keys.)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">253</context></context-group>
</trans-unit>
- <trans-unit id="_msg416">
+ <trans-unit id="_msg424">
<source xml:space="preserve">Transaction is fully signed and ready for broadcast.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">261</context></context-group>
</trans-unit>
- <trans-unit id="_msg417">
+ <trans-unit id="_msg425">
<source xml:space="preserve">Transaction status is unknown.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">265</context></context-group>
@@ -2266,17 +2308,17 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
</body></file>
<file original="../paymentserver.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PaymentServer">
- <trans-unit id="_msg418">
+ <trans-unit id="_msg426">
<source xml:space="preserve">Payment request error</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">173</context></context-group>
</trans-unit>
- <trans-unit id="_msg419">
+ <trans-unit id="_msg427">
<source xml:space="preserve">Cannot start bitcoin: click-to-pay handler</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
</trans-unit>
- <trans-unit id="_msg420">
+ <trans-unit id="_msg428">
<source xml:space="preserve">URI handling</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">224</context></context-group>
@@ -2284,12 +2326,12 @@ Signing is only possible with addresses of the type &apos;legacy&apos;.</source>
<context-group purpose="location"><context context-type="linenumber">246</context></context-group>
<context-group purpose="location"><context context-type="linenumber">253</context></context-group>
</trans-unit>
- <trans-unit id="_msg421">
+ <trans-unit id="_msg429">
<source xml:space="preserve">&apos;bitcoin://&apos; is not a valid URI. Use &apos;bitcoin:&apos; instead.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">224</context></context-group>
</trans-unit>
- <trans-unit id="_msg422">
+ <trans-unit id="_msg430">
<source xml:space="preserve">Cannot process payment request because BIP70 is not supported.
Due to widespread security flaws in BIP70 it&apos;s strongly recommended that any merchant instructions to switch wallets be ignored.
If you are receiving this error you should request the merchant provide a BIP21 compatible URI.</source>
@@ -2297,12 +2339,12 @@ If you are receiving this error you should request the merchant provide a BIP21
<context-group purpose="location"><context context-type="linenumber">241</context></context-group>
<context-group purpose="location"><context context-type="linenumber">264</context></context-group>
</trans-unit>
- <trans-unit id="_msg423">
+ <trans-unit id="_msg431">
<source xml:space="preserve">URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">254</context></context-group>
</trans-unit>
- <trans-unit id="_msg424">
+ <trans-unit id="_msg432">
<source xml:space="preserve">Payment request file handling</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">263</context></context-group>
@@ -2311,59 +2353,59 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../peertablemodel.h" datatype="c" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="PeerTableModel">
- <trans-unit id="_msg425">
+ <trans-unit id="_msg433">
<source xml:space="preserve">User Agent</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">101</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">107</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which contains the peer&apos;s User Agent string.</note>
</trans-unit>
- <trans-unit id="_msg426">
+ <trans-unit id="_msg434">
<source xml:space="preserve">Ping</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">92</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the current latency of the connection with the peer.</note>
</trans-unit>
- <trans-unit id="_msg427">
+ <trans-unit id="_msg435">
<source xml:space="preserve">Peer</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">80</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">86</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which contains a unique number used to identify a connection.</note>
</trans-unit>
- <trans-unit id="_msg428">
+ <trans-unit id="_msg436">
<source xml:space="preserve">Sent</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">95</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">101</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the total amount of network information we have sent to the peer.</note>
</trans-unit>
- <trans-unit id="_msg429">
+ <trans-unit id="_msg437">
<source xml:space="preserve">Received</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">98</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">104</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which indicates the total amount of network information we have received from the peer.</note>
</trans-unit>
- <trans-unit id="_msg430">
+ <trans-unit id="_msg438">
<source xml:space="preserve">Address</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">83</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">89</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which contains the IP/Onion/I2P address of the connected peer.</note>
</trans-unit>
- <trans-unit id="_msg431">
+ <trans-unit id="_msg439">
<source xml:space="preserve">Type</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">86</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">92</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which describes the type of peer connection. The &quot;type&quot; describes why the connection exists.</note>
</trans-unit>
- <trans-unit id="_msg432">
+ <trans-unit id="_msg440">
<source xml:space="preserve">Network</source>
<target xml:space="preserve" state="needs-review-translation">Network</target>
- <context-group purpose="location"><context context-type="linenumber">89</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">95</context></context-group>
<note annotates="source" from="developer">Title of Peers Table column which states the network the peer connected through.</note>
</trans-unit>
</group>
</body></file>
<file original="../bitcoinunits.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg433">
+ <trans-unit id="_msg441">
<source xml:space="preserve">Amount</source>
<target xml:space="preserve" state="needs-review-translation">Amount</target>
<context-group purpose="location"><context context-type="linenumber">213</context></context-group>
@@ -2372,132 +2414,132 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../guiutil.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="QObject">
- <trans-unit id="_msg434">
+ <trans-unit id="_msg442">
<source xml:space="preserve">Enter a Bitcoin address (e.g. %1)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg435">
+ <trans-unit id="_msg443">
<source xml:space="preserve">Unroutable</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">660</context></context-group>
</trans-unit>
- <trans-unit id="_msg436">
+ <trans-unit id="_msg444">
<source xml:space="preserve">Internal</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">666</context></context-group>
</trans-unit>
- <trans-unit id="_msg437">
+ <trans-unit id="_msg445">
<source xml:space="preserve">Inbound</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">676</context></context-group>
</trans-unit>
- <trans-unit id="_msg438">
+ <trans-unit id="_msg446">
<source xml:space="preserve">Outbound</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">676</context></context-group>
</trans-unit>
- <trans-unit id="_msg439">
+ <trans-unit id="_msg447">
<source xml:space="preserve">Full Relay</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">680</context></context-group>
</trans-unit>
- <trans-unit id="_msg440">
+ <trans-unit id="_msg448">
<source xml:space="preserve">Block Relay</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">681</context></context-group>
</trans-unit>
- <trans-unit id="_msg441">
+ <trans-unit id="_msg449">
<source xml:space="preserve">Manual</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">682</context></context-group>
</trans-unit>
- <trans-unit id="_msg442">
+ <trans-unit id="_msg450">
<source xml:space="preserve">Feeler</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">683</context></context-group>
</trans-unit>
- <trans-unit id="_msg443">
+ <trans-unit id="_msg451">
<source xml:space="preserve">Address Fetch</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">684</context></context-group>
</trans-unit>
- <trans-unit id="_msg444">
+ <trans-unit id="_msg452">
<source xml:space="preserve">%1 d</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">698</context></context-group>
</trans-unit>
- <trans-unit id="_msg445">
+ <trans-unit id="_msg453">
<source xml:space="preserve">%1 h</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">700</context></context-group>
</trans-unit>
- <trans-unit id="_msg446">
+ <trans-unit id="_msg454">
<source xml:space="preserve">%1 m</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">702</context></context-group>
</trans-unit>
- <trans-unit id="_msg447">
+ <trans-unit id="_msg455">
<source xml:space="preserve">%1 s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">704</context></context-group>
<context-group purpose="location"><context context-type="linenumber">732</context></context-group>
</trans-unit>
- <trans-unit id="_msg448">
+ <trans-unit id="_msg456">
<source xml:space="preserve">None</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">720</context></context-group>
</trans-unit>
- <trans-unit id="_msg449">
+ <trans-unit id="_msg457">
<source xml:space="preserve">N/A</source>
<target xml:space="preserve" state="needs-review-translation">N/A</target>
<context-group purpose="location"><context context-type="linenumber">726</context></context-group>
</trans-unit>
- <trans-unit id="_msg450">
+ <trans-unit id="_msg458">
<source xml:space="preserve">%1 ms</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">727</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">745</context></context-group>
- <trans-unit id="_msg451[0]" approved="yes">
+ <trans-unit id="_msg459[0]" approved="yes">
<source xml:space="preserve">%n second(s)</source>
<target xml:space="preserve">%n second</target>
</trans-unit>
- <trans-unit id="_msg451[1]" approved="yes">
+ <trans-unit id="_msg459[1]" approved="yes">
<source xml:space="preserve">%n second(s)</source>
<target xml:space="preserve">%n seconds</target>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">749</context></context-group>
- <trans-unit id="_msg452[0]" approved="yes">
+ <trans-unit id="_msg460[0]" approved="yes">
<source xml:space="preserve">%n minute(s)</source>
<target xml:space="preserve">%n minute</target>
</trans-unit>
- <trans-unit id="_msg452[1]" approved="yes">
+ <trans-unit id="_msg460[1]" approved="yes">
<source xml:space="preserve">%n minute(s)</source>
<target xml:space="preserve">%n minutes</target>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">753</context></context-group>
- <trans-unit id="_msg453[0]">
+ <trans-unit id="_msg461[0]">
<source xml:space="preserve">%n hour(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n hour</target>
</trans-unit>
- <trans-unit id="_msg453[1]">
+ <trans-unit id="_msg461[1]">
<source xml:space="preserve">%n hour(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n hours</target>
</trans-unit>
</group>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">757</context></context-group>
- <trans-unit id="_msg454[0]">
+ <trans-unit id="_msg462[0]">
<source xml:space="preserve">%n day(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n day</target>
</trans-unit>
- <trans-unit id="_msg454[1]">
+ <trans-unit id="_msg462[1]">
<source xml:space="preserve">%n day(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n days</target>
</trans-unit>
@@ -2505,47 +2547,47 @@ If you are receiving this error you should request the merchant provide a BIP21
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">761</context></context-group>
<context-group purpose="location"><context context-type="linenumber">767</context></context-group>
- <trans-unit id="_msg455[0]">
+ <trans-unit id="_msg463[0]">
<source xml:space="preserve">%n week(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n week</target>
</trans-unit>
- <trans-unit id="_msg455[1]">
+ <trans-unit id="_msg463[1]">
<source xml:space="preserve">%n week(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n weeks</target>
</trans-unit>
</group>
- <trans-unit id="_msg456">
+ <trans-unit id="_msg464">
<source xml:space="preserve">%1 and %2</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">767</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">767</context></context-group>
- <trans-unit id="_msg457[0]">
+ <trans-unit id="_msg465[0]">
<source xml:space="preserve">%n year(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n year</target>
</trans-unit>
- <trans-unit id="_msg457[1]">
+ <trans-unit id="_msg465[1]">
<source xml:space="preserve">%n year(s)</source>
<target xml:space="preserve" state="needs-review-translation">%n years</target>
</trans-unit>
</group>
- <trans-unit id="_msg458">
+ <trans-unit id="_msg466">
<source xml:space="preserve">%1 B</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">775</context></context-group>
</trans-unit>
- <trans-unit id="_msg459">
+ <trans-unit id="_msg467">
<source xml:space="preserve">%1 kB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">777</context></context-group>
</trans-unit>
- <trans-unit id="_msg460">
+ <trans-unit id="_msg468">
<source xml:space="preserve">%1 MB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">779</context></context-group>
</trans-unit>
- <trans-unit id="_msg461">
+ <trans-unit id="_msg469">
<source xml:space="preserve">%1 GB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">781</context></context-group>
@@ -2554,37 +2596,37 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../qrimagewidget.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="QRImageWidget">
- <trans-unit id="_msg462">
- <source xml:space="preserve">Save Image…</source>
+ <trans-unit id="_msg470">
+ <source xml:space="preserve">&amp;Save Image…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">30</context></context-group>
</trans-unit>
- <trans-unit id="_msg463">
- <source xml:space="preserve">Copy Image</source>
+ <trans-unit id="_msg471">
+ <source xml:space="preserve">&amp;Copy Image</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">31</context></context-group>
</trans-unit>
- <trans-unit id="_msg464">
+ <trans-unit id="_msg472">
<source xml:space="preserve">Resulting URI too long, try to reduce the text for label / message.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">42</context></context-group>
</trans-unit>
- <trans-unit id="_msg465">
+ <trans-unit id="_msg473">
<source xml:space="preserve">Error encoding URI into QR Code.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg466">
+ <trans-unit id="_msg474">
<source xml:space="preserve">QR code support not available.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg467">
+ <trans-unit id="_msg475">
<source xml:space="preserve">Save QR Code</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg468">
+ <trans-unit id="_msg476">
<source xml:space="preserve">PNG Image</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">123</context></context-group>
@@ -2594,7 +2636,7 @@ If you are receiving this error you should request the merchant provide a BIP21
</body></file>
<file original="../forms/debugwindow.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RPCConsole">
- <trans-unit id="_msg469" approved="yes">
+ <trans-unit id="_msg477" approved="yes">
<source xml:space="preserve">N/A</source>
<target xml:space="preserve">N/A</target>
<context-group purpose="location"><context context-type="linenumber">75</context></context-group>
@@ -2608,480 +2650,480 @@ If you are receiving this error you should request the merchant provide a BIP21
<context-group purpose="location"><context context-type="linenumber">300</context></context-group>
<context-group purpose="location"><context context-type="linenumber">336</context></context-group>
<context-group purpose="location"><context context-type="linenumber">359</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1081</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1107</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1133</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1156</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1179</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1202</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1231</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1257</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1280</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1303</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1326</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1349</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1375</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1401</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1424</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1447</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1470</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1493</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1516</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1542</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1565</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1588</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1614</context></context-group>
- <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.h</context><context context-type="linenumber">138</context></context-group>
- </trans-unit>
- <trans-unit id="_msg470" approved="yes">
+ <context-group purpose="location"><context context-type="linenumber">1051</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1077</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1103</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1126</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1149</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1172</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1201</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1227</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1250</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1273</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1296</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1319</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1345</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1371</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1394</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1417</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1440</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1463</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1486</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1512</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1535</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1558</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1584</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.h</context><context context-type="linenumber">139</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg478" approved="yes">
<source xml:space="preserve">Client version</source>
<target xml:space="preserve">Client version</target>
<context-group purpose="location"><context context-type="linenumber">65</context></context-group>
</trans-unit>
- <trans-unit id="_msg471" approved="yes">
+ <trans-unit id="_msg479" approved="yes">
<source xml:space="preserve">&amp;Information</source>
<target xml:space="preserve">&amp;Information</target>
<context-group purpose="location"><context context-type="linenumber">43</context></context-group>
</trans-unit>
- <trans-unit id="_msg472">
+ <trans-unit id="_msg480">
<source xml:space="preserve">General</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
- <trans-unit id="_msg473">
+ <trans-unit id="_msg481">
<source xml:space="preserve">Datadir</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">114</context></context-group>
</trans-unit>
- <trans-unit id="_msg474">
+ <trans-unit id="_msg482">
<source xml:space="preserve">To specify a non-default location of the data directory use the &apos;%1&apos; option.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">124</context></context-group>
</trans-unit>
- <trans-unit id="_msg475">
+ <trans-unit id="_msg483">
<source xml:space="preserve">Blocksdir</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">143</context></context-group>
</trans-unit>
- <trans-unit id="_msg476">
+ <trans-unit id="_msg484">
<source xml:space="preserve">To specify a non-default location of the blocks directory use the &apos;%1&apos; option.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">153</context></context-group>
</trans-unit>
- <trans-unit id="_msg477" approved="yes">
+ <trans-unit id="_msg485" approved="yes">
<source xml:space="preserve">Startup time</source>
<target xml:space="preserve">Startup time</target>
<context-group purpose="location"><context context-type="linenumber">172</context></context-group>
</trans-unit>
- <trans-unit id="_msg478" approved="yes">
+ <trans-unit id="_msg486" approved="yes">
<source xml:space="preserve">Network</source>
<target xml:space="preserve">Network</target>
<context-group purpose="location"><context context-type="linenumber">201</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1123</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1093</context></context-group>
</trans-unit>
- <trans-unit id="_msg479">
+ <trans-unit id="_msg487">
<source xml:space="preserve">Name</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">208</context></context-group>
</trans-unit>
- <trans-unit id="_msg480" approved="yes">
+ <trans-unit id="_msg488" approved="yes">
<source xml:space="preserve">Number of connections</source>
<target xml:space="preserve">Number of connections</target>
<context-group purpose="location"><context context-type="linenumber">231</context></context-group>
</trans-unit>
- <trans-unit id="_msg481" approved="yes">
+ <trans-unit id="_msg489" approved="yes">
<source xml:space="preserve">Block chain</source>
<target xml:space="preserve">Block chain</target>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg482">
+ <trans-unit id="_msg490">
<source xml:space="preserve">Memory Pool</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">319</context></context-group>
</trans-unit>
- <trans-unit id="_msg483">
+ <trans-unit id="_msg491">
<source xml:space="preserve">Current number of transactions</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg484">
+ <trans-unit id="_msg492">
<source xml:space="preserve">Memory usage</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">349</context></context-group>
</trans-unit>
- <trans-unit id="_msg485">
+ <trans-unit id="_msg493">
<source xml:space="preserve">Wallet: </source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">443</context></context-group>
</trans-unit>
- <trans-unit id="_msg486">
+ <trans-unit id="_msg494">
<source xml:space="preserve">(none)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">454</context></context-group>
</trans-unit>
- <trans-unit id="_msg487">
+ <trans-unit id="_msg495">
<source xml:space="preserve">&amp;Reset</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">695</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">665</context></context-group>
</trans-unit>
- <trans-unit id="_msg488">
+ <trans-unit id="_msg496">
<source xml:space="preserve">Received</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">775</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1483</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">745</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1453</context></context-group>
</trans-unit>
- <trans-unit id="_msg489">
+ <trans-unit id="_msg497">
<source xml:space="preserve">Sent</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">855</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1460</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">825</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1430</context></context-group>
</trans-unit>
- <trans-unit id="_msg490">
+ <trans-unit id="_msg498">
<source xml:space="preserve">&amp;Peers</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">896</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">866</context></context-group>
</trans-unit>
- <trans-unit id="_msg491">
+ <trans-unit id="_msg499">
<source xml:space="preserve">Banned peers</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">972</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">942</context></context-group>
</trans-unit>
- <trans-unit id="_msg492">
+ <trans-unit id="_msg500">
<source xml:space="preserve">Select a peer to view detailed information.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1040</context></context-group>
- <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.cpp</context><context context-type="linenumber">1091</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1010</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.cpp</context><context context-type="linenumber">1124</context></context-group>
</trans-unit>
- <trans-unit id="_msg493">
+ <trans-unit id="_msg501">
<source xml:space="preserve">Version</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1146</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1116</context></context-group>
</trans-unit>
- <trans-unit id="_msg494">
+ <trans-unit id="_msg502">
<source xml:space="preserve">Starting Block</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1270</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1240</context></context-group>
</trans-unit>
- <trans-unit id="_msg495">
+ <trans-unit id="_msg503">
<source xml:space="preserve">Synced Headers</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1293</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1263</context></context-group>
</trans-unit>
- <trans-unit id="_msg496">
+ <trans-unit id="_msg504">
<source xml:space="preserve">Synced Blocks</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1316</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1286</context></context-group>
</trans-unit>
- <trans-unit id="_msg497">
+ <trans-unit id="_msg505">
<source xml:space="preserve">The mapped Autonomous System used for diversifying peer selection.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1601</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1571</context></context-group>
</trans-unit>
- <trans-unit id="_msg498">
+ <trans-unit id="_msg506">
<source xml:space="preserve">Mapped AS</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1604</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1574</context></context-group>
</trans-unit>
- <trans-unit id="_msg499">
+ <trans-unit id="_msg507">
<source xml:space="preserve">User Agent</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">1169</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1139</context></context-group>
</trans-unit>
- <trans-unit id="_msg500">
+ <trans-unit id="_msg508">
<source xml:space="preserve">Node window</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg501">
+ <trans-unit id="_msg509">
<source xml:space="preserve">Current block height</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
- <trans-unit id="_msg502">
+ <trans-unit id="_msg510">
<source xml:space="preserve">Open the %1 debug log file from the current data directory. This can take a few seconds for large log files.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">397</context></context-group>
</trans-unit>
- <trans-unit id="_msg503">
+ <trans-unit id="_msg511">
<source xml:space="preserve">Decrease font size</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">481</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">475</context></context-group>
</trans-unit>
- <trans-unit id="_msg504">
+ <trans-unit id="_msg512">
<source xml:space="preserve">Increase font size</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">513</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">495</context></context-group>
</trans-unit>
- <trans-unit id="_msg505">
+ <trans-unit id="_msg513">
<source xml:space="preserve">Permissions</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1071</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1041</context></context-group>
</trans-unit>
- <trans-unit id="_msg506">
+ <trans-unit id="_msg514">
<source xml:space="preserve">The direction and type of peer connection: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1094</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1064</context></context-group>
</trans-unit>
- <trans-unit id="_msg507">
+ <trans-unit id="_msg515">
<source xml:space="preserve">Direction/Type</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1097</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1067</context></context-group>
</trans-unit>
- <trans-unit id="_msg508">
+ <trans-unit id="_msg516">
<source xml:space="preserve">The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1120</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1090</context></context-group>
</trans-unit>
- <trans-unit id="_msg509">
+ <trans-unit id="_msg517">
<source xml:space="preserve">Services</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1192</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1162</context></context-group>
</trans-unit>
- <trans-unit id="_msg510">
+ <trans-unit id="_msg518">
<source xml:space="preserve">Whether the peer requested us to relay transactions.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1218</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1188</context></context-group>
</trans-unit>
- <trans-unit id="_msg511">
+ <trans-unit id="_msg519">
<source xml:space="preserve">Wants Tx Relay</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1221</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1191</context></context-group>
</trans-unit>
- <trans-unit id="_msg512">
+ <trans-unit id="_msg520">
<source xml:space="preserve">High bandwidth BIP152 compact block relay: %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1244</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1214</context></context-group>
</trans-unit>
- <trans-unit id="_msg513">
+ <trans-unit id="_msg521">
<source xml:space="preserve">High Bandwidth</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1247</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1217</context></context-group>
</trans-unit>
- <trans-unit id="_msg514">
+ <trans-unit id="_msg522">
<source xml:space="preserve">Connection Time</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1339</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1309</context></context-group>
</trans-unit>
- <trans-unit id="_msg515">
+ <trans-unit id="_msg523">
<source xml:space="preserve">Elapsed time since a novel block passing initial validity checks was received from this peer.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1362</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1332</context></context-group>
</trans-unit>
- <trans-unit id="_msg516">
+ <trans-unit id="_msg524">
<source xml:space="preserve">Last Block</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1365</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1335</context></context-group>
</trans-unit>
- <trans-unit id="_msg517">
+ <trans-unit id="_msg525">
<source xml:space="preserve">Elapsed time since a novel transaction accepted into our mempool was received from this peer.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1388</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1358</context></context-group>
</trans-unit>
- <trans-unit id="_msg518">
+ <trans-unit id="_msg526">
<source xml:space="preserve">Last Tx</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1391</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1361</context></context-group>
</trans-unit>
- <trans-unit id="_msg519">
+ <trans-unit id="_msg527">
<source xml:space="preserve">Last Send</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1414</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1384</context></context-group>
</trans-unit>
- <trans-unit id="_msg520">
+ <trans-unit id="_msg528">
<source xml:space="preserve">Last Receive</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1437</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1407</context></context-group>
</trans-unit>
- <trans-unit id="_msg521">
+ <trans-unit id="_msg529">
<source xml:space="preserve">Ping Time</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1506</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1476</context></context-group>
</trans-unit>
- <trans-unit id="_msg522">
+ <trans-unit id="_msg530">
<source xml:space="preserve">The duration of a currently outstanding ping.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1529</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1499</context></context-group>
</trans-unit>
- <trans-unit id="_msg523">
+ <trans-unit id="_msg531">
<source xml:space="preserve">Ping Wait</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1532</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1502</context></context-group>
</trans-unit>
- <trans-unit id="_msg524">
+ <trans-unit id="_msg532">
<source xml:space="preserve">Min Ping</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1555</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1525</context></context-group>
</trans-unit>
- <trans-unit id="_msg525">
+ <trans-unit id="_msg533">
<source xml:space="preserve">Time Offset</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1578</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1548</context></context-group>
</trans-unit>
- <trans-unit id="_msg526" approved="yes">
+ <trans-unit id="_msg534" approved="yes">
<source xml:space="preserve">Last block time</source>
<target xml:space="preserve">Last block time</target>
<context-group purpose="location"><context context-type="linenumber">290</context></context-group>
</trans-unit>
- <trans-unit id="_msg527" approved="yes">
+ <trans-unit id="_msg535" approved="yes">
<source xml:space="preserve">&amp;Open</source>
<target xml:space="preserve">&amp;Open</target>
<context-group purpose="location"><context context-type="linenumber">400</context></context-group>
</trans-unit>
- <trans-unit id="_msg528" approved="yes">
+ <trans-unit id="_msg536" approved="yes">
<source xml:space="preserve">&amp;Console</source>
<target xml:space="preserve">&amp;Console</target>
<context-group purpose="location"><context context-type="linenumber">426</context></context-group>
</trans-unit>
- <trans-unit id="_msg529">
+ <trans-unit id="_msg537">
<source xml:space="preserve">&amp;Network Traffic</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">643</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">613</context></context-group>
</trans-unit>
- <trans-unit id="_msg530">
+ <trans-unit id="_msg538">
<source xml:space="preserve">Totals</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">711</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">681</context></context-group>
</trans-unit>
- <trans-unit id="_msg531" approved="yes">
+ <trans-unit id="_msg539" approved="yes">
<source xml:space="preserve">Debug log file</source>
<target xml:space="preserve">Debug log file</target>
<context-group purpose="location"><context context-type="linenumber">390</context></context-group>
</trans-unit>
- <trans-unit id="_msg532" approved="yes">
+ <trans-unit id="_msg540" approved="yes">
<source xml:space="preserve">Clear console</source>
<target xml:space="preserve">Clear console</target>
- <context-group purpose="location"><context context-type="linenumber">545</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">515</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../rpcconsole.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RPCConsole">
- <trans-unit id="_msg533">
+ <trans-unit id="_msg541">
<source xml:space="preserve">In:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">890</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">923</context></context-group>
</trans-unit>
- <trans-unit id="_msg534">
+ <trans-unit id="_msg542">
<source xml:space="preserve">Out:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">891</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">924</context></context-group>
</trans-unit>
- <trans-unit id="_msg535">
+ <trans-unit id="_msg543">
<source xml:space="preserve">Inbound: initiated by peer</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">474</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">495</context></context-group>
</trans-unit>
- <trans-unit id="_msg536">
+ <trans-unit id="_msg544">
<source xml:space="preserve">Outbound Full Relay: default</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">475</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">496</context></context-group>
</trans-unit>
- <trans-unit id="_msg537">
+ <trans-unit id="_msg545">
<source xml:space="preserve">Outbound Block Relay: does not relay transactions or addresses</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">476</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">497</context></context-group>
</trans-unit>
- <trans-unit id="_msg538">
+ <trans-unit id="_msg546">
<source xml:space="preserve">Outbound Manual: added using RPC %1 or %2/%3 configuration options</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">477</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">498</context></context-group>
</trans-unit>
- <trans-unit id="_msg539">
+ <trans-unit id="_msg547">
<source xml:space="preserve">Outbound Feeler: short-lived, for testing addresses</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">481</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">502</context></context-group>
</trans-unit>
- <trans-unit id="_msg540">
+ <trans-unit id="_msg548">
<source xml:space="preserve">Outbound Address Fetch: short-lived, for soliciting addresses</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">482</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">503</context></context-group>
</trans-unit>
- <trans-unit id="_msg541">
+ <trans-unit id="_msg549">
<source xml:space="preserve">we selected the peer for high bandwidth relay</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">486</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">507</context></context-group>
</trans-unit>
- <trans-unit id="_msg542">
+ <trans-unit id="_msg550">
<source xml:space="preserve">the peer selected us for high bandwidth relay</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">487</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">508</context></context-group>
</trans-unit>
- <trans-unit id="_msg543">
+ <trans-unit id="_msg551">
<source xml:space="preserve">no high bandwidth relay selected</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">488</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">509</context></context-group>
</trans-unit>
- <trans-unit id="_msg544">
+ <trans-unit id="_msg552">
<source xml:space="preserve">Ctrl++</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">501</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">522</context></context-group>
<note annotates="source" from="developer">Main shortcut to increase the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg545">
+ <trans-unit id="_msg553">
<source xml:space="preserve">Ctrl+=</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">503</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">524</context></context-group>
<note annotates="source" from="developer">Secondary shortcut to increase the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg546">
+ <trans-unit id="_msg554">
<source xml:space="preserve">Ctrl+-</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">507</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">528</context></context-group>
<note annotates="source" from="developer">Main shortcut to decrease the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg547">
+ <trans-unit id="_msg555">
<source xml:space="preserve">Ctrl+_</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">509</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">530</context></context-group>
<note annotates="source" from="developer">Secondary shortcut to decrease the RPC console font size.</note>
</trans-unit>
- <trans-unit id="_msg548">
- <source xml:space="preserve">Network activity disabled</source>
+ <trans-unit id="_msg556">
+ <source xml:space="preserve">&amp;Disconnect</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">894</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">680</context></context-group>
</trans-unit>
- <trans-unit id="_msg549">
- <source xml:space="preserve">Executing command without any wallet</source>
+ <trans-unit id="_msg557">
+ <source xml:space="preserve">1 &amp;hour</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">971</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">681</context></context-group>
</trans-unit>
- <trans-unit id="_msg550">
- <source xml:space="preserve">Executing command using &quot;%1&quot; wallet</source>
+ <trans-unit id="_msg558">
+ <source xml:space="preserve">1 d&amp;ay</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">969</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">682</context></context-group>
</trans-unit>
- <trans-unit id="_msg551">
- <source xml:space="preserve">Disconnect</source>
+ <trans-unit id="_msg559">
+ <source xml:space="preserve">1 &amp;week</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">650</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">683</context></context-group>
</trans-unit>
- <trans-unit id="_msg552">
- <source xml:space="preserve">1 hour</source>
+ <trans-unit id="_msg560">
+ <source xml:space="preserve">1 &amp;year</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">651</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">684</context></context-group>
</trans-unit>
- <trans-unit id="_msg553">
- <source xml:space="preserve">1 day</source>
+ <trans-unit id="_msg561">
+ <source xml:space="preserve">&amp;Unban</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">652</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">706</context></context-group>
</trans-unit>
- <trans-unit id="_msg554">
- <source xml:space="preserve">1 week</source>
+ <trans-unit id="_msg562">
+ <source xml:space="preserve">Network activity disabled</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">653</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">927</context></context-group>
</trans-unit>
- <trans-unit id="_msg555">
- <source xml:space="preserve">1 year</source>
+ <trans-unit id="_msg563">
+ <source xml:space="preserve">Executing command without any wallet</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">654</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1004</context></context-group>
</trans-unit>
- <trans-unit id="_msg556">
- <source xml:space="preserve">Unban</source>
+ <trans-unit id="_msg564">
+ <source xml:space="preserve">Executing command using &quot;%1&quot; wallet</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">673</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1002</context></context-group>
</trans-unit>
- <trans-unit id="_msg557">
+ <trans-unit id="_msg565">
<source xml:space="preserve">Welcome to the %1 RPC console.
Use up and down arrows to navigate history, and %2 to clear screen.
Use %3 and %4 to increase or decrease the font size.
@@ -3090,160 +3132,160 @@ For more information on using this console, type %6.
%7WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command.%8</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">823</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">856</context></context-group>
<note annotates="source" from="developer">RPC console welcome message. Placeholders %7 and %8 are style tags for the warning content, and they are not space separated from the rest of the text intentionally.</note>
</trans-unit>
- <trans-unit id="_msg558">
+ <trans-unit id="_msg566">
<source xml:space="preserve">Executing…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">979</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1012</context></context-group>
<note annotates="source" from="developer">A console message indicating an entered command is currently being executed.</note>
</trans-unit>
- <trans-unit id="_msg559">
+ <trans-unit id="_msg567">
<source xml:space="preserve">(peer: %1)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1097</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1130</context></context-group>
</trans-unit>
- <trans-unit id="_msg560">
+ <trans-unit id="_msg568">
<source xml:space="preserve">via %1</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">1099</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">1132</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../rpcconsole.h" datatype="c" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RPCConsole">
- <trans-unit id="_msg561">
+ <trans-unit id="_msg569">
<source xml:space="preserve">Yes</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">137</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
</trans-unit>
- <trans-unit id="_msg562">
+ <trans-unit id="_msg570">
<source xml:space="preserve">No</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">137</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
</trans-unit>
- <trans-unit id="_msg563">
+ <trans-unit id="_msg571">
<source xml:space="preserve">To</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">137</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
</trans-unit>
- <trans-unit id="_msg564">
+ <trans-unit id="_msg572">
<source xml:space="preserve">From</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">137</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
</trans-unit>
- <trans-unit id="_msg565">
+ <trans-unit id="_msg573">
<source xml:space="preserve">Ban for</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg566">
+ <trans-unit id="_msg574">
<source xml:space="preserve">Never</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">176</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">179</context></context-group>
</trans-unit>
- <trans-unit id="_msg567">
+ <trans-unit id="_msg575">
<source xml:space="preserve">Unknown</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">138</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/receivecoinsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveCoinsDialog">
- <trans-unit id="_msg568">
+ <trans-unit id="_msg576">
<source xml:space="preserve">&amp;Amount:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">37</context></context-group>
</trans-unit>
- <trans-unit id="_msg569">
+ <trans-unit id="_msg577">
<source xml:space="preserve">&amp;Label:</source>
<target xml:space="preserve" state="needs-review-translation">&amp;Label:</target>
<context-group purpose="location"><context context-type="linenumber">83</context></context-group>
</trans-unit>
- <trans-unit id="_msg570">
+ <trans-unit id="_msg578">
<source xml:space="preserve">&amp;Message:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">53</context></context-group>
</trans-unit>
- <trans-unit id="_msg571">
+ <trans-unit id="_msg579">
<source xml:space="preserve">An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg572">
+ <trans-unit id="_msg580">
<source xml:space="preserve">An optional label to associate with the new receiving address.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">80</context></context-group>
</trans-unit>
- <trans-unit id="_msg573">
+ <trans-unit id="_msg581">
<source xml:space="preserve">Use this form to request payments. All fields are &lt;b&gt;optional&lt;/b&gt;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg574">
+ <trans-unit id="_msg582">
<source xml:space="preserve">An optional amount to request. Leave this empty or zero to not request a specific amount.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">34</context></context-group>
<context-group purpose="location"><context context-type="linenumber">193</context></context-group>
</trans-unit>
- <trans-unit id="_msg575">
+ <trans-unit id="_msg583">
<source xml:space="preserve">An optional label to associate with the new receiving address (used by you to identify an invoice). It is also attached to the payment request.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">66</context></context-group>
</trans-unit>
- <trans-unit id="_msg576">
+ <trans-unit id="_msg584">
<source xml:space="preserve">An optional message that is attached to the payment request and may be displayed to the sender.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg577">
+ <trans-unit id="_msg585">
<source xml:space="preserve">&amp;Create new receiving address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg578">
+ <trans-unit id="_msg586">
<source xml:space="preserve">Clear all fields of the form.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg579">
+ <trans-unit id="_msg587">
<source xml:space="preserve">Clear</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">137</context></context-group>
</trans-unit>
- <trans-unit id="_msg580">
+ <trans-unit id="_msg588">
<source xml:space="preserve">Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don&apos;t support them. When unchecked, an address compatible with older wallets will be created instead.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg581">
+ <trans-unit id="_msg589">
<source xml:space="preserve">Generate native segwit (Bech32) address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">218</context></context-group>
</trans-unit>
- <trans-unit id="_msg582">
+ <trans-unit id="_msg590">
<source xml:space="preserve">Requested payments history</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">279</context></context-group>
</trans-unit>
- <trans-unit id="_msg583">
+ <trans-unit id="_msg591">
<source xml:space="preserve">Show the selected request (does the same as double clicking an entry)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">304</context></context-group>
</trans-unit>
- <trans-unit id="_msg584">
+ <trans-unit id="_msg592">
<source xml:space="preserve">Show</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">307</context></context-group>
</trans-unit>
- <trans-unit id="_msg585">
+ <trans-unit id="_msg593">
<source xml:space="preserve">Remove the selected entries from the list</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">324</context></context-group>
</trans-unit>
- <trans-unit id="_msg586">
+ <trans-unit id="_msg594">
<source xml:space="preserve">Remove</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">327</context></context-group>
@@ -3252,37 +3294,37 @@ For more information on using this console, type %6.
</body></file>
<file original="../receivecoinsdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveCoinsDialog">
- <trans-unit id="_msg587">
- <source xml:space="preserve">Copy URI</source>
+ <trans-unit id="_msg595">
+ <source xml:space="preserve">Copy &amp;URI</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg588">
- <source xml:space="preserve">Copy address</source>
+ <trans-unit id="_msg596">
+ <source xml:space="preserve">&amp;Copy address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">48</context></context-group>
</trans-unit>
- <trans-unit id="_msg589">
- <source xml:space="preserve">Copy label</source>
+ <trans-unit id="_msg597">
+ <source xml:space="preserve">Copy &amp;label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg590">
- <source xml:space="preserve">Copy message</source>
+ <trans-unit id="_msg598">
+ <source xml:space="preserve">Copy &amp;message</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">50</context></context-group>
</trans-unit>
- <trans-unit id="_msg591">
- <source xml:space="preserve">Copy amount</source>
+ <trans-unit id="_msg599">
+ <source xml:space="preserve">Copy &amp;amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg592">
+ <trans-unit id="_msg600">
<source xml:space="preserve">Could not unlock wallet.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">176</context></context-group>
</trans-unit>
- <trans-unit id="_msg593">
+ <trans-unit id="_msg601">
<source xml:space="preserve">Could not generate new %1 address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">181</context></context-group>
@@ -3291,52 +3333,62 @@ For more information on using this console, type %6.
</body></file>
<file original="../forms/receiverequestdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveRequestDialog">
- <trans-unit id="_msg594">
+ <trans-unit id="_msg602">
<source xml:space="preserve">Request payment to …</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg595">
+ <trans-unit id="_msg603">
<source xml:space="preserve">Address:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg596">
+ <trans-unit id="_msg604">
<source xml:space="preserve">Amount:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">119</context></context-group>
</trans-unit>
- <trans-unit id="_msg597">
+ <trans-unit id="_msg605">
<source xml:space="preserve">Label:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">148</context></context-group>
</trans-unit>
- <trans-unit id="_msg598">
+ <trans-unit id="_msg606">
<source xml:space="preserve">Message:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg599">
+ <trans-unit id="_msg607">
<source xml:space="preserve">Wallet:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">212</context></context-group>
</trans-unit>
- <trans-unit id="_msg600">
+ <trans-unit id="_msg608">
<source xml:space="preserve">Copy &amp;URI</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
</trans-unit>
- <trans-unit id="_msg601">
+ <trans-unit id="_msg609">
<source xml:space="preserve">Copy &amp;Address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">250</context></context-group>
</trans-unit>
- <trans-unit id="_msg602">
- <source xml:space="preserve">&amp;Save Image…</source>
+ <trans-unit id="_msg610">
+ <source xml:space="preserve">&amp;Verify</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg603">
+ <trans-unit id="_msg611">
+ <source xml:space="preserve">Verify this address on e.g. a hardware wallet screen</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">263</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg612">
+ <source xml:space="preserve">&amp;Save Image…</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">273</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg613">
<source xml:space="preserve">Payment information</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">39</context></context-group>
@@ -3345,7 +3397,7 @@ For more information on using this console, type %6.
</body></file>
<file original="../receiverequestdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="ReceiveRequestDialog">
- <trans-unit id="_msg604">
+ <trans-unit id="_msg614">
<source xml:space="preserve">Request payment to %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
@@ -3354,229 +3406,229 @@ For more information on using this console, type %6.
</body></file>
<file original="../recentrequeststablemodel.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="RecentRequestsTableModel">
- <trans-unit id="_msg605">
+ <trans-unit id="_msg615">
<source xml:space="preserve">Date</source>
<target xml:space="preserve" state="needs-review-translation">Date</target>
- <context-group purpose="location"><context context-type="linenumber">30</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg606">
+ <trans-unit id="_msg616">
<source xml:space="preserve">Label</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">30</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg607">
+ <trans-unit id="_msg617">
<source xml:space="preserve">Message</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">30</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">32</context></context-group>
</trans-unit>
- <trans-unit id="_msg608">
+ <trans-unit id="_msg618">
<source xml:space="preserve">(no label)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">71</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg609">
+ <trans-unit id="_msg619">
<source xml:space="preserve">(no message)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">80</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">82</context></context-group>
</trans-unit>
- <trans-unit id="_msg610">
+ <trans-unit id="_msg620">
<source xml:space="preserve">(no amount requested)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">88</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg611">
+ <trans-unit id="_msg621">
<source xml:space="preserve">Requested</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">131</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">133</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/sendcoinsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendCoinsDialog">
- <trans-unit id="_msg612" approved="yes">
+ <trans-unit id="_msg622" approved="yes">
<source xml:space="preserve">Send Coins</source>
<target xml:space="preserve">Send Coins</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
- <context-group purpose="location"><context context-type="sourcefile">../sendcoinsdialog.cpp</context><context context-type="linenumber">674</context></context-group>
+ <context-group purpose="location"><context context-type="sourcefile">../sendcoinsdialog.cpp</context><context context-type="linenumber">738</context></context-group>
</trans-unit>
- <trans-unit id="_msg613">
+ <trans-unit id="_msg623">
<source xml:space="preserve">Coin Control Features</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg614">
+ <trans-unit id="_msg624">
<source xml:space="preserve">automatically selected</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
</trans-unit>
- <trans-unit id="_msg615">
+ <trans-unit id="_msg625">
<source xml:space="preserve">Insufficient funds!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg616">
+ <trans-unit id="_msg626">
<source xml:space="preserve">Quantity:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">228</context></context-group>
</trans-unit>
- <trans-unit id="_msg617">
+ <trans-unit id="_msg627">
<source xml:space="preserve">Bytes:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">263</context></context-group>
</trans-unit>
- <trans-unit id="_msg618">
+ <trans-unit id="_msg628">
<source xml:space="preserve">Amount:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">311</context></context-group>
</trans-unit>
- <trans-unit id="_msg619">
+ <trans-unit id="_msg629">
<source xml:space="preserve">Fee:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">391</context></context-group>
</trans-unit>
- <trans-unit id="_msg620">
+ <trans-unit id="_msg630">
<source xml:space="preserve">After Fee:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">442</context></context-group>
</trans-unit>
- <trans-unit id="_msg621">
+ <trans-unit id="_msg631">
<source xml:space="preserve">Change:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">474</context></context-group>
</trans-unit>
- <trans-unit id="_msg622">
+ <trans-unit id="_msg632">
<source xml:space="preserve">If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">518</context></context-group>
</trans-unit>
- <trans-unit id="_msg623">
+ <trans-unit id="_msg633">
<source xml:space="preserve">Custom change address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">521</context></context-group>
</trans-unit>
- <trans-unit id="_msg624">
+ <trans-unit id="_msg634">
<source xml:space="preserve">Transaction Fee:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">727</context></context-group>
</trans-unit>
- <trans-unit id="_msg625">
+ <trans-unit id="_msg635">
<source xml:space="preserve">Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until you have validated the complete chain.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">765</context></context-group>
</trans-unit>
- <trans-unit id="_msg626">
+ <trans-unit id="_msg636">
<source xml:space="preserve">Warning: Fee estimation is currently not possible.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">774</context></context-group>
</trans-unit>
- <trans-unit id="_msg627">
+ <trans-unit id="_msg637">
<source xml:space="preserve">per kilobyte</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">856</context></context-group>
</trans-unit>
- <trans-unit id="_msg628">
+ <trans-unit id="_msg638">
<source xml:space="preserve">Hide</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">803</context></context-group>
</trans-unit>
- <trans-unit id="_msg629">
+ <trans-unit id="_msg639">
<source xml:space="preserve">Recommended:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">915</context></context-group>
</trans-unit>
- <trans-unit id="_msg630">
+ <trans-unit id="_msg640">
<source xml:space="preserve">Custom:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">945</context></context-group>
</trans-unit>
- <trans-unit id="_msg631" approved="yes">
+ <trans-unit id="_msg641" approved="yes">
<source xml:space="preserve">Send to multiple recipients at once</source>
<target xml:space="preserve">Send to multiple recipients at once</target>
<context-group purpose="location"><context context-type="linenumber">1160</context></context-group>
</trans-unit>
- <trans-unit id="_msg632" approved="yes">
+ <trans-unit id="_msg642" approved="yes">
<source xml:space="preserve">Add &amp;Recipient</source>
<target xml:space="preserve">Add &amp;Recipient</target>
<context-group purpose="location"><context context-type="linenumber">1163</context></context-group>
</trans-unit>
- <trans-unit id="_msg633">
+ <trans-unit id="_msg643">
<source xml:space="preserve">Clear all fields of the form.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">1143</context></context-group>
</trans-unit>
- <trans-unit id="_msg634">
+ <trans-unit id="_msg644">
<source xml:space="preserve">Inputs…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">110</context></context-group>
</trans-unit>
- <trans-unit id="_msg635">
+ <trans-unit id="_msg645">
<source xml:space="preserve">Dust:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">343</context></context-group>
</trans-unit>
- <trans-unit id="_msg636">
+ <trans-unit id="_msg646">
<source xml:space="preserve">Choose…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">741</context></context-group>
</trans-unit>
- <trans-unit id="_msg637">
+ <trans-unit id="_msg647">
<source xml:space="preserve">Hide transaction fee settings</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">800</context></context-group>
</trans-unit>
- <trans-unit id="_msg638">
+ <trans-unit id="_msg648">
<source xml:space="preserve">Specify a custom fee per kB (1,000 bytes) of the transaction&apos;s virtual size.
Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100 satoshis per kvB&quot; for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">851</context></context-group>
</trans-unit>
- <trans-unit id="_msg639">
+ <trans-unit id="_msg649">
<source xml:space="preserve">When there is less transaction volume than space in the blocks, miners as well as relaying nodes may enforce a minimum fee. Paying only this minimum fee is just fine, but be aware that this can result in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">886</context></context-group>
</trans-unit>
- <trans-unit id="_msg640">
+ <trans-unit id="_msg650">
<source xml:space="preserve">A too low fee might result in a never confirming transaction (read the tooltip)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">889</context></context-group>
</trans-unit>
- <trans-unit id="_msg641">
+ <trans-unit id="_msg651">
<source xml:space="preserve">(Smart fee not initialized yet. This usually takes a few blocks…)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">994</context></context-group>
</trans-unit>
- <trans-unit id="_msg642">
+ <trans-unit id="_msg652">
<source xml:space="preserve">Confirmation time target:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">1020</context></context-group>
</trans-unit>
- <trans-unit id="_msg643">
+ <trans-unit id="_msg653">
<source xml:space="preserve">Enable Replace-By-Fee</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">1078</context></context-group>
</trans-unit>
- <trans-unit id="_msg644">
+ <trans-unit id="_msg654">
<source xml:space="preserve">With Replace-By-Fee (BIP-125) you can increase a transaction&apos;s fee after it is sent. Without this, a higher fee may be recommended to compensate for increased transaction delay risk.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">1081</context></context-group>
</trans-unit>
- <trans-unit id="_msg645" approved="yes">
+ <trans-unit id="_msg655" approved="yes">
<source xml:space="preserve">Clear &amp;All</source>
<target xml:space="preserve">Clear &amp;All</target>
<context-group purpose="location"><context context-type="linenumber">1146</context></context-group>
</trans-unit>
- <trans-unit id="_msg646" approved="yes">
+ <trans-unit id="_msg656" approved="yes">
<source xml:space="preserve">Balance:</source>
<target xml:space="preserve">Balance:</target>
<context-group purpose="location"><context context-type="linenumber">1201</context></context-group>
</trans-unit>
- <trans-unit id="_msg647" approved="yes">
+ <trans-unit id="_msg657" approved="yes">
<source xml:space="preserve">Confirm the send action</source>
<target xml:space="preserve">Confirm the send action</target>
<context-group purpose="location"><context context-type="linenumber">1117</context></context-group>
</trans-unit>
- <trans-unit id="_msg648" approved="yes">
+ <trans-unit id="_msg658" approved="yes">
<source xml:space="preserve">S&amp;end</source>
<target xml:space="preserve">S&amp;end</target>
<context-group purpose="location"><context context-type="linenumber">1120</context></context-group>
@@ -3585,344 +3637,383 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../sendcoinsdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendCoinsDialog">
- <trans-unit id="_msg649">
+ <trans-unit id="_msg659">
<source xml:space="preserve">Copy quantity</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">92</context></context-group>
</trans-unit>
- <trans-unit id="_msg650">
+ <trans-unit id="_msg660">
<source xml:space="preserve">Copy amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">93</context></context-group>
</trans-unit>
- <trans-unit id="_msg651">
+ <trans-unit id="_msg661">
<source xml:space="preserve">Copy fee</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">94</context></context-group>
</trans-unit>
- <trans-unit id="_msg652">
+ <trans-unit id="_msg662">
<source xml:space="preserve">Copy after fee</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">95</context></context-group>
</trans-unit>
- <trans-unit id="_msg653">
+ <trans-unit id="_msg663">
<source xml:space="preserve">Copy bytes</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">96</context></context-group>
</trans-unit>
- <trans-unit id="_msg654">
+ <trans-unit id="_msg664">
<source xml:space="preserve">Copy dust</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">97</context></context-group>
</trans-unit>
- <trans-unit id="_msg655">
+ <trans-unit id="_msg665">
<source xml:space="preserve">Copy change</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg656">
+ <trans-unit id="_msg666">
<source xml:space="preserve">%1 (%2 blocks)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
</trans-unit>
- <trans-unit id="_msg657">
+ <trans-unit id="_msg667">
+ <source xml:space="preserve">Sign on device</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">204</context></context-group>
+ <note annotates="source" from="developer">&quot;device&quot; usually means a hardware wallet</note>
+ </trans-unit>
+ <trans-unit id="_msg668">
+ <source xml:space="preserve">Connect your hardware wallet first.</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">207</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg669">
+ <source xml:space="preserve">Set external signer script path in Options -&gt; Wallet</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">211</context></context-group>
+ <note annotates="source" from="developer">&quot;External signer&quot; means using devices such as hardware wallets.</note>
+ </trans-unit>
+ <trans-unit id="_msg670">
<source xml:space="preserve">Cr&amp;eate Unsigned</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">203</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">214</context></context-group>
</trans-unit>
- <trans-unit id="_msg658">
+ <trans-unit id="_msg671">
<source xml:space="preserve">Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">204</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg659">
+ <trans-unit id="_msg672">
<source xml:space="preserve"> from wallet &apos;%1&apos;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">294</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
</trans-unit>
- <trans-unit id="_msg660">
+ <trans-unit id="_msg673">
<source xml:space="preserve">%1 to &apos;%2&apos;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">305</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">316</context></context-group>
</trans-unit>
- <trans-unit id="_msg661">
+ <trans-unit id="_msg674">
<source xml:space="preserve">%1 to %2</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">310</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg662">
+ <trans-unit id="_msg675">
<source xml:space="preserve">Do you want to draft this transaction?</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">317</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">328</context></context-group>
</trans-unit>
- <trans-unit id="_msg663">
+ <trans-unit id="_msg676">
<source xml:space="preserve">Are you sure you want to send?</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">319</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">330</context></context-group>
</trans-unit>
- <trans-unit id="_msg664">
+ <trans-unit id="_msg677">
<source xml:space="preserve">To review recipient list click &quot;Show Details…&quot;</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">371</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">382</context></context-group>
</trans-unit>
- <trans-unit id="_msg665">
+ <trans-unit id="_msg678">
<source xml:space="preserve">Create Unsigned</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">390</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">401</context></context-group>
</trans-unit>
- <trans-unit id="_msg666">
+ <trans-unit id="_msg679">
+ <source xml:space="preserve">Sign and send</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">401</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg680">
+ <source xml:space="preserve">Sign failed</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">426</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg681">
+ <source xml:space="preserve">External signer not found</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">432</context></context-group>
+ <note annotates="source" from="developer">&quot;External signer&quot; means using devices such as hardware wallets.</note>
+ </trans-unit>
+ <trans-unit id="_msg682">
+ <source xml:space="preserve">External signer failure</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">438</context></context-group>
+ <note annotates="source" from="developer">&quot;External signer&quot; means using devices such as hardware wallets.</note>
+ </trans-unit>
+ <trans-unit id="_msg683">
<source xml:space="preserve">Save Transaction Data</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">434</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">496</context></context-group>
</trans-unit>
- <trans-unit id="_msg667">
+ <trans-unit id="_msg684">
<source xml:space="preserve">Partially Signed Transaction (Binary)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">436</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">498</context></context-group>
<note annotates="source" from="developer">Expanded name of the binary PSBT file format. See: BIP 174.</note>
</trans-unit>
- <trans-unit id="_msg668">
+ <trans-unit id="_msg685">
<source xml:space="preserve">PSBT saved</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">443</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">505</context></context-group>
</trans-unit>
- <trans-unit id="_msg669">
+ <trans-unit id="_msg686">
+ <source xml:space="preserve">External balance:</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">680</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg687">
<source xml:space="preserve">or</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">367</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">378</context></context-group>
</trans-unit>
- <trans-unit id="_msg670">
+ <trans-unit id="_msg688">
<source xml:space="preserve">You can increase the fee later (signals Replace-By-Fee, BIP-125).</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">348</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">359</context></context-group>
</trans-unit>
- <trans-unit id="_msg671">
+ <trans-unit id="_msg689">
<source xml:space="preserve">Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">324</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg672">
+ <trans-unit id="_msg690">
<source xml:space="preserve">Please, review your transaction.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">326</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">337</context></context-group>
</trans-unit>
- <trans-unit id="_msg673">
+ <trans-unit id="_msg691">
<source xml:space="preserve">Transaction fee</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">334</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">345</context></context-group>
</trans-unit>
- <trans-unit id="_msg674">
+ <trans-unit id="_msg692">
<source xml:space="preserve">Not signalling Replace-By-Fee, BIP-125.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">350</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">361</context></context-group>
</trans-unit>
- <trans-unit id="_msg675">
+ <trans-unit id="_msg693">
<source xml:space="preserve">Total Amount</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">364</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">375</context></context-group>
</trans-unit>
- <trans-unit id="_msg676">
+ <trans-unit id="_msg694">
<source xml:space="preserve">Confirm send coins</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">389</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">400</context></context-group>
</trans-unit>
- <trans-unit id="_msg677">
+ <trans-unit id="_msg695">
<source xml:space="preserve">Confirm transaction proposal</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">389</context></context-group>
- </trans-unit>
- <trans-unit id="_msg678">
- <source xml:space="preserve">Send</source>
- <target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">390</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">400</context></context-group>
</trans-unit>
- <trans-unit id="_msg679">
+ <trans-unit id="_msg696">
<source xml:space="preserve">Watch-only balance:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">619</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">683</context></context-group>
</trans-unit>
- <trans-unit id="_msg680">
+ <trans-unit id="_msg697">
<source xml:space="preserve">The recipient address is not valid. Please recheck.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">643</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">707</context></context-group>
</trans-unit>
- <trans-unit id="_msg681">
+ <trans-unit id="_msg698">
<source xml:space="preserve">The amount to pay must be larger than 0.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">646</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">710</context></context-group>
</trans-unit>
- <trans-unit id="_msg682">
+ <trans-unit id="_msg699">
<source xml:space="preserve">The amount exceeds your balance.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">649</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">713</context></context-group>
</trans-unit>
- <trans-unit id="_msg683">
+ <trans-unit id="_msg700">
<source xml:space="preserve">The total exceeds your balance when the %1 transaction fee is included.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">652</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">716</context></context-group>
</trans-unit>
- <trans-unit id="_msg684">
+ <trans-unit id="_msg701">
<source xml:space="preserve">Duplicate address found: addresses should only be used once each.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">655</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">719</context></context-group>
</trans-unit>
- <trans-unit id="_msg685">
+ <trans-unit id="_msg702">
<source xml:space="preserve">Transaction creation failed!</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">658</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">722</context></context-group>
</trans-unit>
- <trans-unit id="_msg686">
+ <trans-unit id="_msg703">
<source xml:space="preserve">A fee higher than %1 is considered an absurdly high fee.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">662</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">726</context></context-group>
</trans-unit>
- <trans-unit id="_msg687">
+ <trans-unit id="_msg704">
<source xml:space="preserve">Payment request expired.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">665</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">729</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
- <context-group purpose="location"><context context-type="linenumber">789</context></context-group>
- <trans-unit id="_msg688[0]" approved="yes">
+ <context-group purpose="location"><context context-type="linenumber">853</context></context-group>
+ <trans-unit id="_msg705[0]" approved="yes">
<source xml:space="preserve">Estimated to begin confirmation within %n block(s).</source>
<target xml:space="preserve">Estimated to begin confirmation within %n block.</target>
</trans-unit>
- <trans-unit id="_msg688[1]" approved="yes">
+ <trans-unit id="_msg705[1]" approved="yes">
<source xml:space="preserve">Estimated to begin confirmation within %n block(s).</source>
<target xml:space="preserve">Estimated to begin confirmation within %n blocks.</target>
</trans-unit>
</group>
- <trans-unit id="_msg689">
+ <trans-unit id="_msg706">
<source xml:space="preserve">Warning: Invalid Bitcoin address</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">890</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">954</context></context-group>
</trans-unit>
- <trans-unit id="_msg690">
+ <trans-unit id="_msg707">
<source xml:space="preserve">Warning: Unknown change address</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">895</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">959</context></context-group>
</trans-unit>
- <trans-unit id="_msg691">
+ <trans-unit id="_msg708">
<source xml:space="preserve">Confirm custom change address</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">898</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">962</context></context-group>
</trans-unit>
- <trans-unit id="_msg692">
+ <trans-unit id="_msg709">
<source xml:space="preserve">The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">898</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">962</context></context-group>
</trans-unit>
- <trans-unit id="_msg693">
+ <trans-unit id="_msg710">
<source xml:space="preserve">(no label)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">919</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">983</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../forms/sendcoinsentry.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SendCoinsEntry">
- <trans-unit id="_msg694" approved="yes">
+ <trans-unit id="_msg711" approved="yes">
<source xml:space="preserve">A&amp;mount:</source>
<target xml:space="preserve">A&amp;mount:</target>
<context-group purpose="location"><context context-type="linenumber">155</context></context-group>
<context-group purpose="location"><context context-type="linenumber">705</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1238</context></context-group>
</trans-unit>
- <trans-unit id="_msg695" approved="yes">
+ <trans-unit id="_msg712" approved="yes">
<source xml:space="preserve">Pay &amp;To:</source>
<target xml:space="preserve">Pay &amp;To:</target>
<context-group purpose="location"><context context-type="linenumber">39</context></context-group>
</trans-unit>
- <trans-unit id="_msg696" approved="yes">
+ <trans-unit id="_msg713" approved="yes">
<source xml:space="preserve">&amp;Label:</source>
<target xml:space="preserve">&amp;Label:</target>
<context-group purpose="location"><context context-type="linenumber">132</context></context-group>
</trans-unit>
- <trans-unit id="_msg697">
+ <trans-unit id="_msg714">
<source xml:space="preserve">Choose previously used address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">64</context></context-group>
</trans-unit>
- <trans-unit id="_msg698">
+ <trans-unit id="_msg715">
<source xml:space="preserve">The Bitcoin address to send the payment to</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">57</context></context-group>
</trans-unit>
- <trans-unit id="_msg699" approved="yes">
+ <trans-unit id="_msg716" approved="yes">
<source xml:space="preserve">Alt+A</source>
<target xml:space="preserve">Alt+A</target>
<context-group purpose="location"><context context-type="linenumber">80</context></context-group>
</trans-unit>
- <trans-unit id="_msg700" approved="yes">
+ <trans-unit id="_msg717" approved="yes">
<source xml:space="preserve">Paste address from clipboard</source>
<target xml:space="preserve">Paste address from clipboard</target>
<context-group purpose="location"><context context-type="linenumber">87</context></context-group>
</trans-unit>
- <trans-unit id="_msg701" approved="yes">
+ <trans-unit id="_msg718" approved="yes">
<source xml:space="preserve">Alt+P</source>
<target xml:space="preserve">Alt+P</target>
<context-group purpose="location"><context context-type="linenumber">103</context></context-group>
</trans-unit>
- <trans-unit id="_msg702">
+ <trans-unit id="_msg719">
<source xml:space="preserve">Remove this entry</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">110</context></context-group>
<context-group purpose="location"><context context-type="linenumber">672</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1205</context></context-group>
</trans-unit>
- <trans-unit id="_msg703">
+ <trans-unit id="_msg720">
<source xml:space="preserve">The amount to send in the selected unit</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">170</context></context-group>
</trans-unit>
- <trans-unit id="_msg704">
+ <trans-unit id="_msg721">
<source xml:space="preserve">The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">177</context></context-group>
</trans-unit>
- <trans-unit id="_msg705">
+ <trans-unit id="_msg722">
<source xml:space="preserve">S&amp;ubtract fee from amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg706">
+ <trans-unit id="_msg723">
<source xml:space="preserve">Use available balance</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">187</context></context-group>
</trans-unit>
- <trans-unit id="_msg707">
+ <trans-unit id="_msg724">
<source xml:space="preserve">Message:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">196</context></context-group>
</trans-unit>
- <trans-unit id="_msg708">
+ <trans-unit id="_msg725">
<source xml:space="preserve">This is an unauthenticated payment request.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">639</context></context-group>
</trans-unit>
- <trans-unit id="_msg709">
+ <trans-unit id="_msg726">
<source xml:space="preserve">This is an authenticated payment request.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">1168</context></context-group>
</trans-unit>
- <trans-unit id="_msg710">
+ <trans-unit id="_msg727">
<source xml:space="preserve">Enter a label for this address to add it to the list of used addresses</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">145</context></context-group>
<context-group purpose="location"><context context-type="linenumber">148</context></context-group>
</trans-unit>
- <trans-unit id="_msg711">
+ <trans-unit id="_msg728">
<source xml:space="preserve">A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
</trans-unit>
- <trans-unit id="_msg712">
+ <trans-unit id="_msg729">
<source xml:space="preserve">Pay To:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">654</context></context-group>
<context-group purpose="location"><context context-type="linenumber">1183</context></context-group>
</trans-unit>
- <trans-unit id="_msg713">
+ <trans-unit id="_msg730">
<source xml:space="preserve">Memo:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">688</context></context-group>
@@ -3932,128 +4023,128 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../forms/signverifymessagedialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SignVerifyMessageDialog">
- <trans-unit id="_msg714" approved="yes">
+ <trans-unit id="_msg731" approved="yes">
<source xml:space="preserve">Signatures - Sign / Verify a Message</source>
<target xml:space="preserve">Signatures - Sign / Verify a Message</target>
<context-group purpose="location"><context context-type="linenumber">14</context></context-group>
</trans-unit>
- <trans-unit id="_msg715" approved="yes">
+ <trans-unit id="_msg732" approved="yes">
<source xml:space="preserve">&amp;Sign Message</source>
<target xml:space="preserve">&amp;Sign Message</target>
<context-group purpose="location"><context context-type="linenumber">27</context></context-group>
</trans-unit>
- <trans-unit id="_msg716">
+ <trans-unit id="_msg733">
<source xml:space="preserve">You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">33</context></context-group>
</trans-unit>
- <trans-unit id="_msg717">
+ <trans-unit id="_msg734">
<source xml:space="preserve">The Bitcoin address to sign the message with</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg718">
+ <trans-unit id="_msg735">
<source xml:space="preserve">Choose previously used address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">58</context></context-group>
<context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg719" approved="yes">
+ <trans-unit id="_msg736" approved="yes">
<source xml:space="preserve">Alt+A</source>
<target xml:space="preserve">Alt+A</target>
<context-group purpose="location"><context context-type="linenumber">68</context></context-group>
<context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg720" approved="yes">
+ <trans-unit id="_msg737" approved="yes">
<source xml:space="preserve">Paste address from clipboard</source>
<target xml:space="preserve">Paste address from clipboard</target>
<context-group purpose="location"><context context-type="linenumber">78</context></context-group>
</trans-unit>
- <trans-unit id="_msg721" approved="yes">
+ <trans-unit id="_msg738" approved="yes">
<source xml:space="preserve">Alt+P</source>
<target xml:space="preserve">Alt+P</target>
<context-group purpose="location"><context context-type="linenumber">88</context></context-group>
</trans-unit>
- <trans-unit id="_msg722" approved="yes">
+ <trans-unit id="_msg739" approved="yes">
<source xml:space="preserve">Enter the message you want to sign here</source>
<target xml:space="preserve">Enter the message you want to sign here</target>
<context-group purpose="location"><context context-type="linenumber">100</context></context-group>
<context-group purpose="location"><context context-type="linenumber">103</context></context-group>
</trans-unit>
- <trans-unit id="_msg723" approved="yes">
+ <trans-unit id="_msg740" approved="yes">
<source xml:space="preserve">Signature</source>
<target xml:space="preserve">Signature</target>
<context-group purpose="location"><context context-type="linenumber">110</context></context-group>
</trans-unit>
- <trans-unit id="_msg724" approved="yes">
+ <trans-unit id="_msg741" approved="yes">
<source xml:space="preserve">Copy the current signature to the system clipboard</source>
<target xml:space="preserve">Copy the current signature to the system clipboard</target>
<context-group purpose="location"><context context-type="linenumber">140</context></context-group>
</trans-unit>
- <trans-unit id="_msg725" approved="yes">
+ <trans-unit id="_msg742" approved="yes">
<source xml:space="preserve">Sign the message to prove you own this Bitcoin address</source>
<target xml:space="preserve">Sign the message to prove you own this Bitcoin address</target>
<context-group purpose="location"><context context-type="linenumber">161</context></context-group>
</trans-unit>
- <trans-unit id="_msg726" approved="yes">
+ <trans-unit id="_msg743" approved="yes">
<source xml:space="preserve">Sign &amp;Message</source>
<target xml:space="preserve">Sign &amp;Message</target>
<context-group purpose="location"><context context-type="linenumber">164</context></context-group>
</trans-unit>
- <trans-unit id="_msg727" approved="yes">
+ <trans-unit id="_msg744" approved="yes">
<source xml:space="preserve">Reset all sign message fields</source>
<target xml:space="preserve">Reset all sign message fields</target>
<context-group purpose="location"><context context-type="linenumber">178</context></context-group>
</trans-unit>
- <trans-unit id="_msg728" approved="yes">
+ <trans-unit id="_msg745" approved="yes">
<source xml:space="preserve">Clear &amp;All</source>
<target xml:space="preserve">Clear &amp;All</target>
<context-group purpose="location"><context context-type="linenumber">181</context></context-group>
<context-group purpose="location"><context context-type="linenumber">338</context></context-group>
</trans-unit>
- <trans-unit id="_msg729" approved="yes">
+ <trans-unit id="_msg746" approved="yes">
<source xml:space="preserve">&amp;Verify Message</source>
<target xml:space="preserve">&amp;Verify Message</target>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
</trans-unit>
- <trans-unit id="_msg730">
+ <trans-unit id="_msg747">
<source xml:space="preserve">Enter the receiver&apos;s address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">246</context></context-group>
</trans-unit>
- <trans-unit id="_msg731">
+ <trans-unit id="_msg748">
<source xml:space="preserve">The Bitcoin address the message was signed with</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">267</context></context-group>
</trans-unit>
- <trans-unit id="_msg732">
+ <trans-unit id="_msg749">
<source xml:space="preserve">The signed message to verify</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">296</context></context-group>
<context-group purpose="location"><context context-type="linenumber">299</context></context-group>
</trans-unit>
- <trans-unit id="_msg733">
+ <trans-unit id="_msg750">
<source xml:space="preserve">The signature given when the message was signed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
<context-group purpose="location"><context context-type="linenumber">309</context></context-group>
</trans-unit>
- <trans-unit id="_msg734" approved="yes">
+ <trans-unit id="_msg751" approved="yes">
<source xml:space="preserve">Verify the message to ensure it was signed with the specified Bitcoin address</source>
<target xml:space="preserve">Verify the message to ensure it was signed with the specified Bitcoin address</target>
<context-group purpose="location"><context context-type="linenumber">318</context></context-group>
</trans-unit>
- <trans-unit id="_msg735" approved="yes">
+ <trans-unit id="_msg752" approved="yes">
<source xml:space="preserve">Verify &amp;Message</source>
<target xml:space="preserve">Verify &amp;Message</target>
<context-group purpose="location"><context context-type="linenumber">321</context></context-group>
</trans-unit>
- <trans-unit id="_msg736" approved="yes">
+ <trans-unit id="_msg753" approved="yes">
<source xml:space="preserve">Reset all verify message fields</source>
<target xml:space="preserve">Reset all verify message fields</target>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg737">
+ <trans-unit id="_msg754">
<source xml:space="preserve">Click &quot;Sign Message&quot; to generate signature</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">125</context></context-group>
@@ -4062,13 +4153,13 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../signverifymessagedialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="SignVerifyMessageDialog">
- <trans-unit id="_msg738">
+ <trans-unit id="_msg755">
<source xml:space="preserve">The entered address is invalid.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
<context-group purpose="location"><context context-type="linenumber">219</context></context-group>
</trans-unit>
- <trans-unit id="_msg739">
+ <trans-unit id="_msg756">
<source xml:space="preserve">Please check the address and try again.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">120</context></context-group>
@@ -4076,59 +4167,59 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<context-group purpose="location"><context context-type="linenumber">220</context></context-group>
<context-group purpose="location"><context context-type="linenumber">227</context></context-group>
</trans-unit>
- <trans-unit id="_msg740">
+ <trans-unit id="_msg757">
<source xml:space="preserve">The entered address does not refer to a key.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">127</context></context-group>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg741">
+ <trans-unit id="_msg758">
<source xml:space="preserve">Wallet unlock was cancelled.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">135</context></context-group>
</trans-unit>
- <trans-unit id="_msg742">
+ <trans-unit id="_msg759">
<source xml:space="preserve">No error</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">146</context></context-group>
</trans-unit>
- <trans-unit id="_msg743">
+ <trans-unit id="_msg760">
<source xml:space="preserve">Private key for the entered address is not available.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">149</context></context-group>
</trans-unit>
- <trans-unit id="_msg744">
+ <trans-unit id="_msg761">
<source xml:space="preserve">Message signing failed.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg745">
+ <trans-unit id="_msg762">
<source xml:space="preserve">Message signed.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">164</context></context-group>
</trans-unit>
- <trans-unit id="_msg746">
+ <trans-unit id="_msg763">
<source xml:space="preserve">The signature could not be decoded.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">233</context></context-group>
</trans-unit>
- <trans-unit id="_msg747">
+ <trans-unit id="_msg764">
<source xml:space="preserve">Please check the signature and try again.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">234</context></context-group>
<context-group purpose="location"><context context-type="linenumber">241</context></context-group>
</trans-unit>
- <trans-unit id="_msg748">
+ <trans-unit id="_msg765">
<source xml:space="preserve">The signature did not match the message digest.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">240</context></context-group>
</trans-unit>
- <trans-unit id="_msg749">
+ <trans-unit id="_msg766">
<source xml:space="preserve">Message verification failed.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">246</context></context-group>
</trans-unit>
- <trans-unit id="_msg750">
+ <trans-unit id="_msg767">
<source xml:space="preserve">Message verified.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">214</context></context-group>
@@ -4137,7 +4228,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../trafficgraphwidget.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TrafficGraphWidget">
- <trans-unit id="_msg751">
+ <trans-unit id="_msg768">
<source xml:space="preserve">kB/s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">82</context></context-group>
@@ -4148,111 +4239,111 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
<group restype="x-trolltech-linguist-context" resname="TransactionDesc">
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">36</context></context-group>
- <trans-unit id="_msg752[0]" approved="yes">
+ <trans-unit id="_msg769[0]" approved="yes">
<source xml:space="preserve">Open for %n more block(s)</source>
<target xml:space="preserve">Open for %n more block</target>
</trans-unit>
- <trans-unit id="_msg752[1]" approved="yes">
+ <trans-unit id="_msg769[1]" approved="yes">
<source xml:space="preserve">Open for %n more block(s)</source>
<target xml:space="preserve">Open for %n more blocks</target>
</trans-unit>
</group>
- <trans-unit id="_msg753">
+ <trans-unit id="_msg770">
<source xml:space="preserve">Open until %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">38</context></context-group>
</trans-unit>
- <trans-unit id="_msg754">
+ <trans-unit id="_msg771">
<source xml:space="preserve">conflicted with a transaction with %1 confirmations</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">44</context></context-group>
</trans-unit>
- <trans-unit id="_msg755">
+ <trans-unit id="_msg772">
<source xml:space="preserve">0/unconfirmed, %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg756">
+ <trans-unit id="_msg773">
<source xml:space="preserve">in memory pool</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg757">
+ <trans-unit id="_msg774">
<source xml:space="preserve">not in memory pool</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">47</context></context-group>
</trans-unit>
- <trans-unit id="_msg758">
+ <trans-unit id="_msg775">
<source xml:space="preserve">abandoned</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">46</context></context-group>
</trans-unit>
- <trans-unit id="_msg759">
+ <trans-unit id="_msg776">
<source xml:space="preserve">%1/unconfirmed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg760">
+ <trans-unit id="_msg777">
<source xml:space="preserve">%1 confirmations</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg761">
+ <trans-unit id="_msg778">
<source xml:space="preserve">Status</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">102</context></context-group>
</trans-unit>
- <trans-unit id="_msg762">
+ <trans-unit id="_msg779">
<source xml:space="preserve">Date</source>
<target xml:space="preserve" state="needs-review-translation">Date</target>
<context-group purpose="location"><context context-type="linenumber">105</context></context-group>
</trans-unit>
- <trans-unit id="_msg763">
+ <trans-unit id="_msg780">
<source xml:space="preserve">Source</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">112</context></context-group>
</trans-unit>
- <trans-unit id="_msg764">
+ <trans-unit id="_msg781">
<source xml:space="preserve">Generated</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">112</context></context-group>
</trans-unit>
- <trans-unit id="_msg765">
+ <trans-unit id="_msg782">
<source xml:space="preserve">From</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">117</context></context-group>
<context-group purpose="location"><context context-type="linenumber">131</context></context-group>
<context-group purpose="location"><context context-type="linenumber">203</context></context-group>
</trans-unit>
- <trans-unit id="_msg766">
+ <trans-unit id="_msg783">
<source xml:space="preserve">unknown</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">131</context></context-group>
</trans-unit>
- <trans-unit id="_msg767">
+ <trans-unit id="_msg784">
<source xml:space="preserve">To</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">132</context></context-group>
<context-group purpose="location"><context context-type="linenumber">152</context></context-group>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
</trans-unit>
- <trans-unit id="_msg768">
+ <trans-unit id="_msg785">
<source xml:space="preserve">own address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg769">
+ <trans-unit id="_msg786">
<source xml:space="preserve">watch-only</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
<context-group purpose="location"><context context-type="linenumber">203</context></context-group>
</trans-unit>
- <trans-unit id="_msg770">
+ <trans-unit id="_msg787">
<source xml:space="preserve">label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">136</context></context-group>
</trans-unit>
- <trans-unit id="_msg771">
+ <trans-unit id="_msg788">
<source xml:space="preserve">Credit</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">172</context></context-group>
@@ -4263,120 +4354,120 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
- <trans-unit id="_msg772[0]" approved="yes">
+ <trans-unit id="_msg789[0]" approved="yes">
<source xml:space="preserve">matures in %n more block(s)</source>
<target xml:space="preserve">matures in %n more block</target>
</trans-unit>
- <trans-unit id="_msg772[1]" approved="yes">
+ <trans-unit id="_msg789[1]" approved="yes">
<source xml:space="preserve">matures in %n more block(s)</source>
<target xml:space="preserve">matures in %n more blocks</target>
</trans-unit>
</group>
- <trans-unit id="_msg773">
+ <trans-unit id="_msg790">
<source xml:space="preserve">not accepted</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">176</context></context-group>
</trans-unit>
- <trans-unit id="_msg774">
+ <trans-unit id="_msg791">
<source xml:space="preserve">Debit</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">236</context></context-group>
<context-group purpose="location"><context context-type="linenumber">262</context></context-group>
<context-group purpose="location"><context context-type="linenumber">325</context></context-group>
</trans-unit>
- <trans-unit id="_msg775">
+ <trans-unit id="_msg792">
<source xml:space="preserve">Total debit</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">246</context></context-group>
</trans-unit>
- <trans-unit id="_msg776">
+ <trans-unit id="_msg793">
<source xml:space="preserve">Total credit</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">247</context></context-group>
</trans-unit>
- <trans-unit id="_msg777">
+ <trans-unit id="_msg794">
<source xml:space="preserve">Transaction fee</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">252</context></context-group>
</trans-unit>
- <trans-unit id="_msg778">
+ <trans-unit id="_msg795">
<source xml:space="preserve">Net amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">274</context></context-group>
</trans-unit>
- <trans-unit id="_msg779">
+ <trans-unit id="_msg796">
<source xml:space="preserve">Message</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">280</context></context-group>
<context-group purpose="location"><context context-type="linenumber">292</context></context-group>
</trans-unit>
- <trans-unit id="_msg780">
+ <trans-unit id="_msg797">
<source xml:space="preserve">Comment</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">282</context></context-group>
</trans-unit>
- <trans-unit id="_msg781">
+ <trans-unit id="_msg798">
<source xml:space="preserve">Transaction ID</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">284</context></context-group>
</trans-unit>
- <trans-unit id="_msg782">
+ <trans-unit id="_msg799">
<source xml:space="preserve">Transaction total size</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">285</context></context-group>
</trans-unit>
- <trans-unit id="_msg783">
+ <trans-unit id="_msg800">
<source xml:space="preserve">Transaction virtual size</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">286</context></context-group>
</trans-unit>
- <trans-unit id="_msg784">
+ <trans-unit id="_msg801">
<source xml:space="preserve">Output index</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">287</context></context-group>
</trans-unit>
- <trans-unit id="_msg785">
+ <trans-unit id="_msg802">
<source xml:space="preserve"> (Certificate was not verified)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">303</context></context-group>
</trans-unit>
- <trans-unit id="_msg786">
+ <trans-unit id="_msg803">
<source xml:space="preserve">Merchant</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">306</context></context-group>
</trans-unit>
- <trans-unit id="_msg787">
+ <trans-unit id="_msg804">
<source xml:space="preserve">Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to &quot;not accepted&quot; and it won&apos;t be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">314</context></context-group>
</trans-unit>
- <trans-unit id="_msg788">
+ <trans-unit id="_msg805">
<source xml:space="preserve">Debug information</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">322</context></context-group>
</trans-unit>
- <trans-unit id="_msg789">
+ <trans-unit id="_msg806">
<source xml:space="preserve">Transaction</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">330</context></context-group>
</trans-unit>
- <trans-unit id="_msg790">
+ <trans-unit id="_msg807">
<source xml:space="preserve">Inputs</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">333</context></context-group>
</trans-unit>
- <trans-unit id="_msg791">
+ <trans-unit id="_msg808">
<source xml:space="preserve">Amount</source>
<target xml:space="preserve" state="needs-review-translation">Amount</target>
<context-group purpose="location"><context context-type="linenumber">354</context></context-group>
</trans-unit>
- <trans-unit id="_msg792">
+ <trans-unit id="_msg809">
<source xml:space="preserve">true</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">355</context></context-group>
<context-group purpose="location"><context context-type="linenumber">356</context></context-group>
</trans-unit>
- <trans-unit id="_msg793">
+ <trans-unit id="_msg810">
<source xml:space="preserve">false</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">355</context></context-group>
@@ -4386,7 +4477,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../forms/transactiondescdialog.ui" datatype="x-trolltech-designer-ui" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionDescDialog">
- <trans-unit id="_msg794" approved="yes">
+ <trans-unit id="_msg811" approved="yes">
<source xml:space="preserve">This pane shows a detailed description of the transaction</source>
<target xml:space="preserve">This pane shows a detailed description of the transaction</target>
<context-group purpose="location"><context context-type="linenumber">20</context></context-group>
@@ -4395,7 +4486,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactiondescdialog.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionDescDialog">
- <trans-unit id="_msg795">
+ <trans-unit id="_msg812">
<source xml:space="preserve">Details for %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">18</context></context-group>
@@ -4404,138 +4495,138 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactiontablemodel.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionTableModel">
- <trans-unit id="_msg796">
+ <trans-unit id="_msg813">
<source xml:space="preserve">Date</source>
<target xml:space="preserve" state="needs-review-translation">Date</target>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg797">
+ <trans-unit id="_msg814">
<source xml:space="preserve">Type</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
- <trans-unit id="_msg798">
+ <trans-unit id="_msg815">
<source xml:space="preserve">Label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">260</context></context-group>
</trans-unit>
<group restype="x-gettext-plurals">
<context-group purpose="location"><context context-type="linenumber">320</context></context-group>
- <trans-unit id="_msg799[0]" approved="yes">
+ <trans-unit id="_msg816[0]" approved="yes">
<source xml:space="preserve">Open for %n more block(s)</source>
<target xml:space="preserve">Open for %n more block</target>
</trans-unit>
- <trans-unit id="_msg799[1]" approved="yes">
+ <trans-unit id="_msg816[1]" approved="yes">
<source xml:space="preserve">Open for %n more block(s)</source>
<target xml:space="preserve">Open for %n more blocks</target>
</trans-unit>
</group>
- <trans-unit id="_msg800">
+ <trans-unit id="_msg817">
<source xml:space="preserve">Open until %1</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">323</context></context-group>
</trans-unit>
- <trans-unit id="_msg801">
+ <trans-unit id="_msg818">
<source xml:space="preserve">Unconfirmed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">326</context></context-group>
</trans-unit>
- <trans-unit id="_msg802">
+ <trans-unit id="_msg819">
<source xml:space="preserve">Abandoned</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">329</context></context-group>
</trans-unit>
- <trans-unit id="_msg803">
+ <trans-unit id="_msg820">
<source xml:space="preserve">Confirming (%1 of %2 recommended confirmations)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">332</context></context-group>
</trans-unit>
- <trans-unit id="_msg804">
+ <trans-unit id="_msg821">
<source xml:space="preserve">Confirmed (%1 confirmations)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">335</context></context-group>
</trans-unit>
- <trans-unit id="_msg805">
+ <trans-unit id="_msg822">
<source xml:space="preserve">Conflicted</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">338</context></context-group>
</trans-unit>
- <trans-unit id="_msg806">
+ <trans-unit id="_msg823">
<source xml:space="preserve">Immature (%1 confirmations, will be available after %2)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">341</context></context-group>
</trans-unit>
- <trans-unit id="_msg807">
+ <trans-unit id="_msg824">
<source xml:space="preserve">Generated but not accepted</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">344</context></context-group>
</trans-unit>
- <trans-unit id="_msg808">
+ <trans-unit id="_msg825">
<source xml:space="preserve">Received with</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">383</context></context-group>
</trans-unit>
- <trans-unit id="_msg809">
+ <trans-unit id="_msg826">
<source xml:space="preserve">Received from</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">385</context></context-group>
</trans-unit>
- <trans-unit id="_msg810">
+ <trans-unit id="_msg827">
<source xml:space="preserve">Sent to</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">388</context></context-group>
</trans-unit>
- <trans-unit id="_msg811">
+ <trans-unit id="_msg828">
<source xml:space="preserve">Payment to yourself</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">390</context></context-group>
</trans-unit>
- <trans-unit id="_msg812">
+ <trans-unit id="_msg829">
<source xml:space="preserve">Mined</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">392</context></context-group>
</trans-unit>
- <trans-unit id="_msg813">
+ <trans-unit id="_msg830">
<source xml:space="preserve">watch-only</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">420</context></context-group>
</trans-unit>
- <trans-unit id="_msg814">
+ <trans-unit id="_msg831">
<source xml:space="preserve">(n/a)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">436</context></context-group>
</trans-unit>
- <trans-unit id="_msg815">
+ <trans-unit id="_msg832">
<source xml:space="preserve">(no label)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">646</context></context-group>
</trans-unit>
- <trans-unit id="_msg816">
+ <trans-unit id="_msg833">
<source xml:space="preserve">Transaction status. Hover over this field to show number of confirmations.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">685</context></context-group>
</trans-unit>
- <trans-unit id="_msg817">
+ <trans-unit id="_msg834">
<source xml:space="preserve">Date and time that the transaction was received.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">687</context></context-group>
</trans-unit>
- <trans-unit id="_msg818">
+ <trans-unit id="_msg835">
<source xml:space="preserve">Type of transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">689</context></context-group>
</trans-unit>
- <trans-unit id="_msg819">
+ <trans-unit id="_msg836">
<source xml:space="preserve">Whether or not a watch-only address is involved in this transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">691</context></context-group>
</trans-unit>
- <trans-unit id="_msg820">
+ <trans-unit id="_msg837">
<source xml:space="preserve">User-defined intent/purpose of the transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">693</context></context-group>
</trans-unit>
- <trans-unit id="_msg821">
+ <trans-unit id="_msg838">
<source xml:space="preserve">Amount removed from or added to balance.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">695</context></context-group>
@@ -4544,199 +4635,199 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../transactionview.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="TransactionView">
- <trans-unit id="_msg822">
+ <trans-unit id="_msg839">
<source xml:space="preserve">All</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">70</context></context-group>
<context-group purpose="location"><context context-type="linenumber">86</context></context-group>
</trans-unit>
- <trans-unit id="_msg823">
+ <trans-unit id="_msg840">
<source xml:space="preserve">Today</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">71</context></context-group>
</trans-unit>
- <trans-unit id="_msg824">
+ <trans-unit id="_msg841">
<source xml:space="preserve">This week</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">72</context></context-group>
</trans-unit>
- <trans-unit id="_msg825">
+ <trans-unit id="_msg842">
<source xml:space="preserve">This month</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">73</context></context-group>
</trans-unit>
- <trans-unit id="_msg826">
+ <trans-unit id="_msg843">
<source xml:space="preserve">Last month</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">74</context></context-group>
</trans-unit>
- <trans-unit id="_msg827">
+ <trans-unit id="_msg844">
<source xml:space="preserve">This year</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">75</context></context-group>
</trans-unit>
- <trans-unit id="_msg828">
+ <trans-unit id="_msg845">
<source xml:space="preserve">Received with</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">87</context></context-group>
</trans-unit>
- <trans-unit id="_msg829">
+ <trans-unit id="_msg846">
<source xml:space="preserve">Sent to</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">89</context></context-group>
</trans-unit>
- <trans-unit id="_msg830">
+ <trans-unit id="_msg847">
<source xml:space="preserve">To yourself</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">91</context></context-group>
</trans-unit>
- <trans-unit id="_msg831">
+ <trans-unit id="_msg848">
<source xml:space="preserve">Mined</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">92</context></context-group>
</trans-unit>
- <trans-unit id="_msg832">
+ <trans-unit id="_msg849">
<source xml:space="preserve">Other</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">93</context></context-group>
</trans-unit>
- <trans-unit id="_msg833">
+ <trans-unit id="_msg850">
<source xml:space="preserve">Enter address, transaction id, or label to search</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">98</context></context-group>
</trans-unit>
- <trans-unit id="_msg834">
+ <trans-unit id="_msg851">
<source xml:space="preserve">Min amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">102</context></context-group>
</trans-unit>
- <trans-unit id="_msg835">
- <source xml:space="preserve">Abandon transaction</source>
- <target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">177</context></context-group>
- </trans-unit>
- <trans-unit id="_msg836">
- <source xml:space="preserve">Increase transaction fee</source>
+ <trans-unit id="_msg852">
+ <source xml:space="preserve">Range…</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">174</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">76</context></context-group>
</trans-unit>
- <trans-unit id="_msg837">
- <source xml:space="preserve">Copy address</source>
+ <trans-unit id="_msg853">
+ <source xml:space="preserve">&amp;Copy address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">166</context></context-group>
</trans-unit>
- <trans-unit id="_msg838">
- <source xml:space="preserve">Copy label</source>
+ <trans-unit id="_msg854">
+ <source xml:space="preserve">Copy &amp;label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">167</context></context-group>
</trans-unit>
- <trans-unit id="_msg839">
- <source xml:space="preserve">Copy amount</source>
+ <trans-unit id="_msg855">
+ <source xml:space="preserve">Copy &amp;amount</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">168</context></context-group>
</trans-unit>
- <trans-unit id="_msg840">
- <source xml:space="preserve">Copy transaction ID</source>
+ <trans-unit id="_msg856">
+ <source xml:space="preserve">Copy transaction &amp;ID</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">169</context></context-group>
</trans-unit>
- <trans-unit id="_msg841">
- <source xml:space="preserve">Copy raw transaction</source>
+ <trans-unit id="_msg857">
+ <source xml:space="preserve">Copy &amp;raw transaction</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">170</context></context-group>
</trans-unit>
- <trans-unit id="_msg842">
- <source xml:space="preserve">Copy full transaction details</source>
+ <trans-unit id="_msg858">
+ <source xml:space="preserve">Copy full transaction &amp;details</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">171</context></context-group>
</trans-unit>
- <trans-unit id="_msg843">
- <source xml:space="preserve">Edit address label</source>
+ <trans-unit id="_msg859">
+ <source xml:space="preserve">&amp;Show transaction details</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">178</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">172</context></context-group>
</trans-unit>
- <trans-unit id="_msg844">
- <source xml:space="preserve">Show transaction details</source>
+ <trans-unit id="_msg860">
+ <source xml:space="preserve">Increase transaction &amp;fee</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">172</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">174</context></context-group>
</trans-unit>
- <trans-unit id="_msg845">
- <source xml:space="preserve">Range…</source>
+ <trans-unit id="_msg861">
+ <source xml:space="preserve">A&amp;bandon transaction</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">76</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">177</context></context-group>
</trans-unit>
- <trans-unit id="_msg846">
+ <trans-unit id="_msg862">
+ <source xml:space="preserve">&amp;Edit address label</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">178</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg863">
<source xml:space="preserve">Export Transaction History</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">352</context></context-group>
</trans-unit>
- <trans-unit id="_msg847">
+ <trans-unit id="_msg864">
<source xml:space="preserve">Comma separated file</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">355</context></context-group>
<note annotates="source" from="developer">Expanded name of the CSV file format. See https://en.wikipedia.org/wiki/Comma-separated_values</note>
</trans-unit>
- <trans-unit id="_msg848">
+ <trans-unit id="_msg865">
<source xml:space="preserve">Confirmed</source>
<target xml:space="preserve" state="needs-review-translation">Confirmed</target>
<context-group purpose="location"><context context-type="linenumber">364</context></context-group>
</trans-unit>
- <trans-unit id="_msg849">
+ <trans-unit id="_msg866">
<source xml:space="preserve">Watch-only</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">366</context></context-group>
</trans-unit>
- <trans-unit id="_msg850">
+ <trans-unit id="_msg867">
<source xml:space="preserve">Date</source>
<target xml:space="preserve" state="needs-review-translation">Date</target>
<context-group purpose="location"><context context-type="linenumber">367</context></context-group>
</trans-unit>
- <trans-unit id="_msg851">
+ <trans-unit id="_msg868">
<source xml:space="preserve">Type</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">368</context></context-group>
</trans-unit>
- <trans-unit id="_msg852">
+ <trans-unit id="_msg869">
<source xml:space="preserve">Label</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">369</context></context-group>
</trans-unit>
- <trans-unit id="_msg853">
+ <trans-unit id="_msg870">
<source xml:space="preserve">Address</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">370</context></context-group>
</trans-unit>
- <trans-unit id="_msg854">
+ <trans-unit id="_msg871">
<source xml:space="preserve">ID</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">372</context></context-group>
</trans-unit>
- <trans-unit id="_msg855">
+ <trans-unit id="_msg872">
<source xml:space="preserve">Exporting Failed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">375</context></context-group>
</trans-unit>
- <trans-unit id="_msg856">
+ <trans-unit id="_msg873">
<source xml:space="preserve">There was an error trying to save the transaction history to %1.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">375</context></context-group>
</trans-unit>
- <trans-unit id="_msg857">
+ <trans-unit id="_msg874">
<source xml:space="preserve">Exporting Successful</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">379</context></context-group>
</trans-unit>
- <trans-unit id="_msg858">
+ <trans-unit id="_msg875">
<source xml:space="preserve">The transaction history was successfully saved to %1.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">379</context></context-group>
</trans-unit>
- <trans-unit id="_msg859">
+ <trans-unit id="_msg876">
<source xml:space="preserve">Range:</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">551</context></context-group>
</trans-unit>
- <trans-unit id="_msg860">
+ <trans-unit id="_msg877">
<source xml:space="preserve">to</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">559</context></context-group>
@@ -4745,178 +4836,183 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of &quot;100
</body></file>
<file original="../walletframe.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="WalletFrame">
- <trans-unit id="_msg861">
+ <trans-unit id="_msg878">
<source xml:space="preserve">No wallet has been loaded.
Go to File &gt; Open Wallet to load a wallet.
- OR -</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">39</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">35</context></context-group>
</trans-unit>
- <trans-unit id="_msg862">
+ <trans-unit id="_msg879">
<source xml:space="preserve">Create a new wallet</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">44</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">40</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../walletmodel.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="WalletModel">
- <trans-unit id="_msg863">
+ <trans-unit id="_msg880">
<source xml:space="preserve">Send Coins</source>
<target xml:space="preserve" state="needs-review-translation">Send Coins</target>
<context-group purpose="location"><context context-type="linenumber">218</context></context-group>
</trans-unit>
- <trans-unit id="_msg864">
+ <trans-unit id="_msg881">
<source xml:space="preserve">Fee bump error</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">497</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">549</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">562</context></context-group>
- <context-group purpose="location"><context context-type="linenumber">567</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">478</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">530</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">543</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">548</context></context-group>
</trans-unit>
- <trans-unit id="_msg865">
+ <trans-unit id="_msg882">
<source xml:space="preserve">Increasing transaction fee failed</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">497</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">478</context></context-group>
</trans-unit>
- <trans-unit id="_msg866">
+ <trans-unit id="_msg883">
<source xml:space="preserve">Do you want to increase the fee?</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">505</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">486</context></context-group>
</trans-unit>
- <trans-unit id="_msg867">
+ <trans-unit id="_msg884">
<source xml:space="preserve">Do you want to draft a transaction with fee increase?</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">505</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">486</context></context-group>
</trans-unit>
- <trans-unit id="_msg868">
+ <trans-unit id="_msg885">
<source xml:space="preserve">Current fee:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">509</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">490</context></context-group>
</trans-unit>
- <trans-unit id="_msg869">
+ <trans-unit id="_msg886">
<source xml:space="preserve">Increase:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">513</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">494</context></context-group>
</trans-unit>
- <trans-unit id="_msg870">
+ <trans-unit id="_msg887">
<source xml:space="preserve">New fee:</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">517</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">498</context></context-group>
</trans-unit>
- <trans-unit id="_msg871">
+ <trans-unit id="_msg888">
<source xml:space="preserve">Warning: This may pay the additional fee by reducing change outputs or adding inputs, when necessary. It may add a new change output if one does not already exist. These changes may potentially leak privacy.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">525</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">506</context></context-group>
</trans-unit>
- <trans-unit id="_msg872">
+ <trans-unit id="_msg889">
<source xml:space="preserve">Confirm fee bump</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">528</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">509</context></context-group>
</trans-unit>
- <trans-unit id="_msg873">
+ <trans-unit id="_msg890">
<source xml:space="preserve">Can&apos;t draft transaction.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">549</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">530</context></context-group>
</trans-unit>
- <trans-unit id="_msg874">
+ <trans-unit id="_msg891">
<source xml:space="preserve">PSBT copied</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">556</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">537</context></context-group>
</trans-unit>
- <trans-unit id="_msg875">
+ <trans-unit id="_msg892">
<source xml:space="preserve">Can&apos;t sign transaction.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">562</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">543</context></context-group>
</trans-unit>
- <trans-unit id="_msg876">
+ <trans-unit id="_msg893">
<source xml:space="preserve">Could not commit transaction</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">567</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">548</context></context-group>
</trans-unit>
- <trans-unit id="_msg877">
+ <trans-unit id="_msg894">
+ <source xml:space="preserve">Can&apos;t display address</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">562</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg895">
<source xml:space="preserve">default wallet</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">587</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">580</context></context-group>
</trans-unit>
</group>
</body></file>
<file original="../walletview.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="WalletView">
- <trans-unit id="_msg878">
+ <trans-unit id="_msg896">
<source xml:space="preserve">&amp;Export</source>
<target xml:space="preserve" state="needs-review-translation">&amp;Export</target>
<context-group purpose="location"><context context-type="linenumber">51</context></context-group>
</trans-unit>
- <trans-unit id="_msg879">
+ <trans-unit id="_msg897">
<source xml:space="preserve">Export the data in the current tab to a file</source>
<target xml:space="preserve" state="needs-review-translation">Export the data in the current tab to a file</target>
<context-group purpose="location"><context context-type="linenumber">52</context></context-group>
</trans-unit>
- <trans-unit id="_msg880">
+ <trans-unit id="_msg898">
<source xml:space="preserve">Error</source>
<target xml:space="preserve" state="needs-review-translation">Error</target>
<context-group purpose="location"><context context-type="linenumber">217</context></context-group>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
<context-group purpose="location"><context context-type="linenumber">236</context></context-group>
</trans-unit>
- <trans-unit id="_msg881">
+ <trans-unit id="_msg899">
<source xml:space="preserve">Unable to decode PSBT from clipboard (invalid base64)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">217</context></context-group>
</trans-unit>
- <trans-unit id="_msg882">
+ <trans-unit id="_msg900">
<source xml:space="preserve">Load Transaction Data</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
</trans-unit>
- <trans-unit id="_msg883">
+ <trans-unit id="_msg901">
<source xml:space="preserve">Partially Signed Transaction (*.psbt)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">223</context></context-group>
</trans-unit>
- <trans-unit id="_msg884">
+ <trans-unit id="_msg902">
<source xml:space="preserve">PSBT file must be smaller than 100 MiB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg885">
+ <trans-unit id="_msg903">
<source xml:space="preserve">Unable to decode PSBT</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">236</context></context-group>
</trans-unit>
- <trans-unit id="_msg886">
+ <trans-unit id="_msg904">
<source xml:space="preserve">Backup Wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">275</context></context-group>
</trans-unit>
- <trans-unit id="_msg887">
+ <trans-unit id="_msg905">
<source xml:space="preserve">Wallet Data</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">277</context></context-group>
<note annotates="source" from="developer">Name of the wallet data file format.</note>
</trans-unit>
- <trans-unit id="_msg888">
+ <trans-unit id="_msg906">
<source xml:space="preserve">Backup Failed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">283</context></context-group>
</trans-unit>
- <trans-unit id="_msg889">
+ <trans-unit id="_msg907">
<source xml:space="preserve">There was an error trying to save the wallet data to %1.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">283</context></context-group>
</trans-unit>
- <trans-unit id="_msg890">
+ <trans-unit id="_msg908">
<source xml:space="preserve">Backup Successful</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">287</context></context-group>
</trans-unit>
- <trans-unit id="_msg891">
+ <trans-unit id="_msg909">
<source xml:space="preserve">The wallet data was successfully saved to %1.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">287</context></context-group>
</trans-unit>
- <trans-unit id="_msg892">
+ <trans-unit id="_msg910">
<source xml:space="preserve">Cancel</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">331</context></context-group>
@@ -4925,766 +5021,776 @@ Go to File &gt; Open Wallet to load a wallet.
</body></file>
<file original="../bitcoinstrings.cpp" datatype="cpp" source-language="en" target-language="en"><body>
<group restype="x-trolltech-linguist-context" resname="bitcoin-core">
- <trans-unit id="_msg893">
+ <trans-unit id="_msg911">
<source xml:space="preserve">The %s developers</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">12</context></context-group>
</trans-unit>
- <trans-unit id="_msg894">
+ <trans-unit id="_msg912">
<source xml:space="preserve">%s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">13</context></context-group>
</trans-unit>
- <trans-unit id="_msg895">
+ <trans-unit id="_msg913">
<source xml:space="preserve">-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">16</context></context-group>
</trans-unit>
- <trans-unit id="_msg896">
+ <trans-unit id="_msg914">
<source xml:space="preserve">Cannot downgrade wallet from version %i to version %i. Wallet version unchanged.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">19</context></context-group>
</trans-unit>
- <trans-unit id="_msg897">
+ <trans-unit id="_msg915">
<source xml:space="preserve">Cannot obtain a lock on data directory %s. %s is probably already running.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">22</context></context-group>
</trans-unit>
- <trans-unit id="_msg898">
+ <trans-unit id="_msg916">
<source xml:space="preserve">Cannot provide specific connections and have addrman find outgoing connections at the same.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">24</context></context-group>
</trans-unit>
- <trans-unit id="_msg899">
+ <trans-unit id="_msg917">
<source xml:space="preserve">Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">27</context></context-group>
</trans-unit>
- <trans-unit id="_msg900">
+ <trans-unit id="_msg918">
<source xml:space="preserve">Distributed under the MIT software license, see the accompanying file %s or %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">31</context></context-group>
</trans-unit>
- <trans-unit id="_msg901">
+ <trans-unit id="_msg919">
<source xml:space="preserve">Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">34</context></context-group>
</trans-unit>
- <trans-unit id="_msg902">
+ <trans-unit id="_msg920">
<source xml:space="preserve">Error: Dumpfile format record is incorrect. Got &quot;%s&quot;, expected &quot;format&quot;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">37</context></context-group>
</trans-unit>
- <trans-unit id="_msg903">
+ <trans-unit id="_msg921">
<source xml:space="preserve">Error: Dumpfile identifier record is incorrect. Got &quot;%s&quot;, expected &quot;%s&quot;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">39</context></context-group>
</trans-unit>
- <trans-unit id="_msg904">
+ <trans-unit id="_msg922">
<source xml:space="preserve">Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">41</context></context-group>
</trans-unit>
- <trans-unit id="_msg905">
- <source xml:space="preserve">Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <trans-unit id="_msg923">
+ <source xml:space="preserve">Error: Legacy wallets only support the &quot;legacy&quot;, &quot;p2sh-segwit&quot;, and &quot;bech32&quot; address types</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">44</context></context-group>
</trans-unit>
- <trans-unit id="_msg906">
+ <trans-unit id="_msg924">
+ <source xml:space="preserve">Error: Listening for incoming connections failed (listen returned error %s)</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">47</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg925">
<source xml:space="preserve">Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">46</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">49</context></context-group>
</trans-unit>
- <trans-unit id="_msg907">
+ <trans-unit id="_msg926">
<source xml:space="preserve">File %s already exists. If you are sure this is what you want, move it out of the way first.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">49</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">52</context></context-group>
</trans-unit>
- <trans-unit id="_msg908">
+ <trans-unit id="_msg927">
<source xml:space="preserve">Invalid amount for -maxtxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least the minrelay fee of %s to prevent stuck transactions)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">52</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">55</context></context-group>
</trans-unit>
- <trans-unit id="_msg909">
+ <trans-unit id="_msg928">
<source xml:space="preserve">More than one onion bind address is provided. Using %s for the automatically created Tor onion service.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">55</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">58</context></context-group>
</trans-unit>
- <trans-unit id="_msg910">
+ <trans-unit id="_msg929">
<source xml:space="preserve">No dump file provided. To use createfromdump, -dumpfile=&lt;filename&gt; must be provided.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">58</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">61</context></context-group>
</trans-unit>
- <trans-unit id="_msg911">
+ <trans-unit id="_msg930">
<source xml:space="preserve">No dump file provided. To use dump, -dumpfile=&lt;filename&gt; must be provided.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">61</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">64</context></context-group>
</trans-unit>
- <trans-unit id="_msg912">
+ <trans-unit id="_msg931">
<source xml:space="preserve">No wallet file format provided. To use createfromdump, -format=&lt;format&gt; must be provided.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">63</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">66</context></context-group>
</trans-unit>
- <trans-unit id="_msg913">
+ <trans-unit id="_msg932">
<source xml:space="preserve">Please check that your computer&apos;s date and time are correct! If your clock is wrong, %s will not work properly.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">66</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">69</context></context-group>
</trans-unit>
- <trans-unit id="_msg914">
+ <trans-unit id="_msg933">
<source xml:space="preserve">Please contribute if you find %s useful. Visit %s for further information about the software.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">69</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">72</context></context-group>
</trans-unit>
- <trans-unit id="_msg915">
+ <trans-unit id="_msg934">
<source xml:space="preserve">Prune configured below the minimum of %d MiB. Please use a higher number.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">72</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">75</context></context-group>
</trans-unit>
- <trans-unit id="_msg916">
+ <trans-unit id="_msg935">
<source xml:space="preserve">Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">74</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">77</context></context-group>
</trans-unit>
- <trans-unit id="_msg917">
+ <trans-unit id="_msg936">
<source xml:space="preserve">SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">77</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">80</context></context-group>
</trans-unit>
- <trans-unit id="_msg918">
+ <trans-unit id="_msg937">
<source xml:space="preserve">The block database contains a block which appears to be from the future. This may be due to your computer&apos;s date and time being set incorrectly. Only rebuild the block database if you are sure that your computer&apos;s date and time are correct</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">80</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">83</context></context-group>
</trans-unit>
- <trans-unit id="_msg919">
+ <trans-unit id="_msg938">
<source xml:space="preserve">The transaction amount is too small to send after the fee has been deducted</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">85</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">88</context></context-group>
</trans-unit>
- <trans-unit id="_msg920">
+ <trans-unit id="_msg939">
<source xml:space="preserve">This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">87</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">90</context></context-group>
</trans-unit>
- <trans-unit id="_msg921">
+ <trans-unit id="_msg940">
<source xml:space="preserve">This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">91</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">94</context></context-group>
</trans-unit>
- <trans-unit id="_msg922">
+ <trans-unit id="_msg941">
<source xml:space="preserve">This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">94</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">97</context></context-group>
</trans-unit>
- <trans-unit id="_msg923">
+ <trans-unit id="_msg942">
<source xml:space="preserve">This is the transaction fee you may discard if change is smaller than dust at this level</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">97</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">100</context></context-group>
</trans-unit>
- <trans-unit id="_msg924">
+ <trans-unit id="_msg943">
<source xml:space="preserve">This is the transaction fee you may pay when fee estimates are not available.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">100</context></context-group>
+ <context-group purpose="location"><context context-type="linenumber">103</context></context-group>
</trans-unit>
- <trans-unit id="_msg925">
+ <trans-unit id="_msg944">
<source xml:space="preserve">Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source>
<target xml:space="preserve"></target>
- <context-group purpose="location"><context context-type="linenumber">102</context></context-group>
- </trans-unit>
- <trans-unit id="_msg926">
- <source xml:space="preserve">Transaction needs a change address, but we can&apos;t generate it. Please call keypoolrefill first.</source>
- <target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">105</context></context-group>
</trans-unit>
- <trans-unit id="_msg927">
+ <trans-unit id="_msg945">
<source xml:space="preserve">Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">108</context></context-group>
</trans-unit>
- <trans-unit id="_msg928">
+ <trans-unit id="_msg946">
<source xml:space="preserve">Unknown wallet file format &quot;%s&quot; provided. Please provide one of &quot;bdb&quot; or &quot;sqlite&quot;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">111</context></context-group>
</trans-unit>
- <trans-unit id="_msg929">
+ <trans-unit id="_msg947">
<source xml:space="preserve">Warning: Dumpfile wallet format &quot;%s&quot; does not match command line specified format &quot;%s&quot;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">114</context></context-group>
</trans-unit>
- <trans-unit id="_msg930">
+ <trans-unit id="_msg948">
<source xml:space="preserve">Warning: Private keys detected in wallet {%s} with disabled private keys</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">117</context></context-group>
</trans-unit>
- <trans-unit id="_msg931">
+ <trans-unit id="_msg949">
<source xml:space="preserve">Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">119</context></context-group>
</trans-unit>
- <trans-unit id="_msg932">
+ <trans-unit id="_msg950">
<source xml:space="preserve">Witness data for blocks after height %d requires validation. Please restart with -reindex.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">122</context></context-group>
</trans-unit>
- <trans-unit id="_msg933">
+ <trans-unit id="_msg951">
<source xml:space="preserve">You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">125</context></context-group>
</trans-unit>
- <trans-unit id="_msg934">
+ <trans-unit id="_msg952">
<source xml:space="preserve">%s is set very high!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">128</context></context-group>
</trans-unit>
- <trans-unit id="_msg935">
+ <trans-unit id="_msg953">
<source xml:space="preserve">-maxmempool must be at least %d MB</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">129</context></context-group>
</trans-unit>
- <trans-unit id="_msg936">
+ <trans-unit id="_msg954">
<source xml:space="preserve">A fatal internal error occurred, see debug.log for details</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">130</context></context-group>
</trans-unit>
- <trans-unit id="_msg937">
+ <trans-unit id="_msg955">
<source xml:space="preserve">Cannot resolve -%s address: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">131</context></context-group>
</trans-unit>
- <trans-unit id="_msg938">
+ <trans-unit id="_msg956">
<source xml:space="preserve">Cannot set -peerblockfilters without -blockfilterindex.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">132</context></context-group>
</trans-unit>
- <trans-unit id="_msg939">
+ <trans-unit id="_msg957">
<source xml:space="preserve">Cannot write to data directory &apos;%s&apos;; check permissions.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">133</context></context-group>
</trans-unit>
- <trans-unit id="_msg940">
+ <trans-unit id="_msg958">
<source xml:space="preserve">Change index out of range</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">134</context></context-group>
</trans-unit>
- <trans-unit id="_msg941">
+ <trans-unit id="_msg959">
<source xml:space="preserve">Config setting for %s only applied on %s network when in [%s] section.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">135</context></context-group>
</trans-unit>
- <trans-unit id="_msg942">
+ <trans-unit id="_msg960">
<source xml:space="preserve">Copyright (C) %i-%i</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">136</context></context-group>
</trans-unit>
- <trans-unit id="_msg943">
+ <trans-unit id="_msg961">
<source xml:space="preserve">Corrupted block database detected</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">137</context></context-group>
</trans-unit>
- <trans-unit id="_msg944">
+ <trans-unit id="_msg962">
<source xml:space="preserve">Could not find asmap file %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">138</context></context-group>
</trans-unit>
- <trans-unit id="_msg945">
+ <trans-unit id="_msg963">
<source xml:space="preserve">Could not parse asmap file %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">139</context></context-group>
</trans-unit>
- <trans-unit id="_msg946">
+ <trans-unit id="_msg964">
<source xml:space="preserve">Disk space is too low!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">140</context></context-group>
</trans-unit>
- <trans-unit id="_msg947">
+ <trans-unit id="_msg965">
<source xml:space="preserve">Do you want to rebuild the block database now?</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">141</context></context-group>
</trans-unit>
- <trans-unit id="_msg948">
+ <trans-unit id="_msg966">
<source xml:space="preserve">Done loading</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">142</context></context-group>
</trans-unit>
- <trans-unit id="_msg949">
+ <trans-unit id="_msg967">
<source xml:space="preserve">Dump file %s does not exist.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">143</context></context-group>
</trans-unit>
- <trans-unit id="_msg950">
+ <trans-unit id="_msg968">
<source xml:space="preserve">Error creating %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">144</context></context-group>
</trans-unit>
- <trans-unit id="_msg951">
+ <trans-unit id="_msg969">
<source xml:space="preserve">Error initializing block database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">145</context></context-group>
</trans-unit>
- <trans-unit id="_msg952">
+ <trans-unit id="_msg970">
<source xml:space="preserve">Error initializing wallet database environment %s!</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">146</context></context-group>
</trans-unit>
- <trans-unit id="_msg953">
+ <trans-unit id="_msg971">
<source xml:space="preserve">Error loading %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">147</context></context-group>
</trans-unit>
- <trans-unit id="_msg954">
+ <trans-unit id="_msg972">
<source xml:space="preserve">Error loading %s: Private keys can only be disabled during creation</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">148</context></context-group>
</trans-unit>
- <trans-unit id="_msg955">
+ <trans-unit id="_msg973">
<source xml:space="preserve">Error loading %s: Wallet corrupted</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">149</context></context-group>
</trans-unit>
- <trans-unit id="_msg956">
+ <trans-unit id="_msg974">
<source xml:space="preserve">Error loading %s: Wallet requires newer version of %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">150</context></context-group>
</trans-unit>
- <trans-unit id="_msg957">
+ <trans-unit id="_msg975">
<source xml:space="preserve">Error loading block database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">151</context></context-group>
</trans-unit>
- <trans-unit id="_msg958">
+ <trans-unit id="_msg976">
<source xml:space="preserve">Error opening block database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">152</context></context-group>
</trans-unit>
- <trans-unit id="_msg959">
+ <trans-unit id="_msg977">
<source xml:space="preserve">Error reading from database, shutting down.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">153</context></context-group>
</trans-unit>
- <trans-unit id="_msg960">
+ <trans-unit id="_msg978">
<source xml:space="preserve">Error reading next record from wallet database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">154</context></context-group>
</trans-unit>
- <trans-unit id="_msg961">
+ <trans-unit id="_msg979">
<source xml:space="preserve">Error upgrading chainstate database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">155</context></context-group>
</trans-unit>
- <trans-unit id="_msg962">
+ <trans-unit id="_msg980">
<source xml:space="preserve">Error: Couldn&apos;t create cursor into database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">156</context></context-group>
</trans-unit>
- <trans-unit id="_msg963">
+ <trans-unit id="_msg981">
<source xml:space="preserve">Error: Disk space is low for %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">157</context></context-group>
</trans-unit>
- <trans-unit id="_msg964">
+ <trans-unit id="_msg982">
<source xml:space="preserve">Error: Dumpfile checksum does not match. Computed %s, expected %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">158</context></context-group>
</trans-unit>
- <trans-unit id="_msg965">
+ <trans-unit id="_msg983">
<source xml:space="preserve">Error: Got key that was not hex: %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">159</context></context-group>
</trans-unit>
- <trans-unit id="_msg966">
+ <trans-unit id="_msg984">
<source xml:space="preserve">Error: Got value that was not hex: %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">160</context></context-group>
</trans-unit>
- <trans-unit id="_msg967">
+ <trans-unit id="_msg985">
<source xml:space="preserve">Error: Keypool ran out, please call keypoolrefill first</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">161</context></context-group>
</trans-unit>
- <trans-unit id="_msg968">
+ <trans-unit id="_msg986">
<source xml:space="preserve">Error: Missing checksum</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">162</context></context-group>
</trans-unit>
- <trans-unit id="_msg969">
- <source xml:space="preserve">Error: Unable to parse version %u as a uint32_t</source>
+ <trans-unit id="_msg987">
+ <source xml:space="preserve">Error: No %s addresses available.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">163</context></context-group>
</trans-unit>
- <trans-unit id="_msg970">
- <source xml:space="preserve">Error: Unable to write record to new wallet</source>
+ <trans-unit id="_msg988">
+ <source xml:space="preserve">Error: Unable to parse version %u as a uint32_t</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">164</context></context-group>
</trans-unit>
- <trans-unit id="_msg971">
- <source xml:space="preserve">Failed to listen on any port. Use -listen=0 if you want this.</source>
+ <trans-unit id="_msg989">
+ <source xml:space="preserve">Error: Unable to write record to new wallet</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">165</context></context-group>
</trans-unit>
- <trans-unit id="_msg972">
- <source xml:space="preserve">Failed to rescan the wallet during initialization</source>
+ <trans-unit id="_msg990">
+ <source xml:space="preserve">Failed to listen on any port. Use -listen=0 if you want this.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">166</context></context-group>
</trans-unit>
- <trans-unit id="_msg973">
- <source xml:space="preserve">Failed to verify database</source>
+ <trans-unit id="_msg991">
+ <source xml:space="preserve">Failed to rescan the wallet during initialization</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">167</context></context-group>
</trans-unit>
- <trans-unit id="_msg974">
- <source xml:space="preserve">Fee rate (%s) is lower than the minimum fee rate setting (%s)</source>
+ <trans-unit id="_msg992">
+ <source xml:space="preserve">Failed to verify database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">168</context></context-group>
</trans-unit>
- <trans-unit id="_msg975">
- <source xml:space="preserve">Ignoring duplicate -wallet %s.</source>
+ <trans-unit id="_msg993">
+ <source xml:space="preserve">Fee rate (%s) is lower than the minimum fee rate setting (%s)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">169</context></context-group>
</trans-unit>
- <trans-unit id="_msg976">
- <source xml:space="preserve">Importing…</source>
+ <trans-unit id="_msg994">
+ <source xml:space="preserve">Ignoring duplicate -wallet %s.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">170</context></context-group>
</trans-unit>
- <trans-unit id="_msg977">
- <source xml:space="preserve">Incorrect or no genesis block found. Wrong datadir for network?</source>
+ <trans-unit id="_msg995">
+ <source xml:space="preserve">Importing…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">171</context></context-group>
</trans-unit>
- <trans-unit id="_msg978">
- <source xml:space="preserve">Initialization sanity check failed. %s is shutting down.</source>
+ <trans-unit id="_msg996">
+ <source xml:space="preserve">Incorrect or no genesis block found. Wrong datadir for network?</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">172</context></context-group>
</trans-unit>
- <trans-unit id="_msg979">
- <source xml:space="preserve">Insufficient funds</source>
+ <trans-unit id="_msg997">
+ <source xml:space="preserve">Initialization sanity check failed. %s is shutting down.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">173</context></context-group>
</trans-unit>
- <trans-unit id="_msg980">
- <source xml:space="preserve">Invalid -i2psam address or hostname: &apos;%s&apos;</source>
+ <trans-unit id="_msg998">
+ <source xml:space="preserve">Insufficient funds</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">174</context></context-group>
</trans-unit>
- <trans-unit id="_msg981">
- <source xml:space="preserve">Invalid -onion address or hostname: &apos;%s&apos;</source>
+ <trans-unit id="_msg999">
+ <source xml:space="preserve">Invalid -i2psam address or hostname: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">175</context></context-group>
</trans-unit>
- <trans-unit id="_msg982">
- <source xml:space="preserve">Invalid -proxy address or hostname: &apos;%s&apos;</source>
+ <trans-unit id="_msg1000">
+ <source xml:space="preserve">Invalid -onion address or hostname: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">176</context></context-group>
</trans-unit>
- <trans-unit id="_msg983">
- <source xml:space="preserve">Invalid P2P permission: &apos;%s&apos;</source>
+ <trans-unit id="_msg1001">
+ <source xml:space="preserve">Invalid -proxy address or hostname: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">177</context></context-group>
</trans-unit>
- <trans-unit id="_msg984">
- <source xml:space="preserve">Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
+ <trans-unit id="_msg1002">
+ <source xml:space="preserve">Invalid P2P permission: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">178</context></context-group>
</trans-unit>
- <trans-unit id="_msg985">
- <source xml:space="preserve">Invalid amount for -discardfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <trans-unit id="_msg1003">
+ <source xml:space="preserve">Invalid amount for -%s=&lt;amount&gt;: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">179</context></context-group>
</trans-unit>
- <trans-unit id="_msg986">
- <source xml:space="preserve">Invalid amount for -fallbackfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <trans-unit id="_msg1004">
+ <source xml:space="preserve">Invalid amount for -discardfee=&lt;amount&gt;: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">180</context></context-group>
</trans-unit>
- <trans-unit id="_msg987">
- <source xml:space="preserve">Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
+ <trans-unit id="_msg1005">
+ <source xml:space="preserve">Invalid amount for -fallbackfee=&lt;amount&gt;: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">181</context></context-group>
</trans-unit>
- <trans-unit id="_msg988">
- <source xml:space="preserve">Invalid netmask specified in -whitelist: &apos;%s&apos;</source>
+ <trans-unit id="_msg1006">
+ <source xml:space="preserve">Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos; (must be at least %s)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">182</context></context-group>
</trans-unit>
- <trans-unit id="_msg989">
- <source xml:space="preserve">Loading P2P addresses…</source>
+ <trans-unit id="_msg1007">
+ <source xml:space="preserve">Invalid netmask specified in -whitelist: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">183</context></context-group>
</trans-unit>
- <trans-unit id="_msg990">
- <source xml:space="preserve">Loading banlist…</source>
+ <trans-unit id="_msg1008">
+ <source xml:space="preserve">Loading P2P addresses…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">184</context></context-group>
</trans-unit>
- <trans-unit id="_msg991">
- <source xml:space="preserve">Loading block index…</source>
+ <trans-unit id="_msg1009">
+ <source xml:space="preserve">Loading banlist…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">185</context></context-group>
</trans-unit>
- <trans-unit id="_msg992">
- <source xml:space="preserve">Loading wallet…</source>
+ <trans-unit id="_msg1010">
+ <source xml:space="preserve">Loading block index…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">186</context></context-group>
</trans-unit>
- <trans-unit id="_msg993">
- <source xml:space="preserve">Need to specify a port with -whitebind: &apos;%s&apos;</source>
+ <trans-unit id="_msg1011">
+ <source xml:space="preserve">Loading wallet…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">187</context></context-group>
</trans-unit>
- <trans-unit id="_msg994">
- <source xml:space="preserve">No proxy server specified. Use -proxy=&lt;ip&gt; or -proxy=&lt;ip:port&gt;.</source>
+ <trans-unit id="_msg1012">
+ <source xml:space="preserve">Need to specify a port with -whitebind: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">188</context></context-group>
</trans-unit>
- <trans-unit id="_msg995">
- <source xml:space="preserve">Not enough file descriptors available.</source>
+ <trans-unit id="_msg1013">
+ <source xml:space="preserve">No proxy server specified. Use -proxy=&lt;ip&gt; or -proxy=&lt;ip:port&gt;.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">189</context></context-group>
</trans-unit>
- <trans-unit id="_msg996">
- <source xml:space="preserve">Prune cannot be configured with a negative value.</source>
+ <trans-unit id="_msg1014">
+ <source xml:space="preserve">Not enough file descriptors available.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">190</context></context-group>
</trans-unit>
- <trans-unit id="_msg997">
- <source xml:space="preserve">Prune mode is incompatible with -coinstatsindex.</source>
+ <trans-unit id="_msg1015">
+ <source xml:space="preserve">Prune cannot be configured with a negative value.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">191</context></context-group>
</trans-unit>
- <trans-unit id="_msg998">
- <source xml:space="preserve">Prune mode is incompatible with -txindex.</source>
+ <trans-unit id="_msg1016">
+ <source xml:space="preserve">Prune mode is incompatible with -coinstatsindex.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">192</context></context-group>
</trans-unit>
- <trans-unit id="_msg999">
- <source xml:space="preserve">Pruning blockstore…</source>
+ <trans-unit id="_msg1017">
+ <source xml:space="preserve">Prune mode is incompatible with -txindex.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">193</context></context-group>
</trans-unit>
- <trans-unit id="_msg1000">
- <source xml:space="preserve">Reducing -maxconnections from %d to %d, because of system limitations.</source>
+ <trans-unit id="_msg1018">
+ <source xml:space="preserve">Pruning blockstore…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">194</context></context-group>
</trans-unit>
- <trans-unit id="_msg1001">
- <source xml:space="preserve">Replaying blocks…</source>
+ <trans-unit id="_msg1019">
+ <source xml:space="preserve">Reducing -maxconnections from %d to %d, because of system limitations.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">195</context></context-group>
</trans-unit>
- <trans-unit id="_msg1002">
- <source xml:space="preserve">Rescanning…</source>
+ <trans-unit id="_msg1020">
+ <source xml:space="preserve">Replaying blocks…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">196</context></context-group>
</trans-unit>
- <trans-unit id="_msg1003">
- <source xml:space="preserve">SQLiteDatabase: Failed to execute statement to verify database: %s</source>
+ <trans-unit id="_msg1021">
+ <source xml:space="preserve">Rescanning…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">197</context></context-group>
</trans-unit>
- <trans-unit id="_msg1004">
- <source xml:space="preserve">SQLiteDatabase: Failed to prepare statement to verify database: %s</source>
+ <trans-unit id="_msg1022">
+ <source xml:space="preserve">SQLiteDatabase: Failed to execute statement to verify database: %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">198</context></context-group>
</trans-unit>
- <trans-unit id="_msg1005">
- <source xml:space="preserve">SQLiteDatabase: Failed to read database verification error: %s</source>
+ <trans-unit id="_msg1023">
+ <source xml:space="preserve">SQLiteDatabase: Failed to prepare statement to verify database: %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">199</context></context-group>
</trans-unit>
- <trans-unit id="_msg1006">
- <source xml:space="preserve">SQLiteDatabase: Unexpected application id. Expected %u, got %u</source>
+ <trans-unit id="_msg1024">
+ <source xml:space="preserve">SQLiteDatabase: Failed to read database verification error: %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">200</context></context-group>
</trans-unit>
- <trans-unit id="_msg1007">
- <source xml:space="preserve">Section [%s] is not recognized.</source>
+ <trans-unit id="_msg1025">
+ <source xml:space="preserve">SQLiteDatabase: Unexpected application id. Expected %u, got %u</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">201</context></context-group>
</trans-unit>
- <trans-unit id="_msg1008">
- <source xml:space="preserve">Signing transaction failed</source>
+ <trans-unit id="_msg1026">
+ <source xml:space="preserve">Section [%s] is not recognized.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">202</context></context-group>
</trans-unit>
- <trans-unit id="_msg1009">
- <source xml:space="preserve">Specified -walletdir &quot;%s&quot; does not exist</source>
+ <trans-unit id="_msg1027">
+ <source xml:space="preserve">Signing transaction failed</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">203</context></context-group>
</trans-unit>
- <trans-unit id="_msg1010">
- <source xml:space="preserve">Specified -walletdir &quot;%s&quot; is a relative path</source>
+ <trans-unit id="_msg1028">
+ <source xml:space="preserve">Specified -walletdir &quot;%s&quot; does not exist</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">204</context></context-group>
</trans-unit>
- <trans-unit id="_msg1011">
- <source xml:space="preserve">Specified -walletdir &quot;%s&quot; is not a directory</source>
+ <trans-unit id="_msg1029">
+ <source xml:space="preserve">Specified -walletdir &quot;%s&quot; is a relative path</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">205</context></context-group>
</trans-unit>
- <trans-unit id="_msg1012">
- <source xml:space="preserve">Specified blocks directory &quot;%s&quot; does not exist.</source>
+ <trans-unit id="_msg1030">
+ <source xml:space="preserve">Specified -walletdir &quot;%s&quot; is not a directory</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">206</context></context-group>
</trans-unit>
- <trans-unit id="_msg1013">
- <source xml:space="preserve">Starting network threads…</source>
+ <trans-unit id="_msg1031">
+ <source xml:space="preserve">Specified blocks directory &quot;%s&quot; does not exist.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">207</context></context-group>
</trans-unit>
- <trans-unit id="_msg1014">
- <source xml:space="preserve">The source code is available from %s.</source>
+ <trans-unit id="_msg1032">
+ <source xml:space="preserve">Starting network threads…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">208</context></context-group>
</trans-unit>
- <trans-unit id="_msg1015">
- <source xml:space="preserve">The specified config file %s does not exist</source>
+ <trans-unit id="_msg1033">
+ <source xml:space="preserve">The source code is available from %s.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">209</context></context-group>
</trans-unit>
- <trans-unit id="_msg1016">
- <source xml:space="preserve">The transaction amount is too small to pay the fee</source>
+ <trans-unit id="_msg1034">
+ <source xml:space="preserve">The specified config file %s does not exist</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">210</context></context-group>
</trans-unit>
- <trans-unit id="_msg1017">
- <source xml:space="preserve">The wallet will avoid paying less than the minimum relay fee.</source>
+ <trans-unit id="_msg1035">
+ <source xml:space="preserve">The transaction amount is too small to pay the fee</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">211</context></context-group>
</trans-unit>
- <trans-unit id="_msg1018">
- <source xml:space="preserve">This is experimental software.</source>
+ <trans-unit id="_msg1036">
+ <source xml:space="preserve">The wallet will avoid paying less than the minimum relay fee.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">212</context></context-group>
</trans-unit>
- <trans-unit id="_msg1019">
- <source xml:space="preserve">This is the minimum transaction fee you pay on every transaction.</source>
+ <trans-unit id="_msg1037">
+ <source xml:space="preserve">This is experimental software.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">213</context></context-group>
</trans-unit>
- <trans-unit id="_msg1020">
- <source xml:space="preserve">This is the transaction fee you will pay if you send a transaction.</source>
+ <trans-unit id="_msg1038">
+ <source xml:space="preserve">This is the minimum transaction fee you pay on every transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">214</context></context-group>
</trans-unit>
- <trans-unit id="_msg1021">
- <source xml:space="preserve">Transaction amount too small</source>
+ <trans-unit id="_msg1039">
+ <source xml:space="preserve">This is the transaction fee you will pay if you send a transaction.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">215</context></context-group>
</trans-unit>
- <trans-unit id="_msg1022">
- <source xml:space="preserve">Transaction amounts must not be negative</source>
+ <trans-unit id="_msg1040">
+ <source xml:space="preserve">Transaction amount too small</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">216</context></context-group>
</trans-unit>
- <trans-unit id="_msg1023">
- <source xml:space="preserve">Transaction has too long of a mempool chain</source>
+ <trans-unit id="_msg1041">
+ <source xml:space="preserve">Transaction amounts must not be negative</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">217</context></context-group>
</trans-unit>
- <trans-unit id="_msg1024">
- <source xml:space="preserve">Transaction must have at least one recipient</source>
+ <trans-unit id="_msg1042">
+ <source xml:space="preserve">Transaction has too long of a mempool chain</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">218</context></context-group>
</trans-unit>
- <trans-unit id="_msg1025">
- <source xml:space="preserve">Transaction too large</source>
+ <trans-unit id="_msg1043">
+ <source xml:space="preserve">Transaction must have at least one recipient</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">219</context></context-group>
</trans-unit>
- <trans-unit id="_msg1026">
- <source xml:space="preserve">Unable to bind to %s on this computer (bind returned error %s)</source>
+ <trans-unit id="_msg1044">
+ <source xml:space="preserve">Transaction needs a change address, but we can&apos;t generate it. %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">220</context></context-group>
</trans-unit>
- <trans-unit id="_msg1027">
- <source xml:space="preserve">Unable to bind to %s on this computer. %s is probably already running.</source>
+ <trans-unit id="_msg1045">
+ <source xml:space="preserve">Transaction too large</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">221</context></context-group>
</trans-unit>
- <trans-unit id="_msg1028">
- <source xml:space="preserve">Unable to create the PID file &apos;%s&apos;: %s</source>
+ <trans-unit id="_msg1046">
+ <source xml:space="preserve">Unable to bind to %s on this computer (bind returned error %s)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">222</context></context-group>
</trans-unit>
- <trans-unit id="_msg1029">
- <source xml:space="preserve">Unable to generate initial keys</source>
+ <trans-unit id="_msg1047">
+ <source xml:space="preserve">Unable to bind to %s on this computer. %s is probably already running.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">223</context></context-group>
</trans-unit>
- <trans-unit id="_msg1030">
- <source xml:space="preserve">Unable to generate keys</source>
+ <trans-unit id="_msg1048">
+ <source xml:space="preserve">Unable to create the PID file &apos;%s&apos;: %s</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">224</context></context-group>
</trans-unit>
- <trans-unit id="_msg1031">
- <source xml:space="preserve">Unable to open %s for writing</source>
+ <trans-unit id="_msg1049">
+ <source xml:space="preserve">Unable to generate initial keys</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">225</context></context-group>
</trans-unit>
- <trans-unit id="_msg1032">
- <source xml:space="preserve">Unable to start HTTP server. See debug log for details.</source>
+ <trans-unit id="_msg1050">
+ <source xml:space="preserve">Unable to generate keys</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">226</context></context-group>
</trans-unit>
- <trans-unit id="_msg1033">
- <source xml:space="preserve">Unknown -blockfilterindex value %s.</source>
+ <trans-unit id="_msg1051">
+ <source xml:space="preserve">Unable to open %s for writing</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">227</context></context-group>
</trans-unit>
- <trans-unit id="_msg1034">
- <source xml:space="preserve">Unknown address type &apos;%s&apos;</source>
+ <trans-unit id="_msg1052">
+ <source xml:space="preserve">Unable to start HTTP server. See debug log for details.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">228</context></context-group>
</trans-unit>
- <trans-unit id="_msg1035">
- <source xml:space="preserve">Unknown change type &apos;%s&apos;</source>
+ <trans-unit id="_msg1053">
+ <source xml:space="preserve">Unknown -blockfilterindex value %s.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">229</context></context-group>
</trans-unit>
- <trans-unit id="_msg1036">
- <source xml:space="preserve">Unknown network specified in -onlynet: &apos;%s&apos;</source>
+ <trans-unit id="_msg1054">
+ <source xml:space="preserve">Unknown address type &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">230</context></context-group>
</trans-unit>
- <trans-unit id="_msg1037">
- <source xml:space="preserve">Unsupported logging category %s=%s.</source>
+ <trans-unit id="_msg1055">
+ <source xml:space="preserve">Unknown change type &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">231</context></context-group>
</trans-unit>
- <trans-unit id="_msg1038">
- <source xml:space="preserve">Upgrading UTXO database</source>
+ <trans-unit id="_msg1056">
+ <source xml:space="preserve">Unknown network specified in -onlynet: &apos;%s&apos;</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">232</context></context-group>
</trans-unit>
- <trans-unit id="_msg1039">
- <source xml:space="preserve">Upgrading txindex database</source>
+ <trans-unit id="_msg1057">
+ <source xml:space="preserve">Unknown new rules activated (versionbit %i)</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">233</context></context-group>
</trans-unit>
- <trans-unit id="_msg1040">
- <source xml:space="preserve">User Agent comment (%s) contains unsafe characters.</source>
+ <trans-unit id="_msg1058">
+ <source xml:space="preserve">Unsupported logging category %s=%s.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">234</context></context-group>
</trans-unit>
- <trans-unit id="_msg1041">
- <source xml:space="preserve">Verifying blocks…</source>
+ <trans-unit id="_msg1059">
+ <source xml:space="preserve">Upgrading UTXO database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">235</context></context-group>
</trans-unit>
- <trans-unit id="_msg1042">
- <source xml:space="preserve">Verifying wallet(s)…</source>
+ <trans-unit id="_msg1060">
+ <source xml:space="preserve">Upgrading txindex database</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">236</context></context-group>
</trans-unit>
- <trans-unit id="_msg1043">
- <source xml:space="preserve">Wallet needed to be rewritten: restart %s to complete</source>
+ <trans-unit id="_msg1061">
+ <source xml:space="preserve">User Agent comment (%s) contains unsafe characters.</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">237</context></context-group>
</trans-unit>
- <trans-unit id="_msg1044">
- <source xml:space="preserve">Warning: unknown new rules activated (versionbit %i)</source>
+ <trans-unit id="_msg1062">
+ <source xml:space="preserve">Verifying blocks…</source>
<target xml:space="preserve"></target>
<context-group purpose="location"><context context-type="linenumber">238</context></context-group>
</trans-unit>
+ <trans-unit id="_msg1063">
+ <source xml:space="preserve">Verifying wallet(s)…</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">239</context></context-group>
+ </trans-unit>
+ <trans-unit id="_msg1064">
+ <source xml:space="preserve">Wallet needed to be rewritten: restart %s to complete</source>
+ <target xml:space="preserve"></target>
+ <context-group purpose="location"><context context-type="linenumber">240</context></context-group>
+ </trans-unit>
</group>
</body></file>
</xliff>
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 26e3dd0d60..864a62edc8 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -69,20 +69,18 @@ public:
foreground = brush.color();
}
- painter->setPen(foreground);
- QRect boundingRect;
- painter->drawText(addressRect, Qt::AlignLeft | Qt::AlignVCenter, address, &boundingRect);
- int address_rect_min_width = boundingRect.width();
-
- if (index.data(TransactionTableModel::WatchonlyRole).toBool())
- {
+ if (index.data(TransactionTableModel::WatchonlyRole).toBool()) {
QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
- QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
+ QRect watchonlyRect(addressRect.left(), addressRect.top(), 16, addressRect.height());
iconWatchonly = platformStyle->TextColorIcon(iconWatchonly);
iconWatchonly.paint(painter, watchonlyRect);
- address_rect_min_width += 5 + watchonlyRect.width();
+ addressRect.setLeft(addressRect.left() + watchonlyRect.width() + 5);
}
+ painter->setPen(foreground);
+ QRect boundingRect;
+ painter->drawText(addressRect, Qt::AlignLeft | Qt::AlignVCenter, address, &boundingRect);
+
if(amount < 0)
{
foreground = COLOR_NEGATIVE;
@@ -109,7 +107,8 @@ public:
QRect date_bounding_rect;
painter->drawText(amountRect, Qt::AlignLeft | Qt::AlignVCenter, GUIUtil::dateTimeStr(date), &date_bounding_rect);
- const int minimum_width = std::max(address_rect_min_width, amount_bounding_rect.width() + date_bounding_rect.width());
+ // 0.4*date_bounding_rect.width() is used to visually distinguish a date from an amount.
+ const int minimum_width = 1.4 * date_bounding_rect.width() + amount_bounding_rect.width();
const auto search = m_minimum_width.find(index.row());
if (search == m_minimum_width.end() || search->second != minimum_width) {
m_minimum_width[index.row()] = minimum_width;
@@ -297,13 +296,13 @@ void OverviewPage::setWalletModel(WalletModel *model)
void OverviewPage::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
QIcon icon = m_platform_style->SingleColorIcon(QStringLiteral(":/icons/warning"));
ui->labelTransactionsStatus->setIcon(icon);
ui->labelWalletStatus->setIcon(icon);
}
-#endif
+
+ QWidget::changeEvent(e);
}
void OverviewPage::updateDisplayUnit()
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index b324693692..1b7fda6e77 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -179,5 +179,7 @@ void PeerTableModel::refresh()
m_peers_data.swap(new_peers_data);
}
- Q_EMIT changed();
+ const auto top_left = index(0, 0);
+ const auto bottom_right = index(rowCount() - 1, columnCount() - 1);
+ Q_EMIT dataChanged(top_left, bottom_right);
}
diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h
index 0ff1b5dba7..0d841ebf28 100644
--- a/src/qt/peertablemodel.h
+++ b/src/qt/peertablemodel.h
@@ -73,9 +73,6 @@ public:
public Q_SLOTS:
void refresh();
-Q_SIGNALS:
- void changed();
-
private:
//! Internal peer data structure.
QList<CNodeCombinedStats> m_peers_data{};
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index ff4bfb16f6..9c57816f91 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -35,6 +35,7 @@
#endif
#include <QAbstractButton>
+#include <QAbstractItemModel>
#include <QDateTime>
#include <QFont>
#include <QKeyEvent>
@@ -529,6 +530,8 @@ RPCConsole::RPCConsole(interfaces::Node& node, const PlatformStyle *_platformSty
//: Secondary shortcut to decrease the RPC console font size.
GUIUtil::AddButtonShortcut(ui->fontSmallerButton, tr("Ctrl+_"));
+ ui->promptIcon->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/prompticon")));
+
// Install event filter for up and down arrow
ui->lineEdit->installEventFilter(this);
ui->lineEdit->setMaxLength(16 * 1024 * 1024);
@@ -684,7 +687,7 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
// peer table signal handling - update peer details when selecting new node
connect(ui->peerWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RPCConsole::updateDetailWidget);
- connect(model->getPeerTableModel(), &PeerTableModel::changed, this, &RPCConsole::updateDetailWidget);
+ connect(model->getPeerTableModel(), &QAbstractItemModel::dataChanged, [this] { updateDetailWidget(); });
// set up ban table
ui->banlistWidget->setModel(model->getBanTableModel());
@@ -882,7 +885,6 @@ void RPCConsole::keyPressEvent(QKeyEvent *event)
void RPCConsole::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
ui->clearButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
ui->fontBiggerButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/fontbigger")));
@@ -896,7 +898,8 @@ void RPCConsole::changeEvent(QEvent* e)
platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(QSize(consoleFontSize * 2, consoleFontSize * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
}
-#endif
+
+ QWidget::changeEvent(e);
}
void RPCConsole::message(int category, const QString &message, bool html)
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index f701bb9615..683c0441fa 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -238,7 +238,6 @@ void SendCoinsEntry::updateDisplayUnit()
void SendCoinsEntry::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
ui->pasteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editpaste")));
@@ -246,7 +245,8 @@ void SendCoinsEntry::changeEvent(QEvent* e)
ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
}
-#endif
+
+ QStackedWidget::changeEvent(e);
}
bool SendCoinsEntry::updateLabel(const QString &address)
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index b982cc577d..33589f09bf 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -286,7 +286,6 @@ bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
void SignVerifyMessageDialog::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
ui->addressBookButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
ui->pasteButton_SM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editpaste")));
@@ -297,5 +296,6 @@ void SignVerifyMessageDialog::changeEvent(QEvent* e)
ui->verifyMessageButton_VM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/transaction_0")));
ui->clearButton_VM->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
}
-#endif
+
+ QDialog::changeEvent(e);
}
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index 3e1a0e0fa9..e883337fb5 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -69,7 +69,7 @@ uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDe
->findChild<QCheckBox*>("optInRBF")
->setCheckState(rbf ? Qt::Checked : Qt::Unchecked);
uint256 txid;
- boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](CWallet*, const uint256& hash, ChangeType status) {
+ boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const uint256& hash, ChangeType status) {
if (status == CT_NEW) txid = hash;
}));
ConfirmSend();
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 4b1a546c7c..83d17a32c0 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -245,7 +245,6 @@ void TransactionView::setModel(WalletModel *_model)
void TransactionView::changeEvent(QEvent* e)
{
-#ifdef Q_OS_MACOS
if (e->type() == QEvent::PaletteChange) {
watchOnlyWidget->setItemIcon(
TransactionFilterProxy::WatchOnlyFilter_Yes,
@@ -254,7 +253,8 @@ void TransactionView::changeEvent(QEvent* e)
TransactionFilterProxy::WatchOnlyFilter_No,
m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_minus")));
}
-#endif
+
+ QWidget::changeEvent(e);
}
void TransactionView::chooseDate(int idx)
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 4d4d3fb7d0..b630458f23 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -10,8 +10,11 @@
#include <chain.h>
#include <chainparams.h>
#include <coins.h>
+#include <consensus/params.h>
#include <consensus/validation.h>
#include <core_io.h>
+#include <deploymentinfo.h>
+#include <deploymentstatus.h>
#include <hash.h>
#include <index/blockfilterindex.h>
#include <index/coinstatsindex.h>
@@ -37,6 +40,7 @@
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
+#include <versionbits.h>
#include <warnings.h>
#include <stdint.h>
@@ -1343,32 +1347,32 @@ static RPCHelpMan verifychain()
};
}
-static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int softfork_height, int tip_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{
// For buried deployments.
// A buried deployment is one where the height of the activation has been hardcoded into
// the client implementation long after the consensus change has activated. See BIP 90.
// Buried deployments with activation height value of
// std::numeric_limits<int>::max() are disabled and thus hidden.
- if (softfork_height == std::numeric_limits<int>::max()) return;
+ if (!DeploymentEnabled(params, dep)) return;
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried");
// getblockchaininfo reports the softfork as active from when the chain height is
// one below the activation height
- rv.pushKV("active", tip_height + 1 >= softfork_height);
- rv.pushKV("height", softfork_height);
- softforks.pushKV(name, rv);
+ rv.pushKV("active", DeploymentActiveAfter(active_chain_tip, params, dep));
+ rv.pushKV("height", params.DeploymentHeight(dep));
+ softforks.pushKV(DeploymentName(dep), rv);
}
-static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
{
// For BIP9 deployments.
// Deployments that are never active are hidden.
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
UniValue bip9(UniValue::VOBJ);
- const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, versionbitscache);
+ const ThresholdState thresholdState = g_versionbitscache.State(active_chain_tip, consensusParams, id);
switch (thresholdState) {
case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); break;
case ThresholdState::STARTED: bip9.pushKV("status", "started"); break;
@@ -1382,12 +1386,12 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniVal
}
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
- int64_t since_height = VersionBitsStateSinceHeight(active_chain_tip, consensusParams, id, versionbitscache);
+ int64_t since_height = g_versionbitscache.StateSinceHeight(active_chain_tip, consensusParams, id);
bip9.pushKV("since", since_height);
if (ThresholdState::STARTED == thresholdState)
{
UniValue statsUV(UniValue::VOBJ);
- BIP9Stats statsStruct = VersionBitsStatistics(active_chain_tip, consensusParams, id);
+ BIP9Stats statsStruct = g_versionbitscache.Statistics(active_chain_tip, consensusParams, id);
statsUV.pushKV("period", statsStruct.period);
statsUV.pushKV("threshold", statsStruct.threshold);
statsUV.pushKV("elapsed", statsStruct.elapsed);
@@ -1405,7 +1409,7 @@ static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniVal
}
rv.pushKV("active", ThresholdState::ACTIVE == thresholdState);
- softforks.pushKV(name, rv);
+ softforks.pushKV(DeploymentName(id), rv);
}
RPCHelpMan getblockchaininfo()
@@ -1502,14 +1506,14 @@ RPCHelpMan getblockchaininfo()
const Consensus::Params& consensusParams = Params().GetConsensus();
UniValue softforks(UniValue::VOBJ);
- BuriedForkDescPushBack(softforks, "bip34", consensusParams.BIP34Height, height);
- BuriedForkDescPushBack(softforks, "bip66", consensusParams.BIP66Height, height);
- BuriedForkDescPushBack(softforks, "bip65", consensusParams.BIP65Height, height);
- BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight, height);
- BuriedForkDescPushBack(softforks, "segwit", consensusParams.SegwitHeight, height);
- BIP9SoftForkDescPushBack(tip, softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
- BIP9SoftForkDescPushBack(tip, softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
- obj.pushKV("softforks", softforks);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_DERSIG);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CLTV);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_CSV);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
+ SoftForkDescPushBack(tip, softforks, consensusParams, Consensus::DEPLOYMENT_TAPROOT);
+ obj.pushKV("softforks", softforks);
obj.pushKV("warnings", GetWarnings(false).original);
return obj;
@@ -1706,7 +1710,7 @@ static RPCHelpMan preciousblock()
}
BlockValidationState state;
- chainman.ActiveChainstate().PreciousBlock(state, Params(), pblockindex);
+ chainman.ActiveChainstate().PreciousBlock(state, pblockindex);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -1743,10 +1747,10 @@ static RPCHelpMan invalidateblock()
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
- chainman.ActiveChainstate().InvalidateBlock(state, Params(), pblockindex);
+ chainman.ActiveChainstate().InvalidateBlock(state, pblockindex);
if (state.IsValid()) {
- chainman.ActiveChainstate().ActivateBestChain(state, Params());
+ chainman.ActiveChainstate().ActivateBestChain(state);
}
if (!state.IsValid()) {
@@ -1787,7 +1791,7 @@ static RPCHelpMan reconsiderblock()
}
BlockValidationState state;
- chainman.ActiveChainstate().ActivateBestChain(state, Params());
+ chainman.ActiveChainstate().ActivateBestChain(state);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -2258,6 +2262,7 @@ public:
if (g_scan_in_progress.exchange(true)) {
return false;
}
+ CHECK_NONFATAL(g_scan_progress == 0);
m_could_reserve = true;
return true;
}
@@ -2265,6 +2270,7 @@ public:
~CoinsViewScanReserver() {
if (m_could_reserve) {
g_scan_in_progress = false;
+ g_scan_progress = 0;
}
}
};
@@ -2381,7 +2387,6 @@ static RPCHelpMan scantxoutset()
std::vector<CTxOut> input_txos;
std::map<COutPoint, Coin> coins;
g_should_abort_scan = false;
- g_scan_progress = 0;
int64_t count = 0;
std::unique_ptr<CCoinsViewCursor> pcursor;
CBlockIndex* tip;
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 327f961196..2762d78493 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -10,6 +10,8 @@
#include <consensus/params.h>
#include <consensus/validation.h>
#include <core_io.h>
+#include <deploymentinfo.h>
+#include <deploymentstatus.h>
#include <key_io.h>
#include <miner.h>
#include <net.h>
@@ -34,7 +36,6 @@
#include <util/translation.h>
#include <validation.h>
#include <validationinterface.h>
-#include <versionbitsinfo.h>
#include <warnings.h>
#include <memory>
@@ -774,7 +775,7 @@ static RPCHelpMan getblocktemplate()
pblock->nNonce = 0;
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
- const bool fPreSegWit = (pindexPrev->nHeight + 1 < consensusParams.SegwitHeight);
+ const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT);
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
@@ -840,7 +841,7 @@ static RPCHelpMan getblocktemplate()
UniValue vbavailable(UniValue::VOBJ);
for (int j = 0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
Consensus::DeploymentPos pos = Consensus::DeploymentPos(j);
- ThresholdState state = VersionBitsState(pindexPrev, consensusParams, pos, versionbitscache);
+ ThresholdState state = g_versionbitscache.State(pindexPrev, consensusParams, pos);
switch (state) {
case ThresholdState::DEFINED:
case ThresholdState::FAILED:
@@ -848,7 +849,7 @@ static RPCHelpMan getblocktemplate()
break;
case ThresholdState::LOCKED_IN:
// Ensure bit is set in block version
- pblock->nVersion |= VersionBitsMask(consensusParams, pos);
+ pblock->nVersion |= g_versionbitscache.Mask(consensusParams, pos);
// FALL THROUGH to get vbavailable set...
case ThresholdState::STARTED:
{
@@ -857,7 +858,7 @@ static RPCHelpMan getblocktemplate()
if (setClientRules.find(vbinfo.name) == setClientRules.end()) {
if (!vbinfo.gbt_force) {
// If the client doesn't support this, don't indicate it in the [default] version
- pblock->nVersion &= ~VersionBitsMask(consensusParams, pos);
+ pblock->nVersion &= ~g_versionbitscache.Mask(consensusParams, pos);
}
}
break;
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
index ab239fe79c..5178ce60e8 100644
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -131,6 +131,9 @@ static RPCHelpMan createmultisig()
if (!ParseOutputType(request.params[2].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
}
+ if (output_type == OutputType::BECH32M) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
+ }
}
// Construct using pay-to-script-hash:
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index be97a618f3..682b55742a 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -166,7 +166,7 @@ public:
* write_cache is the cache to write keys to (if not nullptr)
* Caches are not exclusive but this is not tested. Currently we use them exclusively
*/
- virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) = 0;
+ virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const = 0;
/** Whether this represent multiple public keys at different positions. */
virtual bool IsRange() const = 0;
@@ -181,7 +181,7 @@ public:
virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
/** Get the descriptor string form with the xpub at the last hardened derivation */
- virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, bool priv) const = 0;
+ virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
/** Derive a private key, if private data is available in arg. */
virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
@@ -199,7 +199,7 @@ class OriginPubkeyProvider final : public PubkeyProvider
public:
OriginPubkeyProvider(uint32_t exp_index, KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(provider)) {}
- bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
+ bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
{
if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache)) return false;
std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.fingerprint);
@@ -216,10 +216,10 @@ public:
ret = "[" + OriginString() + "]" + std::move(sub);
return true;
}
- bool ToNormalizedString(const SigningProvider& arg, std::string& ret, bool priv) const override
+ bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
{
std::string sub;
- if (!m_provider->ToNormalizedString(arg, sub, priv)) return false;
+ if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
// If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
// In that case, we need to strip out the leading square bracket and fingerprint from the substring,
// and append that to our own origin string.
@@ -245,7 +245,7 @@ class ConstPubkeyProvider final : public PubkeyProvider
public:
ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey, bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
- bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
+ bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
{
key = m_pubkey;
info.path.clear();
@@ -263,9 +263,8 @@ public:
ret = EncodeSecret(key);
return true;
}
- bool ToNormalizedString(const SigningProvider& arg, std::string& ret, bool priv) const override
+ bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
{
- if (priv) return ToPrivateString(arg, ret);
ret = ToString();
return true;
}
@@ -288,9 +287,6 @@ class BIP32PubkeyProvider final : public PubkeyProvider
CExtPubKey m_root_extkey;
KeyPath m_path;
DeriveType m_derive;
- // Cache of the parent of the final derived pubkeys.
- // Primarily useful for situations when no read_cache is provided
- CExtPubKey m_cached_xpub;
bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
{
@@ -305,11 +301,14 @@ class BIP32PubkeyProvider final : public PubkeyProvider
}
// Derives the last xprv
- bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv) const
+ bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened) const
{
if (!GetExtKey(arg, xprv)) return false;
for (auto entry : m_path) {
xprv.Derive(xprv, entry);
+ if (entry >> 31) {
+ last_hardened = xprv;
+ }
}
return true;
}
@@ -327,7 +326,7 @@ public:
BIP32PubkeyProvider(uint32_t exp_index, const CExtPubKey& extkey, KeyPath path, DeriveType derive) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive) {}
bool IsRange() const override { return m_derive != DeriveType::NO; }
size_t GetSize() const override { return 33; }
- bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) override
+ bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
{
// Info of parent of the to be derived pubkey
KeyOriginInfo parent_info;
@@ -343,6 +342,7 @@ public:
// Derive keys or fetch them from cache
CExtPubKey final_extkey = m_root_extkey;
CExtPubKey parent_extkey = m_root_extkey;
+ CExtPubKey last_hardened_extkey;
bool der = true;
if (read_cache) {
if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
@@ -352,16 +352,17 @@ public:
final_extkey = parent_extkey;
if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
}
- } else if (m_cached_xpub.pubkey.IsValid() && m_derive != DeriveType::HARDENED) {
- parent_extkey = final_extkey = m_cached_xpub;
- if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
} else if (IsHardened()) {
CExtKey xprv;
- if (!GetDerivedExtKey(arg, xprv)) return false;
+ CExtKey lh_xprv;
+ if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
parent_extkey = xprv.Neuter();
if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
final_extkey = xprv.Neuter();
+ if (lh_xprv.key.IsValid()) {
+ last_hardened_extkey = lh_xprv.Neuter();
+ }
} else {
for (auto entry : m_path) {
der = parent_extkey.Derive(parent_extkey, entry);
@@ -376,15 +377,14 @@ public:
final_info_out = final_info_out_tmp;
key_out = final_extkey.pubkey;
- // We rely on the consumer to check that m_derive isn't HARDENED as above
- // But we can't have already cached something in case we read something from the cache
- // and parent_extkey isn't actually the parent.
- if (!m_cached_xpub.pubkey.IsValid()) m_cached_xpub = parent_extkey;
-
if (write_cache) {
// Only cache parent if there is any unhardened derivation
if (m_derive != DeriveType::HARDENED) {
write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
+ // Cache last hardened xpub if we have it
+ if (last_hardened_extkey.pubkey.IsValid()) {
+ write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
+ }
} else if (final_info_out.path.size() > 0) {
write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
}
@@ -412,11 +412,10 @@ public:
}
return true;
}
- bool ToNormalizedString(const SigningProvider& arg, std::string& out, bool priv) const override
+ bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override
{
// For hardened derivation type, just return the typical string, nothing to normalize
if (m_derive == DeriveType::HARDENED) {
- if (priv) return ToPrivateString(arg, out);
out = ToString();
return true;
}
@@ -429,33 +428,42 @@ public:
}
// Either no derivation or all unhardened derivation
if (i == -1) {
- if (priv) return ToPrivateString(arg, out);
out = ToString();
return true;
}
- // Derive the xpub at the last hardened step
- CExtKey xprv;
- if (!GetExtKey(arg, xprv)) return false;
+ // Get the path to the last hardened stup
KeyOriginInfo origin;
int k = 0;
for (; k <= i; ++k) {
- // Derive
- xprv.Derive(xprv, m_path.at(k));
// Add to the path
origin.path.push_back(m_path.at(k));
- // First derivation element, get the fingerprint for origin
- if (k == 0) {
- std::copy(xprv.vchFingerprint, xprv.vchFingerprint + 4, origin.fingerprint);
- }
}
// Build the remaining path
KeyPath end_path;
for (; k < (int)m_path.size(); ++k) {
end_path.push_back(m_path.at(k));
}
+ // Get the fingerprint
+ CKeyID id = m_root_extkey.pubkey.GetID();
+ std::copy(id.begin(), id.begin() + 4, origin.fingerprint);
+
+ CExtPubKey xpub;
+ CExtKey lh_xprv;
+ // If we have the cache, just get the parent xpub
+ if (cache != nullptr) {
+ cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
+ }
+ if (!xpub.pubkey.IsValid()) {
+ // Cache miss, or nor cache, or need privkey
+ CExtKey xprv;
+ if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
+ xpub = lh_xprv.Neuter();
+ }
+ assert(xpub.pubkey.IsValid());
+
// Build the string
std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
- out = "[" + origin_str + "]" + (priv ? EncodeExtKey(xprv) : EncodeExtPubKey(xprv.Neuter())) + FormatHDKeypath(end_path);
+ out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path);
if (IsRange()) {
out += "/*";
assert(m_derive == DeriveType::UNHARDENED);
@@ -465,7 +473,8 @@ public:
bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
{
CExtKey extkey;
- if (!GetDerivedExtKey(arg, extkey)) return false;
+ CExtKey dummy;
+ if (!GetDerivedExtKey(arg, extkey, dummy)) return false;
if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL);
key = extkey.key;
@@ -508,6 +517,13 @@ public:
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(Vector(std::move(script))) {}
DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(std::move(scripts)) {}
+ enum class StringType
+ {
+ PUBLIC,
+ PRIVATE,
+ NORMALIZED,
+ };
+
bool IsSolvable() const override
{
for (const auto& arg : m_subdescriptor_args) {
@@ -527,19 +543,19 @@ public:
return false;
}
- virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, bool priv, bool normalized) const
+ virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
{
size_t pos = 0;
for (const auto& scriptarg : m_subdescriptor_args) {
if (pos++) ret += ",";
std::string tmp;
- if (!scriptarg->ToStringHelper(arg, tmp, priv, normalized)) return false;
+ if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false;
ret += std::move(tmp);
}
return true;
}
- bool ToStringHelper(const SigningProvider* arg, std::string& out, bool priv, bool normalized) const
+ bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
{
std::string extra = ToStringExtra();
size_t pos = extra.size() > 0 ? 1 : 0;
@@ -547,17 +563,21 @@ public:
for (const auto& pubkey : m_pubkey_args) {
if (pos++) ret += ",";
std::string tmp;
- if (normalized) {
- if (!pubkey->ToNormalizedString(*arg, tmp, priv)) return false;
- } else if (priv) {
- if (!pubkey->ToPrivateString(*arg, tmp)) return false;
- } else {
- tmp = pubkey->ToString();
+ switch (type) {
+ case StringType::NORMALIZED:
+ if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
+ break;
+ case StringType::PRIVATE:
+ if (!pubkey->ToPrivateString(*arg, tmp)) return false;
+ break;
+ case StringType::PUBLIC:
+ tmp = pubkey->ToString();
+ break;
}
ret += std::move(tmp);
}
std::string subscript;
- if (!ToStringSubScriptHelper(arg, subscript, priv, normalized)) return false;
+ if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false;
if (pos && subscript.size()) ret += ',';
out = std::move(ret) + std::move(subscript) + ")";
return true;
@@ -566,20 +586,20 @@ public:
std::string ToString() const final
{
std::string ret;
- ToStringHelper(nullptr, ret, false, false);
+ ToStringHelper(nullptr, ret, StringType::PUBLIC);
return AddChecksum(ret);
}
bool ToPrivateString(const SigningProvider& arg, std::string& out) const final
{
- bool ret = ToStringHelper(&arg, out, true, false);
+ bool ret = ToStringHelper(&arg, out, StringType::PRIVATE);
out = AddChecksum(out);
return ret;
}
- bool ToNormalizedString(const SigningProvider& arg, std::string& out, bool priv) const override final
+ bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
{
- bool ret = ToStringHelper(&arg, out, priv, true);
+ bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
out = AddChecksum(out);
return ret;
}
@@ -640,20 +660,6 @@ public:
std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
};
-static std::optional<OutputType> OutputTypeFromDestination(const CTxDestination& dest) {
- if (std::holds_alternative<PKHash>(dest) ||
- std::holds_alternative<ScriptHash>(dest)) {
- return OutputType::LEGACY;
- }
- if (std::holds_alternative<WitnessV0KeyHash>(dest) ||
- std::holds_alternative<WitnessV0ScriptHash>(dest) ||
- std::holds_alternative<WitnessV1Taproot>(dest) ||
- std::holds_alternative<WitnessUnknown>(dest)) {
- return OutputType::BECH32;
- }
- return std::nullopt;
-}
-
/** A parsed addr(A) descriptor. */
class AddressDescriptor final : public DescriptorImpl
{
@@ -847,7 +853,7 @@ protected:
out.tr_spenddata[output].Merge(builder.GetSpendData());
return Vector(GetScriptForDestination(output));
}
- bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, bool priv, bool normalized) const override
+ bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const override
{
if (m_depths.empty()) return true;
std::vector<bool> path;
@@ -858,7 +864,7 @@ protected:
path.push_back(false);
}
std::string tmp;
- if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, priv, normalized)) return false;
+ if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)) return false;
ret += std::move(tmp);
while (!path.empty() && path.back()) {
if (path.size() > 1) ret += '}';
@@ -874,7 +880,7 @@ public:
{
assert(m_subdescriptor_args.size() == m_depths.size());
}
- std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
+ std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
bool IsSingleType() const final { return true; }
};
@@ -1425,6 +1431,11 @@ void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_i
xpubs[der_index] = xpub;
}
+void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
+{
+ m_last_hardened_xpubs[key_exp_pos] = xpub;
+}
+
bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
{
const auto& it = m_parent_xpubs.find(key_exp_pos);
@@ -1443,6 +1454,55 @@ bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t d
return true;
}
+bool DescriptorCache::GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
+{
+ const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
+ if (it == m_last_hardened_xpubs.end()) return false;
+ xpub = it->second;
+ return true;
+}
+
+DescriptorCache DescriptorCache::MergeAndDiff(const DescriptorCache& other)
+{
+ DescriptorCache diff;
+ for (const auto& parent_xpub_pair : other.GetCachedParentExtPubKeys()) {
+ CExtPubKey xpub;
+ if (GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
+ if (xpub != parent_xpub_pair.second) {
+ throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
+ }
+ continue;
+ }
+ CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
+ diff.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
+ }
+ for (const auto& derived_xpub_map_pair : other.GetCachedDerivedExtPubKeys()) {
+ for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
+ CExtPubKey xpub;
+ if (GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
+ if (xpub != derived_xpub_pair.second) {
+ throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
+ }
+ continue;
+ }
+ CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
+ diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
+ }
+ }
+ for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
+ CExtPubKey xpub;
+ if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
+ if (xpub != lh_xpub_pair.second) {
+ throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
+ }
+ continue;
+ }
+ CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
+ diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
+ }
+ return diff;
+}
+
const ExtPubKeyMap DescriptorCache::GetCachedParentExtPubKeys() const
{
return m_parent_xpubs;
@@ -1452,3 +1512,8 @@ const std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDeriv
{
return m_derived_xpubs;
}
+
+const ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const
+{
+ return m_last_hardened_xpubs;
+}
diff --git a/src/script/descriptor.h b/src/script/descriptor.h
index 332ae2f230..ecd7c4eea5 100644
--- a/src/script/descriptor.h
+++ b/src/script/descriptor.h
@@ -22,6 +22,8 @@ private:
std::unordered_map<uint32_t, ExtPubKeyMap> m_derived_xpubs;
/** Map key expression index -> parent xpub */
ExtPubKeyMap m_parent_xpubs;
+ /** Map key expression index -> last hardened xpub */
+ ExtPubKeyMap m_last_hardened_xpubs;
public:
/** Cache a parent xpub
@@ -50,11 +52,30 @@ public:
* @param[in] xpub The CExtPubKey to get from cache
*/
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const;
+ /** Cache a last hardened xpub
+ *
+ * @param[in] key_exp_pos Position of the key expression within the descriptor
+ * @param[in] xpub The CExtPubKey to cache
+ */
+ void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub);
+ /** Retrieve a cached last hardened xpub
+ *
+ * @param[in] key_exp_pos Position of the key expression within the descriptor
+ * @param[in] xpub The CExtPubKey to get from cache
+ */
+ bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const;
/** Retrieve all cached parent xpubs */
const ExtPubKeyMap GetCachedParentExtPubKeys() const;
/** Retrieve all cached derived xpubs */
const std::unordered_map<uint32_t, ExtPubKeyMap> GetCachedDerivedExtPubKeys() const;
+ /** Retrieve all cached last hardened xpubs */
+ const ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const;
+
+ /** Combine another DescriptorCache into this one.
+ * Returns a cache containing the items from the other cache unknown to current cache
+ */
+ DescriptorCache MergeAndDiff(const DescriptorCache& other);
};
/** \brief Interface for parsed descriptor objects.
@@ -94,7 +115,7 @@ struct Descriptor {
virtual bool ToPrivateString(const SigningProvider& provider, std::string& out) const = 0;
/** Convert the descriptor to a normalized string. Normalized descriptors have the xpub at the last hardened step. This fails if the provided provider does not have the private keys to derive that xpub. */
- virtual bool ToNormalizedString(const SigningProvider& provider, std::string& out, bool priv) const = 0;
+ virtual bool ToNormalizedString(const SigningProvider& provider, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
/** Expand a descriptor at a specified position.
*
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 8cebbc5d10..ef48f89965 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1740,9 +1740,9 @@ bool GenericTransactionSignatureChecker<T>::CheckLockTime(const CScriptNum& nLoc
if (nLockTime > (int64_t)txTo->nLockTime)
return false;
- // Finally the nLockTime feature can be disabled and thus
- // CHECKLOCKTIMEVERIFY bypassed if every txin has been
- // finalized by setting nSequence to maxint. The
+ // Finally the nLockTime feature can be disabled in IsFinalTx()
+ // and thus CHECKLOCKTIMEVERIFY bypassed if every txin has
+ // been finalized by setting nSequence to maxint. The
// transaction would be allowed into the blockchain, making
// the opcode ineffective.
//
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 0fa5e56eb6..b8349bb9ab 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -407,7 +407,13 @@ void TaprootSpendData::Merge(TaprootSpendData other)
merkle_root = other.merkle_root;
}
for (auto& [key, control_blocks] : other.scripts) {
- scripts[key].merge(std::move(control_blocks));
+ // Once P0083R3 is supported by all our targeted platforms,
+ // this loop body can be replaced with:
+ // scripts[key].merge(std::move(control_blocks));
+ auto& target = scripts[key];
+ for (auto& control_block: control_blocks) {
+ target.insert(std::move(control_block));
+ }
}
}
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index eb5c37b34d..1103292c1a 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -783,6 +783,46 @@ BOOST_AUTO_TEST_CASE(addrman_serialization)
BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.second != bucketAndEntry_asmap1_deser_addr2.second);
}
+BOOST_AUTO_TEST_CASE(remove_invalid)
+{
+ // Confirm that invalid addresses are ignored in unserialization.
+
+ CAddrManTest addrman;
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+
+ const CAddress new1{ResolveService("5.5.5.5"), NODE_NONE};
+ const CAddress new2{ResolveService("6.6.6.6"), NODE_NONE};
+ const CAddress tried1{ResolveService("7.7.7.7"), NODE_NONE};
+ const CAddress tried2{ResolveService("8.8.8.8"), NODE_NONE};
+
+ addrman.Add({new1, tried1, new2, tried2}, CNetAddr{});
+ addrman.Good(tried1);
+ addrman.Good(tried2);
+ BOOST_REQUIRE_EQUAL(addrman.size(), 4);
+
+ stream << addrman;
+
+ const std::string str{stream.str()};
+ size_t pos;
+
+ const char new2_raw[]{6, 6, 6, 6};
+ const uint8_t new2_raw_replacement[]{0, 0, 0, 0}; // 0.0.0.0 is !IsValid()
+ pos = str.find(new2_raw, 0, sizeof(new2_raw));
+ BOOST_REQUIRE(pos != std::string::npos);
+ BOOST_REQUIRE(pos + sizeof(new2_raw_replacement) <= stream.size());
+ memcpy(stream.data() + pos, new2_raw_replacement, sizeof(new2_raw_replacement));
+
+ const char tried2_raw[]{8, 8, 8, 8};
+ const uint8_t tried2_raw_replacement[]{255, 255, 255, 255}; // 255.255.255.255 is !IsValid()
+ pos = str.find(tried2_raw, 0, sizeof(tried2_raw));
+ BOOST_REQUIRE(pos != std::string::npos);
+ BOOST_REQUIRE(pos + sizeof(tried2_raw_replacement) <= stream.size());
+ memcpy(stream.data() + pos, tried2_raw_replacement, sizeof(tried2_raw_replacement));
+
+ addrman.Clear();
+ stream >> addrman;
+ BOOST_CHECK_EQUAL(addrman.size(), 2);
+}
BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
{
diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp
index 36e2dac3ff..8553f80a17 100644
--- a/src/test/descriptor_tests.cpp
+++ b/src/test/descriptor_tests.cpp
@@ -124,14 +124,10 @@ void DoCheck(const std::string& prv, const std::string& pub, const std::string&
// Check that private can produce the normalized descriptors
std::string norm1;
- BOOST_CHECK(parse_priv->ToNormalizedString(keys_priv, norm1, false));
+ BOOST_CHECK(parse_priv->ToNormalizedString(keys_priv, norm1));
BOOST_CHECK(EqualDescriptor(norm1, norm_pub));
- BOOST_CHECK(parse_pub->ToNormalizedString(keys_priv, norm1, false));
+ BOOST_CHECK(parse_pub->ToNormalizedString(keys_priv, norm1));
BOOST_CHECK(EqualDescriptor(norm1, norm_pub));
- BOOST_CHECK(parse_priv->ToNormalizedString(keys_priv, norm1, true));
- BOOST_CHECK(EqualDescriptor(norm1, norm_prv));
- BOOST_CHECK(parse_pub->ToNormalizedString(keys_priv, norm1, true));
- BOOST_CHECK(EqualDescriptor(norm1, norm_prv));
// Check whether IsRange on both returns the expected result
BOOST_CHECK_EQUAL(parse_pub->IsRange(), (flags & RANGE) != 0);
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
index cca41e79ae..182aabc79b 100644
--- a/src/test/fuzz/banman.cpp
+++ b/src/test/fuzz/banman.cpp
@@ -32,6 +32,13 @@ void initialize_banman()
static const auto testing_setup = MakeNoLogFileContext<>();
}
+static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs)
+{
+ return lhs.nVersion == rhs.nVersion &&
+ lhs.nCreateTime == rhs.nCreateTime &&
+ lhs.nBanUntil == rhs.nBanUntil;
+}
+
FUZZ_TARGET_INIT(banman, initialize_banman)
{
// The complexity is O(N^2), where N is the input size, because each call
@@ -43,19 +50,20 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};
+ bool force_read_and_write_to_err{false};
if (start_with_corrupted_banlist) {
const std::string sfx{fuzzed_data_provider.ConsumeBool() ? ".dat" : ".json"};
assert(WriteBinaryFile(banlist_file.string() + sfx,
fuzzed_data_provider.ConsumeRandomLengthString()));
} else {
- const bool force_read_and_write_to_err{fuzzed_data_provider.ConsumeBool()};
+ force_read_and_write_to_err = fuzzed_data_provider.ConsumeBool();
if (force_read_and_write_to_err) {
banlist_file = fs::path{"path"} / "to" / "inaccessible" / "fuzzed_banlist";
}
}
{
- BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)};
+ BanMan ban_man{banlist_file, /* client_interface */ nullptr, /* default_ban_time */ ConsumeBanTimeOffset(fuzzed_data_provider)};
while (--limit_max_ops >= 0 && fuzzed_data_provider.ConsumeBool()) {
CallOneOf(
fuzzed_data_provider,
@@ -93,6 +101,16 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
});
}
+ if (!force_read_and_write_to_err) {
+ ban_man.DumpBanlist();
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
+ banmap_t banmap;
+ ban_man.GetBanned(banmap);
+ BanMan ban_man_read{banlist_file, /* client_interface */ nullptr, /* default_ban_time */ 0};
+ banmap_t banmap_read;
+ ban_man_read.GetBanned(banmap_read);
+ assert(banmap == banmap_read);
+ }
}
fs::remove(banlist_file.string() + ".dat");
fs::remove(banlist_file.string() + ".json");
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index e9fa343896..e28e2feb0a 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -16,8 +16,6 @@
#include <pow.h>
#include <protocol.h>
#include <pubkey.h>
-#include <rpc/util.h>
-#include <script/signingprovider.h>
#include <script/standard.h>
#include <serialize.h>
#include <streams.h>
@@ -158,20 +156,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
const CKeyID key_id{u160};
const CScriptID script_id{u160};
- // CTxDestination = CNoDestination ∪ PKHash ∪ ScriptHash ∪ WitnessV0ScriptHash ∪ WitnessV0KeyHash ∪ WitnessUnknown
- const PKHash pk_hash{u160};
- const ScriptHash script_hash{u160};
- const WitnessV0KeyHash witness_v0_key_hash{u160};
- const WitnessV0ScriptHash witness_v0_script_hash{u256};
- const std::vector<CTxDestination> destinations{pk_hash, script_hash, witness_v0_key_hash, witness_v0_script_hash};
- const SigningProvider store;
- for (const CTxDestination& destination : destinations) {
- (void)DescribeAddress(destination);
- (void)EncodeDestination(destination);
- (void)GetKeyForDestination(store, destination);
- (void)GetScriptForDestination(destination);
- (void)IsValidDestination(destination);
- }
{
CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION);
diff --git a/src/test/fuzz/key_io.cpp b/src/test/fuzz/key_io.cpp
index 665ca01fa1..f58bf8b316 100644
--- a/src/test/fuzz/key_io.cpp
+++ b/src/test/fuzz/key_io.cpp
@@ -4,9 +4,6 @@
#include <chainparams.h>
#include <key_io.h>
-#include <rpc/util.h>
-#include <script/signingprovider.h>
-#include <script/standard.h>
#include <test/fuzz/fuzz.h>
#include <cassert>
@@ -39,12 +36,4 @@ FUZZ_TARGET_INIT(key_io, initialize_key_io)
if (ext_pub_key.pubkey.size() == CPubKey::COMPRESSED_SIZE) {
assert(ext_pub_key == DecodeExtPubKey(EncodeExtPubKey(ext_pub_key)));
}
-
- const CTxDestination tx_destination = DecodeDestination(random_string);
- (void)DescribeAddress(tx_destination);
- (void)GetKeyForDestination(/* store */ {}, tx_destination);
- (void)GetScriptForDestination(tx_destination);
- (void)IsValidDestination(tx_destination);
-
- (void)IsValidDestinationString(random_string);
}
diff --git a/src/test/fuzz/load_external_block_file.cpp b/src/test/fuzz/load_external_block_file.cpp
index a7770c90e8..bfa977520b 100644
--- a/src/test/fuzz/load_external_block_file.cpp
+++ b/src/test/fuzz/load_external_block_file.cpp
@@ -32,5 +32,5 @@ FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
return;
}
FlatFilePos flat_file_pos;
- g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
+ g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
}
diff --git a/src/test/fuzz/netaddress.cpp b/src/test/fuzz/netaddress.cpp
index f9d8129ca9..6cb81901cb 100644
--- a/src/test/fuzz/netaddress.cpp
+++ b/src/test/fuzz/netaddress.cpp
@@ -54,7 +54,7 @@ FUZZ_TARGET(netaddress)
(void)net_addr.IsRFC3927();
(void)net_addr.IsRFC3964();
if (net_addr.IsRFC4193()) {
- assert(net_addr.GetNetwork() == Network::NET_ONION || net_addr.GetNetwork() == Network::NET_INTERNAL || net_addr.GetNetwork() == Network::NET_UNROUTABLE);
+ assert(net_addr.GetNetwork() == Network::NET_INTERNAL || net_addr.GetNetwork() == Network::NET_UNROUTABLE);
}
(void)net_addr.IsRFC4380();
(void)net_addr.IsRFC4843();
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index b87bcf2ef5..950ee45d1d 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -6,8 +6,10 @@
#include <compressor.h>
#include <core_io.h>
#include <core_memusage.h>
+#include <key_io.h>
#include <policy/policy.h>
#include <pubkey.h>
+#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/interpreter.h>
#include <script/script.h>
@@ -184,26 +186,26 @@ FUZZ_TARGET_INIT(script, initialize_script)
}
{
- WitnessUnknown witness_unknown_1{};
- witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown_1.length = witness_unknown_program_1.size();
- std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown_1.program);
-
- WitnessUnknown witness_unknown_2{};
- witness_unknown_2.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- const std::vector<uint8_t> witness_unknown_program_2 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown_2.length = witness_unknown_program_2.size();
- std::copy(witness_unknown_program_2.begin(), witness_unknown_program_2.end(), witness_unknown_2.program);
-
- (void)(witness_unknown_1 == witness_unknown_2);
- (void)(witness_unknown_1 < witness_unknown_2);
- }
+ const CTxDestination tx_destination_1{
+ fuzzed_data_provider.ConsumeBool() ?
+ DecodeDestination(fuzzed_data_provider.ConsumeRandomLengthString()) :
+ ConsumeTxDestination(fuzzed_data_provider)};
+ const CTxDestination tx_destination_2{ConsumeTxDestination(fuzzed_data_provider)};
+ const std::string encoded_dest{EncodeDestination(tx_destination_1)};
+ const UniValue json_dest{DescribeAddress(tx_destination_1)};
+ Assert(tx_destination_1 == DecodeDestination(encoded_dest));
+ (void)GetKeyForDestination(/* store */ {}, tx_destination_1);
+ const CScript dest{GetScriptForDestination(tx_destination_1)};
+ const bool valid{IsValidDestination(tx_destination_1)};
+ Assert(dest.empty() != valid);
+
+ Assert(valid == IsValidDestinationString(encoded_dest));
- {
- const CTxDestination tx_destination_1 = ConsumeTxDestination(fuzzed_data_provider);
- const CTxDestination tx_destination_2 = ConsumeTxDestination(fuzzed_data_provider);
- (void)(tx_destination_1 == tx_destination_2);
(void)(tx_destination_1 < tx_destination_2);
+ if (tx_destination_1 == tx_destination_2) {
+ Assert(encoded_dest == EncodeDestination(tx_destination_2));
+ Assert(json_dest.write() == DescribeAddress(tx_destination_2).write());
+ Assert(dest == GetScriptForDestination(tx_destination_2));
+ }
}
}
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index bcf0b0ce72..ece3214ed5 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <pubkey.h>
#include <test/fuzz/util.h>
#include <test/util/script.h>
#include <util/rbf.h>
@@ -304,3 +305,41 @@ uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept
}) :
fuzzed_data_provider.ConsumeIntegral<uint32_t>();
}
+
+CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ CTxDestination tx_destination;
+ const size_t call_size{CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ tx_destination = CNoDestination{};
+ },
+ [&] {
+ tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV1Taproot{XOnlyPubKey{ConsumeUInt256(fuzzed_data_provider)}};
+ },
+ [&] {
+ WitnessUnknown witness_unknown{};
+ witness_unknown.version = fuzzed_data_provider.ConsumeIntegralInRange(2, 16);
+ std::vector<uint8_t> witness_unknown_program_1{fuzzed_data_provider.ConsumeBytes<uint8_t>(40)};
+ if (witness_unknown_program_1.size() < 2) {
+ witness_unknown_program_1 = {0, 0};
+ }
+ witness_unknown.length = witness_unknown_program_1.size();
+ std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
+ tx_destination = witness_unknown;
+ })};
+ Assert(call_size == std::variant_size_v<CTxDestination>);
+ return tx_destination;
+}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 023dcdb3e5..9f09395a9a 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -37,7 +37,7 @@
#include <vector>
template <typename... Callables>
-void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
+size_t CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
{
constexpr size_t call_size{sizeof...(callables)};
static_assert(call_size >= 1);
@@ -45,6 +45,7 @@ void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
size_t i{0};
((i++ == call_index ? callables() : void()), ...);
+ return call_size;
}
template <typename Collection>
@@ -178,36 +179,7 @@ template <typename WeakEnumType, size_t size>
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
}
-[[nodiscard]] inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
-{
- CTxDestination tx_destination;
- CallOneOf(
- fuzzed_data_provider,
- [&] {
- tx_destination = CNoDestination{};
- },
- [&] {
- tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
- },
- [&] {
- tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
- },
- [&] {
- tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
- },
- [&] {
- tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
- },
- [&] {
- WitnessUnknown witness_unknown{};
- witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown.length = witness_unknown_program_1.size();
- std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
- tx_destination = witness_unknown;
- });
- return tx_destination;
-}
+[[nodiscard]] CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept;
template <typename T>
[[nodiscard]] bool MultiplicationOverflow(const T i, const T j) noexcept
diff --git a/src/test/interfaces_tests.cpp b/src/test/interfaces_tests.cpp
index 42a7c7798c..44779f7d7c 100644
--- a/src/test/interfaces_tests.cpp
+++ b/src/test/interfaces_tests.cpp
@@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findCommonAncestor)
auto* orig_tip = active.Tip();
for (int i = 0; i < 10; ++i) {
BlockValidationState state;
- m_node.chainman->ActiveChainstate().InvalidateBlock(state, Params(), active.Tip());
+ m_node.chainman->ActiveChainstate().InvalidateBlock(state, active.Tip());
}
BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10);
coinbaseKey.MakeNewKey(true);
diff --git a/src/test/serfloat_tests.cpp b/src/test/serfloat_tests.cpp
index 54e07b0f61..7876c0bcda 100644
--- a/src/test/serfloat_tests.cpp
+++ b/src/test/serfloat_tests.cpp
@@ -36,9 +36,9 @@ uint64_t TestDouble(double f) {
} // namespace
BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
- BOOST_CHECK_EQUAL(TestDouble(0.0), 0);
+ BOOST_CHECK_EQUAL(TestDouble(0.0), 0U);
BOOST_CHECK_EQUAL(TestDouble(-0.0), 0x8000000000000000);
- BOOST_CHECK_EQUAL(TestDouble(std::numeric_limits<double>::infinity()), 0x7ff0000000000000);
+ BOOST_CHECK_EQUAL(TestDouble(std::numeric_limits<double>::infinity()), 0x7ff0000000000000U);
BOOST_CHECK_EQUAL(TestDouble(-std::numeric_limits<double>::infinity()), 0xfff0000000000000);
BOOST_CHECK_EQUAL(TestDouble(0.5), 0x3fe0000000000000ULL);
BOOST_CHECK_EQUAL(TestDouble(1.0), 0x3ff0000000000000ULL);
@@ -48,8 +48,8 @@ BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
// Roundtrip test on IEC559-compatible systems
if (std::numeric_limits<double>::is_iec559) {
- BOOST_CHECK_EQUAL(sizeof(double), 8);
- BOOST_CHECK_EQUAL(sizeof(uint64_t), 8);
+ BOOST_CHECK_EQUAL(sizeof(double), 8U);
+ BOOST_CHECK_EQUAL(sizeof(uint64_t), 8U);
// Test extreme values
TestDouble(std::numeric_limits<double>::min());
TestDouble(-std::numeric_limits<double>::min());
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index 7af2b79f37..acd0151e1a 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(streams_vector_reader_rvalue)
uint32_t varint = 0;
// Deserialize into r-value
reader >> VARINT(varint);
- BOOST_CHECK_EQUAL(varint, 54321);
+ BOOST_CHECK_EQUAL(varint, 54321U);
BOOST_CHECK(reader.empty());
}
diff --git a/src/test/system_tests.cpp b/src/test/system_tests.cpp
index 940145b84f..e97eab2c00 100644
--- a/src/test/system_tests.cpp
+++ b/src/test/system_tests.cpp
@@ -7,6 +7,11 @@
#include <univalue.h>
#ifdef ENABLE_EXTERNAL_SIGNER
+#if defined(WIN32) && !defined(__kernel_entry)
+// A workaround for boost 1.71 incompatibility with mingw-w64 compiler.
+// For details see https://github.com/bitcoin/bitcoin/pull/22348.
+#define __kernel_entry
+#endif
#include <boost/process.hpp>
#endif // ENABLE_EXTERNAL_SIGNER
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index f71d9148b6..748272bb1d 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -186,12 +186,12 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk());
m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23);
assert(m_node.chainman->ActiveChainstate().CanFlushToDisk());
- if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock(chainparams)) {
+ if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock()) {
throw std::runtime_error("LoadGenesisBlock failed.");
}
BlockValidationState state;
- if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state, chainparams)) {
+ if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state)) {
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
}
diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp
index 0b912acb08..7c1db9d4b9 100644
--- a/src/test/validation_chainstatemanager_tests.cpp
+++ b/src/test/validation_chainstatemanager_tests.cpp
@@ -31,7 +31,6 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
CTxMemPool& mempool = *m_node.mempool;
std::vector<CChainState*> chainstates;
- const CChainParams& chainparams = Params();
BOOST_CHECK(!manager.SnapshotBlockhash().has_value());
@@ -76,9 +75,9 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23));
// Unlike c1, which doesn't have any blocks. Gets us different tip, height.
- c2.LoadGenesisBlock(chainparams);
+ c2.LoadGenesisBlock();
BlockValidationState _;
- BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr));
+ BOOST_CHECK(c2.ActivateBestChain(_, nullptr));
BOOST_CHECK(manager.IsSnapshotActive());
BOOST_CHECK(!manager.IsSnapshotValidated());
@@ -138,7 +137,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
{
LOCK(::cs_main);
c1.InitCoinsCache(1 << 23);
- BOOST_REQUIRE(c1.LoadGenesisBlock(Params()));
+ BOOST_REQUIRE(c1.LoadGenesisBlock());
c1.CoinsTip().SetBestBlock(InsecureRand256());
manager.MaybeRebalanceCaches();
}
@@ -156,7 +155,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
{
LOCK(::cs_main);
c2.InitCoinsCache(1 << 23);
- BOOST_REQUIRE(c2.LoadGenesisBlock(Params()));
+ BOOST_REQUIRE(c2.LoadGenesisBlock());
c2.CoinsTip().SetBestBlock(InsecureRand256());
manager.MaybeRebalanceCaches();
}
diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp
index 304cd8feb0..690031cdc1 100644
--- a/src/test/versionbits_tests.cpp
+++ b/src/test/versionbits_tests.cpp
@@ -5,6 +5,7 @@
#include <chain.h>
#include <chainparams.h>
#include <consensus/params.h>
+#include <deploymentstatus.h>
#include <test/util/setup_common.h>
#include <validation.h>
#include <versionbits.h>
@@ -258,8 +259,8 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
/** Check that ComputeBlockVersion will set the appropriate bit correctly */
static void check_computeblockversion(const Consensus::Params& params, Consensus::DeploymentPos dep)
{
- // This implicitly uses versionbitscache, so clear it every time
- versionbitscache.Clear();
+ // This implicitly uses g_versionbitscache, so clear it every time
+ g_versionbitscache.Clear();
int64_t bit = params.vDeployments[dep].bit;
int64_t nStartTime = params.vDeployments[dep].nStartTime;
@@ -267,7 +268,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
int min_activation_height = params.vDeployments[dep].min_activation_height;
// should not be any signalling for first block
- BOOST_CHECK_EQUAL(ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
// always/never active deployments shouldn't need to be tested further
if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
@@ -287,7 +288,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// Check min_activation_height is on a retarget boundary
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
- const uint32_t bitmask{VersionBitsMask(params, dep)};
+ const uint32_t bitmask{g_versionbitscache.Mask(params, dep)};
BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
// In the first chain, test that the bit is set by CBV until it has failed.
@@ -306,9 +307,9 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// earlier time, so will transition from DEFINED to STARTED at the
// end of the first period by mining blocks at nTime == 0
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// then we'll keep mining at nStartTime...
} else {
// use a time 1s earlier than start time to check we stay DEFINED
@@ -316,28 +317,28 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// Start generating blocks before nStartTime
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
// CBV should still not yet set the bit.
nTime = nStartTime;
for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
// Next we will advance to the next period and transition to STARTED,
}
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
// so ComputeBlockVersion should now set the bit,
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// and should also be using the VERSIONBITS_TOP_BITS.
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
// Check that ComputeBlockVersion will set the bit until nTimeout
nTime += 600;
@@ -346,8 +347,8 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// These blocks are all before nTimeout is reached.
while (nTime < nTimeout && blocksToMine > 0) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
blocksToMine--;
nTime += 600;
nHeight += 1;
@@ -361,7 +362,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// finish the last period before we start timing out
while (nHeight % params.nMinerConfirmationWindow != 0) {
lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
nHeight += 1;
}
@@ -369,12 +370,12 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// the bit until the period transition.
for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
nHeight += 1;
}
// The next block should trigger no longer setting the bit.
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
// On a new chain:
@@ -385,30 +386,30 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
// Mine one period worth of blocks, and check that the bit will be on for the
// next period.
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// Mine another period worth of blocks, signaling the new bit.
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
// After one period of setting the bit on each block, it should have locked in.
// We keep setting the bit for one more period though, until activation.
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// Now check that we keep mining the block until the end of this period, and
// then stop at the beginning of the next period.
lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
if (lastBlock->nHeight + 1 < min_activation_height) {
// check signalling continues while min_activation_height is not reached
lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
// then reach min_activation_height, which was already REQUIRE'd to start a new period
lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
}
// Check that we don't signal after activation
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
}
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
@@ -425,7 +426,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
// not take precedence over STARTED/LOCKED_IN. So all softforks on
// the same bit might overlap, even when non-overlapping start-end
// times are picked.
- const uint32_t dep_mask{VersionBitsMask(chainParams->GetConsensus(), dep)};
+ const uint32_t dep_mask{g_versionbitscache.Mask(chainParams->GetConsensus(), dep)};
BOOST_CHECK(!(chain_all_vbits & dep_mask));
chain_all_vbits |= dep_mask;
check_computeblockversion(chainParams->GetConsensus(), dep);
diff --git a/src/util/system.cpp b/src/util/system.cpp
index ee7a76be29..258ba2f235 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -6,6 +6,11 @@
#include <util/system.h>
#ifdef ENABLE_EXTERNAL_SIGNER
+#if defined(WIN32) && !defined(__kernel_entry)
+// A workaround for boost 1.71 incompatibility with mingw-w64 compiler.
+// For details see https://github.com/bitcoin/bitcoin/pull/22348.
+#define __kernel_entry
+#endif
#include <boost/process.hpp>
#endif // ENABLE_EXTERNAL_SIGNER
diff --git a/src/validation.cpp b/src/validation.cpp
index b48e49a10b..c80f015143 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -15,6 +15,7 @@
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <cuckoocache.h>
+#include <deploymentstatus.h>
#include <flatfile.h>
#include <hash.h>
#include <index/blockfilterindex.h>
@@ -586,9 +587,13 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
if (!CheckFinalTx(m_active_chainstate.m_chain.Tip(), tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-final");
- // is it already in the memory pool?
- if (m_pool.exists(hash)) {
+ if (m_pool.exists(GenTxid(true, tx.GetWitnessHash()))) {
+ // Exact transaction already exists in the mempool.
return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-in-mempool");
+ } else if (m_pool.exists(GenTxid(false, tx.GetHash()))) {
+ // Transaction with the same non-witness data but different witness (same txid, different
+ // wtxid) already exists in the mempool.
+ return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-same-nonwitness-data-in-mempool");
}
// Check for conflicts with in-memory transactions
@@ -683,9 +688,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
// Check for non-standard pay-to-script-hash in inputs
- const auto& params = args.m_chainparams.GetConsensus();
- auto taproot_state = VersionBitsState(m_active_chainstate.m_chain.Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
- if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
+ const bool taproot_active = DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), args.m_chainparams.GetConsensus(), Consensus::DEPLOYMENT_TAPROOT);
+ if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_active)) {
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
}
@@ -1124,7 +1128,7 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
}
// After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
BlockValidationState state_dummy;
- active_chainstate.FlushStateToDisk(chainparams, state_dummy, FlushStateMode::PERIODIC);
+ active_chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
return result;
}
@@ -1210,6 +1214,7 @@ void CoinsViews::InitCache()
CChainState::CChainState(CTxMemPool& mempool, BlockManager& blockman, std::optional<uint256> from_snapshot_blockhash)
: m_mempool(mempool),
+ m_params(::Params()),
m_blockman(blockman),
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
@@ -1605,23 +1610,6 @@ void StopScriptCheckWorkerThreads()
scriptcheckqueue.StopWorkerThreads();
}
-VersionBitsCache versionbitscache GUARDED_BY(cs_main);
-
-int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
-{
- LOCK(cs_main);
- int32_t nVersion = VERSIONBITS_TOP_BITS;
-
- for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
- ThresholdState state = VersionBitsState(pindexPrev, params, static_cast<Consensus::DeploymentPos>(i), versionbitscache);
- if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
- nVersion |= VersionBitsMask(params, static_cast<Consensus::DeploymentPos>(i));
- }
- }
-
- return nVersion;
-}
-
/**
* Threshold condition checker that triggers when unknown versionbits are seen on the network.
*/
@@ -1643,24 +1631,14 @@ public:
return pindex->nHeight >= params.MinBIP9WarningHeight &&
((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) &&
((pindex->nVersion >> bit) & 1) != 0 &&
- ((ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
+ ((g_versionbitscache.ComputeBlockVersion(pindex->pprev, params) >> bit) & 1) == 0;
}
};
static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_main);
-// 0.13.0 was shipped with a segwit deployment defined for testnet, but not for
-// mainnet. We no longer need to support disabling the segwit deployment
-// except for testing purposes, due to limitations of the functional test
-// environment. See test/functional/p2p-segwit.py.
-static bool IsScriptWitnessEnabled(const Consensus::Params& params)
+static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams)
{
- return params.SegwitHeight != std::numeric_limits<int>::max();
-}
-
-static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
- AssertLockHeld(cs_main);
-
unsigned int flags = SCRIPT_VERIFY_NONE;
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
@@ -1677,32 +1655,32 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
// Enforce WITNESS rules whenever P2SH is in effect (and the segwit
// deployment is defined).
- if (flags & SCRIPT_VERIFY_P2SH && IsScriptWitnessEnabled(consensusparams)) {
+ if (flags & SCRIPT_VERIFY_P2SH && DeploymentEnabled(consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
flags |= SCRIPT_VERIFY_WITNESS;
}
- // Start enforcing the DERSIG (BIP66) rule
- if (pindex->nHeight >= consensusparams.BIP66Height) {
+ // Enforce the DERSIG (BIP66) rule
+ if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_DERSIG)) {
flags |= SCRIPT_VERIFY_DERSIG;
}
- // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule
- if (pindex->nHeight >= consensusparams.BIP65Height) {
+ // Enforce CHECKLOCKTIMEVERIFY (BIP65)
+ if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_CLTV)) {
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
}
- // Start enforcing BIP112 (CHECKSEQUENCEVERIFY)
- if (pindex->nHeight >= consensusparams.CSVHeight) {
+ // Enforce CHECKSEQUENCEVERIFY (BIP112)
+ if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_CSV)) {
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
}
- // Start enforcing Taproot using versionbits logic.
- if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_TAPROOT, versionbitscache) == ThresholdState::ACTIVE) {
+ // Enforce Taproot (BIP340-BIP342)
+ if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_TAPROOT)) {
flags |= SCRIPT_VERIFY_TAPROOT;
}
- // Start enforcing BIP147 NULLDUMMY (activated simultaneously with segwit)
- if (IsWitnessEnabled(pindex->pprev, consensusparams)) {
+ // Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
+ if (DeploymentActiveAt(*pindex, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
flags |= SCRIPT_VERIFY_NULLDUMMY;
}
@@ -1724,7 +1702,7 @@ static int64_t nBlocksTotal = 0;
* Validity checks that depend on the UTXO set are also done; ConnectBlock()
* can fail if those validity checks fail (among other reasons). */
bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
- CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck)
+ CCoinsViewCache& view, bool fJustCheck)
{
AssertLockHeld(cs_main);
assert(pindex);
@@ -1744,7 +1722,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// is enforced in ContextualCheckBlockHeader(); we wouldn't want to
// re-enforce that rule here (at least until we make it impossible for
// GetAdjustedTime() to go backward).
- if (!CheckBlock(block, state, chainparams.GetConsensus(), !fJustCheck, !fJustCheck)) {
+ if (!CheckBlock(block, state, m_params.GetConsensus(), !fJustCheck, !fJustCheck)) {
if (state.GetResult() == BlockValidationResult::BLOCK_MUTATED) {
// We don't write down blocks to disk if they may have been
// corrupted, so this should be impossible unless we're having hardware
@@ -1762,7 +1740,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
- if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
+ if (block.GetHash() == m_params.GetConsensus().hashGenesisBlock) {
if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash());
return true;
@@ -1794,7 +1772,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// artificially set the default assumed verified block further back.
// The test against nMinimumChainWork prevents the skipping when denied access to any chain at
// least as good as the expected chain.
- fScriptChecks = (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, chainparams.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
+ fScriptChecks = (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, m_params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
}
}
}
@@ -1874,9 +1852,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// be reset before it reaches block 1,983,702 and starts doing unnecessary
// BIP30 checking again.
assert(pindex->pprev);
- CBlockIndex *pindexBIP34height = pindex->pprev->GetAncestor(chainparams.GetConsensus().BIP34Height);
+ CBlockIndex* pindexBIP34height = pindex->pprev->GetAncestor(m_params.GetConsensus().BIP34Height);
//Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond.
- fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == chainparams.GetConsensus().BIP34Hash));
+ fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == m_params.GetConsensus().BIP34Hash));
// TODO: Remove BIP30 checking from block height 1,983,702 on, once we have a
// consensus change that ensures coinbases at those heights can not
@@ -1892,14 +1870,14 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
}
}
- // Start enforcing BIP68 (sequence locks)
+ // Enforce BIP68 (sequence locks)
int nLockTimeFlags = 0;
- if (pindex->nHeight >= chainparams.GetConsensus().CSVHeight) {
+ if (DeploymentActiveAt(*pindex, m_params.GetConsensus(), Consensus::DEPLOYMENT_CSV)) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
}
// Get the script flags for this block
- unsigned int flags = GetBlockScriptFlags(pindex, chainparams.GetConsensus());
+ unsigned int flags = GetBlockScriptFlags(pindex, m_params.GetConsensus());
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
@@ -1989,7 +1967,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal);
- CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
+ CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, m_params.GetConsensus());
if (block.vtx[0]->GetValueOut() > blockReward) {
LogPrintf("ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.vtx[0]->GetValueOut(), blockReward);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount");
@@ -2005,8 +1983,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
if (fJustCheck)
return true;
- if (!WriteUndoDataForBlock(blockundo, state, pindex, chainparams))
+ if (!WriteUndoDataForBlock(blockundo, state, pindex, m_params)) {
return false;
+ }
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
@@ -2059,7 +2038,6 @@ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(
}
bool CChainState::FlushStateToDisk(
- const CChainParams& chainparams,
BlockValidationState &state,
FlushStateMode mode,
int nManualPruneHeight)
@@ -2096,7 +2074,7 @@ bool CChainState::FlushStateToDisk(
} else {
LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH);
- m_blockman.FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload());
+ m_blockman.FindFilesToPrune(setFilesToPrune, m_params.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload());
fCheckForPruning = false;
}
if (!setFilesToPrune.empty()) {
@@ -2196,20 +2174,19 @@ bool CChainState::FlushStateToDisk(
return true;
}
-void CChainState::ForceFlushStateToDisk() {
+void CChainState::ForceFlushStateToDisk()
+{
BlockValidationState state;
- const CChainParams& chainparams = Params();
- if (!this->FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS)) {
+ if (!this->FlushStateToDisk(state, FlushStateMode::ALWAYS)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
}
}
-void CChainState::PruneAndFlush() {
+void CChainState::PruneAndFlush()
+{
BlockValidationState state;
fCheckForPruning = true;
- const CChainParams& chainparams = Params();
-
- if (!this->FlushStateToDisk(chainparams, state, FlushStateMode::NONE)) {
+ if (!this->FlushStateToDisk(state, FlushStateMode::NONE)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
}
}
@@ -2278,7 +2255,7 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
* disconnectpool (note that the caller is responsible for mempool consistency
* in any case).
*/
-bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool)
+bool CChainState::DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool)
{
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs);
@@ -2288,8 +2265,9 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
// Read block from disk.
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock& block = *pblock;
- if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus()))
+ if (!ReadBlockFromDisk(block, pindexDelete, m_params.GetConsensus())) {
return error("DisconnectTip(): Failed to read block");
+ }
// Apply the block atomically to the chain state.
int64_t nStart = GetTimeMicros();
{
@@ -2302,8 +2280,9 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
}
LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * MILLI);
// Write the chain state to disk, if necessary.
- if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
+ if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
return false;
+ }
if (disconnectpool) {
// Save transactions to re-add to mempool at end of reorg
@@ -2320,7 +2299,7 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
m_chain.SetTip(pindexDelete->pprev);
- UpdateTip(m_mempool, pindexDelete->pprev, chainparams, *this);
+ UpdateTip(m_mempool, pindexDelete->pprev, m_params, *this);
// Let wallets know transactions went from 1-confirmed to
// 0-confirmed or conflicted:
GetMainSignals().BlockDisconnected(pblock, pindexDelete);
@@ -2379,7 +2358,7 @@ public:
*
* The block is added to connectTrace if connection succeeds.
*/
-bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool)
+bool CChainState::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool)
{
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs);
@@ -2390,8 +2369,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
std::shared_ptr<const CBlock> pthisBlock;
if (!pblock) {
std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
- if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus()))
+ if (!ReadBlockFromDisk(*pblockNew, pindexNew, m_params.GetConsensus())) {
return AbortNode(state, "Failed to read block");
+ }
pthisBlock = pblockNew;
} else {
pthisBlock = pblock;
@@ -2403,7 +2383,7 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
{
CCoinsViewCache view(&CoinsTip());
- bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
+ bool rv = ConnectBlock(blockConnecting, state, pindexNew, view);
GetMainSignals().BlockChecked(blockConnecting, state);
if (!rv) {
if (state.IsInvalid())
@@ -2419,8 +2399,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
LogPrint(BCLog::BENCH, " - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
// Write the chain state to disk, if necessary.
- if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
+ if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
return false;
+ }
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
LogPrint(BCLog::BENCH, " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
// Remove conflicting transactions from the mempool.;
@@ -2428,7 +2409,7 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
disconnectpool.removeForBlock(blockConnecting.vtx);
// Update m_chain & related variables.
m_chain.SetTip(pindexNew);
- UpdateTip(m_mempool, pindexNew, chainparams, *this);
+ UpdateTip(m_mempool, pindexNew, m_params, *this);
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
LogPrint(BCLog::BENCH, " - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
@@ -2515,7 +2496,7 @@ void CChainState::PruneBlockIndexCandidates() {
*
* @returns true unless a system error occurred
*/
-bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
+bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
{
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs);
@@ -2527,7 +2508,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
bool fBlocksDisconnected = false;
DisconnectedBlockTransactions disconnectpool;
while (m_chain.Tip() && m_chain.Tip() != pindexFork) {
- if (!DisconnectTip(state, chainparams, &disconnectpool)) {
+ if (!DisconnectTip(state, &disconnectpool)) {
// This is likely a fatal error, but keep the mempool consistent,
// just in case. Only remove from the mempool in this case.
UpdateMempoolForReorg(*this, m_mempool, disconnectpool, false);
@@ -2560,7 +2541,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
// Connect new blocks.
for (CBlockIndex* pindexConnect : reverse_iterate(vpindexToConnect)) {
- if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
+ if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
if (state.IsInvalid()) {
// The block violates a consensus rule.
if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
@@ -2637,7 +2618,8 @@ static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main) {
}
}
-bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) {
+bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr<const CBlock> pblock)
+{
// Note that while we're often called here from ProcessNewBlock, this is
// far from a guarantee. Things in the P2P/RPC will often end up calling
// us in the middle of ProcessNewBlock - do not assume pblock is set
@@ -2683,7 +2665,7 @@ bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainPar
bool fInvalidFound = false;
std::shared_ptr<const CBlock> nullBlockPtr;
- if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
+ if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
// A system error occurred
return false;
}
@@ -2725,17 +2707,17 @@ bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainPar
// that the best block hash is non-null.
if (ShutdownRequested()) break;
} while (pindexNewTip != pindexMostWork);
- CheckBlockIndex(chainparams.GetConsensus());
+ CheckBlockIndex();
// Write changes periodically to disk, after relay.
- if (!FlushStateToDisk(chainparams, state, FlushStateMode::PERIODIC)) {
+ if (!FlushStateToDisk(state, FlushStateMode::PERIODIC)) {
return false;
}
return true;
}
-bool CChainState::PreciousBlock(BlockValidationState& state, const CChainParams& params, CBlockIndex *pindex)
+bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex)
{
{
LOCK(cs_main);
@@ -2761,10 +2743,10 @@ bool CChainState::PreciousBlock(BlockValidationState& state, const CChainParams&
}
}
- return ActivateBestChain(state, params, std::shared_ptr<const CBlock>());
+ return ActivateBestChain(state, std::shared_ptr<const CBlock>());
}
-bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex)
+bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex)
{
// Genesis block can't be invalidated
assert(pindex);
@@ -2822,7 +2804,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
// ActivateBestChain considers blocks already in m_chain
// unconditionally valid already, so force disconnect away from it.
DisconnectedBlockTransactions disconnectpool;
- bool ret = DisconnectTip(state, chainparams, &disconnectpool);
+ bool ret = DisconnectTip(state, &disconnectpool);
// DisconnectTip will add transactions to disconnectpool.
// Adjust the mempool to be consistent with the new tip, adding
// transactions back to the mempool if disconnecting was successful,
@@ -2864,7 +2846,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
to_mark_failed = invalid_walk_tip;
}
- CheckBlockIndex(chainparams.GetConsensus());
+ CheckBlockIndex();
{
LOCK(cs_main);
@@ -2975,7 +2957,7 @@ CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block)
}
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
-void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos, const Consensus::Params& consensusParams)
+void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos)
{
pindexNew->nTx = block.vtx.size();
pindexNew->nChainTx = 0;
@@ -2983,7 +2965,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0;
pindexNew->nStatus |= BLOCK_HAVE_DATA;
- if (IsWitnessEnabled(pindexNew->pprev, consensusParams)) {
+ if (DeploymentActiveAt(*pindexNew, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
pindexNew->nStatus |= BLOCK_OPT_WITNESS;
}
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
@@ -3104,17 +3086,11 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
return true;
}
-bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
-{
- int height = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
- return (height >= params.SegwitHeight);
-}
-
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams)
{
int commitpos = GetWitnessCommitmentIndex(block);
static const std::vector<unsigned char> nonce(32, 0x00);
- if (commitpos != NO_WITNESS_COMMITMENT && IsWitnessEnabled(pindexPrev, consensusParams) && !block.vtx[0]->HasWitness()) {
+ if (commitpos != NO_WITNESS_COMMITMENT && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT) && !block.vtx[0]->HasWitness()) {
CMutableTransaction tx(*block.vtx[0]);
tx.vin[0].scriptWitness.stack.resize(1);
tx.vin[0].scriptWitness.stack[0] = nonce;
@@ -3127,7 +3103,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
std::vector<unsigned char> commitment;
int commitpos = GetWitnessCommitmentIndex(block);
std::vector<unsigned char> ret(32, 0x00);
- if (consensusParams.SegwitHeight != std::numeric_limits<int>::max()) {
+ if (DeploymentEnabled(consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
if (commitpos == NO_WITNESS_COMMITMENT) {
uint256 witnessroot = BlockWitnessMerkleRoot(block, nullptr);
CHash256().Write(witnessroot).Write(ret).Finalize(witnessroot);
@@ -3205,13 +3181,13 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
- // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
- // check for version 2, 3 and 4 upgrades
- if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
- (block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
- (block.nVersion < 4 && nHeight >= consensusParams.BIP65Height))
+ // Reject blocks with outdated version
+ if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
+ (block.nVersion < 3 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DERSIG)) ||
+ (block.nVersion < 4 && DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CLTV))) {
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, strprintf("bad-version(0x%08x)", block.nVersion),
strprintf("rejected nVersion=0x%08x block", block.nVersion));
+ }
return true;
}
@@ -3226,9 +3202,9 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
{
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
- // Start enforcing BIP113 (Median Time Past).
+ // Enforce BIP113 (Median Time Past).
int nLockTimeFlags = 0;
- if (nHeight >= consensusParams.CSVHeight) {
+ if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV)) {
assert(pindexPrev != nullptr);
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
}
@@ -3245,7 +3221,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
}
// Enforce rule that the coinbase starts with serialized block height
- if (nHeight >= consensusParams.BIP34Height)
+ if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_HEIGHTINCB))
{
CScript expect = CScript() << nHeight;
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
@@ -3263,7 +3239,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are
// multiple, the last one is used.
bool fHaveWitness = false;
- if (nHeight >= consensusParams.SegwitHeight) {
+ if (DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT)) {
int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != NO_WITNESS_COMMITMENT) {
bool malleated = false;
@@ -3400,7 +3376,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
bool accepted = m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex);
- ActiveChainstate().CheckBlockIndex(chainparams.GetConsensus());
+ ActiveChainstate().CheckBlockIndex();
if (!accepted) {
return false;
@@ -3419,7 +3395,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
}
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
-bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
+bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
{
const CBlock& block = *pblock;
@@ -3429,8 +3405,8 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
CBlockIndex *pindexDummy = nullptr;
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
- bool accepted_header = m_blockman.AcceptBlockHeader(block, state, chainparams, &pindex);
- CheckBlockIndex(chainparams.GetConsensus());
+ bool accepted_header = m_blockman.AcceptBlockHeader(block, state, m_params, &pindex);
+ CheckBlockIndex();
if (!accepted_header)
return false;
@@ -3467,8 +3443,8 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
if (pindex->nChainWork < nMinimumChainWork) return true;
}
- if (!CheckBlock(block, state, chainparams.GetConsensus()) ||
- !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) {
+ if (!CheckBlock(block, state, m_params.GetConsensus()) ||
+ !ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) {
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindex);
@@ -3484,19 +3460,19 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file
if (fNewBlock) *fNewBlock = true;
try {
- FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, chainparams, dbp);
+ FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, m_params, dbp);
if (blockPos.IsNull()) {
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
return false;
}
- ReceivedBlockTransactions(block, pindex, blockPos, chainparams.GetConsensus());
+ ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) {
return AbortNode(state, std::string("System error: ") + e.what());
}
- FlushStateToDisk(chainparams, state, FlushStateMode::NONE);
+ FlushStateToDisk(state, FlushStateMode::NONE);
- CheckBlockIndex(chainparams.GetConsensus());
+ CheckBlockIndex();
return true;
}
@@ -3522,7 +3498,7 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
bool ret = CheckBlock(*block, state, chainparams.GetConsensus());
if (ret) {
// Store to disk
- ret = ActiveChainstate().AcceptBlock(block, state, chainparams, &pindex, force_processing, nullptr, new_block);
+ ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block);
}
if (!ret) {
GetMainSignals().BlockChecked(*block, state);
@@ -3533,8 +3509,9 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
NotifyHeaderTip(ActiveChainstate());
BlockValidationState state; // Only used to report errors, not invalidity - ignore it
- if (!ActiveChainstate().ActivateBestChain(state, chainparams, block))
+ if (!ActiveChainstate().ActivateBestChain(state, block)) {
return error("%s: ActivateBestChain failed (%s)", __func__, state.ToString());
+ }
return true;
}
@@ -3563,8 +3540,9 @@ bool TestBlockValidity(BlockValidationState& state,
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
- if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true))
+ if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) {
return false;
+ }
assert(state.IsValid());
return true;
@@ -3635,9 +3613,8 @@ void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nM
void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight)
{
BlockValidationState state;
- const CChainParams& chainparams = Params();
if (!active_chainstate.FlushStateToDisk(
- chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
+ state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
}
}
@@ -3787,10 +3764,10 @@ void BlockManager::Unload() {
m_block_index.clear();
}
-bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams)
+bool CChainState::LoadBlockIndexDB()
{
if (!m_blockman.LoadBlockIndex(
- chainparams.GetConsensus(), *pblocktree,
+ m_params.GetConsensus(), *pblocktree,
setBlockIndexCandidates)) {
return false;
}
@@ -3850,7 +3827,7 @@ void CChainState::LoadMempool(const ArgsManager& args)
m_mempool.SetIsLoaded(!ShutdownRequested());
}
-bool CChainState::LoadChainTip(const CChainParams& chainparams)
+bool CChainState::LoadChainTip()
{
AssertLockHeld(cs_main);
const CCoinsViewCache& coins_cache = CoinsTip();
@@ -3871,10 +3848,10 @@ bool CChainState::LoadChainTip(const CChainParams& chainparams)
tip = m_chain.Tip();
LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
- tip->GetBlockHash().ToString(),
- m_chain.Height(),
- FormatISO8601DateTime(tip->GetBlockTime()),
- GuessVerificationProgress(chainparams.TxData(), tip));
+ tip->GetBlockHash().ToString(),
+ m_chain.Height(),
+ FormatISO8601DateTime(tip->GetBlockTime()),
+ GuessVerificationProgress(m_params.TxData(), tip));
return true;
}
@@ -3985,8 +3962,9 @@ bool CVerifyDB::VerifyDB(
CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
- if (!chainstate.ConnectBlock(block, state, pindex, coins, chainparams))
+ if (!chainstate.ConnectBlock(block, state, pindex, coins)) {
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
+ }
if (ShutdownRequested()) return true;
}
}
@@ -3998,11 +3976,11 @@ bool CVerifyDB::VerifyDB(
}
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
-bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params)
+bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs)
{
// TODO: merge with ConnectBlock
CBlock block;
- if (!ReadBlockFromDisk(block, pindex, params.GetConsensus())) {
+ if (!ReadBlockFromDisk(block, pindex, m_params.GetConsensus())) {
return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
}
@@ -4018,7 +3996,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
return true;
}
-bool CChainState::ReplayBlocks(const CChainParams& params)
+bool CChainState::ReplayBlocks()
{
LOCK(cs_main);
@@ -4054,7 +4032,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
while (pindexOld != pindexFork) {
if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
CBlock block;
- if (!ReadBlockFromDisk(block, pindexOld, params.GetConsensus())) {
+ if (!ReadBlockFromDisk(block, pindexOld, m_params.GetConsensus())) {
return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
}
LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
@@ -4076,7 +4054,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight);
LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight);
uiInterface.ShowProgress(_("Replaying blocks…").translated, (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false);
- if (!RollforwardBlock(pindex, cache, params)) return false;
+ if (!RollforwardBlock(pindex, cache)) return false;
}
cache.SetBestBlock(pindexNew->GetBlockHash());
@@ -4085,15 +4063,14 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
return true;
}
-bool CChainState::NeedsRedownload(const CChainParams& params) const
+bool CChainState::NeedsRedownload() const
{
AssertLockHeld(cs_main);
- // At and above params.SegwitHeight, segwit consensus rules must be validated
+ // At and above m_params.SegwitHeight, segwit consensus rules must be validated
CBlockIndex* block{m_chain.Tip()};
- const int segwit_height{params.GetConsensus().SegwitHeight};
- while (block != nullptr && block->nHeight >= segwit_height) {
+ while (block != nullptr && DeploymentActiveAt(*block, m_params.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
// block is insufficiently validated for a segwit client
return true;
@@ -4123,20 +4100,20 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
nLastBlockFile = 0;
setDirtyBlockIndex.clear();
setDirtyFileInfo.clear();
- versionbitscache.Clear();
+ g_versionbitscache.Clear();
for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
warningcache[b].clear();
}
fHavePruned = false;
}
-bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams)
+bool ChainstateManager::LoadBlockIndex()
{
AssertLockHeld(cs_main);
// Load block index from databases
bool needs_init = fReindex;
if (!fReindex) {
- bool ret = ActiveChainstate().LoadBlockIndexDB(chainparams);
+ bool ret = ActiveChainstate().LoadBlockIndexDB();
if (!ret) return false;
needs_init = m_blockman.m_block_index.empty();
}
@@ -4153,7 +4130,7 @@ bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams)
return true;
}
-bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
+bool CChainState::LoadGenesisBlock()
{
LOCK(cs_main);
@@ -4161,16 +4138,16 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
// m_blockman.m_block_index. Note that we can't use m_chain here, since it is
// set based on the coins db, not the block index db, which is the only
// thing loaded at this point.
- if (m_blockman.m_block_index.count(chainparams.GenesisBlock().GetHash()))
+ if (m_blockman.m_block_index.count(m_params.GenesisBlock().GetHash()))
return true;
try {
- const CBlock& block = chainparams.GenesisBlock();
- FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, chainparams, nullptr);
+ const CBlock& block = m_params.GenesisBlock();
+ FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr);
if (blockPos.IsNull())
return error("%s: writing genesis block to disk failed", __func__);
CBlockIndex *pindex = m_blockman.AddToBlockIndex(block);
- ReceivedBlockTransactions(block, pindex, blockPos, chainparams.GetConsensus());
+ ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) {
return error("%s: failed to write genesis block: %s", __func__, e.what());
}
@@ -4178,7 +4155,7 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
return true;
}
-void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFilePos* dbp)
+void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
{
// Map of disk positions for blocks with unknown parent (only used for reindex)
static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
@@ -4199,11 +4176,12 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
try {
// locate a header
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
- blkdat.FindByte(chainparams.MessageStart()[0]);
+ blkdat.FindByte(m_params.MessageStart()[0]);
nRewind = blkdat.GetPos()+1;
blkdat >> buf;
- if (memcmp(buf, chainparams.MessageStart(), CMessageHeader::MESSAGE_START_SIZE))
+ if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
continue;
+ }
// read size
blkdat >> nSize;
if (nSize < 80 || nSize > MAX_BLOCK_SERIALIZED_SIZE)
@@ -4227,7 +4205,7 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
{
LOCK(cs_main);
// detect out of order blocks, and store them for later
- if (hash != chainparams.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
+ if (hash != m_params.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString());
if (dbp)
@@ -4239,21 +4217,21 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
BlockValidationState state;
- if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) {
+ if (AcceptBlock(pblock, state, nullptr, true, dbp, nullptr)) {
nLoaded++;
}
if (state.IsError()) {
break;
}
- } else if (hash != chainparams.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
- LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
+ } else if (hash != m_params.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
+ LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
}
}
// Activate the genesis block so normal node progress can continue
- if (hash == chainparams.GetConsensus().hashGenesisBlock) {
+ if (hash == m_params.GetConsensus().hashGenesisBlock) {
BlockValidationState state;
- if (!ActivateBestChain(state, chainparams, nullptr)) {
+ if (!ActivateBestChain(state, nullptr)) {
break;
}
}
@@ -4270,14 +4248,12 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
while (range.first != range.second) {
std::multimap<uint256, FlatFilePos>::iterator it = range.first;
std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
- if (ReadBlockFromDisk(*pblockrecursive, it->second, chainparams.GetConsensus()))
- {
+ if (ReadBlockFromDisk(*pblockrecursive, it->second, m_params.GetConsensus())) {
LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
head.ToString());
LOCK(cs_main);
BlockValidationState dummy;
- if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr))
- {
+ if (AcceptBlock(pblockrecursive, dummy, nullptr, true, &it->second, nullptr)) {
nLoaded++;
queue.push_back(pblockrecursive->GetHash());
}
@@ -4297,7 +4273,7 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
}
-void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
+void CChainState::CheckBlockIndex()
{
if (!fCheckBlockIndex) {
return;
@@ -4351,7 +4327,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// Begin: actual consistency checks.
if (pindex->pprev == nullptr) {
// Genesis block checks.
- assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match.
+ assert(pindex->GetBlockHash() == m_params.GetConsensus().hashGenesisBlock); // Genesis block's hash must match.
assert(pindex == m_chain.Genesis()); // The current active chain's genesis block must be this block.
}
if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock)
@@ -4507,16 +4483,14 @@ bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
this->ToString(), coinstip_size * (1.0 / 1024 / 1024));
BlockValidationState state;
- const CChainParams& chainparams = Params();
-
bool ret;
if (coinstip_size > old_coinstip_size) {
// Likely no need to flush if cache sizes have grown.
- ret = FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED);
+ ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
} else {
// Otherwise, flush state to disk and deallocate the in-memory coins map.
- ret = FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS);
+ ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
CoinsTip().ReallocateCache();
}
return ret;
@@ -4816,7 +4790,7 @@ bool ChainstateManager::ActivateSnapshot(
LOCK(::cs_main);
assert(!m_snapshot_chainstate);
m_snapshot_chainstate.swap(snapshot_chainstate);
- const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip(::Params());
+ const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip();
assert(chaintip_loaded);
m_active_chainstate = m_snapshot_chainstate.get();
@@ -4879,6 +4853,14 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
coins_count - coins_left);
return false;
}
+ if (coin.nHeight > base_height ||
+ outpoint.n >= std::numeric_limits<decltype(outpoint.n)>::max() // Avoid integer wrap-around in coinstats.cpp:ApplyHash
+ ) {
+ LogPrintf("[snapshot] bad snapshot data after deserializing %d coins\n",
+ coins_count - coins_left);
+ return false;
+ }
+
coins_cache.EmplaceCoinInternalDANGER(std::move(outpoint), std::move(coin));
--coins_left;
@@ -4990,7 +4972,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
// Fake BLOCK_OPT_WITNESS so that CChainState::NeedsRedownload()
// won't ask to rewind the entire assumed-valid chain on startup.
- if (index->pprev && ::IsWitnessEnabled(index->pprev, ::Params().GetConsensus())) {
+ if (index->pprev && DeploymentActiveAt(*index, ::Params().GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) {
index->nStatus |= BLOCK_OPT_WITNESS;
}
}
diff --git a/src/validation.h b/src/validation.h
index 5720ba8071..3d66e3161d 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -24,7 +24,6 @@
#include <sync.h>
#include <txmempool.h> // For CTxMemPool::cs
#include <txdb.h>
-#include <versionbits.h>
#include <serialize.h>
#include <util/check.h>
#include <util/hasher.h>
@@ -345,10 +344,6 @@ bool TestBlockValidity(BlockValidationState& state,
bool fCheckPOW = true,
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-/** Check whether witness commitments are required for a block, and whether to enforce NULLDUMMY (BIP 147) rules.
- * Note that transaction witness validation rules are always enforced when P2SH is enforced. */
-bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params);
-
/** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
@@ -595,6 +590,8 @@ protected:
//! mempool that is kept in sync with the chain
CTxMemPool& m_mempool;
+ const CChainParams& m_params;
+
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
std::unique_ptr<CoinsViews> m_coins_views;
@@ -680,7 +677,7 @@ public:
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** Import blocks from an external file */
- void LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFilePos* dbp = nullptr);
+ void LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp = nullptr);
/**
* Update the on-disk chain state.
@@ -694,8 +691,7 @@ public:
* @returns true unless a system error occurred
*/
bool FlushStateToDisk(
- const CChainParams& chainparams,
- BlockValidationState &state,
+ BlockValidationState& state,
FlushStateMode mode,
int nManualPruneHeight = 0);
@@ -723,37 +719,36 @@ public:
*/
bool ActivateBestChain(
BlockValidationState& state,
- const CChainParams& chainparams,
std::shared_ptr<const CBlock> pblock = nullptr) LOCKS_EXCLUDED(cs_main);
- bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Block (dis)connection on a given view:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view);
bool ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
- CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ CCoinsViewCache& view, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Apply the effects of a block disconnection on the UTXO set.
- bool DisconnectTip(BlockValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
+ bool DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
// Manual block validity manipulation:
/** Mark a block as precious and reorganize.
*
* May not be called in a validationinterface callback.
*/
- bool PreciousBlock(BlockValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
+ bool PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
/** Mark a block as invalid. */
- bool InvalidateBlock(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
+ bool InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
/** Remove invalidity status from a block and its descendants. */
void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Replay blocks that aren't fully applied to the database. */
- bool ReplayBlocks(const CChainParams& params);
+ bool ReplayBlocks();
/** Whether the chain state needs to be redownloaded due to lack of witness data */
- [[nodiscard]] bool NeedsRedownload(const CChainParams& params) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ [[nodiscard]] bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
- bool LoadGenesisBlock(const CChainParams& chainparams);
+ bool LoadGenesisBlock();
void PruneBlockIndexCandidates();
@@ -767,13 +762,13 @@ public:
*
* By default this only executes fully when using the Regtest chain; see: fCheckBlockIndex.
*/
- void CheckBlockIndex(const Consensus::Params& consensusParams);
+ void CheckBlockIndex();
/** Load the persisted mempool from disk */
void LoadMempool(const ArgsManager& args);
/** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */
- bool LoadChainTip(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
//! Dictates whether we need to flush the cache to disk or not.
//!
@@ -789,19 +784,19 @@ public:
std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
private:
- bool ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
- bool ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
+ bool ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
+ bool ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
- void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ void InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void InvalidChainFound(CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- bool LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
friend ChainstateManager;
};
@@ -1002,7 +997,7 @@ public:
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
//! Load the block tree and coins database from disk, initializing state if we're running with -reindex
- bool LoadBlockIndex(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
//! Unload block index and chain data before shutdown.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
@@ -1024,13 +1019,6 @@ public:
/** Global variable that points to the active block tree (protected by cs_main) */
extern std::unique_ptr<CBlockTreeDB> pblocktree;
-extern VersionBitsCache versionbitscache;
-
-/**
- * Determine what nVersion a new block should use.
- */
-int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
-
using FopenFn = std::function<FILE*(const fs::path&, const char*)>;
/** Dump the mempool to disk. */
diff --git a/src/versionbits.cpp b/src/versionbits.cpp
index df2ec4e056..94c3c9559f 100644
--- a/src/versionbits.cpp
+++ b/src/versionbits.cpp
@@ -190,29 +190,48 @@ public:
} // namespace
-ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
+ThresholdState VersionBitsCache::State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
{
- return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
+ LOCK(m_mutex);
+ return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
}
-BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
+BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
{
return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
}
-int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
+int VersionBitsCache::StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
{
- return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
+ LOCK(m_mutex);
+ return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, m_caches[pos]);
}
-uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
+uint32_t VersionBitsCache::Mask(const Consensus::Params& params, Consensus::DeploymentPos pos)
{
return VersionBitsConditionChecker(pos).Mask(params);
}
+int32_t VersionBitsCache::ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
+{
+ LOCK(m_mutex);
+ int32_t nVersion = VERSIONBITS_TOP_BITS;
+
+ for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
+ Consensus::DeploymentPos pos = static_cast<Consensus::DeploymentPos>(i);
+ ThresholdState state = VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
+ if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
+ nVersion |= Mask(params, pos);
+ }
+ }
+
+ return nVersion;
+}
+
void VersionBitsCache::Clear()
{
+ LOCK(m_mutex);
for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
- caches[d].clear();
+ m_caches[d].clear();
}
}
diff --git a/src/versionbits.h b/src/versionbits.h
index 634a848ef5..0b2f4a0258 100644
--- a/src/versionbits.h
+++ b/src/versionbits.h
@@ -6,6 +6,8 @@
#define BITCOIN_VERSIONBITS_H
#include <chain.h>
+#include <sync.h>
+
#include <map>
/** What block version to use for new blocks (pre versionbits) */
@@ -71,21 +73,31 @@ public:
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const;
};
-/** BIP 9 allows multiple softforks to be deployed in parallel. We cache per-period state for every one of them
- * keyed by the bit position used to signal support. */
-struct VersionBitsCache
+/** BIP 9 allows multiple softforks to be deployed in parallel. We cache
+ * per-period state for every one of them. */
+class VersionBitsCache
{
- ThresholdConditionCache caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS];
+private:
+ Mutex m_mutex;
+ ThresholdConditionCache m_caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] GUARDED_BY(m_mutex);
+
+public:
+ /** Get the numerical statistics for a given deployment for the signalling period that includes the block after pindexPrev. */
+ static BIP9Stats Statistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
+
+ static uint32_t Mask(const Consensus::Params& params, Consensus::DeploymentPos pos);
+
+ /** Get the BIP9 state for a given deployment for the block after pindexPrev. */
+ ThresholdState State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
+
+ /** Get the block height at which the BIP9 deployment switched into the state for the block after pindexPrev. */
+ int StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
+
+ /** Determine what nVersion a new block should use
+ */
+ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
void Clear();
};
-/** Get the BIP9 state for a given deployment at the current tip. */
-ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
-/** Get the numerical statistics for the BIP9 state for a given deployment at the current tip. */
-BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos);
-/** Get the block height at which the BIP9 deployment switched into the state for the block building on the current tip. */
-int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache);
-uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos);
-
#endif // BITCOIN_VERSIONBITS_H
diff --git a/src/versionbitsinfo.cpp b/src/versionbitsinfo.cpp
deleted file mode 100644
index fa41bad46d..0000000000
--- a/src/versionbitsinfo.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016-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.
-
-#include <versionbitsinfo.h>
-
-#include <consensus/params.h>
-
-const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
- {
- /*.name =*/ "testdummy",
- /*.gbt_force =*/ true,
- },
- {
- /*.name =*/ "taproot",
- /*.gbt_force =*/ true,
- },
-};
diff --git a/src/versionbitsinfo.h b/src/versionbitsinfo.h
deleted file mode 100644
index a7822bc747..0000000000
--- a/src/versionbitsinfo.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2016-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.
-
-#ifndef BITCOIN_VERSIONBITSINFO_H
-#define BITCOIN_VERSIONBITSINFO_H
-
-struct VBDeploymentInfo {
- /** Deployment name */
- const char *name;
- /** Whether GBT clients can safely ignore this rule in simplified usage */
- bool gbt_force;
-};
-
-extern const struct VBDeploymentInfo VersionBitsDeploymentInfo[];
-
-#endif // BITCOIN_VERSIONBITSINFO_H
diff --git a/src/wallet/external_signer_scriptpubkeyman.h b/src/wallet/external_signer_scriptpubkeyman.h
index 8eed947b7b..61df3d0015 100644
--- a/src/wallet/external_signer_scriptpubkeyman.h
+++ b/src/wallet/external_signer_scriptpubkeyman.h
@@ -15,8 +15,8 @@ class ExternalSignerScriptPubKeyMan : public DescriptorScriptPubKeyMan
ExternalSignerScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor)
: DescriptorScriptPubKeyMan(storage, descriptor)
{}
- ExternalSignerScriptPubKeyMan(WalletStorage& storage, bool internal)
- : DescriptorScriptPubKeyMan(storage, internal)
+ ExternalSignerScriptPubKeyMan(WalletStorage& storage)
+ : DescriptorScriptPubKeyMan(storage)
{}
/** Provide a descriptor at setup time
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 5a832d020b..e33adf94c9 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -475,13 +475,13 @@ public:
std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) override
{
return MakeHandler(m_wallet->NotifyAddressBookChanged.connect(
- [fn](CWallet*, const CTxDestination& address, const std::string& label, bool is_mine,
- const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); }));
+ [fn](const CTxDestination& address, const std::string& label, bool is_mine,
+ const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); }));
}
std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override
{
return MakeHandler(m_wallet->NotifyTransactionChanged.connect(
- [fn](CWallet*, const uint256& txid, ChangeType status) { fn(txid, status); }));
+ [fn](const uint256& txid, ChangeType status) { fn(txid, status); }));
}
std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override
{
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 4e9ba83ead..ea97b339cf 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -286,6 +286,9 @@ RPCHelpMan importaddress()
if (fP2SH) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot use the p2sh flag with an address - use a script instead");
}
+ if (OutputTypeFromDestination(dest) == OutputType::BECH32M) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m addresses cannot be imported into legacy wallets");
+ }
pwallet->MarkDirty();
@@ -962,6 +965,9 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address \"" + output + "\"");
}
+ if (OutputTypeFromDestination(dest) == OutputType::BECH32M) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m addresses cannot be imported into legacy wallets");
+ }
script = GetScriptForDestination(dest);
} else {
if (!IsHex(output)) {
@@ -1086,6 +1092,9 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
if (!parsed_desc) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
}
+ if (parsed_desc->GetOutputType() == OutputType::BECH32M) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m descriptors cannot be imported into legacy wallets");
+ }
have_solving_data = parsed_desc->IsSolvable();
const bool watch_only = data.exists("watchonly") ? data["watchonly"].get_bool() : false;
@@ -1557,9 +1566,8 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
// Check if the wallet already contains the descriptor
auto existing_spk_manager = wallet.GetDescriptorScriptPubKeyMan(w_desc);
if (existing_spk_manager) {
- LOCK(existing_spk_manager->cs_desc_man);
- if (range_start > existing_spk_manager->GetWalletDescriptor().range_start) {
- throw JSONRPCError(RPC_INVALID_PARAMS, strprintf("range_start can only decrease; current range = [%d,%d]", existing_spk_manager->GetWalletDescriptor().range_start, existing_spk_manager->GetWalletDescriptor().range_end));
+ if (!existing_spk_manager->CanUpdateToWalletDescriptor(w_desc, error)) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, error);
}
}
@@ -1576,16 +1584,16 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
} else {
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
}
+ } else {
+ if (w_desc.descriptor->GetOutputType()) {
+ wallet.DeactivateScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
+ }
}
result.pushKV("success", UniValue(true));
} catch (const UniValue& e) {
result.pushKV("success", UniValue(false));
result.pushKV("error", e);
- } catch (...) {
- result.pushKV("success", UniValue(false));
-
- result.pushKV("error", JSONRPCError(RPC_MISC_ERROR, "Missing required fields"));
}
if (warnings.size()) result.pushKV("warnings", warnings);
return result;
@@ -1778,8 +1786,6 @@ RPCHelpMan listdescriptors()
throw JSONRPCError(RPC_WALLET_ERROR, "listdescriptors is not available for non-descriptor wallets");
}
- EnsureWalletIsUnlocked(*wallet);
-
LOCK(wallet->cs_wallet);
UniValue descriptors(UniValue::VARR);
@@ -1793,7 +1799,7 @@ RPCHelpMan listdescriptors()
LOCK(desc_spk_man->cs_desc_man);
const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
std::string descriptor;
- if (!desc_spk_man->GetDescriptorString(descriptor, false)) {
+ if (!desc_spk_man->GetDescriptorString(descriptor)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Can't get normalized descriptor string.");
}
spk.pushKV("desc", descriptor);
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index e03835eaff..f1d5117415 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -269,6 +269,9 @@ static RPCHelpMan getnewaddress()
if (!ParseOutputType(request.params[1].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
}
+ if (output_type == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
+ }
}
CTxDestination dest;
@@ -313,6 +316,9 @@ static RPCHelpMan getrawchangeaddress()
if (!ParseOutputType(request.params[0].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
}
+ if (output_type == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
+ }
}
CTxDestination dest;
@@ -1004,6 +1010,9 @@ static RPCHelpMan addmultisigaddress()
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
}
+ if (output_type == OutputType::BECH32M) {
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m multisig addresses cannot be created with legacy wallets");
+ }
}
// Construct using pay-to-script-hash:
@@ -3863,7 +3872,7 @@ RPCHelpMan getaddressinfo()
DescriptorScriptPubKeyMan* desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(pwallet->GetScriptPubKeyMan(scriptPubKey));
if (desc_spk_man) {
std::string desc_str;
- if (desc_spk_man->GetDescriptorString(desc_str, false)) {
+ if (desc_spk_man->GetDescriptorString(desc_str)) {
ret.pushKV("parent_desc", desc_str);
}
}
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index c8baa0665e..73433214f1 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -22,6 +22,12 @@ const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
{
+ if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
+ error = _("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types").translated;
+ return false;
+ }
+ assert(type != OutputType::BECH32M);
+
LOCK(cs_KeyStore);
error.clear();
@@ -289,14 +295,22 @@ bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBat
return true;
}
-bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
+bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error)
{
+ if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
+ error = _("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types").translated;
+ return false;
+ }
+ assert(type != OutputType::BECH32M);
+
LOCK(cs_KeyStore);
if (!CanGetAddresses(internal)) {
+ error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}
if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
+ error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}
address = GetDestinationForKey(keypool.vchPubKey, type);
@@ -1294,6 +1308,7 @@ void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const
void LegacyScriptPubKeyMan::KeepDestination(int64_t nIndex, const OutputType& type)
{
+ assert(type != OutputType::BECH32M);
// Remove from key pool
WalletBatch batch(m_storage.GetDatabase());
batch.ErasePool(nIndex);
@@ -1327,6 +1342,7 @@ void LegacyScriptPubKeyMan::ReturnDestination(int64_t nIndex, bool fInternal, co
bool LegacyScriptPubKeyMan::GetKeyFromPool(CPubKey& result, const OutputType type, bool internal)
{
+ assert(type != OutputType::BECH32M);
if (!CanGetAddresses(internal)) {
return false;
}
@@ -1395,6 +1411,7 @@ bool LegacyScriptPubKeyMan::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& key
void LegacyScriptPubKeyMan::LearnRelatedScripts(const CPubKey& key, OutputType type)
{
+ assert(type != OutputType::BECH32M);
if (key.IsCompressed() && (type == OutputType::P2SH_SEGWIT || type == OutputType::BECH32)) {
CTxDestination witdest = WitnessV0KeyHash(key.GetID());
CScript witprog = GetScriptForDestination(witdest);
@@ -1596,12 +1613,10 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const
return set_address;
}
-void LegacyScriptPubKeyMan::SetInternal(bool internal) {}
-
bool DescriptorScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error)
{
// Returns true if this descriptor supports getting new addresses. Conditions where we may be unable to fetch them (e.g. locked) are caught later
- if (!CanGetAddresses(m_internal)) {
+ if (!CanGetAddresses()) {
error = "No addresses available";
return false;
}
@@ -1706,10 +1721,9 @@ bool DescriptorScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, Walle
return true;
}
-bool DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
+bool DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error)
{
LOCK(cs_desc_man);
- std::string error;
bool result = GetNewDestination(type, address, error);
index = m_wallet_descriptor.next_index - 1;
return result;
@@ -1789,34 +1803,10 @@ bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
}
m_map_pubkeys[pubkey] = i;
}
- // Write the cache
- for (const auto& parent_xpub_pair : temp_cache.GetCachedParentExtPubKeys()) {
- CExtPubKey xpub;
- if (m_wallet_descriptor.cache.GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
- if (xpub != parent_xpub_pair.second) {
- throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
- }
- continue;
- }
- if (!batch.WriteDescriptorParentCache(parent_xpub_pair.second, id, parent_xpub_pair.first)) {
- throw std::runtime_error(std::string(__func__) + ": writing cache item failed");
- }
- m_wallet_descriptor.cache.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
- }
- for (const auto& derived_xpub_map_pair : temp_cache.GetCachedDerivedExtPubKeys()) {
- for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
- CExtPubKey xpub;
- if (m_wallet_descriptor.cache.GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
- if (xpub != derived_xpub_pair.second) {
- throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
- }
- continue;
- }
- if (!batch.WriteDescriptorDerivedCache(derived_xpub_pair.second, id, derived_xpub_map_pair.first, derived_xpub_pair.first)) {
- throw std::runtime_error(std::string(__func__) + ": writing cache item failed");
- }
- m_wallet_descriptor.cache.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
- }
+ // Merge and write the cache
+ DescriptorCache new_items = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
+ if (!batch.WriteDescriptorCacheItems(id, new_items)) {
+ throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
}
m_max_cached_index++;
}
@@ -1859,6 +1849,12 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
AssertLockHeld(cs_desc_man);
assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
+ // Check if provided key already exists
+ if (m_map_keys.find(pubkey.GetID()) != m_map_keys.end() ||
+ m_map_crypted_keys.find(pubkey.GetID()) != m_map_crypted_keys.end()) {
+ return true;
+ }
+
if (m_storage.HasEncryptionKeys()) {
if (m_storage.IsLocked()) {
return false;
@@ -1878,8 +1874,14 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
}
}
-bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type)
+bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type, bool internal)
{
+ if (addr_type == OutputType::BECH32M) {
+ // Don't allow setting up taproot descriptors yet
+ // TODO: Allow setting up taproot descriptors
+ return false;
+ }
+
LOCK(cs_desc_man);
assert(m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
@@ -1909,6 +1911,7 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_
desc_prefix = "wpkh(" + xpub + "/84'";
break;
}
+ case OutputType::BECH32M: assert(false); // TODO: Setup taproot descriptor
} // no default case, so the compiler can warn about missing cases
assert(!desc_prefix.empty());
@@ -1919,7 +1922,7 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_
desc_prefix += "/0'";
}
- std::string internal_path = m_internal ? "/1" : "/0";
+ std::string internal_path = internal ? "/1" : "/0";
std::string desc_str = desc_prefix + "/0'" + internal_path + desc_suffix;
// Make the descriptor
@@ -1974,13 +1977,6 @@ int64_t DescriptorScriptPubKeyMan::GetOldestKeyPoolTime() const
return 0;
}
-size_t DescriptorScriptPubKeyMan::KeypoolCountExternalKeys() const
-{
- if (m_internal) {
- return 0;
- }
- return GetKeyPoolSize();
-}
unsigned int DescriptorScriptPubKeyMan::GetKeyPoolSize() const
{
@@ -2182,11 +2178,6 @@ uint256 DescriptorScriptPubKeyMan::GetID() const
return id;
}
-void DescriptorScriptPubKeyMan::SetInternal(bool internal)
-{
- this->m_internal = internal;
-}
-
void DescriptorScriptPubKeyMan::SetCache(const DescriptorCache& cache)
{
LOCK(cs_desc_man);
@@ -2267,15 +2258,75 @@ const std::vector<CScript> DescriptorScriptPubKeyMan::GetScriptPubKeys() const
return script_pub_keys;
}
-bool DescriptorScriptPubKeyMan::GetDescriptorString(std::string& out, bool priv) const
+bool DescriptorScriptPubKeyMan::GetDescriptorString(std::string& out) const
{
LOCK(cs_desc_man);
- if (m_storage.IsLocked()) {
- return false;
+
+ FlatSigningProvider provider;
+ provider.keys = GetKeys();
+
+ return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out, &m_wallet_descriptor.cache);
+}
+
+void DescriptorScriptPubKeyMan::UpgradeDescriptorCache()
+{
+ LOCK(cs_desc_man);
+ if (m_storage.IsLocked() || m_storage.IsWalletFlagSet(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED)) {
+ return;
}
+ // Skip if we have the last hardened xpub cache
+ if (m_wallet_descriptor.cache.GetCachedLastHardenedExtPubKeys().size() > 0) {
+ return;
+ }
+
+ // Expand the descriptor
FlatSigningProvider provider;
provider.keys = GetKeys();
+ FlatSigningProvider out_keys;
+ std::vector<CScript> scripts_temp;
+ DescriptorCache temp_cache;
+ if (!m_wallet_descriptor.descriptor->Expand(0, provider, scripts_temp, out_keys, &temp_cache)){
+ throw std::runtime_error("Unable to expand descriptor");
+ }
+
+ // Cache the last hardened xpubs
+ DescriptorCache diff = m_wallet_descriptor.cache.MergeAndDiff(temp_cache);
+ if (!WalletBatch(m_storage.GetDatabase()).WriteDescriptorCacheItems(GetID(), diff)) {
+ throw std::runtime_error(std::string(__func__) + ": writing cache items failed");
+ }
+}
- return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out, priv);
+void DescriptorScriptPubKeyMan::UpdateWalletDescriptor(WalletDescriptor& descriptor)
+{
+ LOCK(cs_desc_man);
+ std::string error;
+ if (!CanUpdateToWalletDescriptor(descriptor, error)) {
+ throw std::runtime_error(std::string(__func__) + ": " + error);
+ }
+
+ m_map_pubkeys.clear();
+ m_map_script_pub_keys.clear();
+ m_max_cached_index = -1;
+ m_wallet_descriptor = descriptor;
+}
+
+bool DescriptorScriptPubKeyMan::CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error)
+{
+ LOCK(cs_desc_man);
+ if (!HasWalletDescriptor(descriptor)) {
+ error = "can only update matching descriptor";
+ return false;
+ }
+
+ if (descriptor.range_start > m_wallet_descriptor.range_start ||
+ descriptor.range_end < m_wallet_descriptor.range_end) {
+ // Use inclusive range for error
+ error = strprintf("new range must include current range = [%d,%d]",
+ m_wallet_descriptor.range_start,
+ m_wallet_descriptor.range_end - 1);
+ return false;
+ }
+
+ return true;
}
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 3c4603608c..572a695662 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -181,7 +181,7 @@ public:
virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
- virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { return false; }
+ virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) { return false; }
virtual void KeepDestination(int64_t index, const OutputType& type) {}
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
@@ -216,7 +216,6 @@ public:
virtual int64_t GetOldestKeyPoolTime() const { return GetTime(); }
- virtual size_t KeypoolCountExternalKeys() const { return 0; }
virtual unsigned int GetKeyPoolSize() const { return 0; }
virtual int64_t GetTimeFirstKey() const { return 0; }
@@ -239,8 +238,6 @@ public:
virtual uint256 GetID() const { return uint256(); }
- virtual void SetInternal(bool internal) {}
-
/** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */
template<typename... Params>
void WalletLogPrintf(std::string fmt, Params... parameters) const {
@@ -254,6 +251,13 @@ public:
boost::signals2::signal<void ()> NotifyCanGetAddressesChanged;
};
+/** OutputTypes supported by the LegacyScriptPubKeyMan */
+static const std::unordered_set<OutputType> LEGACY_OUTPUT_TYPES {
+ OutputType::LEGACY,
+ OutputType::P2SH_SEGWIT,
+ OutputType::BECH32,
+};
+
class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProvider
{
private:
@@ -357,7 +361,7 @@ public:
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
- bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
+ bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) override;
void KeepDestination(int64_t index, const OutputType& type) override;
void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
@@ -379,7 +383,7 @@ public:
void RewriteDB() override;
int64_t GetOldestKeyPoolTime() const override;
- size_t KeypoolCountExternalKeys() const override;
+ size_t KeypoolCountExternalKeys() const;
unsigned int GetKeyPoolSize() const override;
int64_t GetTimeFirstKey() const override;
@@ -398,8 +402,6 @@ public:
uint256 GetID() const override;
- void SetInternal(bool internal) override;
-
// Map from Key ID to key metadata.
std::map<CKeyID, CKeyMetadata> mapKeyMetadata GUARDED_BY(cs_KeyStore);
@@ -526,8 +528,6 @@ private:
PubKeyMap m_map_pubkeys GUARDED_BY(cs_desc_man);
int32_t m_max_cached_index = -1;
- bool m_internal = false;
-
KeyMap m_map_keys GUARDED_BY(cs_desc_man);
CryptedKeyMap m_map_crypted_keys GUARDED_BY(cs_desc_man);
@@ -553,9 +553,8 @@ public:
: ScriptPubKeyMan(storage),
m_wallet_descriptor(descriptor)
{}
- DescriptorScriptPubKeyMan(WalletStorage& storage, bool internal)
- : ScriptPubKeyMan(storage),
- m_internal(internal)
+ DescriptorScriptPubKeyMan(WalletStorage& storage)
+ : ScriptPubKeyMan(storage)
{}
mutable RecursiveMutex cs_desc_man;
@@ -566,7 +565,7 @@ public:
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
- bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
+ bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) override;
void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) override;
// Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file
@@ -580,7 +579,7 @@ public:
bool IsHDEnabled() const override;
//! Setup descriptors based on the given CExtkey
- bool SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type);
+ bool SetupDescriptorGeneration(const CExtKey& master_key, OutputType addr_type, bool internal);
/** Provide a descriptor at setup time
* Returns false if already setup or setup fails, true if setup is successful
@@ -590,7 +589,6 @@ public:
bool HavePrivateKeys() const override;
int64_t GetOldestKeyPoolTime() const override;
- size_t KeypoolCountExternalKeys() const override;
unsigned int GetKeyPoolSize() const override;
int64_t GetTimeFirstKey() const override;
@@ -609,21 +607,23 @@ public:
uint256 GetID() const override;
- void SetInternal(bool internal) override;
-
void SetCache(const DescriptorCache& cache);
bool AddKey(const CKeyID& key_id, const CKey& key);
bool AddCryptedKey(const CKeyID& key_id, const CPubKey& pubkey, const std::vector<unsigned char>& crypted_key);
bool HasWalletDescriptor(const WalletDescriptor& desc) const;
+ void UpdateWalletDescriptor(WalletDescriptor& descriptor);
+ bool CanUpdateToWalletDescriptor(const WalletDescriptor& descriptor, std::string& error);
void AddDescriptorKey(const CKey& key, const CPubKey &pubkey);
void WriteDescriptor();
const WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
const std::vector<CScript> GetScriptPubKeys() const;
- bool GetDescriptorString(std::string& out, bool priv) const;
+ bool GetDescriptorString(std::string& out) const;
+
+ void UpgradeDescriptorCache();
};
#endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index c8ded4c51e..6a8df437ae 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -618,8 +618,9 @@ bool CWallet::CreateTransactionInternal(
// Reserve a new key pair from key pool. If it fails, provide a dummy
// destination in case we don't need change.
CTxDestination dest;
- if (!reservedest.GetReservedDestination(dest, true)) {
- error = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
+ std::string dest_err;
+ if (!reservedest.GetReservedDestination(dest, true, dest_err)) {
+ error = strprintf(_("Transaction needs a change address, but we can't generate it. %s"), dest_err);
}
scriptChange = GetScriptForDestination(dest);
// A valid destination implies a change script (and
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 256faf2b23..27565aefc9 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -374,6 +374,19 @@ void CWallet::UpgradeKeyMetadata()
SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
}
+void CWallet::UpgradeDescriptorCache()
+{
+ if (!IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) || IsLocked() || IsWalletFlagSet(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED)) {
+ return;
+ }
+
+ for (ScriptPubKeyMan* spkm : GetAllScriptPubKeyMans()) {
+ DescriptorScriptPubKeyMan* desc_spkm = dynamic_cast<DescriptorScriptPubKeyMan*>(spkm);
+ desc_spkm->UpgradeDescriptorCache();
+ }
+ SetWalletFlag(WALLET_FLAG_LAST_HARDENED_XPUB_CACHED);
+}
+
bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
{
CCrypter crypter;
@@ -390,6 +403,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_key
if (Unlock(_vMasterKey, accept_no_keys)) {
// Now that we've unlocked, upgrade the key metadata
UpgradeKeyMetadata();
+ // Now that we've unlocked, upgrade the descriptor cache
+ UpgradeDescriptorCache();
return true;
}
}
@@ -801,7 +816,7 @@ bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
success = false;
}
- NotifyTransactionChanged(this, originalHash, CT_UPDATED);
+ NotifyTransactionChanged(originalHash, CT_UPDATED);
return success;
}
@@ -930,7 +945,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
wtx.MarkDirty();
// Notify UI of new or updated transaction
- NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
+ NotifyTransactionChanged(hash, fInsertedNew ? CT_NEW : CT_UPDATED);
#if HAVE_SYSTEM
// notify an external script when a wallet transaction comes in or is updated
@@ -1104,7 +1119,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
wtx.setAbandoned();
wtx.MarkDirty();
batch.WriteTx(wtx);
- NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
+ NotifyTransactionChanged(wtx.GetHash(), CT_UPDATED);
// Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
while (iter != mapTxSpends.end() && iter->first.hash == now) {
@@ -1909,7 +1924,13 @@ OutputType CWallet::TransactionChangeType(const std::optional<OutputType>& chang
int witnessversion = 0;
std::vector<unsigned char> witnessprogram;
if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
- return OutputType::BECH32;
+ if (GetScriptPubKeyMan(OutputType::BECH32M, true)) {
+ return OutputType::BECH32M;
+ } else if (GetScriptPubKeyMan(OutputType::BECH32, true)) {
+ return OutputType::BECH32;
+ } else {
+ return m_default_address_type;
+ }
}
}
@@ -1938,7 +1959,7 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
for (const CTxIn& txin : tx->vin) {
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
coin.MarkDirty();
- NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
+ NotifyTransactionChanged(coin.GetHash(), CT_UPDATED);
}
// Get the inserted-CWalletTx from mapWallet so that the
@@ -1993,7 +2014,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
for (const auto& txin : it->second.tx->vin)
mapTxSpends.erase(txin.prevout);
mapWallet.erase(it);
- NotifyTransactionChanged(this, hash, CT_DELETED);
+ NotifyTransactionChanged(hash, CT_DELETED);
}
if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
@@ -2027,8 +2048,8 @@ bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& add
m_address_book[address].purpose = strPurpose;
is_mine = IsMine(address) != ISMINE_NO;
}
- NotifyAddressBookChanged(this, address, strName, is_mine,
- strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
+ NotifyAddressBookChanged(address, strName, is_mine,
+ strPurpose, (fUpdated ? CT_UPDATED : CT_NEW));
if (!strPurpose.empty() && !batch.WritePurpose(EncodeDestination(address), strPurpose))
return false;
return batch.WriteName(EncodeDestination(address), strName);
@@ -2063,7 +2084,7 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
is_mine = IsMine(address) != ISMINE_NO;
}
- NotifyAddressBookChanged(this, address, "", is_mine, "", CT_DELETED);
+ NotifyAddressBookChanged(address, "", is_mine, "", CT_DELETED);
batch.ErasePurpose(EncodeDestination(address));
return batch.EraseName(EncodeDestination(address));
@@ -2073,9 +2094,14 @@ size_t CWallet::KeypoolCountExternalKeys() const
{
AssertLockHeld(cs_wallet);
+ auto legacy_spk_man = GetLegacyScriptPubKeyMan();
+ if (legacy_spk_man) {
+ return legacy_spk_man->KeypoolCountExternalKeys();
+ }
+
unsigned int count = 0;
- for (auto spk_man : GetActiveScriptPubKeyMans()) {
- count += spk_man->KeypoolCountExternalKeys();
+ for (auto spk_man : m_external_spk_managers) {
+ count += spk_man.second->GetKeyPoolSize();
}
return count;
@@ -2112,7 +2138,7 @@ bool CWallet::GetNewDestination(const OutputType type, const std::string label,
spk_man->TopUp();
result = spk_man->GetNewDestination(type, dest, error);
} else {
- error = strprintf("Error: No %s addresses available.", FormatOutputType(type));
+ error = strprintf(_("Error: No %s addresses available."), FormatOutputType(type)).translated;
}
if (result) {
SetAddressBook(dest, label, "receive");
@@ -2127,8 +2153,7 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des
error.clear();
ReserveDestination reservedest(this, type);
- if (!reservedest.GetReservedDestination(dest, true)) {
- error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
+ if (!reservedest.GetReservedDestination(dest, true, error)) {
return false;
}
@@ -2175,10 +2200,11 @@ std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) co
return result;
}
-bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal)
+bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal, std::string& error)
{
m_spk_man = pwallet->GetScriptPubKeyMan(type, internal);
if (!m_spk_man) {
+ error = strprintf(_("Error: No %s addresses available."), FormatOutputType(type)).translated;
return false;
}
@@ -2188,7 +2214,7 @@ bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool inter
m_spk_man->TopUp();
CKeyPool keypool;
- if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool)) {
+ if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool, error)) {
return false;
}
fInternal = keypool.fInternal;
@@ -2956,7 +2982,6 @@ ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(const OutputType& type, bool intern
const std::map<OutputType, ScriptPubKeyMan*>& spk_managers = internal ? m_internal_spk_managers : m_external_spk_managers;
std::map<OutputType, ScriptPubKeyMan*>::const_iterator it = spk_managers.find(type);
if (it == spk_managers.end()) {
- WalletLogPrintf("%s scriptPubKey Manager for output type %d does not exist\n", internal ? "Internal" : "External", static_cast<int>(type));
return nullptr;
}
return it->second;
@@ -3033,7 +3058,7 @@ void CWallet::SetupLegacyScriptPubKeyMan()
}
auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new LegacyScriptPubKeyMan(*this));
- for (const auto& type : OUTPUT_TYPES) {
+ for (const auto& type : LEGACY_OUTPUT_TYPES) {
m_internal_spk_managers[type] = spk_manager.get();
m_external_spk_managers[type] = spk_manager.get();
}
@@ -3086,7 +3111,12 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
for (bool internal : {false, true}) {
for (OutputType t : OUTPUT_TYPES) {
- auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, internal));
+ if (t == OutputType::BECH32M) {
+ // Skip taproot (bech32m) for now
+ // TODO: Setup taproot (bech32m) descriptors by default
+ continue;
+ }
+ auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this));
if (IsCrypted()) {
if (IsLocked()) {
throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors");
@@ -3095,7 +3125,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors");
}
}
- spk_manager->SetupDescriptorGeneration(master_key, t);
+ spk_manager->SetupDescriptorGeneration(master_key, t, internal);
uint256 id = spk_manager->GetID();
m_spk_managers[id] = std::move(spk_manager);
AddActiveScriptPubKeyMan(id, t, internal);
@@ -3121,7 +3151,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
continue;
}
OutputType t = *desc->GetOutputType();
- auto spk_manager = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this, internal));
+ auto spk_manager = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this));
spk_manager->SetupDescriptor(std::move(desc));
uint256 id = spk_manager->GetID();
m_spk_managers[id] = std::move(spk_manager);
@@ -3142,12 +3172,37 @@ void CWallet::AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool interna
void CWallet::LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
{
+ // Activating ScriptPubKeyManager for a given output and change type is incompatible with legacy wallets.
+ // Legacy wallets have only one ScriptPubKeyManager and it's active for all output and change types.
+ Assert(IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
+
WalletLogPrintf("Setting spkMan to active: id = %s, type = %d, internal = %d\n", id.ToString(), static_cast<int>(type), static_cast<int>(internal));
auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
+ auto& spk_mans_other = internal ? m_external_spk_managers : m_internal_spk_managers;
auto spk_man = m_spk_managers.at(id).get();
- spk_man->SetInternal(internal);
spk_mans[type] = spk_man;
+ if (spk_mans_other[type] == spk_man) {
+ spk_mans_other.erase(type);
+ }
+
+ NotifyCanGetAddressesChanged();
+}
+
+void CWallet::DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal)
+{
+ auto spk_man = GetScriptPubKeyMan(type, internal);
+ if (spk_man != nullptr && spk_man->GetID() == id) {
+ WalletLogPrintf("Deactivate spkMan: id = %s, type = %d, internal = %d\n", id.ToString(), static_cast<int>(type), static_cast<int>(internal));
+ WalletBatch batch(GetDatabase());
+ if (!batch.EraseActiveScriptPubKeyMan(static_cast<uint8_t>(type), internal)) {
+ throw std::runtime_error(std::string(__func__) + ": erasing active ScriptPubKeyMan id failed");
+ }
+
+ auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
+ spk_mans.erase(type);
+ }
+
NotifyCanGetAddressesChanged();
}
@@ -3181,44 +3236,26 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat
}
LOCK(cs_wallet);
- auto new_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
-
- // If we already have this descriptor, remove it from the maps but add the existing cache to desc
- auto old_spk_man = GetDescriptorScriptPubKeyMan(desc);
- if (old_spk_man) {
+ auto spk_man = GetDescriptorScriptPubKeyMan(desc);
+ if (spk_man) {
WalletLogPrintf("Update existing descriptor: %s\n", desc.descriptor->ToString());
+ spk_man->UpdateWalletDescriptor(desc);
+ } else {
+ auto new_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
+ spk_man = new_spk_man.get();
- {
- LOCK(old_spk_man->cs_desc_man);
- new_spk_man->SetCache(old_spk_man->GetWalletDescriptor().cache);
- }
-
- // Remove from maps of active spkMans
- auto old_spk_man_id = old_spk_man->GetID();
- for (bool internal : {false, true}) {
- for (OutputType t : OUTPUT_TYPES) {
- auto active_spk_man = GetScriptPubKeyMan(t, internal);
- if (active_spk_man && active_spk_man->GetID() == old_spk_man_id) {
- if (internal) {
- m_internal_spk_managers.erase(t);
- } else {
- m_external_spk_managers.erase(t);
- }
- break;
- }
- }
- }
- m_spk_managers.erase(old_spk_man_id);
+ // Save the descriptor to memory
+ m_spk_managers[new_spk_man->GetID()] = std::move(new_spk_man);
}
// Add the private keys to the descriptor
for (const auto& entry : signing_provider.keys) {
const CKey& key = entry.second;
- new_spk_man->AddDescriptorKey(key, key.GetPubKey());
+ spk_man->AddDescriptorKey(key, key.GetPubKey());
}
// Top up key pool, the manager will generate new scriptPubKeys internally
- if (!new_spk_man->TopUp()) {
+ if (!spk_man->TopUp()) {
WalletLogPrintf("Could not top up scriptPubKeys\n");
return nullptr;
}
@@ -3226,7 +3263,7 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat
// Apply the label if necessary
// Note: we disable labels for ranged descriptors
if (!desc.descriptor->IsRange()) {
- auto script_pub_keys = new_spk_man->GetScriptPubKeys();
+ auto script_pub_keys = spk_man->GetScriptPubKeys();
if (script_pub_keys.empty()) {
WalletLogPrintf("Could not generate scriptPubKeys (cache is empty)\n");
return nullptr;
@@ -3238,12 +3275,8 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat
}
}
- // Save the descriptor to memory
- auto ret = new_spk_man.get();
- m_spk_managers[new_spk_man->GetID()] = std::move(new_spk_man);
-
// Save the descriptor to DB
- ret->WriteDescriptor();
+ spk_man->WriteDescriptor();
- return ret;
+ return spk_man;
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 66f39edb4d..3997751f52 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -117,6 +117,7 @@ static constexpr uint64_t KNOWN_WALLET_FLAGS =
WALLET_FLAG_AVOID_REUSE
| WALLET_FLAG_BLANK_WALLET
| WALLET_FLAG_KEY_ORIGIN_METADATA
+ | WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
| WALLET_FLAG_DISABLE_PRIVATE_KEYS
| WALLET_FLAG_DESCRIPTORS
| WALLET_FLAG_EXTERNAL_SIGNER;
@@ -128,6 +129,7 @@ static const std::map<std::string,WalletFlags> WALLET_FLAG_MAP{
{"avoid_reuse", WALLET_FLAG_AVOID_REUSE},
{"blank", WALLET_FLAG_BLANK_WALLET},
{"key_origin_metadata", WALLET_FLAG_KEY_ORIGIN_METADATA},
+ {"last_hardened_xpub_cached", WALLET_FLAG_LAST_HARDENED_XPUB_CACHED},
{"disable_private_keys", WALLET_FLAG_DISABLE_PRIVATE_KEYS},
{"descriptor_wallet", WALLET_FLAG_DESCRIPTORS},
{"external_signer", WALLET_FLAG_EXTERNAL_SIGNER}
@@ -181,7 +183,7 @@ public:
}
//! Reserve an address
- bool GetReservedDestination(CTxDestination& pubkey, bool internal);
+ bool GetReservedDestination(CTxDestination& pubkey, bool internal, std::string& error);
//! Return reserved address
void ReturnDestination();
//! Keep the address. Do not return it's key to the keypool when this object goes out of scope
@@ -476,6 +478,9 @@ public:
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ //! Upgrade DescriptorCaches
+ void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+
bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; return true; }
//! Adds a destination data tuple to the store, without saving it to disk
@@ -724,19 +729,18 @@ public:
/**
* Address book entry changed.
- * @note called with lock cs_wallet held.
+ * @note called without lock cs_wallet held.
*/
- boost::signals2::signal<void (CWallet *wallet, const CTxDestination
- &address, const std::string &label, bool isMine,
- const std::string &purpose,
- ChangeType status)> NotifyAddressBookChanged;
+ boost::signals2::signal<void(const CTxDestination& address,
+ const std::string& label, bool isMine,
+ const std::string& purpose, ChangeType status)>
+ NotifyAddressBookChanged;
/**
* Wallet transaction added, removed or updated.
* @note called with lock cs_wallet held.
*/
- boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
- ChangeType status)> NotifyTransactionChanged;
+ boost::signals2::signal<void(const uint256& hashTx, ChangeType status)> NotifyTransactionChanged;
/** Show progress e.g. for rescan */
boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
@@ -895,6 +899,12 @@ public:
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal);
+ //! Remove specified ScriptPubKeyMan from set of active SPK managers. Writes the change to the wallet file.
+ //! @param[in] id The unique id for the ScriptPubKeyMan
+ //! @param[in] type The OutputType this ScriptPubKeyMan provides addresses for
+ //! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
+ void DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal);
+
//! Create new DescriptorScriptPubKeyMans and add them to the wallet
void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 24d5351945..1e5d8dfa3a 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -52,6 +52,7 @@ const std::string TX{"tx"};
const std::string VERSION{"version"};
const std::string WALLETDESCRIPTOR{"walletdescriptor"};
const std::string WALLETDESCRIPTORCACHE{"walletdescriptorcache"};
+const std::string WALLETDESCRIPTORLHCACHE{"walletdescriptorlhcache"};
const std::string WALLETDESCRIPTORCKEY{"walletdescriptorckey"};
const std::string WALLETDESCRIPTORKEY{"walletdescriptorkey"};
const std::string WATCHMETA{"watchmeta"};
@@ -209,6 +210,12 @@ bool WalletBatch::WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bo
return WriteIC(make_pair(key, type), id);
}
+bool WalletBatch::EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
+{
+ const std::string key{internal ? DBKeys::ACTIVEINTERNALSPK : DBKeys::ACTIVEEXTERNALSPK};
+ return EraseIC(make_pair(key, type));
+}
+
bool WalletBatch::WriteDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const CPrivKey& privkey)
{
// hash pubkey/privkey to accelerate wallet load
@@ -248,6 +255,35 @@ bool WalletBatch::WriteDescriptorParentCache(const CExtPubKey& xpub, const uint2
return WriteIC(std::make_pair(std::make_pair(DBKeys::WALLETDESCRIPTORCACHE, desc_id), key_exp_index), ser_xpub);
}
+bool WalletBatch::WriteDescriptorLastHardenedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index)
+{
+ std::vector<unsigned char> ser_xpub(BIP32_EXTKEY_SIZE);
+ xpub.Encode(ser_xpub.data());
+ return WriteIC(std::make_pair(std::make_pair(DBKeys::WALLETDESCRIPTORLHCACHE, desc_id), key_exp_index), ser_xpub);
+}
+
+bool WalletBatch::WriteDescriptorCacheItems(const uint256& desc_id, const DescriptorCache& cache)
+{
+ for (const auto& parent_xpub_pair : cache.GetCachedParentExtPubKeys()) {
+ if (!WriteDescriptorParentCache(parent_xpub_pair.second, desc_id, parent_xpub_pair.first)) {
+ return false;
+ }
+ }
+ for (const auto& derived_xpub_map_pair : cache.GetCachedDerivedExtPubKeys()) {
+ for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
+ if (!WriteDescriptorDerivedCache(derived_xpub_pair.second, desc_id, derived_xpub_map_pair.first, derived_xpub_pair.first)) {
+ return false;
+ }
+ }
+ }
+ for (const auto& lh_xpub_pair : cache.GetCachedLastHardenedExtPubKeys()) {
+ if (!WriteDescriptorLastHardenedCache(lh_xpub_pair.second, desc_id, lh_xpub_pair.first)) {
+ return false;
+ }
+ }
+ return true;
+}
+
class CWalletScanState {
public:
unsigned int nKeys{0};
@@ -602,6 +638,17 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
} else {
wss.m_descriptor_caches[desc_id].CacheDerivedExtPubKey(key_exp_index, der_index, xpub);
}
+ } else if (strType == DBKeys::WALLETDESCRIPTORLHCACHE) {
+ uint256 desc_id;
+ uint32_t key_exp_index;
+ ssKey >> desc_id;
+ ssKey >> key_exp_index;
+
+ std::vector<unsigned char> ser_xpub(BIP32_EXTKEY_SIZE);
+ ssValue >> ser_xpub;
+ CExtPubKey xpub;
+ xpub.Decode(ser_xpub.data());
+ wss.m_descriptor_caches[desc_id].CacheLastHardenedExtPubKey(key_exp_index, xpub);
} else if (strType == DBKeys::WALLETDESCRIPTORKEY) {
uint256 desc_id;
CPubKey pubkey;
@@ -843,6 +890,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
result = DBErrors::CORRUPT;
}
+ // Upgrade all of the descriptor caches to cache the last hardened xpub
+ // This operation is not atomic, but if it fails, only new entries are added so it is backwards compatible
+ try {
+ pwallet->UpgradeDescriptorCache();
+ } catch (...) {
+ result = DBErrors::CORRUPT;
+ }
+
// Set the inactive chain
if (wss.m_hd_chains.size() > 0) {
LegacyScriptPubKeyMan* legacy_spkm = pwallet->GetLegacyScriptPubKeyMan();
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index e7b2d7d780..9b775eb481 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -246,6 +246,8 @@ public:
bool WriteDescriptor(const uint256& desc_id, const WalletDescriptor& descriptor);
bool WriteDescriptorDerivedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index, uint32_t der_index);
bool WriteDescriptorParentCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
+ bool WriteDescriptorLastHardenedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
+ bool WriteDescriptorCacheItems(const uint256& desc_id, const DescriptorCache& cache);
/// Write destination data key,value tuple to database
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
@@ -253,6 +255,7 @@ public:
bool EraseDestData(const std::string &address, const std::string &key);
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bool internal);
+ bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal);
DBErrors LoadWallet(CWallet* pwallet);
DBErrors FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWalletTx>& vWtx);
diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h
index 0713f768c1..c75e1759bc 100644
--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -43,6 +43,9 @@ enum WalletFlags : uint64_t {
// Indicates that the metadata has already been upgraded to contain key origins
WALLET_FLAG_KEY_ORIGIN_METADATA = (1ULL << 1),
+ // Indicates that the descriptor cache has been upgraded to cache last hardened xpubs
+ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED = (1ULL << 2),
+
// will enforce the rule that the wallet can't contain any private keys (only watch-only/pubkeys)
WALLET_FLAG_DISABLE_PRIVATE_KEYS = (1ULL << 32),
diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
index fab921ef19..cde0399d8b 100644
--- a/test/functional/data/invalid_txs.py
+++ b/test/functional/data/invalid_txs.py
@@ -29,27 +29,32 @@ from test_framework.messages import (
CTxOut,
MAX_MONEY,
)
-from test_framework import script as sc
from test_framework.blocktools import create_tx_with_script, MAX_BLOCK_SIGOPS
from test_framework.script import (
CScript,
+ OP_0,
+ OP_2DIV,
+ OP_2MUL,
+ OP_AND,
OP_CAT,
- OP_SUBSTR,
- OP_LEFT,
- OP_RIGHT,
+ OP_CHECKSIG,
+ OP_DIV,
OP_INVERT,
- OP_AND,
+ OP_LEFT,
+ OP_LSHIFT,
+ OP_MOD,
+ OP_MUL,
OP_OR,
+ OP_RIGHT,
+ OP_RSHIFT,
+ OP_SUBSTR,
+ OP_TRUE,
OP_XOR,
- OP_2MUL,
- OP_2DIV,
- OP_MUL,
- OP_DIV,
- OP_MOD,
- OP_LSHIFT,
- OP_RSHIFT
)
-basic_p2sh = sc.CScript([sc.OP_HASH160, sc.hash160(sc.CScript([sc.OP_0])), sc.OP_EQUAL])
+from test_framework.script_util import (
+ script_to_p2sh_script,
+)
+basic_p2sh = script_to_p2sh_script(CScript([OP_0]))
class BadTxTemplate:
@@ -116,7 +121,7 @@ class SizeTooSmall(BadTxTemplate):
def get_tx(self):
tx = CTransaction()
tx.vin.append(self.valid_txin)
- tx.vout.append(CTxOut(0, sc.CScript([sc.OP_TRUE])))
+ tx.vout.append(CTxOut(0, CScript([OP_TRUE])))
tx.calc_sha256()
return tx
@@ -151,6 +156,19 @@ class DuplicateInput(BadTxTemplate):
return tx
+class PrevoutNullInput(BadTxTemplate):
+ reject_reason = 'bad-txns-prevout-null'
+ expect_disconnect = True
+
+ def get_tx(self):
+ tx = CTransaction()
+ tx.vin.append(self.valid_txin)
+ tx.vin.append(CTxIn(COutPoint(hash=0, n=0xffffffff)))
+ tx.vout.append(CTxOut(1, basic_p2sh))
+ tx.calc_sha256()
+ return tx
+
+
class NonexistentInput(BadTxTemplate):
reject_reason = None # Added as an orphan tx.
expect_disconnect = False
@@ -217,7 +235,7 @@ class TooManySigops(BadTxTemplate):
expect_disconnect = False
def get_tx(self):
- lotsa_checksigs = sc.CScript([sc.OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
+ lotsa_checksigs = CScript([OP_CHECKSIG] * (MAX_BLOCK_SIGOPS))
return create_tx_with_script(
self.spend_tx, 0,
script_pub_key=lotsa_checksigs,
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 389db73bc9..c11eabc917 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -37,17 +37,17 @@ from test_framework.script import (
OP_CHECKSIGVERIFY,
OP_ELSE,
OP_ENDIF,
- OP_EQUAL,
OP_DROP,
OP_FALSE,
- OP_HASH160,
OP_IF,
OP_INVALIDOPCODE,
OP_RETURN,
OP_TRUE,
SIGHASH_ALL,
LegacySignatureHash,
- hash160,
+)
+from test_framework.script_util import (
+ script_to_p2sh_script,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
@@ -469,8 +469,7 @@ class FullBlockTest(BitcoinTestFramework):
# Build the redeem script, hash it, use hash to create the p2sh script
redeem_script = CScript([self.coinbase_pubkey] + [OP_2DUP, OP_CHECKSIGVERIFY] * 5 + [OP_CHECKSIG])
- redeem_script_hash = hash160(redeem_script)
- p2sh_script = CScript([OP_HASH160, redeem_script_hash, OP_EQUAL])
+ p2sh_script = script_to_p2sh_script(redeem_script)
# Create a transaction that spends one satoshi to the p2sh_script, the rest to OP_TRUE
# This must be signed because it is spending a coinbase
diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py
index 8ccdf87ff3..5322b02414 100755
--- a/test/functional/feature_fee_estimation.py
+++ b/test/functional/feature_fee_estimation.py
@@ -18,10 +18,10 @@ from test_framework.script import (
OP_1,
OP_2,
OP_DROP,
- OP_EQUAL,
- OP_HASH160,
OP_TRUE,
- hash160,
+)
+from test_framework.script_util import (
+ script_to_p2sh_script,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -37,8 +37,8 @@ from test_framework.util import (
# time signing.
REDEEM_SCRIPT_1 = CScript([OP_1, OP_DROP])
REDEEM_SCRIPT_2 = CScript([OP_2, OP_DROP])
-P2SH_1 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_1), OP_EQUAL])
-P2SH_2 = CScript([OP_HASH160, hash160(REDEEM_SCRIPT_2), OP_EQUAL])
+P2SH_1 = script_to_p2sh_script(REDEEM_SCRIPT_1)
+P2SH_2 = script_to_p2sh_script(REDEEM_SCRIPT_2)
# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
SCRIPT_SIG = [CScript([OP_TRUE, REDEEM_SCRIPT_1]), CScript([OP_TRUE, REDEEM_SCRIPT_2])]
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index e42f8045db..ed944274e3 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -122,6 +122,9 @@ class ReplaceByFeeTest(BitcoinTestFramework):
self.log.info("Running test no inherited signaling...")
self.test_no_inherited_signaling()
+ self.log.info("Running test replacement relay fee...")
+ self.test_replacement_relay_fee()
+
self.log.info("Passed")
def test_simple_doublespend(self):
@@ -627,6 +630,15 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert_equal(True, self.nodes[0].getmempoolentry(optin_parent_tx['txid'])['bip125-replaceable'])
assert_raises_rpc_error(-26, 'txn-mempool-conflict', self.nodes[0].sendrawtransaction, replacement_child_tx["hex"], 0)
+ def test_replacement_relay_fee(self):
+ wallet = MiniWallet(self.nodes[0])
+ wallet.scan_blocks(start=77, num=1)
+ tx = wallet.send_self_transfer(from_node=self.nodes[0])['tx']
+
+ # Higher fee, higher feerate, different txid, but the replacement does not provide a relay
+ # fee conforming to node's `incrementalrelayfee` policy of 1000 sat per KB.
+ tx.vout[0].nValue -= 1
+ assert_raises_rpc_error(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx.serialize().hex())
if __name__ == '__main__':
ReplaceByFeeTest().main()
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 42910904d7..9cf46d9d11 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -23,7 +23,6 @@ from test_framework.messages import (
CTransaction,
CTxIn,
CTxOut,
- sha256,
tx_from_hex,
)
from test_framework.script import (
@@ -34,12 +33,13 @@ from test_framework.script import (
OP_CHECKMULTISIG,
OP_CHECKSIG,
OP_DROP,
- OP_DUP,
- OP_EQUAL,
- OP_EQUALVERIFY,
- OP_HASH160,
OP_TRUE,
- hash160,
+)
+from test_framework.script_util import (
+ key_to_p2pkh_script,
+ key_to_p2wpkh_script,
+ script_to_p2sh_script,
+ script_to_p2wsh_script,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -353,7 +353,7 @@ class SegWitTest(BitcoinTestFramework):
multisig_without_privkey_address = self.nodes[0].addmultisigaddress(2, [pubkeys[3], pubkeys[4]])['address']
script = CScript([OP_2, hex_str_to_bytes(pubkeys[3]), hex_str_to_bytes(pubkeys[4]), OP_2, OP_CHECKMULTISIG])
- solvable_after_importaddress.append(CScript([OP_HASH160, hash160(script), OP_EQUAL]))
+ solvable_after_importaddress.append(script_to_p2sh_script(script))
for i in compressed_spendable_address:
v = self.nodes[0].getaddressinfo(i)
@@ -427,10 +427,10 @@ class SegWitTest(BitcoinTestFramework):
op0 = CScript([OP_0])
# 2N7MGY19ti4KDMSzRfPAssP6Pxyuxoi6jLe is the P2SH(P2PKH) version of mjoE3sSrb8ByYEvgnC3Aox86u1CHnfJA4V
unsolvable_address_key = hex_str_to_bytes("02341AEC7587A51CDE5279E0630A531AEA2615A9F80B17E8D9376327BAEAA59E3D")
- unsolvablep2pkh = CScript([OP_DUP, OP_HASH160, hash160(unsolvable_address_key), OP_EQUALVERIFY, OP_CHECKSIG])
- unsolvablep2wshp2pkh = CScript([OP_0, sha256(unsolvablep2pkh)])
- p2shop0 = CScript([OP_HASH160, hash160(op0), OP_EQUAL])
- p2wshop1 = CScript([OP_0, sha256(op1)])
+ unsolvablep2pkh = key_to_p2pkh_script(unsolvable_address_key)
+ unsolvablep2wshp2pkh = script_to_p2wsh_script(unsolvablep2pkh)
+ p2shop0 = script_to_p2sh_script(op0)
+ p2wshop1 = script_to_p2wsh_script(op1)
unsolvable_after_importaddress.append(unsolvablep2pkh)
unsolvable_after_importaddress.append(unsolvablep2wshp2pkh)
unsolvable_after_importaddress.append(op1) # OP_1 will be imported as script
@@ -450,16 +450,16 @@ class SegWitTest(BitcoinTestFramework):
if (v['isscript']):
bare = hex_str_to_bytes(v['hex'])
importlist.append(bare.hex())
- importlist.append(CScript([OP_0, sha256(bare)]).hex())
+ importlist.append(script_to_p2wsh_script(bare).hex())
else:
pubkey = hex_str_to_bytes(v['pubkey'])
p2pk = CScript([pubkey, OP_CHECKSIG])
- p2pkh = CScript([OP_DUP, OP_HASH160, hash160(pubkey), OP_EQUALVERIFY, OP_CHECKSIG])
+ p2pkh = key_to_p2pkh_script(pubkey)
importlist.append(p2pk.hex())
importlist.append(p2pkh.hex())
- importlist.append(CScript([OP_0, hash160(pubkey)]).hex())
- importlist.append(CScript([OP_0, sha256(p2pk)]).hex())
- importlist.append(CScript([OP_0, sha256(p2pkh)]).hex())
+ importlist.append(key_to_p2wpkh_script(pubkey).hex())
+ importlist.append(script_to_p2wsh_script(p2pk).hex())
+ importlist.append(script_to_p2wsh_script(p2pkh).hex())
importlist.append(unsolvablep2pkh.hex())
importlist.append(unsolvablep2wshp2pkh.hex())
@@ -614,22 +614,22 @@ class SegWitTest(BitcoinTestFramework):
def p2sh_address_to_script(self, v):
bare = CScript(hex_str_to_bytes(v['hex']))
p2sh = CScript(hex_str_to_bytes(v['scriptPubKey']))
- p2wsh = CScript([OP_0, sha256(bare)])
- p2sh_p2wsh = CScript([OP_HASH160, hash160(p2wsh), OP_EQUAL])
+ p2wsh = script_to_p2wsh_script(bare)
+ p2sh_p2wsh = script_to_p2sh_script(p2wsh)
return([bare, p2sh, p2wsh, p2sh_p2wsh])
def p2pkh_address_to_script(self, v):
pubkey = hex_str_to_bytes(v['pubkey'])
- p2wpkh = CScript([OP_0, hash160(pubkey)])
- p2sh_p2wpkh = CScript([OP_HASH160, hash160(p2wpkh), OP_EQUAL])
+ p2wpkh = key_to_p2wpkh_script(pubkey)
+ p2sh_p2wpkh = script_to_p2sh_script(p2wpkh)
p2pk = CScript([pubkey, OP_CHECKSIG])
p2pkh = CScript(hex_str_to_bytes(v['scriptPubKey']))
- p2sh_p2pk = CScript([OP_HASH160, hash160(p2pk), OP_EQUAL])
- p2sh_p2pkh = CScript([OP_HASH160, hash160(p2pkh), OP_EQUAL])
- p2wsh_p2pk = CScript([OP_0, sha256(p2pk)])
- p2wsh_p2pkh = CScript([OP_0, sha256(p2pkh)])
- p2sh_p2wsh_p2pk = CScript([OP_HASH160, hash160(p2wsh_p2pk), OP_EQUAL])
- p2sh_p2wsh_p2pkh = CScript([OP_HASH160, hash160(p2wsh_p2pkh), OP_EQUAL])
+ p2sh_p2pk = script_to_p2sh_script(p2pk)
+ p2sh_p2pkh = script_to_p2sh_script(p2pkh)
+ p2wsh_p2pk = script_to_p2wsh_script(p2pk)
+ p2wsh_p2pkh = script_to_p2wsh_script(p2pkh)
+ p2sh_p2wsh_p2pk = script_to_p2sh_script(p2wsh_p2pk)
+ p2sh_p2wsh_p2pkh = script_to_p2sh_script(p2wsh_p2pkh)
return [p2wpkh, p2sh_p2wpkh, p2pk, p2pkh, p2sh_p2pk, p2sh_p2pkh, p2wsh_p2pk, p2wsh_p2pkh, p2sh_p2wsh_p2pk, p2sh_p2wsh_p2pkh]
def create_and_mine_tx_from_txids(self, txids, success=True):
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 99283b69b0..17be29c7bf 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -57,7 +57,6 @@ from test_framework.script import (
OP_ENDIF,
OP_EQUAL,
OP_EQUALVERIFY,
- OP_HASH160,
OP_IF,
OP_NOP,
OP_NOT,
@@ -76,12 +75,17 @@ from test_framework.script import (
is_op_success,
taproot_construct,
)
+from test_framework.script_util import (
+ key_to_p2wpkh_script,
+ keyhash_to_p2pkh_script,
+ script_to_p2sh_script,
+ script_to_p2wsh_script,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_raises_rpc_error, assert_equal
from test_framework.key import generate_privkey, compute_xonly_pubkey, sign_schnorr, tweak_add_privkey, ECKey
from test_framework.address import (
hash160,
- sha256,
)
from collections import OrderedDict, namedtuple
from io import BytesIO
@@ -458,13 +462,13 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
# P2WPKH
assert script is None
pubkeyhash = hash160(pkh)
- spk = CScript([OP_0, pubkeyhash])
- conf["scriptcode"] = CScript([OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])
+ spk = key_to_p2wpkh_script(pkh)
+ conf["scriptcode"] = keyhash_to_p2pkh_script(pubkeyhash)
conf["script_witv0"] = None
conf["inputs"] = [getter("sign"), pkh]
elif script is not None:
# P2WSH
- spk = CScript([OP_0, sha256(script)])
+ spk = script_to_p2wsh_script(script)
conf["scriptcode"] = script
conf["script_witv0"] = script
else:
@@ -475,7 +479,7 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
# P2PKH
assert script is None
pubkeyhash = hash160(pkh)
- spk = CScript([OP_DUP, OP_HASH160, pubkeyhash, OP_EQUALVERIFY, OP_CHECKSIG])
+ spk = keyhash_to_p2pkh_script(pubkeyhash)
conf["scriptcode"] = spk
conf["inputs"] = [getter("sign"), pkh]
elif script is not None:
@@ -496,7 +500,7 @@ def make_spender(comment, *, tap=None, witv0=False, script=None, pkh=None, p2sh=
if p2sh:
# P2SH wrapper can be combined with anything else
conf["script_p2sh"] = spk
- spk = CScript([OP_HASH160, hash160(spk), OP_EQUAL])
+ spk = script_to_p2sh_script(spk)
conf = {**conf, **kwargs}
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 1705d957aa..60c0953f6f 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -13,22 +13,24 @@ from test_framework.messages import (
BIP125_SEQUENCE_NUMBER,
COIN,
COutPoint,
+ CTxIn,
CTxOut,
MAX_BLOCK_BASE_SIZE,
MAX_MONEY,
tx_from_hex,
)
from test_framework.script import (
- hash160,
CScript,
OP_0,
OP_2,
OP_3,
OP_CHECKMULTISIG,
- OP_EQUAL,
OP_HASH160,
OP_RETURN,
)
+from test_framework.script_util import (
+ script_to_p2sh_script,
+)
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
@@ -247,6 +249,14 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
rawtxs=[tx.serialize().hex()],
)
+ self.log.info('A non-coinbase transaction with coinbase-like outpoint')
+ tx = tx_from_hex(raw_tx_reference)
+ tx.vin.append(CTxIn(COutPoint(hash=0, n=0xffffffff)))
+ self.check_mempool_result(
+ result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bad-txns-prevout-null'}],
+ rawtxs=[tx.serialize().hex()],
+ )
+
self.log.info('A coinbase transaction')
# Pick the input of the first tx we signed, so it has to be a coinbase tx
raw_tx_coinbase_spent = node.getrawtransaction(txid=node.decoderawtransaction(hexstring=raw_tx_in_block)['vin'][0]['txid'])
@@ -291,7 +301,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
rawtxs=[tx.serialize().hex()],
)
tx = tx_from_hex(raw_tx_reference)
- output_p2sh_burn = CTxOut(nValue=540, scriptPubKey=CScript([OP_HASH160, hash160(b'burn'), OP_EQUAL]))
+ output_p2sh_burn = CTxOut(nValue=540, scriptPubKey=script_to_p2sh_script(b'burn'))
num_scripts = 100000 // len(output_p2sh_burn.serialize()) # Use enough outputs to make the tx too large for our policy
tx.vout = [output_p2sh_burn] * num_scripts
self.check_mempool_result(
diff --git a/test/functional/mempool_accept_wtxid.py b/test/functional/mempool_accept_wtxid.py
new file mode 100755
index 0000000000..dd1f8997ad
--- /dev/null
+++ b/test/functional/mempool_accept_wtxid.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+# Copyright (c) 2021 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""
+Test mempool acceptance in case of an already known transaction
+with identical non-witness data different witness.
+"""
+
+from test_framework.messages import (
+ COIN,
+ COutPoint,
+ CTransaction,
+ CTxIn,
+ CTxInWitness,
+ CTxOut,
+ sha256,
+)
+from test_framework.script import (
+ CScript,
+ OP_0,
+ OP_ELSE,
+ OP_ENDIF,
+ OP_EQUAL,
+ OP_HASH160,
+ OP_IF,
+ OP_TRUE,
+ hash160,
+)
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal,
+)
+
+class MempoolWtxidTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+ self.setup_clean_chain = True
+
+ def run_test(self):
+ node = self.nodes[0]
+
+ self.log.info('Start with empty mempool and 101 blocks')
+ # The last 100 coinbase transactions are premature
+ blockhash = node.generate(101)[0]
+ txid = node.getblock(blockhash=blockhash, verbosity=2)["tx"][0]["txid"]
+ assert_equal(node.getmempoolinfo()['size'], 0)
+
+ self.log.info("Submit parent with multiple script branches to mempool")
+ hashlock = hash160(b'Preimage')
+ witness_script = CScript([OP_IF, OP_HASH160, hashlock, OP_EQUAL, OP_ELSE, OP_TRUE, OP_ENDIF])
+ witness_program = sha256(witness_script)
+ script_pubkey = CScript([OP_0, witness_program])
+
+ parent = CTransaction()
+ parent.vin.append(CTxIn(COutPoint(int(txid, 16), 0), b""))
+ parent.vout.append(CTxOut(int(9.99998 * COIN), script_pubkey))
+ parent.rehash()
+
+ privkeys = [node.get_deterministic_priv_key().key]
+ raw_parent = node.signrawtransactionwithkey(hexstring=parent.serialize().hex(), privkeys=privkeys)['hex']
+ parent_txid = node.sendrawtransaction(hexstring=raw_parent, maxfeerate=0)
+ node.generate(1)
+
+ # Create a new transaction with witness solving first branch
+ child_witness_script = CScript([OP_TRUE])
+ child_witness_program = sha256(child_witness_script)
+ child_script_pubkey = CScript([OP_0, child_witness_program])
+
+ child_one = CTransaction()
+ child_one.vin.append(CTxIn(COutPoint(int(parent_txid, 16), 0), b""))
+ child_one.vout.append(CTxOut(int(9.99996 * COIN), child_script_pubkey))
+ child_one.wit.vtxinwit.append(CTxInWitness())
+ child_one.wit.vtxinwit[0].scriptWitness.stack = [b'Preimage', b'\x01', witness_script]
+ child_one_wtxid = child_one.getwtxid()
+ child_one_txid = child_one.rehash()
+
+ # Create another identical transaction with witness solving second branch
+ child_two = CTransaction()
+ child_two.vin.append(CTxIn(COutPoint(int(parent_txid, 16), 0), b""))
+ child_two.vout.append(CTxOut(int(9.99996 * COIN), child_script_pubkey))
+ child_two.wit.vtxinwit.append(CTxInWitness())
+ child_two.wit.vtxinwit[0].scriptWitness.stack = [b'', witness_script]
+ child_two_wtxid = child_two.getwtxid()
+ child_two_txid = child_two.rehash()
+
+ assert_equal(child_one_txid, child_two_txid)
+ assert child_one_wtxid != child_two_wtxid
+
+ self.log.info("Submit one child to the mempool")
+ txid_submitted = node.sendrawtransaction(child_one.serialize().hex())
+ assert_equal(node.getrawmempool(True)[txid_submitted]['wtxid'], child_one_wtxid)
+
+ # testmempoolaccept reports the "already in mempool" error
+ assert_equal(node.testmempoolaccept([child_one.serialize().hex()]), [{
+ "txid": child_one_txid,
+ "wtxid": child_one_wtxid,
+ "allowed": False,
+ "reject-reason": "txn-already-in-mempool"
+ }])
+ testres_child_two = node.testmempoolaccept([child_two.serialize().hex()])[0]
+ assert_equal(testres_child_two, {
+ "txid": child_two_txid,
+ "wtxid": child_two_wtxid,
+ "allowed": False,
+ "reject-reason": "txn-same-nonwitness-data-in-mempool"
+ })
+
+ # sendrawtransaction will not throw but quits early when the exact same transaction is already in mempool
+ node.sendrawtransaction(child_one.serialize().hex())
+ # sendrawtransaction will not throw but quits early when a transaction with the same non-witness data is already in mempool
+ node.sendrawtransaction(child_two.serialize().hex())
+
+
+if __name__ == '__main__':
+ MempoolWtxidTest().main()
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index 95c7aec318..ead9d852fe 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -41,7 +41,6 @@ from test_framework.messages import (
ser_vector,
sha256,
tx_from_hex,
- uint256_from_str,
)
from test_framework.p2p import (
P2PInterface,
@@ -60,12 +59,8 @@ from test_framework.script import (
OP_CHECKMULTISIG,
OP_CHECKSIG,
OP_DROP,
- OP_DUP,
OP_ELSE,
OP_ENDIF,
- OP_EQUAL,
- OP_EQUALVERIFY,
- OP_HASH160,
OP_IF,
OP_RETURN,
OP_TRUE,
@@ -77,6 +72,12 @@ from test_framework.script import (
LegacySignatureHash,
hash160,
)
+from test_framework.script_util import (
+ key_to_p2wpkh_script,
+ keyhash_to_p2pkh_script,
+ script_to_p2sh_script,
+ script_to_p2wsh_script,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
@@ -100,10 +101,6 @@ class UTXO():
self.n = n
self.nValue = value
-def get_p2pkh_script(pubkeyhash):
- """Get the script associated with a P2PKH."""
- return CScript([CScriptOp(OP_DUP), CScriptOp(OP_HASH160), pubkeyhash, CScriptOp(OP_EQUALVERIFY), CScriptOp(OP_CHECKSIG)])
-
def sign_p2pk_witness_input(script, tx_to, in_idx, hashtype, value, key):
"""Add signature for a P2PK witness program."""
tx_hash = SegwitV0SignatureHash(script, tx_to, in_idx, hashtype, value)
@@ -492,11 +489,8 @@ class SegWitTest(BitcoinTestFramework):
# Create two outputs, a p2wsh and p2sh-p2wsh
witness_program = CScript([OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
-
- p2sh_pubkey = hash160(script_pubkey)
- p2sh_script_pubkey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
+ script_pubkey = script_to_p2wsh_script(witness_program)
+ p2sh_script_pubkey = script_to_p2sh_script(script_pubkey)
value = self.utxo[0].nValue // 3
@@ -631,11 +625,8 @@ class SegWitTest(BitcoinTestFramework):
V0 segwit inputs may only be mined after activation, but not before."""
witness_program = CScript([OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
-
- p2sh_pubkey = hash160(witness_program)
- p2sh_script_pubkey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
+ script_pubkey = script_to_p2wsh_script(witness_program)
+ p2sh_script_pubkey = script_to_p2sh_script(witness_program)
# First prepare a p2sh output (so that spending it will pass standardness)
p2sh_tx = CTransaction()
@@ -662,6 +653,7 @@ class SegWitTest(BitcoinTestFramework):
test_transaction_acceptance(self.nodes[1], self.std_node, tx, with_witness=True, accepted=True)
# Now create something that looks like a P2PKH output. This won't be spendable.
+ witness_hash = sha256(witness_program)
script_pubkey = CScript([OP_0, hash160(witness_hash)])
tx2 = CTransaction()
# tx was accepted, so we spend the second output.
@@ -740,10 +732,8 @@ class SegWitTest(BitcoinTestFramework):
# Prepare the p2sh-wrapped witness output
witness_program = CScript([OP_DROP, OP_TRUE])
- witness_hash = sha256(witness_program)
- p2wsh_pubkey = CScript([OP_0, witness_hash])
- p2sh_witness_hash = hash160(p2wsh_pubkey)
- script_pubkey = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL])
+ p2wsh_pubkey = script_to_p2wsh_script(witness_program)
+ script_pubkey = script_to_p2sh_script(p2wsh_pubkey)
script_sig = CScript([p2wsh_pubkey]) # a push of the redeem script
# Fund the P2SH output
@@ -837,8 +827,7 @@ class SegWitTest(BitcoinTestFramework):
# Let's construct a witness program
witness_program = CScript([OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
tx.vout.append(CTxOut(self.utxo[0].nValue - 1000, script_pubkey))
tx.rehash()
@@ -951,8 +940,7 @@ class SegWitTest(BitcoinTestFramework):
NUM_OUTPUTS = 50
witness_program = CScript([OP_2DROP] * NUM_DROPS + [OP_TRUE])
- witness_hash = uint256_from_str(sha256(witness_program))
- script_pubkey = CScript([OP_0, ser_uint256(witness_hash)])
+ script_pubkey = script_to_p2wsh_script(witness_program)
prevout = COutPoint(self.utxo[0].sha256, self.utxo[0].n)
value = self.utxo[0].nValue
@@ -1054,8 +1042,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block()
witness_program = CScript([OP_DROP, OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
# First try extra witness data on a tx that doesn't require a witness
tx = CTransaction()
@@ -1127,8 +1114,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block()
witness_program = CScript([OP_DROP, OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))
@@ -1166,8 +1152,7 @@ class SegWitTest(BitcoinTestFramework):
# This program is 19 max pushes (9937 bytes), then 64 more opcode-bytes.
long_witness_program = CScript([b'a' * MAX_SCRIPT_ELEMENT_SIZE] * 19 + [OP_DROP] * 63 + [OP_TRUE])
assert len(long_witness_program) == MAX_PROGRAM_LENGTH + 1
- long_witness_hash = sha256(long_witness_program)
- long_script_pubkey = CScript([OP_0, long_witness_hash])
+ long_script_pubkey = script_to_p2wsh_script(long_witness_program)
block = self.build_next_block()
@@ -1190,8 +1175,7 @@ class SegWitTest(BitcoinTestFramework):
# Try again with one less byte in the witness program
witness_program = CScript([b'a' * MAX_SCRIPT_ELEMENT_SIZE] * 19 + [OP_DROP] * 62 + [OP_TRUE])
assert len(witness_program) == MAX_PROGRAM_LENGTH
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
tx.vout[0] = CTxOut(tx.vout[0].nValue, script_pubkey)
tx.rehash()
@@ -1210,8 +1194,7 @@ class SegWitTest(BitcoinTestFramework):
"""Test that vin length must match vtxinwit length."""
witness_program = CScript([OP_DROP, OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
# Create a transaction that splits our utxo into many outputs
tx = CTransaction()
@@ -1318,8 +1301,7 @@ class SegWitTest(BitcoinTestFramework):
# Now try to add extra witness data to a valid witness tx.
witness_program = CScript([OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(tx_hash, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_pubkey))
@@ -1331,9 +1313,8 @@ class SegWitTest(BitcoinTestFramework):
# Add too-large for IsStandard witness and check that it does not enter reject filter
p2sh_program = CScript([OP_TRUE])
- p2sh_pubkey = hash160(p2sh_program)
witness_program2 = CScript([b'a' * 400000])
- tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])))
+ tx3.vout.append(CTxOut(tx2.vout[0].nValue - 1000, script_to_p2sh_script(p2sh_program)))
tx3.wit.vtxinwit[0].scriptWitness.stack = [witness_program2]
tx3.rehash()
@@ -1482,8 +1463,7 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block()
# Change the output of the block to be a witness output.
witness_program = CScript([OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
block.vtx[0].vout[0].scriptPubKey = script_pubkey
# This next line will rehash the coinbase and update the merkle
# root, and solve.
@@ -1530,7 +1510,7 @@ class SegWitTest(BitcoinTestFramework):
# Test 1: P2WPKH
# First create a P2WPKH output that uses an uncompressed pubkey
pubkeyhash = hash160(pubkey)
- script_pkh = CScript([OP_0, pubkeyhash])
+ script_pkh = key_to_p2wpkh_script(pubkey)
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(utxo.sha256, utxo.n), b""))
tx.vout.append(CTxOut(utxo.nValue - 1000, script_pkh))
@@ -1544,13 +1524,12 @@ class SegWitTest(BitcoinTestFramework):
# Now try to spend it. Send it to a P2WSH output, which we'll
# use in the next test.
witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)])
- witness_hash = sha256(witness_program)
- script_wsh = CScript([OP_0, witness_hash])
+ script_wsh = script_to_p2wsh_script(witness_program)
tx2 = CTransaction()
tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue - 1000, script_wsh))
- script = get_p2pkh_script(pubkeyhash)
+ script = keyhash_to_p2pkh_script(pubkeyhash)
sig_hash = SegwitV0SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
tx2.wit.vtxinwit.append(CTxInWitness())
@@ -1567,8 +1546,7 @@ class SegWitTest(BitcoinTestFramework):
# Test 2: P2WSH
# Try to spend the P2WSH output created in last test.
# Send it to a P2SH(P2WSH) output, which we'll use in the next test.
- p2sh_witness_hash = hash160(script_wsh)
- script_p2sh = CScript([OP_HASH160, p2sh_witness_hash, OP_EQUAL])
+ script_p2sh = script_to_p2sh_script(script_wsh)
script_sig = CScript([script_wsh])
tx3 = CTransaction()
@@ -1587,7 +1565,7 @@ class SegWitTest(BitcoinTestFramework):
# Test 3: P2SH(P2WSH)
# Try to spend the P2SH output created in the last test.
# Send it to a P2PKH output, which we'll use in the next test.
- script_pubkey = get_p2pkh_script(pubkeyhash)
+ script_pubkey = keyhash_to_p2pkh_script(pubkeyhash)
tx4 = CTransaction()
tx4.vin.append(CTxIn(COutPoint(tx3.sha256, 0), script_sig))
tx4.vout.append(CTxOut(tx3.vout[0].nValue - 1000, script_pubkey))
@@ -1624,8 +1602,7 @@ class SegWitTest(BitcoinTestFramework):
pubkey = key.get_pubkey().get_bytes()
witness_program = CScript([pubkey, CScriptOp(OP_CHECKSIG)])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
# First create a witness output for use in the tests.
tx = CTransaction()
@@ -1744,7 +1721,7 @@ class SegWitTest(BitcoinTestFramework):
# Now test witness version 0 P2PKH transactions
pubkeyhash = hash160(pubkey)
- script_pkh = CScript([OP_0, pubkeyhash])
+ script_pkh = key_to_p2wpkh_script(pubkey)
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b""))
tx.vout.append(CTxOut(temp_utxos[0].nValue, script_pkh))
@@ -1754,7 +1731,7 @@ class SegWitTest(BitcoinTestFramework):
tx2.vin.append(CTxIn(COutPoint(tx.sha256, 0), b""))
tx2.vout.append(CTxOut(tx.vout[0].nValue, CScript([OP_TRUE])))
- script = get_p2pkh_script(pubkeyhash)
+ script = keyhash_to_p2pkh_script(pubkeyhash)
sig_hash = SegwitV0SignatureHash(script, tx2, 0, SIGHASH_ALL, tx.vout[0].nValue)
signature = key.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL
@@ -1806,8 +1783,7 @@ class SegWitTest(BitcoinTestFramework):
# rules (an anyone-can-spend OP_TRUE would be rejected, if not wrapped
# in P2SH).
p2sh_program = CScript([OP_TRUE])
- p2sh_pubkey = hash160(p2sh_program)
- script_pubkey = CScript([OP_HASH160, p2sh_pubkey, OP_EQUAL])
+ script_pubkey = script_to_p2sh_script(p2sh_program)
# Now check that unnecessary witnesses can't be used to blind a node
# to a transaction, eg by violating standardness checks.
@@ -1872,11 +1848,10 @@ class SegWitTest(BitcoinTestFramework):
# For each script, generate a pair of P2WSH and P2SH-P2WSH output.
outputvalue = (self.utxo[0].nValue - 1000) // (len(scripts) * 2)
for i in scripts:
- p2wsh = CScript([OP_0, sha256(i)])
- p2sh = hash160(p2wsh)
+ p2wsh = script_to_p2wsh_script(i)
p2wsh_scripts.append(p2wsh)
tx.vout.append(CTxOut(outputvalue, p2wsh))
- tx.vout.append(CTxOut(outputvalue, CScript([OP_HASH160, p2sh, OP_EQUAL])))
+ tx.vout.append(CTxOut(outputvalue, script_to_p2sh_script(p2wsh)))
tx.rehash()
txid = tx.sha256
test_transaction_acceptance(self.nodes[0], self.test_node, tx, with_witness=False, accepted=True)
@@ -1890,13 +1865,13 @@ class SegWitTest(BitcoinTestFramework):
for i in range(len(scripts)):
p2wsh_tx = CTransaction()
p2wsh_tx.vin.append(CTxIn(COutPoint(txid, i * 2)))
- p2wsh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))])))
+ p2wsh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(b"")])))
p2wsh_tx.wit.vtxinwit.append(CTxInWitness())
p2wsh_tx.rehash()
p2wsh_txs.append(p2wsh_tx)
p2sh_tx = CTransaction()
p2sh_tx.vin.append(CTxIn(COutPoint(txid, i * 2 + 1), CScript([p2wsh_scripts[i]])))
- p2sh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(hex_str_to_bytes(""))])))
+ p2sh_tx.vout.append(CTxOut(outputvalue - 5000, CScript([OP_0, hash160(b"")])))
p2sh_tx.wit.vtxinwit.append(CTxInWitness())
p2sh_tx.rehash()
p2sh_txs.append(p2sh_tx)
@@ -1991,8 +1966,7 @@ class SegWitTest(BitcoinTestFramework):
# Keep this under MAX_OPS_PER_SCRIPT (201)
witness_program = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKMULTISIG] * 5 + [OP_CHECKSIG] * 193 + [OP_ENDIF])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
sigops_per_script = 20 * 5 + 193 * 1
# We'll produce 2 extra outputs, one with a program that would take us
@@ -2008,14 +1982,12 @@ class SegWitTest(BitcoinTestFramework):
# N(=MAX_SIGOP_COST//sigops_per_script) outputs of our transaction,
# would push us just over the block sigop limit.
witness_program_toomany = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG] * (extra_sigops_available + 1) + [OP_ENDIF])
- witness_hash_toomany = sha256(witness_program_toomany)
- script_pubkey_toomany = CScript([OP_0, witness_hash_toomany])
+ script_pubkey_toomany = script_to_p2wsh_script(witness_program_toomany)
# If we spend this script instead, we would exactly reach our sigop
# limit (for witness sigops).
witness_program_justright = CScript([OP_TRUE, OP_IF, OP_TRUE, OP_ELSE] + [OP_CHECKSIG] * (extra_sigops_available) + [OP_ENDIF])
- witness_hash_justright = sha256(witness_program_justright)
- script_pubkey_justright = CScript([OP_0, witness_hash_justright])
+ script_pubkey_justright = script_to_p2wsh_script(witness_program_justright)
# First split our available utxo into a bunch of outputs
split_value = self.utxo[0].nValue // outputs
@@ -2148,8 +2120,7 @@ class SegWitTest(BitcoinTestFramework):
# Create a Segwit output from the latest UTXO
# and announce it to the network
witness_program = CScript([OP_TRUE])
- witness_hash = sha256(witness_program)
- script_pubkey = CScript([OP_0, witness_hash])
+ script_pubkey = script_to_p2wsh_script(witness_program)
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(self.utxo[0].sha256, self.utxo[0].n), b""))
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index af515f3a27..816ec67492 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -97,6 +97,9 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
sorted_key_desc = descsum_create('sh(multi(2,{}))'.format(sorted_key_str))
assert_equal(self.nodes[0].deriveaddresses(sorted_key_desc)[0], t['address'])
+ # Check that bech32m is currently not allowed
+ assert_raises_rpc_error(-5, "createmultisig cannot create bech32m multisig addresses", self.nodes[0].createmultisig, 2, self.pub, "bech32m")
+
def check_addmultisigaddress_errors(self):
if self.options.descriptors:
return
@@ -108,6 +111,10 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
self.nodes[0].importaddress(a)
assert_raises_rpc_error(-5, 'no full public key for address', lambda: self.nodes[0].addmultisigaddress(nrequired=1, keys=addresses))
+ # Bech32m address type is disallowed for legacy wallets
+ pubs = [self.nodes[1].getaddressinfo(addr)["pubkey"] for addr in addresses]
+ assert_raises_rpc_error(-5, "Bech32m multisig addresses cannot be created with legacy wallets", self.nodes[0].addmultisigaddress, 2, pubs, "", "bech32m")
+
def checkbalances(self):
node0, node1, node2 = self.nodes
node0.generate(COINBASE_MATURITY)
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 4b07a32c54..fa98c44152 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -551,7 +551,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# creating the key must be impossible because the wallet is locked
outputs = {self.nodes[0].getnewaddress():1.1}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
- assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.", self.nodes[1].fundrawtransaction, rawtx)
+ assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", self.nodes[1].fundrawtransaction, rawtx)
# Refill the keypool.
self.nodes[1].walletpassphrase("test", 100)
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index ef5d08e7b9..f3627d1e37 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -6,7 +6,6 @@
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.address import (
- check_script,
script_to_p2sh,
script_to_p2wsh,
)
@@ -20,12 +19,10 @@ from test_framework.util import (
)
from test_framework.messages import (
CTxInWitness,
- sha256,
tx_from_hex,
)
from test_framework.script import (
CScript,
- OP_0,
OP_CHECKLOCKTIMEVERIFY,
OP_CHECKSIG,
OP_CHECKSEQUENCEVERIFY,
@@ -233,7 +230,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
'P2PKH': key_to_p2pkh_script(embedded_pubkey).hex(),
'P2PK': CScript([hex_str_to_bytes(embedded_pubkey), OP_CHECKSIG]).hex()
}.get(tx_type, "Invalid tx_type")
- redeem_script = CScript([OP_0, sha256(check_script(witness_script))]).hex()
+ redeem_script = script_to_p2wsh_script(witness_script).hex()
addr = script_to_p2sh(redeem_script)
script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey']
# Fund that address
diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py
index bc43438810..833a215993 100644
--- a/test/functional/test_framework/blocktools.py
+++ b/test/functional/test_framework/blocktools.py
@@ -26,7 +26,6 @@ from .messages import (
hash256,
hex_str_to_bytes,
ser_uint256,
- sha256,
tx_from_hex,
uint256_from_str,
)
@@ -34,13 +33,15 @@ from .script import (
CScript,
CScriptNum,
CScriptOp,
- OP_0,
OP_1,
OP_CHECKMULTISIG,
OP_CHECKSIG,
OP_RETURN,
OP_TRUE,
- hash160,
+)
+from .script_util import (
+ key_to_p2wpkh_script,
+ script_to_p2wsh_script,
)
from .util import assert_equal
@@ -206,13 +207,11 @@ def witness_script(use_p2wsh, pubkey):
scriptPubKey."""
if not use_p2wsh:
# P2WPKH instead
- pubkeyhash = hash160(hex_str_to_bytes(pubkey))
- pkscript = CScript([OP_0, pubkeyhash])
+ pkscript = key_to_p2wpkh_script(pubkey)
else:
# 1-of-1 multisig
witness_program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG])
- scripthash = sha256(witness_program)
- pkscript = CScript([OP_0, scripthash])
+ pkscript = script_to_p2wsh_script(witness_program)
return pkscript.hex()
def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount):
diff --git a/test/functional/test_framework/wallet_util.py b/test/functional/test_framework/wallet_util.py
index b9c0fb6691..acbc040741 100755
--- a/test/functional/test_framework/wallet_util.py
+++ b/test/functional/test_framework/wallet_util.py
@@ -17,17 +17,15 @@ from test_framework.address import (
from test_framework.key import ECKey
from test_framework.script import (
CScript,
- OP_0,
OP_2,
OP_3,
OP_CHECKMULTISIG,
- OP_CHECKSIG,
- OP_DUP,
- OP_EQUAL,
- OP_EQUALVERIFY,
- OP_HASH160,
- hash160,
- sha256,
+)
+from test_framework.script_util import (
+ key_to_p2pkh_script,
+ key_to_p2wpkh_script,
+ script_to_p2sh_script,
+ script_to_p2wsh_script,
)
from test_framework.util import hex_str_to_bytes
@@ -57,15 +55,14 @@ def get_key(node):
Returns a named tuple of privkey, pubkey and all address and scripts."""
addr = node.getnewaddress()
pubkey = node.getaddressinfo(addr)['pubkey']
- pkh = hash160(hex_str_to_bytes(pubkey))
return Key(privkey=node.dumpprivkey(addr),
pubkey=pubkey,
- p2pkh_script=CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG]).hex(),
+ p2pkh_script=key_to_p2pkh_script(pubkey).hex(),
p2pkh_addr=key_to_p2pkh(pubkey),
- p2wpkh_script=CScript([OP_0, pkh]).hex(),
+ p2wpkh_script=key_to_p2wpkh_script(pubkey).hex(),
p2wpkh_addr=key_to_p2wpkh(pubkey),
- p2sh_p2wpkh_script=CScript([OP_HASH160, hash160(CScript([OP_0, pkh])), OP_EQUAL]).hex(),
- p2sh_p2wpkh_redeem_script=CScript([OP_0, pkh]).hex(),
+ p2sh_p2wpkh_script=script_to_p2sh_script(key_to_p2wpkh_script(pubkey)).hex(),
+ p2sh_p2wpkh_redeem_script=key_to_p2wpkh_script(pubkey).hex(),
p2sh_p2wpkh_addr=key_to_p2sh_p2wpkh(pubkey))
def get_generate_key():
@@ -76,15 +73,14 @@ def get_generate_key():
eckey.generate()
privkey = bytes_to_wif(eckey.get_bytes())
pubkey = eckey.get_pubkey().get_bytes().hex()
- pkh = hash160(hex_str_to_bytes(pubkey))
return Key(privkey=privkey,
pubkey=pubkey,
- p2pkh_script=CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG]).hex(),
+ p2pkh_script=key_to_p2pkh_script(pubkey).hex(),
p2pkh_addr=key_to_p2pkh(pubkey),
- p2wpkh_script=CScript([OP_0, pkh]).hex(),
+ p2wpkh_script=key_to_p2wpkh_script(pubkey).hex(),
p2wpkh_addr=key_to_p2wpkh(pubkey),
- p2sh_p2wpkh_script=CScript([OP_HASH160, hash160(CScript([OP_0, pkh])), OP_EQUAL]).hex(),
- p2sh_p2wpkh_redeem_script=CScript([OP_0, pkh]).hex(),
+ p2sh_p2wpkh_script=script_to_p2sh_script(key_to_p2wpkh_script(pubkey)).hex(),
+ p2sh_p2wpkh_redeem_script=key_to_p2wpkh_script(pubkey).hex(),
p2sh_p2wpkh_addr=key_to_p2sh_p2wpkh(pubkey))
def get_multisig(node):
@@ -98,15 +94,15 @@ def get_multisig(node):
addrs.append(addr['address'])
pubkeys.append(addr['pubkey'])
script_code = CScript([OP_2] + [hex_str_to_bytes(pubkey) for pubkey in pubkeys] + [OP_3, OP_CHECKMULTISIG])
- witness_script = CScript([OP_0, sha256(script_code)])
+ witness_script = script_to_p2wsh_script(script_code)
return Multisig(privkeys=[node.dumpprivkey(addr) for addr in addrs],
pubkeys=pubkeys,
- p2sh_script=CScript([OP_HASH160, hash160(script_code), OP_EQUAL]).hex(),
+ p2sh_script=script_to_p2sh_script(script_code).hex(),
p2sh_addr=script_to_p2sh(script_code),
redeem_script=script_code.hex(),
p2wsh_script=witness_script.hex(),
p2wsh_addr=script_to_p2wsh(script_code),
- p2sh_p2wsh_script=CScript([OP_HASH160, witness_script, OP_EQUAL]).hex(),
+ p2sh_p2wsh_script=script_to_p2sh_script(witness_script).hex(),
p2sh_p2wsh_addr=script_to_p2sh_p2wsh(script_code))
def test_address(node, address, **kwargs):
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index ad1acd2e2f..303742236f 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -279,6 +279,7 @@ BASE_SCRIPTS = [
'feature_asmap.py',
'mempool_unbroadcast.py',
'mempool_compatibility.py',
+ 'mempool_accept_wtxid.py',
'rpc_deriveaddresses.py',
'rpc_deriveaddresses.py --usecli',
'p2p_ping.py',
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 6d93cf412f..9b97d08424 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -373,5 +373,15 @@ class AddressTypeTest(BitcoinTestFramework):
self.test_address(4, self.nodes[4].getrawchangeaddress(), multisig=False, typ='p2sh-segwit')
self.test_address(4, self.nodes[4].getrawchangeaddress('bech32'), multisig=False, typ='bech32')
+ if self.options.descriptors:
+ self.log.info("Descriptor wallets do not have bech32m addresses by default yet")
+ # TODO: Remove this when they do
+ assert_raises_rpc_error(-12, "Error: No bech32m addresses available", self.nodes[0].getnewaddress, "", "bech32m")
+ assert_raises_rpc_error(-12, "Error: No bech32m addresses available", self.nodes[0].getrawchangeaddress, "bech32m")
+ else:
+ self.log.info("Legacy wallets cannot make bech32m addresses")
+ assert_raises_rpc_error(-8, "Legacy wallets cannot provide bech32m addresses", self.nodes[0].getnewaddress, "", "bech32m")
+ assert_raises_rpc_error(-8, "Legacy wallets cannot provide bech32m addresses", self.nodes[0].getrawchangeaddress, "bech32m")
+
if __name__ == '__main__':
AddressTypeTest().main()
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index a052ec7477..b5afc3785e 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -420,6 +420,9 @@ class WalletTest(BitcoinTestFramework):
# This will raise an exception for importing an invalid pubkey
assert_raises_rpc_error(-5, "Pubkey is not a valid public key", self.nodes[0].importpubkey, "5361746f736869204e616b616d6f746f")
+ # Bech32m addresses cannot be imported into a legacy wallet
+ assert_raises_rpc_error(-5, "Bech32m addresses cannot be imported into legacy wallets", self.nodes[0].importaddress, "bcrt1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqc8gma6")
+
# Import address and private key to check correct behavior of spendable unspents
# 1. Send some coins to generate new UTXO
address_to_import = self.nodes[2].getnewaddress()
diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py
index a2da16e5a3..262175c789 100755
--- a/test/functional/wallet_importdescriptors.py
+++ b/test/functional/wallet_importdescriptors.py
@@ -79,7 +79,6 @@ class ImportDescriptorsTest(BitcoinTestFramework):
# RPC importdescriptors -----------------------------------------------
# # Test import fails if no descriptor present
- key = get_generate_key()
self.log.info("Import should fail if a descriptor is not provided")
self.test_importdesc({"timestamp": "now"},
success=False,
@@ -89,10 +88,10 @@ class ImportDescriptorsTest(BitcoinTestFramework):
# # Test importing of a P2PKH descriptor
key = get_generate_key()
self.log.info("Should import a p2pkh descriptor")
- self.test_importdesc({"desc": descsum_create("pkh(" + key.pubkey + ")"),
- "timestamp": "now",
- "label": "Descriptor import test"},
- success=True)
+ import_request = {"desc": descsum_create("pkh(" + key.pubkey + ")"),
+ "timestamp": "now",
+ "label": "Descriptor import test"}
+ self.test_importdesc(import_request, success=True)
test_address(w1,
key.p2pkh_addr,
solvable=True,
@@ -100,11 +99,15 @@ class ImportDescriptorsTest(BitcoinTestFramework):
labels=["Descriptor import test"])
assert_equal(w1.getwalletinfo()['keypoolsize'], 0)
+ self.log.info("Test can import same descriptor with public key twice")
+ self.test_importdesc(import_request, success=True)
+
+ self.log.info("Test can update descriptor label")
+ self.test_importdesc({**import_request, "label": "Updated label"}, success=True)
+ test_address(w1, key.p2pkh_addr, solvable=True, ismine=True, labels=["Updated label"])
+
self.log.info("Internal addresses cannot have labels")
- self.test_importdesc({"desc": descsum_create("pkh(" + key.pubkey + ")"),
- "timestamp": "now",
- "internal": True,
- "label": "Descriptor import test"},
+ self.test_importdesc({**import_request, "internal": True},
success=False,
error_code=-8,
error_message="Internal addresses should not have a label")
@@ -252,6 +255,39 @@ class ImportDescriptorsTest(BitcoinTestFramework):
self.test_importdesc({"desc": descsum_create(desc), "timestamp": "now", "range": [0, 1000001]},
success=False, error_code=-8, error_message='Range is too large')
+ self.log.info("Verify we can only extend descriptor's range")
+ range_request = {"desc": descsum_create(desc), "timestamp": "now", "range": [5, 10], 'active': True}
+ self.test_importdesc(range_request, wallet=wpriv, success=True)
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 6)
+ self.test_importdesc({**range_request, "range": [0, 10]}, wallet=wpriv, success=True)
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 11)
+ self.test_importdesc({**range_request, "range": [0, 20]}, wallet=wpriv, success=True)
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
+ # Can keep range the same
+ self.test_importdesc({**range_request, "range": [0, 20]}, wallet=wpriv, success=True)
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
+
+ self.test_importdesc({**range_request, "range": [5, 10]}, wallet=wpriv, success=False,
+ error_code=-8, error_message='new range must include current range = [0,20]')
+ self.test_importdesc({**range_request, "range": [0, 10]}, wallet=wpriv, success=False,
+ error_code=-8, error_message='new range must include current range = [0,20]')
+ self.test_importdesc({**range_request, "range": [5, 20]}, wallet=wpriv, success=False,
+ error_code=-8, error_message='new range must include current range = [0,20]')
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
+
+ self.log.info("Check we can change descriptor internal flag")
+ self.test_importdesc({**range_request, "range": [0, 20], "internal": True}, wallet=wpriv, success=True)
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 0)
+ assert_raises_rpc_error(-4, 'This wallet has no available keys', wpriv.getnewaddress, '', 'p2sh-segwit')
+ assert_equal(wpriv.getwalletinfo()['keypoolsize_hd_internal'], 21)
+ wpriv.getrawchangeaddress('p2sh-segwit')
+
+ self.test_importdesc({**range_request, "range": [0, 20], "internal": False}, wallet=wpriv, success=True)
+ assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
+ wpriv.getnewaddress('', 'p2sh-segwit')
+ assert_equal(wpriv.getwalletinfo()['keypoolsize_hd_internal'], 0)
+ assert_raises_rpc_error(-4, 'This wallet has no available keys', wpriv.getrawchangeaddress, 'p2sh-segwit')
+
# Make sure ranged imports import keys in order
w1 = self.nodes[1].get_wallet_rpc('w1')
self.log.info('Key ranges should be imported in order')
@@ -303,9 +339,21 @@ class ImportDescriptorsTest(BitcoinTestFramework):
w1.keypoolrefill()
assert_equal(w1.getwalletinfo()['keypoolsize'], 5 * 3)
+ self.log.info("Check we can change next_index")
+ # go back and forth with next_index
+ for i in [4, 0, 2, 1, 3]:
+ self.test_importdesc({'desc': descsum_create('wpkh([80002067/0h/0h]' + xpub + '/*)'),
+ 'active': True,
+ 'range': [0, 9],
+ 'next_index': i,
+ 'timestamp': 'now'
+ },
+ success=True)
+ assert_equal(w1.getnewaddress('', 'bech32'), addresses[i])
+
# Check active=False default
self.log.info('Check imported descriptors are not active by default')
- self.test_importdesc({'desc': descsum_create('pkh([12345678/0h/0h]' + xpub + '/*)'),
+ self.test_importdesc({'desc': descsum_create('pkh([12345678/1h]' + xpub + '/*)'),
'range' : [0, 2],
'timestamp': 'now',
'internal': True
@@ -313,6 +361,32 @@ class ImportDescriptorsTest(BitcoinTestFramework):
success=True)
assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')
+ self.log.info('Check can activate inactive descriptor')
+ self.test_importdesc({'desc': descsum_create('pkh([12345678]' + xpub + '/*)'),
+ 'range': [0, 5],
+ 'active': True,
+ 'timestamp': 'now',
+ 'internal': True
+ },
+ success=True)
+ address = w1.getrawchangeaddress('legacy')
+ assert_equal(address, "mpA2Wh9dvZT7yfELq1UnrUmAoc5qCkMetg")
+
+ self.log.info('Check can deactivate active descriptor')
+ self.test_importdesc({'desc': descsum_create('pkh([12345678]' + xpub + '/*)'),
+ 'range': [0, 5],
+ 'active': False,
+ 'timestamp': 'now',
+ 'internal': True
+ },
+ success=True)
+ assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')
+
+ self.log.info('Verify activation state is persistent')
+ w1.unloadwallet()
+ self.nodes[1].loadwallet('w1')
+ assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')
+
# # Test importing a descriptor containing a WIF private key
wif_priv = "cTe1f5rdT8A8DFgVWTjyPwACsDPJM9ff4QngFxUixCSvvbg1x6sh"
address = "2MuhcG52uHPknxDgmGPsV18jSHFBnnRgjPg"
@@ -322,6 +396,10 @@ class ImportDescriptorsTest(BitcoinTestFramework):
"timestamp": "now"},
success=True,
wallet=wpriv)
+
+ self.log.info('Test can import same descriptor with private key twice')
+ self.test_importdesc({"desc": descsum_create(desc), "timestamp": "now"}, success=True, wallet=wpriv)
+
test_address(wpriv,
address,
solvable=True,
@@ -339,14 +417,25 @@ class ImportDescriptorsTest(BitcoinTestFramework):
wmulti_priv = self.nodes[1].get_wallet_rpc("wmulti_priv")
assert_equal(wmulti_priv.getwalletinfo()['keypoolsize'], 0)
- self.test_importdesc({"desc":"wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/0h/0h/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/0h/0h/*,tprv8ZgxMBicQKsPeonDt8Ka2mrQmHa61hQ5FQCsvWBTpSNzBFgM58cV2EuXNAHF14VawVpznnme3SuTbA62sGriwWyKifJmXntfNeK7zeqMCj1/84h/0h/0h/*))#m2sr93jn",
+ xprv1 = 'tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52'
+ acc_xpub1 = 'tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8' # /84'/0'/0'
+ chg_xpub1 = 'tpubDCXqdwWZcszwqYJSnZp8eARkxGJfHAk23KDxbztV4BbschfaTfYLTcSkSJ3TN64dRqwa1rnFUScsYormKkGqNbbPwkorQimVevXjxzUV9Gf' # /84'/1'/0'
+ xprv2 = 'tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq'
+ acc_xprv2 = 'tprv8gVCsmRAxVSxyUpsL13Y7ZEWBFPWbgS5E2MmFVNGuANrknvmmn2vWnmHvU8AwEFYzR2ji6EeZLSCLVacsYkvor3Pcb5JY5FGcevqTwYvdYx'
+ acc_xpub2 = 'tpubDDBF2BTR6s8drwrfDei8WxtckGuSm1cyoKxYY1QaKSBFbHBYQArWhHPA6eJrzZej6nfHGLSURYSLHr7GuYch8aY5n61tGqgn8b4cXrMuoPH'
+ chg_xpub2 = 'tpubDCYfZY2ceyHzYzMMVPt9MNeiqtQ2T7Uyp9QSFwYXh8Vi9iJFYXcuphJaGXfF3jUQJi5Y3GMNXvM11gaL4txzZgNGK22BFAwMXynnzv4z2Jh'
+ xprv3 = 'tprv8ZgxMBicQKsPeonDt8Ka2mrQmHa61hQ5FQCsvWBTpSNzBFgM58cV2EuXNAHF14VawVpznnme3SuTbA62sGriwWyKifJmXntfNeK7zeqMCj1'
+ acc_xpub3 = 'tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E'
+ chg_xpub3 = 'tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb'
+
+ self.test_importdesc({"desc":"wsh(multi(2," + xprv1 + "/84h/0h/0h/*," + xprv2 + "/84h/0h/0h/*," + xprv3 + "/84h/0h/0h/*))#m2sr93jn",
"active": True,
"range": 1000,
"next_index": 0,
"timestamp": "now"},
success=True,
wallet=wmulti_priv)
- self.test_importdesc({"desc":"wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/1h/0h/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/1h/0h/*,tprv8ZgxMBicQKsPeonDt8Ka2mrQmHa61hQ5FQCsvWBTpSNzBFgM58cV2EuXNAHF14VawVpznnme3SuTbA62sGriwWyKifJmXntfNeK7zeqMCj1/84h/1h/0h/*))#q3sztvx5",
+ self.test_importdesc({"desc":"wsh(multi(2," + xprv1 + "/84h/1h/0h/*," + xprv2 + "/84h/1h/0h/*," + xprv3 + "/84h/1h/0h/*))#q3sztvx5",
"active": True,
"internal" : True,
"range": 1000,
@@ -374,14 +463,14 @@ class ImportDescriptorsTest(BitcoinTestFramework):
wmulti_pub = self.nodes[1].get_wallet_rpc("wmulti_pub")
assert_equal(wmulti_pub.getwalletinfo()['keypoolsize'], 0)
- self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/0h/0h]tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/*,[59b09cd6/84h/0h/0h]tpubDDBF2BTR6s8drwrfDei8WxtckGuSm1cyoKxYY1QaKSBFbHBYQArWhHPA6eJrzZej6nfHGLSURYSLHr7GuYch8aY5n61tGqgn8b4cXrMuoPH/*,[e81a0532/84h/0h/0h]tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E/*))#tsry0s5e",
+ self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/0h/0h]" + acc_xpub1 + "/*,[59b09cd6/84h/0h/0h]" + acc_xpub2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 +"/*))#tsry0s5e",
"active": True,
"range": 1000,
"next_index": 0,
"timestamp": "now"},
success=True,
wallet=wmulti_pub)
- self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/1h/0h]tpubDCXqdwWZcszwqYJSnZp8eARkxGJfHAk23KDxbztV4BbschfaTfYLTcSkSJ3TN64dRqwa1rnFUScsYormKkGqNbbPwkorQimVevXjxzUV9Gf/*,[59b09cd6/84h/1h/0h]tpubDCYfZY2ceyHzYzMMVPt9MNeiqtQ2T7Uyp9QSFwYXh8Vi9iJFYXcuphJaGXfF3jUQJi5Y3GMNXvM11gaL4txzZgNGK22BFAwMXynnzv4z2Jh/*,[e81a0532/84h/1h/0h]tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb/*))#c08a2rzv",
+ self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/1h/0h]" + chg_xpub1 + "/*,[59b09cd6/84h/1h/0h]" + chg_xpub2 + "/*,[e81a0532/84h/1h/0h]" + chg_xpub3 + "/*))#c08a2rzv",
"active": True,
"internal" : True,
"range": 1000,
@@ -396,8 +485,15 @@ class ImportDescriptorsTest(BitcoinTestFramework):
change_addr = wmulti_pub.getrawchangeaddress('bech32')
assert_equal(change_addr, 'bcrt1qt9uhe3a9hnq7vajl7a094z4s3crm9ttf8zw3f5v9gr2nyd7e3lnsy44n8e')
assert_equal(wmulti_pub.getwalletinfo()['keypoolsize'], 999)
+
+ # generate some utxos for next tests
txid = w0.sendtoaddress(addr, 10)
vout = find_vout_for_address(self.nodes[0], txid, addr)
+
+ addr2 = wmulti_pub.getnewaddress('', 'bech32')
+ txid2 = w0.sendtoaddress(addr2, 10)
+ vout2 = find_vout_for_address(self.nodes[0], txid2, addr2)
+
self.nodes[0].generate(6)
self.sync_all()
assert_equal(wmulti_pub.getbalance(), wmulti_priv.getbalance())
@@ -411,14 +507,14 @@ class ImportDescriptorsTest(BitcoinTestFramework):
wmulti_priv1 = self.nodes[1].get_wallet_rpc("wmulti_priv1")
res = wmulti_priv1.importdescriptors([
{
- "desc": descsum_create("wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/0h/0h/*,[59b09cd6/84h/0h/0h]tpubDDBF2BTR6s8drwrfDei8WxtckGuSm1cyoKxYY1QaKSBFbHBYQArWhHPA6eJrzZej6nfHGLSURYSLHr7GuYch8aY5n61tGqgn8b4cXrMuoPH/*,[e81a0532/84h/0h/0h]tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E/*))"),
+ "desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/0h/0h/*,[59b09cd6/84h/0h/0h]" + acc_xpub2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
"active": True,
"range": 1000,
"next_index": 0,
"timestamp": "now"
},
{
- "desc": descsum_create("wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/1h/0h/*,[59b09cd6/84h/1h/0h]tpubDCYfZY2ceyHzYzMMVPt9MNeiqtQ2T7Uyp9QSFwYXh8Vi9iJFYXcuphJaGXfF3jUQJi5Y3GMNXvM11gaL4txzZgNGK22BFAwMXynnzv4z2Jh/*,[e81a0532/84h/1h/0h]tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb/*))"),
+ "desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/1h/0h/*,[59b09cd6/84h/1h/0h]" + chg_xpub2 + "/*,[e81a0532/84h/1h/0h]" + chg_xpub3 + "/*))"),
"active": True,
"internal" : True,
"range": 1000,
@@ -434,14 +530,14 @@ class ImportDescriptorsTest(BitcoinTestFramework):
wmulti_priv2 = self.nodes[1].get_wallet_rpc('wmulti_priv2')
res = wmulti_priv2.importdescriptors([
{
- "desc": descsum_create("wsh(multi(2,[7b2d0242/84h/0h/0h]tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/0h/0h/*,[e81a0532/84h/0h/0h]tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E/*))"),
+ "desc": descsum_create("wsh(multi(2,[7b2d0242/84h/0h/0h]" + acc_xpub1 + "/*," + xprv2 + "/84h/0h/0h/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
"active": True,
"range": 1000,
"next_index": 0,
"timestamp": "now"
},
{
- "desc": descsum_create("wsh(multi(2,[7b2d0242/84h/1h/0h]tpubDCXqdwWZcszwqYJSnZp8eARkxGJfHAk23KDxbztV4BbschfaTfYLTcSkSJ3TN64dRqwa1rnFUScsYormKkGqNbbPwkorQimVevXjxzUV9Gf/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/1h/0h/*,[e81a0532/84h/1h/0h]tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb/*))"),
+ "desc": descsum_create("wsh(multi(2,[7b2d0242/84h/1h/0h]" + chg_xpub1 + "/*," + xprv2 + "/84h/1h/0h/*,[e81a0532/84h/1h/0h]" + chg_xpub3 + "/*))"),
"active": True,
"internal" : True,
"range": 1000,
@@ -531,6 +627,33 @@ class ImportDescriptorsTest(BitcoinTestFramework):
)
+ self.log.info("Amending multisig with new private keys")
+ self.nodes[1].createwallet(wallet_name="wmulti_priv3", descriptors=True)
+ wmulti_priv3 = self.nodes[1].get_wallet_rpc("wmulti_priv3")
+ res = wmulti_priv3.importdescriptors([
+ {
+ "desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/0h/0h/*,[59b09cd6/84h/0h/0h]" + acc_xpub2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
+ "active": True,
+ "range": 1000,
+ "next_index": 0,
+ "timestamp": "now"
+ }])
+ assert_equal(res[0]['success'], True)
+ res = wmulti_priv3.importdescriptors([
+ {
+ "desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/0h/0h/*,[59b09cd6/84h/0h/0h]" + acc_xprv2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
+ "active": True,
+ "range": 1000,
+ "next_index": 0,
+ "timestamp": "now"
+ }])
+ assert_equal(res[0]['success'], True)
+
+ rawtx = self.nodes[1].createrawtransaction([{'txid': txid2, 'vout': vout2}], {w0.getnewaddress(): 9.999})
+ tx = wmulti_priv3.signrawtransactionwithwallet(rawtx)
+ assert_equal(tx['complete'], True)
+ self.nodes[1].sendrawtransaction(tx['hex'])
+
self.log.info("Combo descriptors cannot be active")
self.test_importdesc({"desc": descsum_create("combo(tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/*)"),
"active": True,
diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index 0a00c5eed9..baeac655df 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -746,6 +746,27 @@ class ImportMultiTest(BitcoinTestFramework):
assert 'hdmasterfingerprint' not in pub_import_info
assert 'hdkeypath' not in pub_import_info
+ # Bech32m addresses and descriptors cannot be imported
+ self.log.info("Bech32m addresses and descriptors cannot be imported")
+ self.test_importmulti(
+ {
+ "scriptPubKey": {"address": "bcrt1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqc8gma6"},
+ "timestamp": "now",
+ },
+ success=False,
+ error_code=-5,
+ error_message="Bech32m addresses cannot be imported into legacy wallets",
+ )
+ self.test_importmulti(
+ {
+ "desc": descsum_create("tr({})".format(pub)),
+ "timestamp": "now",
+ },
+ success=False,
+ error_code=-5,
+ error_message="Bech32m descriptors cannot be imported into legacy wallets",
+ )
+
# Import some public keys to the keypool of a no privkey wallet
self.log.info("Adding pubkey to keypool of disableprivkey wallet")
self.nodes[1].createwallet(wallet_name="noprivkeys", disable_private_keys=True)
diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py
index 3fe6adeebc..28bfc9116f 100755
--- a/test/functional/wallet_keypool.py
+++ b/test/functional/wallet_keypool.py
@@ -161,7 +161,7 @@ class KeyPoolTest(BitcoinTestFramework):
# Using a fee rate (10 sat / byte) well above the minimum relay rate
# creating a 5,000 sat transaction with change should not be possible
- assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): 0.00005000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
+ assert_raises_rpc_error(-4, "Transaction needs a change address, but we can't generate it.", w2.walletcreatefundedpsbt, inputs=[], outputs=[{addr.pop(): 0.00005000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
# creating a 10,000 sat transaction without change, with a manual input, should still be possible
res = w2.walletcreatefundedpsbt(inputs=w2.listunspent(), outputs=[{destination: 0.00010000}], options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010})
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index 2d792bac52..a571454acf 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -135,31 +135,33 @@ class WalletLabelsTest(BitcoinTestFramework):
# in the label. This is a no-op.
change_label(node, labels[2].addresses[0], labels[2], labels[2])
- self.log.info('Check watchonly labels')
- node.createwallet(wallet_name='watch_only', disable_private_keys=True)
- wallet_watch_only = node.get_wallet_rpc('watch_only')
- BECH32_VALID = {
- '✔️_VER15_PROG40': 'bcrt10qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxkg7fn',
- '✔️_VER16_PROG03': 'bcrt1sqqqqq8uhdgr',
- '✔️_VER16_PROB02': 'bcrt1sqqqq4wstyw',
- }
- BECH32_INVALID = {
- '❌_VER15_PROG41': 'bcrt1sqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqajlxj8',
- '❌_VER16_PROB01': 'bcrt1sqq5r4036',
- }
- for l in BECH32_VALID:
- ad = BECH32_VALID[l]
- wallet_watch_only.importaddress(label=l, rescan=False, address=ad)
- node.generatetoaddress(1, ad)
- assert_equal(wallet_watch_only.getaddressesbylabel(label=l), {ad: {'purpose': 'receive'}})
- assert_equal(wallet_watch_only.getreceivedbylabel(label=l), 0)
- for l in BECH32_INVALID:
- ad = BECH32_INVALID[l]
- assert_raises_rpc_error(
- -5,
- "Address is not valid" if self.options.descriptors else "Invalid Bitcoin address or script",
- lambda: wallet_watch_only.importaddress(label=l, rescan=False, address=ad),
- )
+ if self.options.descriptors:
+ # This is a descriptor wallet test because of segwit v1+ addresses
+ self.log.info('Check watchonly labels')
+ node.createwallet(wallet_name='watch_only', disable_private_keys=True)
+ wallet_watch_only = node.get_wallet_rpc('watch_only')
+ BECH32_VALID = {
+ '✔️_VER15_PROG40': 'bcrt10qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxkg7fn',
+ '✔️_VER16_PROG03': 'bcrt1sqqqqq8uhdgr',
+ '✔️_VER16_PROB02': 'bcrt1sqqqq4wstyw',
+ }
+ BECH32_INVALID = {
+ '❌_VER15_PROG41': 'bcrt1sqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqajlxj8',
+ '❌_VER16_PROB01': 'bcrt1sqq5r4036',
+ }
+ for l in BECH32_VALID:
+ ad = BECH32_VALID[l]
+ wallet_watch_only.importaddress(label=l, rescan=False, address=ad)
+ node.generatetoaddress(1, ad)
+ assert_equal(wallet_watch_only.getaddressesbylabel(label=l), {ad: {'purpose': 'receive'}})
+ assert_equal(wallet_watch_only.getreceivedbylabel(label=l), 0)
+ for l in BECH32_INVALID:
+ ad = BECH32_INVALID[l]
+ assert_raises_rpc_error(
+ -5,
+ "Address is not valid" if self.options.descriptors else "Invalid Bitcoin address or script",
+ lambda: wallet_watch_only.importaddress(label=l, rescan=False, address=ad),
+ )
class Label:
diff --git a/test/functional/wallet_listdescriptors.py b/test/functional/wallet_listdescriptors.py
index c1444164ce..bf53c99855 100755
--- a/test/functional/wallet_listdescriptors.py
+++ b/test/functional/wallet_listdescriptors.py
@@ -72,6 +72,10 @@ class ListDescriptorsTest(BitcoinTestFramework):
}
assert_equal(expected, wallet.listdescriptors())
+ self.log.info("Test listdescriptors with encrypted wallet")
+ wallet.encryptwallet("pass")
+ assert_equal(expected, wallet.listdescriptors())
+
self.log.info('Test non-active non-range combo descriptor')
node.createwallet(wallet_name='w4', blank=True, descriptors=True)
wallet = node.get_wallet_rpc('w4')
diff --git a/test/functional/wallet_taproot.py b/test/functional/wallet_taproot.py
index 0eac814c52..9eb204bf37 100755
--- a/test/functional/wallet_taproot.py
+++ b/test/functional/wallet_taproot.py
@@ -226,7 +226,7 @@ class WalletTaprootTest(BitcoinTestFramework):
result = self.addr_gen.importdescriptors([{"desc": desc_pub, "active": True, "timestamp": "now"}])
assert(result[0]['success'])
for i in range(4):
- addr_g = self.addr_gen.getnewaddress(address_type='bech32')
+ addr_g = self.addr_gen.getnewaddress(address_type='bech32m')
if treefn is not None:
addr_r = self.make_addr(treefn, keys, i)
assert_equal(addr_g, addr_r)
@@ -265,7 +265,7 @@ class WalletTaprootTest(BitcoinTestFramework):
result = self.rpc_online.importdescriptors([{"desc": desc_change, "active": True, "timestamp": "now", "internal": True}])
assert(result[0]['success'])
for i in range(4):
- addr_g = self.rpc_online.getnewaddress(address_type='bech32')
+ addr_g = self.rpc_online.getnewaddress(address_type='bech32m')
if treefn is not None:
addr_r = self.make_addr(treefn, keys_pay, i)
assert_equal(addr_g, addr_r)
@@ -296,7 +296,7 @@ class WalletTaprootTest(BitcoinTestFramework):
result = self.psbt_offline.importdescriptors([{"desc": desc_change, "active": True, "timestamp": "now", "internal": True}])
assert(result[0]['success'])
for i in range(4):
- addr_g = self.psbt_online.getnewaddress(address_type='bech32')
+ addr_g = self.psbt_online.getnewaddress(address_type='bech32m')
if treefn is not None:
addr_r = self.make_addr(treefn, keys_pay, i)
assert_equal(addr_g, addr_r)
diff --git a/test/lint/lint-python.sh b/test/lint/lint-python.sh
index 51815963f6..c448fa6f9a 100755
--- a/test/lint/lint-python.sh
+++ b/test/lint/lint-python.sh
@@ -102,7 +102,7 @@ if ! PYTHONWARNINGS="ignore" flake8 --ignore=B,C,E,F,I,N,W --select=$(IFS=","; e
EXIT_CODE=1
fi
-if ! mypy --ignore-missing-imports $(git ls-files "test/functional/*.py" "contrib/devtools/*.py"); then
+if ! mypy --ignore-missing-imports --show-error-codes $(git ls-files "test/functional/*.py" "contrib/devtools/*.py"); then
EXIT_CODE=1
fi
diff --git a/test/lint/lint-spelling.sh b/test/lint/lint-spelling.sh
index fbdf3c59c1..238fa63c45 100755
--- a/test/lint/lint-spelling.sh
+++ b/test/lint/lint-spelling.sh
@@ -15,6 +15,6 @@ if ! command -v codespell > /dev/null; then
fi
IGNORE_WORDS_FILE=test/lint/lint-spelling.ignore-words.txt
-if ! codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=${IGNORE_WORDS_FILE} $(git ls-files -- ":(exclude)build-aux/m4/" ":(exclude)contrib/seeds/*.txt" ":(exclude)depends/" ":(exclude)doc/release-notes/" ":(exclude)src/leveldb/" ":(exclude)src/crc32c/" ":(exclude)src/qt/locale/" ":(exclude)src/qt/*.qrc" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)contrib/gitian-keys/keys.txt"); then
+if ! codespell --check-filenames --disable-colors --quiet-level=7 --ignore-words=${IGNORE_WORDS_FILE} $(git ls-files -- ":(exclude)build-aux/m4/" ":(exclude)contrib/seeds/*.txt" ":(exclude)depends/" ":(exclude)doc/release-notes/" ":(exclude)src/leveldb/" ":(exclude)src/crc32c/" ":(exclude)src/qt/locale/" ":(exclude)src/qt/*.qrc" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)contrib/gitian-keys/keys.txt" ":(exclude)contrib/guix/patches"); then
echo "^ Warning: codespell identified likely spelling errors. Any false positives? Add them to the list of ignored words in ${IGNORE_WORDS_FILE}"
fi
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 877adaccec..2850cfcea5 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -34,9 +34,6 @@ unsigned-integer-overflow:crypto/
unsigned-integer-overflow:FuzzedDataProvider.h
unsigned-integer-overflow:hash.cpp
unsigned-integer-overflow:leveldb/
-# temporary coinstats suppressions (will be removed and fixed in https://github.com/bitcoin/bitcoin/pull/22146)
-unsigned-integer-overflow:node/coinstats.cpp
-signed-integer-overflow:node/coinstats.cpp
unsigned-integer-overflow:policy/fees.cpp
unsigned-integer-overflow:prevector.h
unsigned-integer-overflow:pubkey.h