aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am1
-rwxr-xr-xci/lint/06_script.sh1
-rw-r--r--configure.ac8
-rwxr-xr-xcontrib/devtools/copyright_header.py1
-rwxr-xr-xcontrib/devtools/symbol-check.py5
-rwxr-xr-xcontrib/devtools/test-symbol-check.py2
-rw-r--r--contrib/seeds/.gitignore1
-rw-r--r--contrib/seeds/README.md18
-rw-r--r--contrib/seeds/asmap.py815
-rwxr-xr-xcontrib/seeds/makeseeds.py69
-rw-r--r--depends/Makefile7
-rw-r--r--depends/README.md2
-rwxr-xr-xdepends/gen_id7
-rw-r--r--depends/hosts/android.mk3
-rw-r--r--depends/hosts/darwin.mk6
-rw-r--r--depends/hosts/freebsd.mk6
-rw-r--r--depends/hosts/linux.mk6
-rw-r--r--depends/hosts/mingw32.mk6
-rw-r--r--depends/hosts/netbsd.mk4
-rw-r--r--depends/hosts/openbsd.mk5
-rw-r--r--depends/packages/bdb.mk1
-rw-r--r--depends/packages/qt.mk2
-rw-r--r--depends/packages/sqlite.mk6
-rw-r--r--depends/packages/systemtap.mk4
-rw-r--r--depends/packages/zeromq.mk1
-rw-r--r--depends/patches/qt/mac-qmake.conf2
-rw-r--r--depends/patches/systemtap/remove_SDT_ASM_SECTION_AUTOGROUP_SUPPORT_check.patch22
-rw-r--r--doc/developer-notes.md4
-rw-r--r--src/Makefile.am1
-rw-r--r--src/bench/mempool_eviction.cpp2
-rw-r--r--src/bench/rpc_mempool.cpp5
-rw-r--r--src/compat.h3
-rw-r--r--src/fs.cpp3
-rw-r--r--src/i2p.cpp4
-rw-r--r--src/net.cpp180
-rw-r--r--src/net.h38
-rw-r--r--src/net_processing.cpp2
-rw-r--r--src/node/blockstorage.h2
-rw-r--r--src/policy/packages.h9
-rw-r--r--src/policy/policy.h58
-rw-r--r--src/psbt.h2
-rw-r--r--src/qt/forms/sendcoinsentry.ui1437
-rw-r--r--src/qt/guiutil.cpp3
-rw-r--r--src/qt/intro.cpp2
-rw-r--r--src/qt/sendcoinsentry.cpp31
-rw-r--r--src/qt/sendcoinsentry.h6
-rw-r--r--src/rest.cpp10
-rw-r--r--src/support/lockedpool.cpp3
-rw-r--r--src/test/blockencodings_tests.cpp8
-rw-r--r--src/test/fuzz/util.cpp9
-rw-r--r--src/test/fuzz/util.h2
-rw-r--r--src/test/mempool_tests.cpp18
-rw-r--r--src/test/net_tests.cpp7
-rw-r--r--src/test/policyestimator_tests.cpp6
-rw-r--r--src/test/util/net.h9
-rw-r--r--src/test/validation_chainstate_tests.cpp2
-rw-r--r--src/test/validation_flush_tests.cpp2
-rw-r--r--src/univalue/.cirrus.yml44
-rw-r--r--src/univalue/COPYING19
-rw-r--r--src/univalue/Makefile.am58
-rw-r--r--src/univalue/README.md21
-rwxr-xr-xsrc/univalue/autogen.sh9
-rw-r--r--src/univalue/build-aux/m4/.gitignore1
-rw-r--r--src/univalue/build-aux/m4/ax_cxx_compile_stdcxx.m4962
-rw-r--r--src/univalue/configure.ac72
-rw-r--r--src/univalue/gen/gen.cpp84
-rw-r--r--src/univalue/include/univalue.h6
-rw-r--r--src/univalue/include/univalue_escapes.h (renamed from src/univalue/lib/univalue_escapes.h)7
-rw-r--r--src/univalue/include/univalue_utffilter.h (renamed from src/univalue/lib/univalue_utffilter.h)6
-rw-r--r--src/univalue/lib/univalue_read.cpp2
-rw-r--r--src/univalue/lib/univalue_write.cpp2
-rw-r--r--src/univalue/pc/libunivalue-uninstalled.pc.in9
-rw-r--r--src/univalue/pc/libunivalue.pc.in10
-rw-r--r--src/univalue/sources.mk6
-rw-r--r--src/univalue/test/unitester.cpp34
-rw-r--r--src/util/sock.cpp112
-rw-r--r--src/util/sock.h71
-rw-r--r--src/util/system.cpp3
-rw-r--r--src/validation.cpp6
-rw-r--r--src/validation.h19
-rw-r--r--src/wallet/coincontrol.h7
-rw-r--r--src/wallet/feebumper.cpp2
-rw-r--r--src/wallet/interfaces.cpp6
-rw-r--r--src/wallet/receive.cpp17
-rw-r--r--src/wallet/rpc/coins.cpp8
-rw-r--r--src/wallet/rpc/spend.cpp29
-rw-r--r--src/wallet/spend.cpp150
-rw-r--r--src/wallet/spend.h19
-rw-r--r--src/wallet/test/coinselector_tests.cpp4
-rw-r--r--src/wallet/test/wallet_tests.cpp8
-rw-r--r--src/wallet/wallet.cpp62
-rw-r--r--src/wallet/wallet.h8
-rwxr-xr-xtest/functional/rpc_createmultisig.py6
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py25
-rw-r--r--test/functional/test_framework/address.py7
-rwxr-xr-xtest/functional/test_framework/script_util.py5
-rw-r--r--test/functional/test_framework/wallet.py45
-rwxr-xr-xtest/functional/wallet_taproot.py8
-rw-r--r--test/lint/README.md1
-rwxr-xr-xtest/lint/lint-files.py2
-rwxr-xr-xtest/lint/lint-format-strings.py2
-rwxr-xr-xtest/lint/lint-include-guards.py1
-rwxr-xr-xtest/lint/lint-includes.py2
-rwxr-xr-xtest/lint/lint-locale-dependence.py1
-rwxr-xr-xtest/lint/lint-shell-locale.py2
-rwxr-xr-xtest/lint/lint-shell.py2
-rwxr-xr-xtest/lint/lint-spelling.py2
-rwxr-xr-xtest/lint/lint-whitespace.py1
109 files changed, 1649 insertions, 3227 deletions
diff --git a/.gitignore b/.gitignore
index 6c888bfdc4..6ca9d39a16 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,8 +44,6 @@ src/obj
share/setup.nsi
share/qt/Info.plist
-src/univalue/gen
-
src/qt/*.moc
src/qt/moc_*.cpp
src/qt/forms/ui_*.h
diff --git a/Makefile.am b/Makefile.am
index 05e89f12b7..011faa62c7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -174,7 +174,6 @@ LCOV_FILTER_PATTERN = \
-p "src/leveldb/" \
-p "src/crc32c/" \
-p "src/bench/" \
- -p "src/univalue" \
-p "src/crypto/ctaes" \
-p "src/minisketch" \
-p "src/secp256k1" \
diff --git a/ci/lint/06_script.sh b/ci/lint/06_script.sh
index 84b3404e78..1f14dd079f 100755
--- a/ci/lint/06_script.sh
+++ b/ci/lint/06_script.sh
@@ -18,7 +18,6 @@ export COMMIT_RANGE
test/lint/git-subtree-check.sh src/crypto/ctaes
test/lint/git-subtree-check.sh src/secp256k1
test/lint/git-subtree-check.sh src/minisketch
-test/lint/git-subtree-check.sh src/univalue
test/lint/git-subtree-check.sh src/leveldb
test/lint/git-subtree-check.sh src/crc32c
test/lint/check-doc.py
diff --git a/configure.ac b/configure.ac
index c3111698f8..163f69988e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -711,6 +711,9 @@ case $host in
fi
CORE_CPPFLAGS="$CORE_CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN"
+ dnl Prevent the definition of min/max macros.
+ dnl We always want to use the standard library.
+ CORE_CPPFLAGS="$CORE_CPPFLAGS -DNOMINMAX"
dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against.
dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override
@@ -1262,8 +1265,8 @@ AC_LINK_IFELSE(
AC_MSG_CHECKING([for ::_wsystem])
AC_LINK_IFELSE(
[ AC_LANG_PROGRAM(
- [[ ]],
- [[ int nErr = ::_wsystem(""); ]]
+ [[ #include <stdlib.h> ]],
+ [[ int nErr = ::_wsystem(NULL); ]]
)],
[ AC_MSG_RESULT([yes]); have_any_system=yes],
[ AC_MSG_RESULT([no]) ]
@@ -1555,6 +1558,7 @@ fi
dnl libevent check
+use_libevent=no
if test "$build_bitcoin_cli$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench" != "nonononono"; then
PKG_CHECK_MODULES([EVENT], [libevent >= 2.1.8], [use_libevent=yes], [AC_MSG_ERROR([libevent version 2.1.8 or greater not found.])])
if test "$TARGET_OS" != "windows"; then
diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py
index e20eb4b0d2..680de1f1b3 100755
--- a/contrib/devtools/copyright_header.py
+++ b/contrib/devtools/copyright_header.py
@@ -35,7 +35,6 @@ EXCLUDE_DIRS = [
"src/leveldb/",
"src/minisketch",
"src/secp256k1/",
- "src/univalue/",
"src/crc32c/",
]
diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py
index a419e392ee..23d29af3f1 100755
--- a/contrib/devtools/symbol-check.py
+++ b/contrib/devtools/symbol-check.py
@@ -50,9 +50,8 @@ MAX_VERSIONS = {
# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
-'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__',
-'__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr',
-'environ', '_environ', '__environ',
+'environ', '_environ', '__environ', '_fini', '_init', 'stdin',
+'stdout', 'stderr',
}
# Expected linker-loader names can be found here:
diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py
index b4c112b266..2881e3efac 100755
--- a/contrib/devtools/test-symbol-check.py
+++ b/contrib/devtools/test-symbol-check.py
@@ -39,7 +39,7 @@ class TestSymbolChecks(unittest.TestCase):
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.
+ # RISC-V in a glibc 2.27 environment and we allow all symbols from 2.27.
if 'riscv' in get_machine(cc):
self.skipTest("test not available for RISC-V")
diff --git a/contrib/seeds/.gitignore b/contrib/seeds/.gitignore
index e4a39d6093..d9a2451f70 100644
--- a/contrib/seeds/.gitignore
+++ b/contrib/seeds/.gitignore
@@ -1 +1,2 @@
seeds_main.txt
+asmap-filled.dat
diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md
index c53446bfb0..b2ea7522ac 100644
--- a/contrib/seeds/README.md
+++ b/contrib/seeds/README.md
@@ -8,21 +8,11 @@ and remove old versions as necessary (at a minimum when GetDesirableServiceFlags
changes its default return value, as those are the services which seeds are added
to addrman with).
-The seeds compiled into the release are created from sipa's DNS seed data, like this:
+The seeds compiled into the release are created from sipa's DNS seed and AS map
+data. Run the following commands from the `/contrib/seeds` directory:
curl https://bitcoin.sipa.be/seeds.txt.gz | gzip -dc > seeds_main.txt
- python3 makeseeds.py < seeds_main.txt > nodes_main.txt
+ curl https://bitcoin.sipa.be/asmap-filled.dat > asmap-filled.dat
+ python3 makeseeds.py -a asmap-filled.dat < seeds_main.txt > nodes_main.txt
cat nodes_main_manual.txt >> nodes_main.txt
python3 generate-seeds.py . > ../../src/chainparamsseeds.h
-
-## Dependencies
-
-Ubuntu, Debian:
-
- sudo apt-get install python3-dnspython
-
-and/or for other operating systems:
-
- pip install dnspython
-
-See https://dnspython.readthedocs.io/en/latest/installation.html for more information.
diff --git a/contrib/seeds/asmap.py b/contrib/seeds/asmap.py
new file mode 100644
index 0000000000..e28e5cf532
--- /dev/null
+++ b/contrib/seeds/asmap.py
@@ -0,0 +1,815 @@
+# Copyright (c) 2022 Pieter Wuille
+# Distributed under the MIT software license, see the accompanying
+# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
+
+"""
+This module provides the ASNEntry and ASMap classes.
+"""
+
+import copy
+import ipaddress
+import random
+import unittest
+from enum import Enum
+from functools import total_ordering
+from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union, overload
+
+def net_to_prefix(net: Union[ipaddress.IPv4Network,ipaddress.IPv6Network]) -> List[bool]:
+ """
+ Convert an IPv4 or IPv6 network to a prefix represented as a list of bits.
+
+ IPv4 ranges are remapped to their IPv4-mapped IPv6 range (::ffff:0:0/96).
+ """
+ num_bits = net.prefixlen
+ netrange = int.from_bytes(net.network_address.packed, 'big')
+
+ # Map an IPv4 prefix into IPv6 space.
+ if isinstance(net, ipaddress.IPv4Network):
+ num_bits += 96
+ netrange += 0xffff00000000
+
+ # Strip unused bottom bits.
+ assert (netrange & ((1 << (128 - num_bits)) - 1)) == 0
+ return [((netrange >> (127 - i)) & 1) != 0 for i in range(num_bits)]
+
+def prefix_to_net(prefix: List[bool]) -> Union[ipaddress.IPv4Network,ipaddress.IPv6Network]:
+ """The reverse operation of net_to_prefix."""
+ # Convert to number
+ netrange = sum(b << (127 - i) for i, b in enumerate(prefix))
+ num_bits = len(prefix)
+ assert num_bits <= 128
+
+ # Return IPv4 range if in ::ffff:0:0/96
+ if num_bits >= 96 and (netrange >> 32) == 0xffff:
+ return ipaddress.IPv4Network((netrange & 0xffffffff, num_bits - 96), True)
+
+ # Return IPv6 range otherwise.
+ return ipaddress.IPv6Network((netrange, num_bits), True)
+
+# Shortcut for (prefix, ASN) entries.
+ASNEntry = Tuple[List[bool], int]
+
+# Shortcut for (prefix, old ASN, new ASN) entries.
+ASNDiff = Tuple[List[bool], int, int]
+
+class _VarLenCoder:
+ """
+ A class representing a custom variable-length binary encoder/decoder for
+ integers. Each object represents a different coder, with different parameters
+ minval and clsbits.
+
+ The encoding is easiest to describe using an example. Let's say minval=100 and
+ clsbits=[4,2,2,3]. In that case:
+ - x in [100..115]: encoded as [0] + [4-bit BE encoding of (x-100)].
+ - x in [116..119]: encoded as [1,0] + [2-bit BE encoding of (x-116)].
+ - x in [120..123]: encoded as [1,1,0] + [2-bit BE encoding of (x-120)].
+ - x in [124..131]: encoded as [1,1,1] + [3-bit BE encoding of (x-124)].
+
+ In general, every number is encoded as:
+ - First, k "1"-bits, where k is the class the number falls in (there is one class
+ per element of clsbits).
+ - Then, a "0"-bit, unless k is the highest class, in which case there is nothing.
+ - Lastly, clsbits[k] bits encoding in big endian the position in its class that
+ number falls into.
+ - Every class k consists of 2^clsbits[k] consecutive integers. k=0 starts at minval,
+ other classes start one past the last element of the class before it.
+ """
+
+ def __init__(self, minval: int, clsbits: List[int]):
+ """Construct a new _VarLenCoder."""
+ self._minval = minval
+ self._clsbits = clsbits
+ self._maxval = minval + sum(1 << b for b in clsbits) - 1
+
+ def can_encode(self, val: int) -> bool:
+ """Check whether value val is in the range this coder supports."""
+ return self._minval <= val <= self._maxval
+
+ def encode(self, val: int, ret: List[int]) -> None:
+ """Append encoding of val onto integer list ret."""
+
+ assert self._minval <= val <= self._maxval
+ val -= self._minval
+ bits = 0
+ for k, bits in enumerate(self._clsbits):
+ if val >> bits:
+ # If the value will not fit in class k, subtract its range from v,
+ # emit a "1" bit and continue with the next class.
+ val -= 1 << bits
+ ret.append(1)
+ else:
+ if k + 1 < len(self._clsbits):
+ # Unless we're in the last class, emit a "0" bit.
+ ret.append(0)
+ break
+ # And then encode v (now the position within the class) in big endian.
+ ret.extend((val >> (bits - 1 - b)) & 1 for b in range(bits))
+
+ def encode_size(self, val: int) -> int:
+ """Compute how many bits are needed to encode val."""
+ assert self._minval <= val <= self._maxval
+ val -= self._minval
+ ret = 0
+ bits = 0
+ for k, bits in enumerate(self._clsbits):
+ if val >> bits:
+ val -= 1 << bits
+ ret += 1
+ else:
+ ret += k + 1 < len(self._clsbits)
+ break
+ return ret + bits
+
+ def decode(self, stream, bitpos) -> Tuple[int,int]:
+ """Decode a number starting at bitpos in stream, returning value and new bitpos."""
+ val = self._minval
+ bits = 0
+ for k, bits in enumerate(self._clsbits):
+ bit = 0
+ if k + 1 < len(self._clsbits):
+ bit = stream[bitpos]
+ bitpos += 1
+ if not bit:
+ break
+ val += 1 << bits
+ for i in range(bits):
+ bit = stream[bitpos]
+ bitpos += 1
+ val += bit << (bits - 1 - i)
+ return val, bitpos
+
+# Variable-length encoders used in the binary asmap format.
+_CODER_INS = _VarLenCoder(0, [0, 0, 1])
+_CODER_ASN = _VarLenCoder(1, list(range(15, 25)))
+_CODER_MATCH = _VarLenCoder(2, list(range(1, 9)))
+_CODER_JUMP = _VarLenCoder(17, list(range(5, 31)))
+
+class _Instruction(Enum):
+ """One instruction in the binary asmap format."""
+ # A return instruction, encoded as [0], returns a constant ASN. It is followed by
+ # an integer using the ASN encoding.
+ RETURN = 0
+ # A jump instruction, encoded as [1,0] inspects the next unused bit in the input
+ # and either continues execution (if 0), or skips a specified number of bits (if 1).
+ # It is followed by an integer, and then two subprograms. The integer uses jump encoding
+ # and corresponds to the length of the first subprogram (so it can be skipped).
+ JUMP = 1
+ # A match instruction, encoded as [1,1,0] inspects 1 or more of the next unused bits
+ # in the input with its argument. If they all match, execution continues. If they do
+ # not, failure is returned. If a default instruction has been executed before, instead
+ # of failure the default instruction's argument is returned. It is followed by an
+ # integer in match encoding, and a subprogram. That value is at least 2 bits and at
+ # most 9 bits. An n-bit value signifies matching (n-1) bits in the input with the lower
+ # (n-1) bits in the match value.
+ MATCH = 2
+ # A default instruction, encoded as [1,1,1] sets the default variable to its argument,
+ # and continues execution. It is followed by an integer in ASN encoding, and a subprogram.
+ DEFAULT = 3
+ # Not an actual instruction, but a way to encode the empty program that fails. In the
+ # encoder, it is used more generally to represent the failure case inside MATCH instructions,
+ # which may (if used inside the context of a DEFAULT instruction) actually correspond to
+ # a successful return. In this usage, they're always converted to an actual MATCH or RETURN
+ # before the top level is reached (see make_default below).
+ END = 4
+
+class _BinNode:
+ """A class representing a (node of) the parsed binary asmap format."""
+
+ @overload
+ def __init__(self, ins: _Instruction): ...
+ @overload
+ def __init__(self, ins: _Instruction, arg1: int): ...
+ @overload
+ def __init__(self, ins: _Instruction, arg1: "_BinNode", arg2: "_BinNode"): ...
+ @overload
+ def __init__(self, ins: _Instruction, arg1: int, arg2: "_BinNode"): ...
+
+ def __init__(self, ins: _Instruction, arg1=None, arg2=None):
+ """
+ Construct a new asmap node. Possibilities are:
+ - _BinNode(_Instruction.RETURN, asn)
+ - _BinNode(_Instruction.JUMP, node_0, node_1)
+ - _BinNode(_Instruction.MATCH, val, node)
+ - _BinNode(_Instruction.DEFAULT, asn, node)
+ - _BinNode(_Instruction.END)
+ """
+ self.ins = ins
+ self.arg1 = arg1
+ self.arg2 = arg2
+ if ins == _Instruction.RETURN:
+ assert isinstance(arg1, int)
+ assert arg2 is None
+ self.size = _CODER_INS.encode_size(ins.value) + _CODER_ASN.encode_size(arg1)
+ elif ins == _Instruction.JUMP:
+ assert isinstance(arg1, _BinNode)
+ assert isinstance(arg2, _BinNode)
+ self.size = (_CODER_INS.encode_size(ins.value) + _CODER_JUMP.encode_size(arg1.size) +
+ arg1.size + arg2.size)
+ elif ins == _Instruction.DEFAULT:
+ assert isinstance(arg1, int)
+ assert isinstance(arg2, _BinNode)
+ self.size = _CODER_INS.encode_size(ins.value) + _CODER_ASN.encode_size(arg1) + arg2.size
+ elif ins == _Instruction.MATCH:
+ assert isinstance(arg1, int)
+ assert isinstance(arg2, _BinNode)
+ self.size = (_CODER_INS.encode_size(ins.value) + _CODER_MATCH.encode_size(arg1)
+ + arg2.size)
+ elif ins == _Instruction.END:
+ assert arg1 is None
+ assert arg2 is None
+ self.size = 0
+ else:
+ assert False
+
+ @staticmethod
+ def make_end() -> "_BinNode":
+ """Constructor for a _BinNode with just an END instruction."""
+ return _BinNode(_Instruction.END)
+
+ @staticmethod
+ def make_leaf(val: int) -> "_BinNode":
+ """Constructor for a _BinNode of just a RETURN instruction."""
+ assert val is not None and val > 0
+ return _BinNode(_Instruction.RETURN, val)
+
+ @staticmethod
+ def make_branch(node0: "_BinNode", node1: "_BinNode") -> "_BinNode":
+ """
+ Construct a _BinNode corresponding to running either the node0 or node1 subprogram,
+ based on the next input bit. It exploits shortcuts that are possible in the encoding,
+ and uses either a JUMP, MATCH, or END instruction.
+ """
+ if node0.ins == _Instruction.END and node1.ins == _Instruction.END:
+ return node0
+ if node0.ins == _Instruction.END:
+ if node1.ins == _Instruction.MATCH and node1.arg1 <= 0xFF:
+ return _BinNode(node1.ins, node1.arg1 + (1 << node1.arg1.bit_length()), node1.arg2)
+ return _BinNode(_Instruction.MATCH, 3, node1)
+ if node1.ins == _Instruction.END:
+ if node0.ins == _Instruction.MATCH and node0.arg1 <= 0xFF:
+ return _BinNode(node0.ins, node0.arg1 + (1 << (node0.arg1.bit_length() - 1)),
+ node0.arg2)
+ return _BinNode(_Instruction.MATCH, 2, node0)
+ return _BinNode(_Instruction.JUMP, node0, node1)
+
+ @staticmethod
+ def make_default(val: int, sub: "_BinNode") -> "_BinNode":
+ """
+ Construct a _BinNode that corresponds to the specified subprogram, with the specified
+ default value. It exploits shortcuts that are possible in the encoding, and will use
+ either a DEFAULT or a RETURN instruction."""
+ assert val is not None and val > 0
+ if sub.ins == _Instruction.END:
+ return _BinNode(_Instruction.RETURN, val)
+ if sub.ins in (_Instruction.RETURN, _Instruction.DEFAULT):
+ return sub
+ return _BinNode(_Instruction.DEFAULT, val, sub)
+
+@total_ordering
+class ASMap:
+ """
+ A class whose objects represent a mapping from subnets to ASNs.
+
+ Internally the mapping is stored as a binary trie, but can be converted
+ from/to a list of ASNEntry objects, and from/to the binary asmap file format.
+
+ In the trie representation, nodes are represented as bare lists for efficiency
+ and ease of manipulation:
+ - [0] means an unassigned subnet (no ASN mapping for it is present)
+ - [int] means a subnet mapped entirely to the specified ASN.
+ - [node,node] means a subnet whose lower half and upper half have different
+ - mappings, represented by new trie nodes.
+ """
+
+ def update(self, prefix: List[bool], asn: int) -> None:
+ """Update this ASMap object to map prefix to the specified asn."""
+ assert asn == 0 or _CODER_ASN.can_encode(asn)
+
+ def recurse(node: List, offset: int) -> None:
+ if offset == len(prefix):
+ # Reached the end of prefix; overwrite this node.
+ node.clear()
+ node.append(asn)
+ return
+ if len(node) == 1:
+ # Need to descend into a leaf node; split it up.
+ oldasn = node[0]
+ node.clear()
+ node.append([oldasn])
+ node.append([oldasn])
+ # Descend into the node.
+ recurse(node[prefix[offset]], offset + 1)
+ # If the result is two identical leaf children, merge them.
+ if len(node[0]) == 1 and len(node[1]) == 1 and node[0] == node[1]:
+ oldasn = node[0][0]
+ node.clear()
+ node.append(oldasn)
+ recurse(self._trie, 0)
+
+ def update_multi(self, entries: List[Tuple[List[bool], int]]) -> None:
+ """Apply multiple update operations, where longer prefixes take precedence."""
+ entries.sort(key=lambda entry: len(entry[0]))
+ for prefix, asn in entries:
+ self.update(prefix, asn)
+
+ def _set_trie(self, trie) -> None:
+ """Set trie directly. Internal use only."""
+ def recurse(node: List) -> None:
+ if len(node) < 2:
+ return
+ recurse(node[0])
+ recurse(node[1])
+ if len(node[0]) == 2:
+ return
+ if node[0] == node[1]:
+ if len(node[0]) == 0:
+ node.clear()
+ else:
+ asn = node[0][0]
+ node.clear()
+ node.append(asn)
+ recurse(trie)
+ self._trie = trie
+
+ def __init__(self, entries: Optional[Iterable[ASNEntry]] = None) -> None:
+ """Construct an ASMap object from an optional list of entries."""
+ self._trie = [0]
+ if entries is not None:
+ def entry_key(entry):
+ """Sort function that places shorter prefixes first."""
+ prefix, asn = entry
+ return len(prefix), prefix, asn
+ for prefix, asn in sorted(entries, key=entry_key):
+ self.update(prefix, asn)
+
+ def lookup(self, prefix: List[bool]) -> Optional[int]:
+ """Look up a prefix. Returns ASN, or 0 if unassigned, or None if indeterminate."""
+ node = self._trie
+ for bit in prefix:
+ if len(node) == 1:
+ break
+ node = node[bit]
+ if len(node) == 1:
+ return node[0]
+ return None
+
+ def _to_entries_flat(self, fill: bool = False) -> List[ASNEntry]:
+ """Convert an ASMap object to a list of non-overlapping (prefix, asn) objects."""
+ prefix : List[bool] = []
+
+ def recurse(node: List) -> List[ASNEntry]:
+ ret = []
+ if len(node) == 1:
+ if node[0] > 0:
+ ret = [(list(prefix), node[0])]
+ elif len(node) == 2:
+ prefix.append(False)
+ ret = recurse(node[0])
+ prefix[-1] = True
+ ret += recurse(node[1])
+ prefix.pop()
+ if fill and len(ret) > 1:
+ asns = set(x[1] for x in ret)
+ if len(asns) == 1:
+ ret = [(list(prefix), list(asns)[0])]
+ return ret
+ return recurse(self._trie)
+
+ def _to_entries_minimal(self, fill: bool = False) -> List[ASNEntry]:
+ """Convert a trie to a minimal list of ASNEntry objects, exploiting overlap."""
+ prefix : List[bool] = []
+
+ def recurse(node: List) -> (Tuple[Dict[Optional[int], List[ASNEntry]], bool]):
+ if len(node) == 1 and node[0] == 0:
+ return {None if fill else 0: []}, True
+ if len(node) == 1:
+ return {node[0]: [], None: [(list(prefix), node[0])]}, False
+ ret: Dict[Optional[int], List[ASNEntry]] = {}
+ prefix.append(False)
+ left, lhole = recurse(node[0])
+ prefix[-1] = True
+ right, rhole = recurse(node[1])
+ prefix.pop()
+ hole = not fill and (lhole or rhole)
+ def candidate(ctx: Optional[int], res0: Optional[List[ASNEntry]],
+ res1: Optional[List[ASNEntry]]):
+ if res0 is not None and res1 is not None:
+ if ctx not in ret or len(res0) + len(res1) < len(ret[ctx]):
+ ret[ctx] = res0 + res1
+ for ctx in set(left) | set(right):
+ candidate(ctx, left.get(ctx), right.get(ctx))
+ candidate(ctx, left.get(None), right.get(ctx))
+ candidate(ctx, left.get(ctx), right.get(None))
+ if not hole:
+ for ctx in list(ret):
+ if ctx is not None:
+ candidate(None, [(list(prefix), ctx)], ret[ctx])
+ if None in ret:
+ ret = {ctx:entries for ctx, entries in ret.items()
+ if ctx is None or len(entries) < len(ret[None])}
+ if hole:
+ ret = {ctx:entries for ctx, entries in ret.items() if ctx is None or ctx == 0}
+ return ret, hole
+ res, _ = recurse(self._trie)
+ return res[0] if 0 in res else res[None]
+
+ def __str__(self) -> str:
+ """Convert this ASMap object to a string containing Python code constructing it."""
+ return f"ASMap({self._trie})"
+
+ def to_entries(self, overlapping: bool = True, fill: bool = False) -> List[ASNEntry]:
+ """
+ Convert the mappings in this ASMap object to a list of ASNEntry objects.
+
+ Arguments:
+ overlapping: Permit the subnets in the resulting ASNEntry to overlap.
+ Setting this can result in a shorter list.
+ fill: Permit the resulting ASNEntry objects to cover subnets that
+ are unassigned in this ASMap object. Setting this can
+ result in a shorter list.
+ """
+ if overlapping:
+ return self._to_entries_minimal(fill)
+ return self._to_entries_flat(fill)
+
+ @staticmethod
+ def from_random(num_leaves: int = 10, max_asn: int = 6,
+ unassigned_prob: float = 0.5) -> "ASMap":
+ """
+ Construct a random ASMap object, with specified:
+ - Number of leaves in its trie (at least 1)
+ - Maximum ASN value (at least 1)
+ - Probability for leaf nodes to be unassigned
+
+ The number of leaves in the resulting object may be less than what is
+ requested. This method is mostly intended for testing.
+ """
+ assert num_leaves >= 1
+ assert max_asn >= 1 or unassigned_prob == 1
+ assert _CODER_ASN.can_encode(max_asn)
+ assert 0.0 <= unassigned_prob <= 1.0
+ trie: List = []
+ leaves = [trie]
+ ret = ASMap()
+ for i in range(1, num_leaves):
+ idx = random.randrange(i)
+ leaf = leaves[idx]
+ lastleaf = leaves.pop()
+ if idx + 1 < i:
+ leaves[idx] = lastleaf
+ leaf.append([])
+ leaf.append([])
+ leaves.append(leaf[0])
+ leaves.append(leaf[1])
+ for leaf in leaves:
+ if random.random() >= unassigned_prob:
+ leaf.append(random.randrange(1, max_asn + 1))
+ else:
+ leaf.append(0)
+ #pylint: disable=protected-access
+ ret._set_trie(trie)
+ return ret
+
+ def _to_binnode(self, fill: bool = False) -> _BinNode:
+ """Convert a trie to a _BinNode object."""
+ def recurse(node: List) -> Tuple[Dict[Optional[int], _BinNode], bool]:
+ if len(node) == 1 and node[0] == 0:
+ return {(None if fill else 0): _BinNode.make_end()}, True
+ if len(node) == 1:
+ return {None: _BinNode.make_leaf(node[0]), node[0]: _BinNode.make_end()}, False
+ ret: Dict[Optional[int], _BinNode] = {}
+ left, lhole = recurse(node[0])
+ right, rhole = recurse(node[1])
+ hole = (lhole or rhole) and not fill
+
+ def candidate(ctx: Optional[int], arg1, arg2, func: Callable):
+ if arg1 is not None and arg2 is not None:
+ cand = func(arg1, arg2)
+ if ctx not in ret or cand.size < ret[ctx].size:
+ ret[ctx] = cand
+
+ for ctx in set(left) | set(right):
+ candidate(ctx, left.get(ctx), right.get(ctx), _BinNode.make_branch)
+ candidate(ctx, left.get(None), right.get(ctx), _BinNode.make_branch)
+ candidate(ctx, left.get(ctx), right.get(None), _BinNode.make_branch)
+ if not hole:
+ for ctx in set(ret) - set([None]):
+ candidate(None, ctx, ret[ctx], _BinNode.make_default)
+ if None in ret:
+ ret = {ctx:enc for ctx, enc in ret.items()
+ if ctx is None or enc.size < ret[None].size}
+ if hole:
+ ret = {ctx:enc for ctx, enc in ret.items() if ctx is None or ctx == 0}
+ return ret, hole
+ res, _ = recurse(self._trie)
+ return res[0] if 0 in res else res[None]
+
+ @staticmethod
+ def _from_binnode(binnode: _BinNode) -> "ASMap":
+ """Construct an ASMap object from a _BinNode. Internal use only."""
+ def recurse(node: _BinNode, default: int) -> List:
+ if node.ins == _Instruction.RETURN:
+ return [node.arg1]
+ if node.ins == _Instruction.JUMP:
+ return [recurse(node.arg1, default), recurse(node.arg2, default)]
+ if node.ins == _Instruction.MATCH:
+ val = node.arg1
+ sub = recurse(node.arg2, default)
+ while val >= 2:
+ bit = val & 1
+ val >>= 1
+ if bit:
+ sub = [[default], sub]
+ else:
+ sub = [sub, [default]]
+ return sub
+ assert node.ins == _Instruction.DEFAULT
+ return recurse(node.arg2, node.arg1)
+ ret = ASMap()
+ if binnode.ins != _Instruction.END:
+ #pylint: disable=protected-access
+ ret._set_trie(recurse(binnode, 0))
+ return ret
+
+ def to_binary(self, fill: bool = False) -> bytes:
+ """
+ Convert this ASMap object to binary.
+
+ Argument:
+ fill: permit the resulting binary encoder to contain mappers for
+ unassigned subnets in this ASMap object. Doing so may
+ reduce the size of the encoding.
+ Returns:
+ A bytes object with the encoding of this ASMap object.
+ """
+ bits: List[int] = []
+
+ def recurse(node: _BinNode) -> None:
+ _CODER_INS.encode(node.ins.value, bits)
+ if node.ins == _Instruction.RETURN:
+ _CODER_ASN.encode(node.arg1, bits)
+ elif node.ins == _Instruction.JUMP:
+ _CODER_JUMP.encode(node.arg1.size, bits)
+ recurse(node.arg1)
+ recurse(node.arg2)
+ elif node.ins == _Instruction.DEFAULT:
+ _CODER_ASN.encode(node.arg1, bits)
+ recurse(node.arg2)
+ else:
+ assert node.ins == _Instruction.MATCH
+ _CODER_MATCH.encode(node.arg1, bits)
+ recurse(node.arg2)
+
+ binnode = self._to_binnode(fill)
+ if binnode.ins != _Instruction.END:
+ recurse(binnode)
+
+ val = 0
+ nbits = 0
+ ret = []
+ for bit in bits:
+ val += (bit << nbits)
+ nbits += 1
+ if nbits == 8:
+ ret.append(val)
+ val = 0
+ nbits = 0
+ if nbits:
+ ret.append(val)
+ return bytes(ret)
+
+ @staticmethod
+ def from_binary(bindata: bytes) -> Optional["ASMap"]:
+ """Decode an ASMap object from the provided binary encoding."""
+
+ bits: List[int] = []
+ for byte in bindata:
+ bits.extend((byte >> i) & 1 for i in range(8))
+
+ def recurse(bitpos: int) -> Tuple[_BinNode, int]:
+ insval, bitpos = _CODER_INS.decode(bits, bitpos)
+ ins = _Instruction(insval)
+ if ins == _Instruction.RETURN:
+ asn, bitpos = _CODER_ASN.decode(bits, bitpos)
+ return _BinNode(ins, asn), bitpos
+ if ins == _Instruction.JUMP:
+ jump, bitpos = _CODER_JUMP.decode(bits, bitpos)
+ left, bitpos1 = recurse(bitpos)
+ if bitpos1 != bitpos + jump:
+ raise ValueError("Inconsistent jump")
+ right, bitpos = recurse(bitpos1)
+ return _BinNode(ins, left, right), bitpos
+ if ins == _Instruction.MATCH:
+ match, bitpos = _CODER_MATCH.decode(bits, bitpos)
+ sub, bitpos = recurse(bitpos)
+ return _BinNode(ins, match, sub), bitpos
+ assert ins == _Instruction.DEFAULT
+ asn, bitpos = _CODER_ASN.decode(bits, bitpos)
+ sub, bitpos = recurse(bitpos)
+ return _BinNode(ins, asn, sub), bitpos
+
+ if len(bits) == 0:
+ binnode = _BinNode(_Instruction.END)
+ else:
+ try:
+ binnode, bitpos = recurse(0)
+ except (ValueError, IndexError):
+ return None
+ if bitpos < len(bits) - 7:
+ return None
+ if not all(bit == 0 for bit in bits[bitpos:]):
+ return None
+
+ return ASMap._from_binnode(binnode)
+
+ def __lt__(self, other: "ASMap") -> bool:
+ return self._trie < other._trie
+
+ def __eq__(self, other: object) -> bool:
+ if isinstance(other, ASMap):
+ return self._trie == other._trie
+ return False
+
+ def extends(self, req: "ASMap") -> bool:
+ """Determine whether this matches req for all subranges where req is assigned."""
+ def recurse(actual: List, require: List) -> bool:
+ if len(require) == 1 and require[0] == 0:
+ return True
+ if len(require) == 1:
+ if len(actual) == 1:
+ return bool(require[0] == actual[0])
+ return recurse(actual[0], require) and recurse(actual[1], require)
+ if len(actual) == 2:
+ return recurse(actual[0], require[0]) and recurse(actual[1], require[1])
+ return recurse(actual, require[0]) and recurse(actual, require[1])
+ assert isinstance(req, ASMap)
+ #pylint: disable=protected-access
+ return recurse(self._trie, req._trie)
+
+ def diff(self, other: "ASMap") -> List[ASNDiff]:
+ """Compute the diff from self to other."""
+ prefix: List[bool] = []
+ ret: List[ASNDiff] = []
+
+ def recurse(old_node: List, new_node: List):
+ if len(old_node) == 1 and len(new_node) == 1:
+ if old_node[0] != new_node[0]:
+ ret.append((list(prefix), old_node[0], new_node[0]))
+ else:
+ old_left: List = old_node if len(old_node) == 1 else old_node[0]
+ old_right: List = old_node if len(old_node) == 1 else old_node[1]
+ new_left: List = new_node if len(new_node) == 1 else new_node[0]
+ new_right: List = new_node if len(new_node) == 1 else new_node[1]
+ prefix.append(False)
+ recurse(old_left, new_left)
+ prefix[-1] = True
+ recurse(old_right, new_right)
+ prefix.pop()
+ assert isinstance(other, ASMap)
+ #pylint: disable=protected-access
+ recurse(self._trie, other._trie)
+ return ret
+
+ def __copy__(self) -> "ASMap":
+ """Construct a copy of this ASMap object. Its state will not be shared."""
+ ret = ASMap()
+ #pylint: disable=protected-access
+ ret._set_trie(copy.deepcopy(self._trie))
+ return ret
+
+ def __deepcopy__(self, _) -> "ASMap":
+ # ASMap objects do not allow sharing of the _trie member, so we don't need the memoization.
+ return self.__copy__()
+
+
+class TestASMap(unittest.TestCase):
+ """Unit tests for this module."""
+
+ def test_ipv6_prefix_roundtrips(self) -> None:
+ """Test that random IPv6 network ranges roundtrip through prefix encoding."""
+ for _ in range(20):
+ net_bits = random.getrandbits(128)
+ for prefix_len in range(0, 129):
+ masked_bits = (net_bits >> (128 - prefix_len)) << (128 - prefix_len)
+ net = ipaddress.IPv6Network((masked_bits.to_bytes(16, 'big'), prefix_len))
+ prefix = net_to_prefix(net)
+ self.assertTrue(len(prefix) <= 128)
+ net2 = prefix_to_net(prefix)
+ self.assertEqual(net, net2)
+
+ def test_ipv4_prefix_roundtrips(self) -> None:
+ """Test that random IPv4 network ranges roundtrip through prefix encoding."""
+ for _ in range(100):
+ net_bits = random.getrandbits(32)
+ for prefix_len in range(0, 33):
+ masked_bits = (net_bits >> (32 - prefix_len)) << (32 - prefix_len)
+ net = ipaddress.IPv4Network((masked_bits.to_bytes(4, 'big'), prefix_len))
+ prefix = net_to_prefix(net)
+ self.assertTrue(32 <= len(prefix) <= 128)
+ net2 = prefix_to_net(prefix)
+ self.assertEqual(net, net2)
+
+ def test_asmap_roundtrips(self) -> None:
+ """Test case that verifies random ASMap objects roundtrip to/from entries/binary."""
+ # Iterate over the number of leaves the random test ASMap objects have.
+ for leaves in range(1, 20):
+ # Iterate over the number of bits in the AS numbers used.
+ for asnbits in range(0, 24):
+ # Iterate over the probability that leaves are unassigned.
+ for pct in range(101):
+ # Construct a random ASMap object according to the above parameters.
+ asmap = ASMap.from_random(num_leaves=leaves, max_asn=1 + (1 << asnbits),
+ unassigned_prob=0.01 * pct)
+ # Run tests for to_entries and construction from those entries, both
+ # for overlapping and non-overlapping ones.
+ for overlapping in [False, True]:
+ entries = asmap.to_entries(overlapping=overlapping, fill=False)
+ random.shuffle(entries)
+ asmap2 = ASMap(entries)
+ assert asmap2 is not None
+ self.assertEqual(asmap2, asmap)
+ entries = asmap.to_entries(overlapping=overlapping, fill=True)
+ random.shuffle(entries)
+ asmap2 = ASMap(entries)
+ assert asmap2 is not None
+ self.assertTrue(asmap2.extends(asmap))
+
+ # Run tests for to_binary and construction from binary.
+ enc = asmap.to_binary(fill=False)
+ asmap3 = ASMap.from_binary(enc)
+ assert asmap3 is not None
+ self.assertEqual(asmap3, asmap)
+ enc = asmap.to_binary(fill=True)
+ asmap3 = ASMap.from_binary(enc)
+ assert asmap3 is not None
+ self.assertTrue(asmap3.extends(asmap))
+
+ def test_patching(self) -> None:
+ """Test behavior of update, lookup, extends, and diff."""
+ #pylint: disable=too-many-locals,too-many-nested-blocks
+ # Iterate over the number of leaves the random test ASMap objects have.
+ for leaves in range(1, 20):
+ # Iterate over the number of bits in the AS numbers used.
+ for asnbits in range(0, 10):
+ # Iterate over the probability that leaves are unassigned.
+ for pct in range(0, 101):
+ # Construct a random ASMap object according to the above parameters.
+ asmap = ASMap.from_random(num_leaves=leaves, max_asn=1 + (1 << asnbits),
+ unassigned_prob=0.01 * pct)
+ # Make a copy of that asmap object to which patches will be applied.
+ # It starts off being equal to asmap.
+ patched = copy.copy(asmap)
+ # Keep a list of patches performed.
+ patches: List[ASNEntry] = []
+ # Initially there cannot be any difference.
+ self.assertEqual(asmap.diff(patched), [])
+ # Make 5 patches, each building on top of the previous ones.
+ for _ in range(0, 5):
+ # Construct a random path and new ASN to assign it to, apply it to patched,
+ # and remember it in patches.
+ pathlen = random.randrange(5)
+ path = [random.getrandbits(1) != 0 for _ in range(pathlen)]
+ newasn = random.randrange(1 + (1 << asnbits))
+ patched.update(path, newasn)
+ patches = [(path, newasn)] + patches
+
+ # Compute the diff, and whether asmap extends patched, and the other way
+ # around.
+ diff = asmap.diff(patched)
+ self.assertEqual(asmap == patched, len(diff) == 0)
+ extends = asmap.extends(patched)
+ back_extends = patched.extends(asmap)
+ # Determine whether those extends results are consistent with the diff
+ # result.
+ self.assertEqual(extends, all(d[2] == 0 for d in diff))
+ self.assertEqual(back_extends, all(d[1] == 0 for d in diff))
+ # For every diff found:
+ for path, old_asn, new_asn in diff:
+ # Verify asmap and patched actually differ there.
+ self.assertTrue(old_asn != new_asn)
+ self.assertEqual(asmap.lookup(path), old_asn)
+ self.assertEqual(patched.lookup(path), new_asn)
+ for _ in range(2):
+ # Extend the path far enough that it's smaller than any mapped
+ # range, and check the lookup holds there too.
+ spec_path = list(path)
+ while len(spec_path) < 32:
+ spec_path.append(random.getrandbits(1) != 0)
+ self.assertEqual(asmap.lookup(spec_path), old_asn)
+ self.assertEqual(patched.lookup(spec_path), new_asn)
+ # Search through the list of performed patches to find the last one
+ # applying to the extended path (note that patches is in reverse
+ # order, so the first match should work).
+ found = False
+ for patch_path, patch_asn in patches:
+ if spec_path[:len(patch_path)] == patch_path:
+ # When found, it must match whatever the result was patched
+ # to.
+ self.assertEqual(new_asn, patch_asn)
+ found = True
+ break
+ # And such a patch must exist.
+ self.assertTrue(found)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/contrib/seeds/makeseeds.py b/contrib/seeds/makeseeds.py
index 78eb04a836..37c6f5fd7c 100755
--- a/contrib/seeds/makeseeds.py
+++ b/contrib/seeds/makeseeds.py
@@ -6,12 +6,15 @@
# Generate seeds.txt from Pieter's DNS seeder
#
+import argparse
+import ipaddress
import re
import sys
-import dns.resolver
import collections
from typing import List, Dict, Union
+from asmap import ASMap, net_to_prefix
+
NSEEDS=512
MAX_SEEDS_PER_ASN = {
@@ -45,7 +48,7 @@ def parseline(line: str) -> Union[dict, None]:
sline = line.split()
if len(sline) < 11:
# line too short to be valid, skip it.
- return None
+ return None
m = PATTERN_IPV4.match(sline[0])
sortkey = None
ip = None
@@ -123,34 +126,8 @@ def filtermultiport(ips: List[Dict]) -> List[Dict]:
hist[ip['sortkey']].append(ip)
return [value[0] for (key,value) in list(hist.items()) if len(value)==1]
-def lookup_asn(net: str, ip: str) -> Union[int, None]:
- """ Look up the asn for an `ip` address by querying cymru.com
- on network `net` (e.g. ipv4 or ipv6).
-
- Returns in integer ASN or None if it could not be found.
- """
- try:
- if net == 'ipv4':
- ipaddr = ip
- prefix = '.origin'
- else: # http://www.team-cymru.com/IP-ASN-mapping.html
- res = str() # 2001:4860:b002:23::68
- for nb in ip.split(':')[:4]: # pick the first 4 nibbles
- for c in nb.zfill(4): # right padded with '0'
- res += c + '.' # 2001 4860 b002 0023
- ipaddr = res.rstrip('.') # 2.0.0.1.4.8.6.0.b.0.0.2.0.0.2.3
- prefix = '.origin6'
-
- asn = int([x.to_text() for x in dns.resolver.resolve('.'.join(
- reversed(ipaddr.split('.'))) + prefix + '.asn.cymru.com',
- 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
- return asn
- except Exception as e:
- sys.stderr.write(f'ERR: Could not resolve ASN for "{ip}": {e}\n')
- return None
-
# Based on Greg Maxwell's seed_filter.py
-def filterbyasn(ips: List[Dict], max_per_asn: Dict, max_per_net: int) -> List[Dict]:
+def filterbyasn(asmap: ASMap, ips: List[Dict], max_per_asn: Dict, max_per_net: int) -> List[Dict]:
""" Prunes `ips` by
(a) trimming ips to have at most `max_per_net` ips from each net (e.g. ipv4, ipv6); and
(b) trimming ips to have at most `max_per_asn` ips from each asn in each net.
@@ -165,21 +142,18 @@ def filterbyasn(ips: List[Dict], max_per_asn: Dict, max_per_net: int) -> List[Di
asn_count: Dict[int, int] = collections.defaultdict(int)
for i, ip in enumerate(ips_ipv46):
- if i % 10 == 0:
- # give progress update
- print(f"{i:6d}/{len(ips_ipv46)} [{100*i/len(ips_ipv46):04.1f}%]\r", file=sys.stderr, end='', flush=True)
-
if net_count[ip['net']] == max_per_net:
# do not add this ip as we already too many
# ips from this network
continue
- asn = lookup_asn(ip['net'], ip['ip'])
- if asn is None or asn_count[asn] == max_per_asn[ip['net']]:
+ asn = asmap.lookup(net_to_prefix(ipaddress.ip_network(ip['ip'])))
+ if not asn or asn_count[ip['net'], asn] == max_per_asn[ip['net']]:
# do not add this ip as we already have too many
# ips from this ASN on this network
continue
- asn_count[asn] += 1
+ asn_count[ip['net'], asn] += 1
net_count[ip['net']] += 1
+ ip['asn'] = asn
result.append(ip)
# Add back Onions (up to max_per_net)
@@ -195,9 +169,23 @@ def ip_stats(ips: List[Dict]) -> str:
return f"{hist['ipv4']:6d} {hist['ipv6']:6d} {hist['onion']:6d}"
+def parse_args():
+ argparser = argparse.ArgumentParser(description='Generate a list of bitcoin node seed ip addresses.')
+ argparser.add_argument("-a","--asmap", help='the location of the asmap asn database file (required)', required=True)
+ return argparser.parse_args()
+
def main():
+ args = parse_args()
+
+ print(f'Loading asmap database "{args.asmap}"…', end='', file=sys.stderr, flush=True)
+ with open(args.asmap, 'rb') as f:
+ asmap = ASMap.from_binary(f.read())
+ print('Done.', file=sys.stderr)
+
+ print('Loading and parsing DNS seeds…', end='', file=sys.stderr, flush=True)
lines = sys.stdin.readlines()
ips = [parseline(line) for line in lines]
+ print('Done.', file=sys.stderr)
print('\x1b[7m IPv4 IPv6 Onion Pass \x1b[0m', file=sys.stderr)
print(f'{ip_stats(ips):s} Initial', file=sys.stderr)
@@ -230,15 +218,18 @@ def main():
ips = filtermultiport(ips)
print(f'{ip_stats(ips):s} Filter out hosts with multiple bitcoin ports', file=sys.stderr)
# Look up ASNs and limit results, both per ASN and globally.
- ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
+ ips = filterbyasn(asmap, ips, MAX_SEEDS_PER_ASN, NSEEDS)
print(f'{ip_stats(ips):s} Look up ASNs and limit results per ASN and per net', file=sys.stderr)
# Sort the results by IP address (for deterministic output).
ips.sort(key=lambda x: (x['net'], x['sortkey']))
for ip in ips:
if ip['net'] == 'ipv6':
- print('[%s]:%i' % (ip['ip'], ip['port']))
+ print(f"[{ip['ip']}]:{ip['port']}", end="")
else:
- print('%s:%i' % (ip['ip'], ip['port']))
+ print(f"{ip['ip']}:{ip['port']}", end="")
+ if 'asn' in ip:
+ print(f" # AS{ip['asn']}", end="")
+ print()
if __name__ == '__main__':
main()
diff --git a/depends/Makefile b/depends/Makefile
index 76f84b1a34..11fdd6dd53 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -45,6 +45,9 @@ MULTIPROCESS ?=
LTO ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
+C_STANDARD ?= c11
+CXX_STANDARD ?= c++17
+
BUILD = $(shell ./config.guess)
HOST ?= $(BUILD)
PATCHES_PATH = $(BASEDIR)/patches
@@ -141,8 +144,8 @@ include packages/packages.mk
# 2. Before including packages/*.mk (excluding packages/packages.mk), since
# they rely on the build_id variables
#
-build_id:=$(shell env CC='$(build_CC)' CXX='$(build_CXX)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
-$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' CXX='$(host_CXX)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
+build_id:=$(shell env CC='$(build_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(build_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(BUILD_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
+$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' C_STANDARD='$(C_STANDARD)' CXX='$(host_CXX)' CXX_STANDARD='$(CXX_STANDARD)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(HOST_ID_SALT)' 'GUIX_ENVIRONMENT=$(realpath $(GUIX_ENVIRONMENT))')
qrencode_packages_$(NO_QR) = $(qrencode_$(host_os)_packages)
diff --git a/depends/README.md b/depends/README.md
index 26bfd9bed5..66e1ddc4eb 100644
--- a/depends/README.md
+++ b/depends/README.md
@@ -96,6 +96,8 @@ The following can be set when running make: `make FOO=bar`
- `BASE_CACHE`: Built packages will be placed here
- `SDK_PATH`: Path where SDKs can be found (used by macOS)
- `FALLBACK_DOWNLOAD_PATH`: If a source file can't be fetched, try here before giving up
+- `C_STANDARD`: Set the C standard version used. Defaults to `c11`.
+- `CXX_STANDARD`: Set the C++ standard version used. Defaults to `c++17`.
- `NO_QT`: Don't download/build/cache Qt and its dependencies
- `NO_QR`: Don't download/build/cache packages needed for enabling qrencode
- `NO_ZMQ`: Don't download/build/cache packages needed for enabling ZeroMQ
diff --git a/depends/gen_id b/depends/gen_id
index a0cd586461..7caf8d764d 100755
--- a/depends/gen_id
+++ b/depends/gen_id
@@ -1,7 +1,8 @@
#!/usr/bin/env bash
-# Usage: env [ CC=... ] [ CXX=... ] [ AR=... ] [ RANLIB=... ] [ STRIP=... ] \
-# [ DEBUG=... ] [ LTO=... ] ./build-id [ID_SALT]...
+# Usage: env [ CC=... ] [ C_STANDARD=...] [ CXX=... ] [CXX_STANDARD=...] \
+# [ AR=... ] [ RANLIB=... ] [ STRIP=... ] [ DEBUG=... ] \
+# [ LTO=... ] ./build-id [ID_SALT]...
#
# Prints to stdout a SHA256 hash representing the current toolset, used by
# depends/Makefile as a build id for caching purposes (detecting when the
@@ -39,12 +40,14 @@
bash -c "${CC} -v"
bash -c "${CC} -v -E -xc -o /dev/null - < /dev/null"
bash -c "${CC} -v -E -xobjective-c -o /dev/null - < /dev/null"
+ echo "C_STANDARD=${C_STANDARD}"
echo "END CC"
echo "BEGIN CXX"
bash -c "${CXX} -v"
bash -c "${CXX} -v -E -xc++ -o /dev/null - < /dev/null"
bash -c "${CXX} -v -E -xobjective-c++ -o /dev/null - < /dev/null"
+ echo "CXX_STANDARD=${CXX_STANDARD}"
echo "END CXX"
echo "BEGIN AR"
diff --git a/depends/hosts/android.mk b/depends/hosts/android.mk
index 9029355460..b53966dcf8 100644
--- a/depends/hosts/android.mk
+++ b/depends/hosts/android.mk
@@ -6,6 +6,9 @@ android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++
android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang
endif
+android_CFLAGS=-std=$(C_STANDARD)
+android_CXXFLAGS=-std=$(CXX_STANDARD)
+
ifneq ($(LTO),)
android_CFLAGS += -flto
android_LDFLAGS += -flto
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
index a564613cb6..8507e28532 100644
--- a/depends/hosts/darwin.mk
+++ b/depends/hosts/darwin.mk
@@ -109,15 +109,15 @@ darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \
-Xclang -internal-externc-isystem$(clang_resource_dir)/include \
-Xclang -internal-externc-isystem$(OSX_SDK)/usr/include
-darwin_CFLAGS=-pipe
+darwin_CFLAGS=-pipe -std=$(C_STANDARD)
+darwin_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
ifneq ($(LTO),)
darwin_CFLAGS += -flto
+darwin_CXXFLAGS += -flto
darwin_LDFLAGS += -flto
endif
-darwin_CXXFLAGS=$(darwin_CFLAGS)
-
darwin_release_CFLAGS=-O2
darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)
diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk
index 853fa0f457..5351d0b900 100644
--- a/depends/hosts/freebsd.mk
+++ b/depends/hosts/freebsd.mk
@@ -1,12 +1,12 @@
-freebsd_CFLAGS=-pipe
+freebsd_CFLAGS=-pipe -std=$(C_STANDARD)
+freebsd_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
ifneq ($(LTO),)
freebsd_CFLAGS += -flto
+freebsd_CXXFLAGS += -flto
freebsd_LDFLAGS += -flto
endif
-freebsd_CXXFLAGS=$(freebsd_CFLAGS)
-
freebsd_release_CFLAGS=-O2
freebsd_release_CXXFLAGS=$(freebsd_release_CFLAGS)
diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk
index 5322520e6f..b101043439 100644
--- a/depends/hosts/linux.mk
+++ b/depends/hosts/linux.mk
@@ -1,12 +1,12 @@
-linux_CFLAGS=-pipe
+linux_CFLAGS=-pipe -std=$(C_STANDARD)
+linux_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
ifneq ($(LTO),)
linux_CFLAGS += -flto
+linux_CXXFLAGS += -flto
linux_LDFLAGS += -flto
endif
-linux_CXXFLAGS=$(linux_CFLAGS)
-
linux_release_CFLAGS=-O2
linux_release_CXXFLAGS=$(linux_release_CFLAGS)
diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk
index 979280b5cb..b98f9ab7ac 100644
--- a/depends/hosts/mingw32.mk
+++ b/depends/hosts/mingw32.mk
@@ -2,15 +2,15 @@ ifneq ($(shell $(SHELL) $(.SHELLFLAGS) "command -v $(host)-g++-posix"),)
mingw32_CXX := $(host)-g++-posix
endif
-mingw32_CFLAGS=-pipe
+mingw32_CFLAGS=-pipe -std=$(C_STANDARD)
+mingw32_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
ifneq ($(LTO),)
mingw32_CFLAGS += -flto
+mingw32_CXXFLAGS += -flto
mingw32_LDFLAGS += -flto
endif
-mingw32_CXXFLAGS=$(mingw32_CFLAGS)
-
mingw32_release_CFLAGS=-O2
mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS)
diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk
index 9e48248b7e..8342dcc6ed 100644
--- a/depends/hosts/netbsd.mk
+++ b/depends/hosts/netbsd.mk
@@ -1,7 +1,9 @@
-netbsd_CFLAGS=-pipe
+netbsd_CFLAGS=-pipe -std=$(C_STANDARD)
+netbsd_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
ifneq ($(LTO),)
netbsd_CFLAGS += -flto
+netbsd_CXXFLAGS += -flto
netbsd_LDFLAGS += -flto
endif
diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk
index c4a629e021..d330e94d2e 100644
--- a/depends/hosts/openbsd.mk
+++ b/depends/hosts/openbsd.mk
@@ -1,8 +1,9 @@
-openbsd_CFLAGS=-pipe
-openbsd_CXXFLAGS=$(openbsd_CFLAGS)
+openbsd_CFLAGS=-pipe -std=$(C_STANDARD)
+openbsd_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
ifneq ($(LTO),)
openbsd_CFLAGS += -flto
+openbsd_CXXFLAGS += -flto
openbsd_LDFLAGS += -flto
endif
diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk
index dc536fd399..80c7ce8429 100644
--- a/depends/packages/bdb.mk
+++ b/depends/packages/bdb.mk
@@ -15,7 +15,6 @@ $(package)_config_opts_netbsd=--with-pic
$(package)_config_opts_openbsd=--with-pic
$(package)_config_opts_android=--with-pic
$(package)_cflags+=-Wno-error=implicit-function-declaration
-$(package)_cxxflags+=-std=c++17
$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
endef
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index 2bc3a81430..7e268fe9a5 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -171,7 +171,7 @@ $(package)_config_opts_mingw32 += -no-freetype
$(package)_config_opts_mingw32 += -xplatform win32-g++
$(package)_config_opts_mingw32 += "QMAKE_CFLAGS = '$($(package)_cflags) $($(package)_cppflags)'"
$(package)_config_opts_mingw32 += "QMAKE_CXX = '$($(package)_cxx)'"
-$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cflags) $($(package)_cppflags)'"
+$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cxxflags) $($(package)_cppflags)'"
$(package)_config_opts_mingw32 += "QMAKE_LFLAGS = '$($(package)_ldflags)'"
$(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-"
$(package)_config_opts_mingw32 += -pch
diff --git a/depends/packages/sqlite.mk b/depends/packages/sqlite.mk
index 126781ceeb..820d724214 100644
--- a/depends/packages/sqlite.mk
+++ b/depends/packages/sqlite.mk
@@ -1,8 +1,8 @@
package=sqlite
-$(package)_version=3320100
-$(package)_download_path=https://sqlite.org/2020/
+$(package)_version=3380500
+$(package)_download_path=https://sqlite.org/2022/
$(package)_file_name=sqlite-autoconf-$($(package)_version).tar.gz
-$(package)_sha256_hash=486748abfb16abd8af664e3a5f03b228e5f124682b0c942e157644bf6fff7d10
+$(package)_sha256_hash=5af07de982ba658fd91a03170c945f99c971f6955bc79df3266544373e39869c
define $(package)_set_vars
$(package)_config_opts=--disable-shared --disable-readline --disable-dynamic-extensions --enable-option-checking
diff --git a/depends/packages/systemtap.mk b/depends/packages/systemtap.mk
index 833e75b978..a57f1b6d36 100644
--- a/depends/packages/systemtap.mk
+++ b/depends/packages/systemtap.mk
@@ -1,8 +1,8 @@
package=systemtap
-$(package)_version=4.5
+$(package)_version=4.7
$(package)_download_path=https://sourceware.org/systemtap/ftp/releases/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=75078ed37e0dd2a769c9d1f9394170b2d9f4d7daa425f43ca80c13bad6cfc925
+$(package)_sha256_hash=43a0a3db91aa4d41e28015b39a65e62059551f3cc7377ebf3a3a5ca7339e7b1f
$(package)_patches=remove_SDT_ASM_SECTION_AUTOGROUP_SUPPORT_check.patch
define $(package)_preprocess_cmds
diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk
index c74ae15b31..267ed11253 100644
--- a/depends/packages/zeromq.mk
+++ b/depends/packages/zeromq.mk
@@ -16,7 +16,6 @@ define $(package)_set_vars
$(package)_config_opts_netbsd=--with-pic
$(package)_config_opts_openbsd=--with-pic
$(package)_config_opts_android=--with-pic
- $(package)_cxxflags+=-std=c++17
endef
define $(package)_preprocess_cmds
diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf
index 543407f853..cb94bf07b4 100644
--- a/depends/patches/qt/mac-qmake.conf
+++ b/depends/patches/qt/mac-qmake.conf
@@ -15,7 +15,7 @@ QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION}
QMAKE_MAC_SDK.macosx.PlatformPath = /phony
!host_build: QMAKE_CFLAGS += -target $${MAC_TARGET}
!host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS
-!host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
+!host_build: QMAKE_CXXFLAGS += -target $${MAC_TARGET}
!host_build: QMAKE_LFLAGS += -target $${MAC_TARGET}
QMAKE_AR = $${CROSS_COMPILE}ar cq
QMAKE_RANLIB=$${CROSS_COMPILE}ranlib
diff --git a/depends/patches/systemtap/remove_SDT_ASM_SECTION_AUTOGROUP_SUPPORT_check.patch b/depends/patches/systemtap/remove_SDT_ASM_SECTION_AUTOGROUP_SUPPORT_check.patch
index eae0cf72d6..c115bc43e8 100644
--- a/depends/patches/systemtap/remove_SDT_ASM_SECTION_AUTOGROUP_SUPPORT_check.patch
+++ b/depends/patches/systemtap/remove_SDT_ASM_SECTION_AUTOGROUP_SUPPORT_check.patch
@@ -1,19 +1,15 @@
-commit b92d4c121486f3c6e8a2cea537c53eb09894479a
-Author: 0xb10c <0xb10c@gmail.com>
-Date: Tue Dec 7 11:02:07 2021 +0100
+Remove _SDT_ASM_SECTION_AUTOGROUP_SUPPORT check
- Remove _SDT_ASM_SECTION_AUTOGROUP_SUPPORT check
-
- We assume that the assembler supports "?" in .pushsection directives.
- This enables us to skip configure and make.
-
- See https://github.com/bitcoin/bitcoin/issues/23297.
+We assume that the assembler supports "?" in .pushsection directives.
+This enables us to skip configure and make.
+
+See https://github.com/bitcoin/bitcoin/issues/23297.
diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h
-index 97766e710..352b4ee25 100644
+index ca0162b..f96e0ee 100644
--- a/includes/sys/sdt.h
+++ b/includes/sys/sdt.h
-@@ -230,12 +230,10 @@ __extension__ extern unsigned long long __sdt_unsp;
+@@ -241,12 +241,10 @@ __extension__ extern unsigned long long __sdt_unsp;
nice with code in COMDAT sections, which comes up in C++ code.
Without that assembler support, some combinations of probe placements
in certain kinds of C++ code may produce link-time errors. */
@@ -27,5 +23,5 @@ index 97766e710..352b4ee25 100644
-# define _SDT_ASM_AUTOGROUP ""
-#endif
- #define _SDT_ASM_BODY(provider, name, pack_args, args) \
- _SDT_ASM_1(990: _SDT_NOP) \
+ #define _SDT_DEF_MACROS \
+ _SDT_ASM_1(.altmacro) \
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index d1b660efff..23f975df34 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -1158,10 +1158,6 @@ Current subtrees include:
- src/crypto/ctaes
- Upstream at https://github.com/bitcoin-core/ctaes ; maintained by Core contributors.
-- src/univalue
- - Subtree at https://github.com/bitcoin-core/univalue-subtree ; maintained by Core contributors.
- - Deviates from upstream https://github.com/jgarzik/univalue.
-
- src/minisketch
- Upstream at https://github.com/sipa/minisketch ; maintained by Core contributors.
diff --git a/src/Makefile.am b/src/Makefile.am
index f90c14bab8..fa716af619 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,7 +29,6 @@ LIBBITCOIN_NODE=libbitcoin_node.a
LIBBITCOIN_COMMON=libbitcoin_common.a
LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a
LIBBITCOIN_CLI=libbitcoin_cli.a
-LIBBITCOIN_KERNEL=libbitcoin_kernel.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO_BASE=crypto/libbitcoin_crypto_base.la
LIBBITCOINQT=qt/libbitcoinqt.a
diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp
index e80b9e1ac2..60d991fab9 100644
--- a/src/bench/mempool_eviction.cpp
+++ b/src/bench/mempool_eviction.cpp
@@ -108,7 +108,7 @@ static void MempoolEviction(benchmark::Bench& bench)
tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
tx7.vout[1].nValue = 10 * COIN;
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(testing_setup->m_node.mempool);
LOCK2(cs_main, pool.cs);
// Create transaction references outside the "hot loop"
const CTransactionRef tx1_r{MakeTransactionRef(tx1)};
diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp
index 6e322ba6aa..0e6fdae3d7 100644
--- a/src/bench/rpc_mempool.cpp
+++ b/src/bench/rpc_mempool.cpp
@@ -3,7 +3,9 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bench/bench.h>
+#include <chainparamsbase.h>
#include <rpc/mempool.h>
+#include <test/util/setup_common.h>
#include <txmempool.h>
#include <univalue.h>
@@ -17,7 +19,8 @@ static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& poo
static void RpcMempool(benchmark::Bench& bench)
{
- CTxMemPool pool;
+ const auto testing_setup = MakeNoLogFileContext<const ChainTestingSetup>(CBaseChainParams::MAIN);
+ CTxMemPool& pool = *Assert(testing_setup->m_node.mempool);
LOCK2(cs_main, pool.cs);
for (int i = 0; i < 1000; ++i) {
diff --git a/src/compat.h b/src/compat.h
index f41c501c84..0a44b98b4e 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -11,9 +11,6 @@
#endif
#ifdef WIN32
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
#ifdef FD_SETSIZE
#undef FD_SETSIZE // prevent redefinition compiler warning
#endif
diff --git a/src/fs.cpp b/src/fs.cpp
index b61115bf01..74b167e313 100644
--- a/src/fs.cpp
+++ b/src/fs.cpp
@@ -12,9 +12,6 @@
#include <sys/utsname.h>
#include <unistd.h>
#else
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
#include <codecvt>
#include <limits>
#include <windows.h>
diff --git a/src/i2p.cpp b/src/i2p.cpp
index eccb048bb3..caff8c1e69 100644
--- a/src/i2p.cpp
+++ b/src/i2p.cpp
@@ -150,8 +150,8 @@ bool Session::Accept(Connection& conn)
throw std::runtime_error("wait on socket failed");
}
- if ((occurred & Sock::RECV) == 0) {
- // Timeout, no incoming connections within MAX_WAIT_FOR_IO.
+ if (occurred == 0) {
+ // Timeout, no incoming connections or errors within MAX_WAIT_FOR_IO.
continue;
}
diff --git a/src/net.cpp b/src/net.cpp
index d0c95dafb4..c05fa771ef 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -250,7 +250,7 @@ std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode)
if (pnode->IsInboundConn()) {
// For inbound connections, assume both the address and the port
// as seen from the peer.
- addrLocal = CAddress{pnode->GetAddrLocal(), addrLocal.nServices};
+ addrLocal = CAddress{pnode->GetAddrLocal(), addrLocal.nServices, addrLocal.nTime};
} else {
// For outbound connections, assume just the address as seen from
// the peer and leave the port in `addrLocal` as returned by
@@ -1404,13 +1404,12 @@ bool CConnman::InactivityCheck(const CNode& node) const
return false;
}
-bool CConnman::GenerateSelectSet(const std::vector<CNode*>& nodes,
- std::set<SOCKET>& recv_set,
- std::set<SOCKET>& send_set,
- std::set<SOCKET>& error_set)
+Sock::EventsPerSock CConnman::GenerateWaitSockets(Span<CNode* const> nodes)
{
+ Sock::EventsPerSock events_per_sock;
+
for (const ListenSocket& hListenSocket : vhListenSocket) {
- recv_set.insert(hListenSocket.sock->Get());
+ events_per_sock.emplace(hListenSocket.sock, Sock::Events{Sock::RECV});
}
for (CNode* pnode : nodes) {
@@ -1437,172 +1436,49 @@ bool CConnman::GenerateSelectSet(const std::vector<CNode*>& nodes,
continue;
}
- error_set.insert(pnode->m_sock->Get());
+ Sock::Event requested{0};
if (select_send) {
- send_set.insert(pnode->m_sock->Get());
- continue;
- }
- if (select_recv) {
- recv_set.insert(pnode->m_sock->Get());
- }
- }
-
- return !recv_set.empty() || !send_set.empty() || !error_set.empty();
-}
-
-#ifdef USE_POLL
-void CConnman::SocketEvents(const std::vector<CNode*>& nodes,
- std::set<SOCKET>& recv_set,
- std::set<SOCKET>& send_set,
- std::set<SOCKET>& error_set)
-{
- std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
- if (!GenerateSelectSet(nodes, recv_select_set, send_select_set, error_select_set)) {
- interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
- return;
- }
-
- std::unordered_map<SOCKET, struct pollfd> pollfds;
- for (SOCKET socket_id : recv_select_set) {
- pollfds[socket_id].fd = socket_id;
- pollfds[socket_id].events |= POLLIN;
- }
-
- for (SOCKET socket_id : send_select_set) {
- pollfds[socket_id].fd = socket_id;
- pollfds[socket_id].events |= POLLOUT;
- }
-
- for (SOCKET socket_id : error_select_set) {
- pollfds[socket_id].fd = socket_id;
- // These flags are ignored, but we set them for clarity
- pollfds[socket_id].events |= POLLERR|POLLHUP;
- }
-
- std::vector<struct pollfd> vpollfds;
- vpollfds.reserve(pollfds.size());
- for (auto it : pollfds) {
- vpollfds.push_back(std::move(it.second));
- }
-
- if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
-
- if (interruptNet) return;
-
- for (struct pollfd pollfd_entry : vpollfds) {
- if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
- if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
- if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
- }
-}
-#else
-void CConnman::SocketEvents(const std::vector<CNode*>& nodes,
- std::set<SOCKET>& recv_set,
- std::set<SOCKET>& send_set,
- std::set<SOCKET>& error_set)
-{
- std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
- if (!GenerateSelectSet(nodes, recv_select_set, send_select_set, error_select_set)) {
- interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
- return;
- }
-
- //
- // Find which sockets have data to receive
- //
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
-
- fd_set fdsetRecv;
- fd_set fdsetSend;
- fd_set fdsetError;
- FD_ZERO(&fdsetRecv);
- FD_ZERO(&fdsetSend);
- FD_ZERO(&fdsetError);
- SOCKET hSocketMax = 0;
-
- for (SOCKET hSocket : recv_select_set) {
- FD_SET(hSocket, &fdsetRecv);
- hSocketMax = std::max(hSocketMax, hSocket);
- }
-
- for (SOCKET hSocket : send_select_set) {
- FD_SET(hSocket, &fdsetSend);
- hSocketMax = std::max(hSocketMax, hSocket);
- }
-
- for (SOCKET hSocket : error_select_set) {
- FD_SET(hSocket, &fdsetError);
- hSocketMax = std::max(hSocketMax, hSocket);
- }
-
- int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
-
- if (interruptNet)
- return;
-
- if (nSelect == SOCKET_ERROR)
- {
- int nErr = WSAGetLastError();
- LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
- for (unsigned int i = 0; i <= hSocketMax; i++)
- FD_SET(i, &fdsetRecv);
- FD_ZERO(&fdsetSend);
- FD_ZERO(&fdsetError);
- if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
- return;
- }
-
- for (SOCKET hSocket : recv_select_set) {
- if (FD_ISSET(hSocket, &fdsetRecv)) {
- recv_set.insert(hSocket);
+ requested = Sock::SEND;
+ } else if (select_recv) {
+ requested = Sock::RECV;
}
- }
- for (SOCKET hSocket : send_select_set) {
- if (FD_ISSET(hSocket, &fdsetSend)) {
- send_set.insert(hSocket);
- }
+ events_per_sock.emplace(pnode->m_sock, Sock::Events{requested});
}
- for (SOCKET hSocket : error_select_set) {
- if (FD_ISSET(hSocket, &fdsetError)) {
- error_set.insert(hSocket);
- }
- }
+ return events_per_sock;
}
-#endif
void CConnman::SocketHandler()
{
AssertLockNotHeld(m_total_bytes_sent_mutex);
- std::set<SOCKET> recv_set;
- std::set<SOCKET> send_set;
- std::set<SOCKET> error_set;
+ Sock::EventsPerSock events_per_sock;
{
const NodesSnapshot snap{*this, /*shuffle=*/false};
+ const auto timeout = std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS);
+
// Check for the readiness of the already connected sockets and the
// listening sockets in one call ("readiness" as in poll(2) or
// select(2)). If none are ready, wait for a short while and return
// empty sets.
- SocketEvents(snap.Nodes(), recv_set, send_set, error_set);
+ events_per_sock = GenerateWaitSockets(snap.Nodes());
+ if (events_per_sock.empty() || !events_per_sock.begin()->first->WaitMany(timeout, events_per_sock)) {
+ interruptNet.sleep_for(timeout);
+ }
// Service (send/receive) each of the already connected nodes.
- SocketHandlerConnected(snap.Nodes(), recv_set, send_set, error_set);
+ SocketHandlerConnected(snap.Nodes(), events_per_sock);
}
// Accept new connections from listening sockets.
- SocketHandlerListening(recv_set);
+ SocketHandlerListening(events_per_sock);
}
void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
- const std::set<SOCKET>& recv_set,
- const std::set<SOCKET>& send_set,
- const std::set<SOCKET>& error_set)
+ const Sock::EventsPerSock& events_per_sock)
{
AssertLockNotHeld(m_total_bytes_sent_mutex);
@@ -1621,9 +1497,12 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
if (!pnode->m_sock) {
continue;
}
- recvSet = recv_set.count(pnode->m_sock->Get()) > 0;
- sendSet = send_set.count(pnode->m_sock->Get()) > 0;
- errorSet = error_set.count(pnode->m_sock->Get()) > 0;
+ const auto it = events_per_sock.find(pnode->m_sock);
+ if (it != events_per_sock.end()) {
+ recvSet = it->second.occurred & Sock::RECV;
+ sendSet = it->second.occurred & Sock::SEND;
+ errorSet = it->second.occurred & Sock::ERR;
+ }
}
if (recvSet || errorSet)
{
@@ -1693,13 +1572,14 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
}
}
-void CConnman::SocketHandlerListening(const std::set<SOCKET>& recv_set)
+void CConnman::SocketHandlerListening(const Sock::EventsPerSock& events_per_sock)
{
for (const ListenSocket& listen_socket : vhListenSocket) {
if (interruptNet) {
return;
}
- if (recv_set.count(listen_socket.sock->Get()) > 0) {
+ const auto it = events_per_sock.find(listen_socket.sock);
+ if (it != events_per_sock.end() && it->second.occurred & Sock::RECV) {
AcceptConnection(listen_socket);
}
}
diff --git a/src/net.h b/src/net.h
index d6b605652b..bf169649c0 100644
--- a/src/net.h
+++ b/src/net.h
@@ -980,28 +980,9 @@ private:
/**
* Generate a collection of sockets to check for IO readiness.
* @param[in] nodes Select from these nodes' sockets.
- * @param[out] recv_set Sockets to check for read readiness.
- * @param[out] send_set Sockets to check for write readiness.
- * @param[out] error_set Sockets to check for errors.
- * @return true if at least one socket is to be checked (the returned set is not empty)
+ * @return sockets to check for readiness
*/
- bool GenerateSelectSet(const std::vector<CNode*>& nodes,
- std::set<SOCKET>& recv_set,
- std::set<SOCKET>& send_set,
- std::set<SOCKET>& error_set);
-
- /**
- * Check which sockets are ready for IO.
- * @param[in] nodes Select from these nodes' sockets.
- * @param[out] recv_set Sockets which are ready for read.
- * @param[out] send_set Sockets which are ready for write.
- * @param[out] error_set Sockets which have errors.
- * This calls `GenerateSelectSet()` to gather a list of sockets to check.
- */
- void SocketEvents(const std::vector<CNode*>& nodes,
- std::set<SOCKET>& recv_set,
- std::set<SOCKET>& send_set,
- std::set<SOCKET>& error_set);
+ Sock::EventsPerSock GenerateWaitSockets(Span<CNode* const> nodes);
/**
* Check connected and listening sockets for IO readiness and process them accordingly.
@@ -1010,23 +991,18 @@ private:
/**
* Do the read/write for connected sockets that are ready for IO.
- * @param[in] nodes Nodes to process. The socket of each node is checked against
- * `recv_set`, `send_set` and `error_set`.
- * @param[in] recv_set Sockets that are ready for read.
- * @param[in] send_set Sockets that are ready for send.
- * @param[in] error_set Sockets that have an exceptional condition (error).
+ * @param[in] nodes Nodes to process. The socket of each node is checked against `what`.
+ * @param[in] events_per_sock Sockets that are ready for IO.
*/
void SocketHandlerConnected(const std::vector<CNode*>& nodes,
- const std::set<SOCKET>& recv_set,
- const std::set<SOCKET>& send_set,
- const std::set<SOCKET>& error_set)
+ const Sock::EventsPerSock& events_per_sock)
EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
/**
* Accept incoming connections, one from each read-ready listening socket.
- * @param[in] recv_set Sockets that are ready for read.
+ * @param[in] events_per_sock Sockets that are ready for IO.
*/
- void SocketHandlerListening(const std::set<SOCKET>& recv_set);
+ void SocketHandlerListening(const Sock::EventsPerSock& events_per_sock);
void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex, !mutexMsgProc);
void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex, !m_nodes_mutex);
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 7b5ba955b2..751a03f01c 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -4635,7 +4635,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
namespace {
class CompareInvMempoolOrder
{
- CTxMemPool *mp;
+ CTxMemPool* mp;
bool m_wtxid_relay;
public:
explicit CompareInvMempoolOrder(CTxMemPool *_mempool, bool use_wtxid)
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
index 2e52716649..e017f3f427 100644
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -49,7 +49,7 @@ extern std::atomic_bool fReindex;
/** Pruning-related variables and constants */
/** True if we're running in -prune mode. */
extern bool fPruneMode;
-/** Number of MiB of block files that we're trying to stay below. */
+/** Number of bytes of block files that we're trying to stay below. */
extern uint64_t nPruneTarget;
// Because validation code takes pointers to the map's CBlockIndex objects, if
diff --git a/src/policy/packages.h b/src/policy/packages.h
index ba6a3a9a06..564ff50d29 100644
--- a/src/policy/packages.h
+++ b/src/policy/packages.h
@@ -19,6 +19,15 @@ static constexpr uint32_t MAX_PACKAGE_COUNT{25};
static constexpr uint32_t MAX_PACKAGE_SIZE{101};
static_assert(MAX_PACKAGE_SIZE * WITNESS_SCALE_FACTOR * 1000 >= MAX_STANDARD_TX_WEIGHT);
+// If a package is submitted, it must be within the mempool's ancestor/descendant limits. Since a
+// submitted package must be child-with-unconfirmed-parents (all of the transactions are an ancestor
+// of the child), package limits are ultimately bounded by mempool package limits. Ensure that the
+// defaults reflect this constraint.
+static_assert(DEFAULT_DESCENDANT_LIMIT >= MAX_PACKAGE_COUNT);
+static_assert(DEFAULT_ANCESTOR_LIMIT >= MAX_PACKAGE_COUNT);
+static_assert(DEFAULT_ANCESTOR_SIZE_LIMIT >= MAX_PACKAGE_SIZE);
+static_assert(DEFAULT_DESCENDANT_SIZE_LIMIT >= MAX_PACKAGE_SIZE);
+
/** A "reason" why a package was invalid. It may be that one or more of the included
* transactions is invalid or the package itself violates our rules.
* We don't distinguish between consensus and policy violations right now.
diff --git a/src/policy/policy.h b/src/policy/policy.h
index 94f9623b8a..cd46652efc 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -20,49 +20,63 @@ class CFeeRate;
class CScript;
/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/
-static const unsigned int DEFAULT_BLOCK_MAX_WEIGHT = MAX_BLOCK_WEIGHT - 4000;
+static constexpr unsigned int DEFAULT_BLOCK_MAX_WEIGHT{MAX_BLOCK_WEIGHT - 4000};
/** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/
-static const unsigned int DEFAULT_BLOCK_MIN_TX_FEE = 1000;
+static constexpr unsigned int DEFAULT_BLOCK_MIN_TX_FEE{1000};
/** The maximum weight for transactions we're willing to relay/mine */
-static const unsigned int MAX_STANDARD_TX_WEIGHT = 400000;
+static constexpr unsigned int MAX_STANDARD_TX_WEIGHT{400000};
/** The minimum non-witness size for transactions we're willing to relay/mine (1 segwit input + 1 P2WPKH output = 82 bytes) */
-static const unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE = 82;
+static constexpr unsigned int MIN_STANDARD_TX_NONWITNESS_SIZE{82};
/** Maximum number of signature check operations in an IsStandard() P2SH script */
-static const unsigned int MAX_P2SH_SIGOPS = 15;
+static constexpr unsigned int MAX_P2SH_SIGOPS{15};
/** The maximum number of sigops we're willing to relay/mine in a single tx */
-static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5;
+static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST{MAX_BLOCK_SIGOPS_COST/5};
/** Default for -maxmempool, maximum megabytes of mempool memory usage */
-static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;
+static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE{300};
/** Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP 125 replacement **/
-static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE = 1000;
+static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000};
/** Default for -bytespersigop */
-static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20;
+static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP{20};
/** Default for -permitbaremultisig */
-static const bool DEFAULT_PERMIT_BAREMULTISIG = true;
+static constexpr bool DEFAULT_PERMIT_BAREMULTISIG{true};
/** The maximum number of witness stack items in a standard P2WSH script */
-static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100;
+static constexpr unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS{100};
/** The maximum size in bytes of each witness stack item in a standard P2WSH script */
-static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80;
+static constexpr unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE{80};
/** The maximum size in bytes of each witness stack item in a standard BIP 342 script (Taproot, leaf version 0xc0) */
-static const unsigned int MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE = 80;
+static constexpr unsigned int MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE{80};
/** The maximum size in bytes of a standard witnessScript */
-static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
+static constexpr unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE{3600};
/** The maximum size of a standard ScriptSig */
-static const unsigned int MAX_STANDARD_SCRIPTSIG_SIZE = 1650;
+static constexpr unsigned int MAX_STANDARD_SCRIPTSIG_SIZE{1650};
/** Min feerate for defining dust. Historically this has been based on the
* minRelayTxFee, however changing the dust limit changes which transactions are
* standard and should be done with care and ideally rarely. It makes sense to
* only increase the dust limit after prior releases were already not creating
* outputs below the new threshold */
-static const unsigned int DUST_RELAY_TX_FEE = 3000;
+static constexpr unsigned int DUST_RELAY_TX_FEE{3000};
/** Default for -minrelaytxfee, minimum relay fee for transactions */
-static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
+static constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE{1000};
+/** Default for -limitancestorcount, max number of in-mempool ancestors */
+static constexpr unsigned int DEFAULT_ANCESTOR_LIMIT{25};
+/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
+static constexpr unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT{101};
+/** Default for -limitdescendantcount, max number of in-mempool descendants */
+static constexpr unsigned int DEFAULT_DESCENDANT_LIMIT{25};
+/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
+static constexpr unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT{101};
+/**
+ * An extra transaction can be added to a package, as long as it only has one
+ * ancestor and is no larger than this. Not really any reason to make this
+ * configurable as it doesn't materially change DoS parameters.
+ */
+static constexpr unsigned int EXTRA_DESCENDANT_TX_SIZE_LIMIT{10000};
/**
* Standard script verification flags that standard transactions will comply
* with. However scripts violating these flags may still be present in valid
* blocks and we must accept those blocks.
*/
-static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |
+static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERIFY_FLAGS |
SCRIPT_VERIFY_DERSIG |
SCRIPT_VERIFY_STRICTENC |
SCRIPT_VERIFY_MINIMALDATA |
@@ -81,14 +95,14 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VE
SCRIPT_VERIFY_TAPROOT |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
- SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE;
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE};
/** For convenience, standard but not mandatory verify flags. */
-static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
+static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS{STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS};
/** Used as the flags parameter to sequence and nLocktime checks in non-consensus code. */
-static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE |
- LOCKTIME_MEDIAN_TIME_PAST;
+static constexpr unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS{LOCKTIME_VERIFY_SEQUENCE |
+ LOCKTIME_MEDIAN_TIME_PAST};
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFee);
diff --git a/src/psbt.h b/src/psbt.h
index 8fda889bb4..4a6d41076f 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -54,7 +54,7 @@ static constexpr uint8_t PSBT_SEPARATOR = 0x00;
// BIP 174 does not specify a maximum file size, but we set a limit anyway
// to prevent reading a stream indefinitely and running out of memory.
-const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
+const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MB
// PSBT version number
static constexpr uint32_t PSBT_HIGHEST_VERSION = 0;
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index 934363af1f..ffebc316b1 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SendCoinsEntry</class>
- <widget class="QStackedWidget" name="SendCoinsEntry">
+ <widget class="QWidget" name="SendCoinsEntry">
<property name="geometry">
<rect>
<x>0</x>
@@ -16,1244 +16,204 @@
<property name="autoFillBackground">
<bool>false</bool>
</property>
- <widget class="QFrame" name="SendCoins">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="topMargin">
+ <number>8</number>
</property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="topMargin">
- <number>8</number>
- </property>
- <property name="bottomMargin">
- <number>4</number>
- </property>
- <property name="horizontalSpacing">
- <number>12</number>
- </property>
- <property name="verticalSpacing">
- <number>8</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="payToLabel">
- <property name="text">
- <string>Pay &amp;To:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="buddy">
- <cstring>payTo</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="payToLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <item>
- <widget class="QValidatedLineEdit" name="payTo">
- <property name="toolTip">
- <string>The Bitcoin address to send the payment to</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="addressBookButton">
- <property name="toolTip">
- <string>Choose previously used address</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../bitcoin.qrc">
- <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="shortcut">
- <string>Alt+A</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="pasteButton">
- <property name="toolTip">
- <string>Paste address from clipboard</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../bitcoin.qrc">
- <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- <property name="shortcut">
- <string>Alt+P</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="deleteButton">
- <property name="toolTip">
- <string>Remove this entry</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../bitcoin.qrc">
- <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>22</width>
- <height>22</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="labellLabel">
- <property name="text">
- <string>&amp;Label:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="buddy">
- <cstring>addAsLabel</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="addAsLabel">
- <property name="toolTip">
- <string>Enter a label for this address to add it to the list of used addresses</string>
- </property>
- <property name="placeholderText">
- <string>Enter a label for this address to add it to the list of used addresses</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="amountLabel">
- <property name="text">
- <string>A&amp;mount:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="buddy">
- <cstring>payAmount</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,1,0">
- <item>
- <widget class="BitcoinAmountField" name="payAmount">
- <property name="toolTip">
- <string>The amount to send in the selected unit</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
- <property name="toolTip">
- <string>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.</string>
- </property>
- <property name="text">
- <string>S&amp;ubtract fee from amount</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="useAvailableBalanceButton">
- <property name="text">
- <string>Use available balance</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="messageLabel">
- <property name="text">
- <string>Message:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="messageTextLabel">
- <property name="toolTip">
- <string>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.</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QFrame" name="SendCoins_UnauthenticatedPaymentRequest">
- <property name="palette">
- <palette>
- <active>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>191</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>127</red>
- <green>127</green>
- <blue>63</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>170</red>
- <green>170</green>
- <blue>84</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>191</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </active>
- <inactive>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>191</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>127</red>
- <green>127</green>
- <blue>63</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>170</red>
- <green>170</green>
- <blue>84</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>191</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </inactive>
- <disabled>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>127</red>
- <green>127</green>
- <blue>63</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>191</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>127</red>
- <green>127</green>
- <blue>63</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>170</red>
- <green>170</green>
- <blue>84</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>127</red>
- <green>127</green>
- <blue>63</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>127</red>
- <green>127</green>
- <blue>63</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>127</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </disabled>
- </palette>
+ <property name="bottomMargin">
+ <number>4</number>
</property>
- <property name="toolTip">
- <string>This is an unauthenticated payment request.</string>
+ <property name="horizontalSpacing">
+ <number>12</number>
</property>
- <property name="autoFillBackground">
- <bool>true</bool>
+ <property name="verticalSpacing">
+ <number>8</number>
</property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout_is">
- <property name="spacing">
- <number>12</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="payToLabel_is">
- <property name="text">
- <string>Pay To:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="payToLayout_is">
- <property name="spacing">
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="payTo_is"/>
- </item>
- <item>
- <widget class="QToolButton" name="deleteButton_is">
- <property name="toolTip">
- <string>Remove this entry</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../bitcoin.qrc">
- <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="memoLabel_is">
- <property name="text">
- <string>Memo:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="memoTextLabel_is">
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="amountLabel_is">
- <property name="text">
- <string>A&amp;mount:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="buddy">
- <cstring>payAmount_is</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="BitcoinAmountField" name="payAmount_is">
- <property name="acceptDrops">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QFrame" name="SendCoins_AuthenticatedPaymentRequest">
- <property name="palette">
- <palette>
- <active>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>230</red>
- <green>255</green>
- <blue>224</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>185</red>
- <green>243</green>
- <blue>171</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>70</red>
- <green>116</green>
- <blue>59</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>93</red>
- <green>155</green>
- <blue>79</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>155</red>
- <green>255</green>
- <blue>147</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>119</red>
- <green>255</green>
- <blue>233</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>197</red>
- <green>243</green>
- <blue>187</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="NoRole">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>125</red>
- <green>194</green>
- <blue>122</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </active>
- <inactive>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>230</red>
- <green>255</green>
- <blue>224</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>185</red>
- <green>243</green>
- <blue>171</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>70</red>
- <green>116</green>
- <blue>59</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>93</red>
- <green>155</green>
- <blue>79</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>155</red>
- <green>255</green>
- <blue>147</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>119</red>
- <green>255</green>
- <blue>233</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>197</red>
- <green>243</green>
- <blue>187</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="NoRole">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>125</red>
- <green>194</green>
- <blue>122</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </inactive>
- <disabled>
- <colorrole role="WindowText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>70</red>
- <green>116</green>
- <blue>59</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Button">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Light">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>230</red>
- <green>255</green>
- <blue>224</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Midlight">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>185</red>
- <green>243</green>
- <blue>171</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Dark">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>70</red>
- <green>116</green>
- <blue>59</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Mid">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>93</red>
- <green>155</green>
- <blue>79</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Text">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>70</red>
- <green>116</green>
- <blue>59</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="BrightText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>155</red>
- <green>255</green>
- <blue>147</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ButtonText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>70</red>
- <green>116</green>
- <blue>59</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Base">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Window">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="Shadow">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="AlternateBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>140</red>
- <green>232</green>
- <blue>119</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="NoRole">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>125</red>
- <green>194</green>
- <blue>122</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipBase">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>255</red>
- <green>255</green>
- <blue>220</blue>
- </color>
- </brush>
- </colorrole>
- <colorrole role="ToolTipText">
- <brush brushstyle="SolidPattern">
- <color alpha="255">
- <red>0</red>
- <green>0</green>
- <blue>0</blue>
- </color>
- </brush>
- </colorrole>
- </disabled>
- </palette>
- </property>
- <property name="toolTip">
- <string>This is an authenticated payment request.</string>
- </property>
- <property name="autoFillBackground">
- <bool>true</bool>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <layout class="QGridLayout" name="gridLayout_s">
- <property name="spacing">
- <number>12</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="payToLabel_s">
- <property name="text">
- <string>Pay To:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="payToLayout_s">
- <property name="spacing">
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="payTo_s">
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="deleteButton_s">
- <property name="toolTip">
- <string>Remove this entry</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../bitcoin.qrc">
- <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="memoLabel_s">
- <property name="text">
- <string>Memo:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="memoTextLabel_s">
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="amountLabel_s">
- <property name="text">
- <string>A&amp;mount:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="buddy">
- <cstring>payAmount_s</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="BitcoinAmountField" name="payAmount_s">
- <property name="acceptDrops">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
+ <item row="0" column="0">
+ <widget class="QLabel" name="payToLabel">
+ <property name="text">
+ <string>Pay &amp;To:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>payTo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="payToLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QValidatedLineEdit" name="payTo">
+ <property name="toolTip">
+ <string>The Bitcoin address to send the payment to</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="addressBookButton">
+ <property name="toolTip">
+ <string>Choose previously used address</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="shortcut">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="pasteButton">
+ <property name="toolTip">
+ <string>Paste address from clipboard</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="shortcut">
+ <string>Alt+P</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteButton">
+ <property name="toolTip">
+ <string>Remove this entry</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labellLabel">
+ <property name="text">
+ <string>&amp;Label:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>addAsLabel</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="addAsLabel">
+ <property name="toolTip">
+ <string>Enter a label for this address to add it to the list of used addresses</string>
+ </property>
+ <property name="placeholderText">
+ <string>Enter a label for this address to add it to the list of used addresses</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="amountLabel">
+ <property name="text">
+ <string>A&amp;mount:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>payAmount</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,1,0">
+ <item>
+ <widget class="BitcoinAmountField" name="payAmount" native="true">
+ <property name="toolTip">
+ <string>The amount to send in the selected unit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
+ <property name="toolTip">
+ <string>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.</string>
+ </property>
+ <property name="text">
+ <string>S&amp;ubtract fee from amount</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="useAvailableBalanceButton">
+ <property name="text">
+ <string>Use available balance</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="messageLabel">
+ <property name="text">
+ <string>Message:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="messageTextLabel">
+ <property name="toolTip">
+ <string>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.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
<customwidgets>
<customwidget>
@@ -1263,8 +223,9 @@
</customwidget>
<customwidget>
<class>BitcoinAmountField</class>
- <extends>QLineEdit</extends>
+ <extends>QWidget</extends>
<header>qt/bitcoinamountfield.h</header>
+ <container>1</container>
</customwidget>
</customwidgets>
<tabstops>
@@ -1274,10 +235,6 @@
<tabstop>deleteButton</tabstop>
<tabstop>addAsLabel</tabstop>
<tabstop>payAmount</tabstop>
- <tabstop>payAmount_is</tabstop>
- <tabstop>deleteButton_is</tabstop>
- <tabstop>payAmount_s</tabstop>
- <tabstop>deleteButton_s</tabstop>
</tabstops>
<resources>
<include location="../bitcoin.qrc"/>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index e3c6d8a624..186ed4f644 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -24,9 +24,6 @@
#include <util/time.h>
#ifdef WIN32
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
#include <shellapi.h>
#include <shlobj.h>
#include <shlwapi.h>
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index f4928951fe..4c8b33bf28 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -287,7 +287,7 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable
ui->freeSpace->setText("");
} else {
m_bytes_available = bytesAvailable;
- if (ui->prune->isEnabled()) {
+ if (ui->prune->isEnabled() && !(gArgs.IsArgSet("-prune") && gArgs.GetIntArg("-prune", 0) == 0)) {
ui->prune->setChecked(m_bytes_available < (m_blockchain_size_gb + m_chain_state_size_gb + 10) * GB_BYTES);
}
UpdateFreeSpaceLabel();
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 339ac580d8..af514d5a43 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -20,7 +20,7 @@
#include <QClipboard>
SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *parent) :
- QStackedWidget(parent),
+ QWidget(parent),
ui(new Ui::SendCoinsEntry),
model(nullptr),
platformStyle(_platformStyle)
@@ -30,25 +30,16 @@ SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *par
ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
- ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
- ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
-
- setCurrentWidget(ui->SendCoins);
if (platformStyle->getUseExtraSpacing())
ui->payToLayout->setSpacing(4);
- // normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
- // just a label for displaying bitcoin address(es)
- ui->payTo_is->setFont(GUIUtil::fixedPitchFont());
// Connect signals
connect(ui->payAmount, &BitcoinAmountField::valueChanged, this, &SendCoinsEntry::payAmountChanged);
connect(ui->checkboxSubtractFeeFromAmount, &QCheckBox::toggled, this, &SendCoinsEntry::subtractFeeFromAmountChanged);
connect(ui->deleteButton, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
- connect(ui->deleteButton_is, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
- connect(ui->deleteButton_s, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
connect(ui->useAvailableBalanceButton, &QPushButton::clicked, this, &SendCoinsEntry::useAvailableBalanceClicked);
}
@@ -103,14 +94,6 @@ void SendCoinsEntry::clear()
ui->messageTextLabel->clear();
ui->messageTextLabel->hide();
ui->messageLabel->hide();
- // clear UI elements for unauthenticated payment request
- ui->payTo_is->clear();
- ui->memoTextLabel_is->clear();
- ui->payAmount_is->clear();
- // clear UI elements for authenticated payment request
- ui->payTo_s->clear();
- ui->memoTextLabel_s->clear();
- ui->payAmount_s->clear();
// update the display unit, to not use the default ("BTC")
updateDisplayUnit();
@@ -219,7 +202,7 @@ void SendCoinsEntry::setAmount(const CAmount &amount)
bool SendCoinsEntry::isClear()
{
- return ui->payTo->text().isEmpty() && ui->payTo_is->text().isEmpty() && ui->payTo_s->text().isEmpty();
+ return ui->payTo->text().isEmpty();
}
void SendCoinsEntry::setFocus()
@@ -229,12 +212,8 @@ void SendCoinsEntry::setFocus()
void SendCoinsEntry::updateDisplayUnit()
{
- if(model && model->getOptionsModel())
- {
- // Update payAmount with the current unit
+ if (model && model->getOptionsModel()) {
ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
- ui->payAmount_is->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
- ui->payAmount_s->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
}
}
@@ -244,11 +223,9 @@ void SendCoinsEntry::changeEvent(QEvent* e)
ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
ui->pasteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editpaste")));
ui->deleteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
- ui->deleteButton_is->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
- ui->deleteButton_s->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
}
- QStackedWidget::changeEvent(e);
+ QWidget::changeEvent(e);
}
bool SendCoinsEntry::updateLabel(const QString &address)
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index e8db1e3a5c..ea9d58fbf8 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -7,7 +7,7 @@
#include <qt/sendcoinsrecipient.h>
-#include <QStackedWidget>
+#include <QWidget>
class WalletModel;
class PlatformStyle;
@@ -22,10 +22,8 @@ namespace Ui {
/**
* A single entry in the dialog for sending bitcoins.
- * Stacked widget, with different UIs for payment requests
- * with a strong payee identity.
*/
-class SendCoinsEntry : public QStackedWidget
+class SendCoinsEntry : public QWidget
{
Q_OBJECT
diff --git a/src/rest.cpp b/src/rest.cpp
index 1b90baaf95..43c248b03b 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -799,10 +799,10 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
if (!maybe_chainman) return false;
ChainstateManager& chainman = *maybe_chainman;
{
- auto process_utxos = [&vOutPoints, &outs, &hits](const CCoinsView& view, const CTxMemPool& mempool) {
+ auto process_utxos = [&vOutPoints, &outs, &hits](const CCoinsView& view, const CTxMemPool* mempool) {
for (const COutPoint& vOutPoint : vOutPoints) {
Coin coin;
- bool hit = !mempool.isSpent(vOutPoint) && view.GetCoin(vOutPoint, coin);
+ bool hit = (!mempool || !mempool->isSpent(vOutPoint)) && view.GetCoin(vOutPoint, coin);
hits.push_back(hit);
if (hit) outs.emplace_back(std::move(coin));
}
@@ -815,10 +815,10 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
LOCK2(cs_main, mempool->cs);
CCoinsViewCache& viewChain = chainman.ActiveChainstate().CoinsTip();
CCoinsViewMemPool viewMempool(&viewChain, *mempool);
- process_utxos(viewMempool, *mempool);
+ process_utxos(viewMempool, mempool);
} else {
- LOCK(cs_main); // no need to lock mempool!
- process_utxos(chainman.ActiveChainstate().CoinsTip(), CTxMemPool());
+ LOCK(cs_main);
+ process_utxos(chainman.ActiveChainstate().CoinsTip(), nullptr);
}
for (size_t i = 0; i < hits.size(); ++i) {
diff --git a/src/support/lockedpool.cpp b/src/support/lockedpool.cpp
index b7ef479675..e48accf0a4 100644
--- a/src/support/lockedpool.cpp
+++ b/src/support/lockedpool.cpp
@@ -10,9 +10,6 @@
#endif
#ifdef WIN32
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
#include <windows.h>
#else
#include <sys/mman.h> // for mmap
diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp
index 875241094d..78b82b9b20 100644
--- a/src/test/blockencodings_tests.cpp
+++ b/src/test/blockencodings_tests.cpp
@@ -54,7 +54,7 @@ constexpr long SHARED_TX_OFFSET{3};
BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
TestMemPoolEntryHelper entry;
CBlock block(BuildBlockTestCase());
@@ -137,7 +137,7 @@ public:
BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
TestMemPoolEntryHelper entry;
CBlock block(BuildBlockTestCase());
@@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
TestMemPoolEntryHelper entry;
CBlock block(BuildBlockTestCase());
@@ -258,7 +258,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
CMutableTransaction coinbase;
coinbase.vin.resize(1);
coinbase.vin[0].scriptSig.resize(10);
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index 033c6e18d5..883698aff1 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -223,6 +223,15 @@ bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event*
return true;
}
+bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const
+{
+ for (auto& [sock, events] : events_per_sock) {
+ (void)sock;
+ events.occurred = m_fuzzed_data_provider.ConsumeBool() ? events.requested : 0;
+ }
+ return true;
+}
+
bool FuzzedSock::IsConnected(std::string& errmsg) const
{
if (m_fuzzed_data_provider.ConsumeBool()) {
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 3fc6fa1cd5..66d00b1767 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -71,6 +71,8 @@ public:
bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override;
+ bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override;
+
bool IsConnected(std::string& errmsg) const override;
};
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 89424a0cd2..bc63122025 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
}
- CTxMemPool testPool;
+ CTxMemPool& testPool = *Assert(m_node.mempool);
LOCK2(cs_main, testPool.cs);
// Nothing in pool, remove should do nothing:
@@ -108,12 +108,12 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
BOOST_CHECK_EQUAL(testPool.size(), 0U);
}
-template<typename name>
-static void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
+template <typename name>
+static void CheckSort(CTxMemPool& pool, std::vector<std::string>& sortedOrder) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
{
BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
typename CTxMemPool::indexed_transaction_set::index<name>::type::iterator it = pool.mapTx.get<name>().begin();
- int count=0;
+ int count = 0;
for (; it != pool.mapTx.get<name>().end(); ++it, ++count) {
BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]);
}
@@ -121,7 +121,7 @@ static void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) E
BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
LOCK2(cs_main, pool.cs);
TestMemPoolEntryHelper entry;
@@ -294,7 +294,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
LOCK2(cs_main, pool.cs);
TestMemPoolEntryHelper entry;
@@ -423,7 +423,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
{
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
LOCK2(cs_main, pool.cs);
TestMemPoolEntryHelper entry;
@@ -594,7 +594,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTests)
{
size_t ancestors, descendants;
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
LOCK2(cs_main, pool.cs);
TestMemPoolEntryHelper entry;
@@ -753,7 +753,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestryTestsDiamond)
{
size_t ancestors, descendants;
- CTxMemPool pool;
+ CTxMemPool& pool = *Assert(m_node.mempool);
LOCK2(::cs_main, pool.cs);
TestMemPoolEntryHelper entry;
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index e7c01bd6d0..115c4b9b24 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -675,10 +675,13 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
const uint16_t bind_port = 20001;
m_node.args->ForceSetArg("-bind", strprintf("3.4.5.6:%u", bind_port));
+ const uint32_t current_time = static_cast<uint32_t>(GetAdjustedTime());
+ SetMockTime(current_time);
+
// Our address:port as seen from the peer, completely different from the above.
in_addr peer_us_addr;
peer_us_addr.s_addr = htonl(0x02030405);
- const CAddress peer_us{CService{peer_us_addr, 20002}, NODE_NETWORK};
+ const CAddress peer_us{CService{peer_us_addr, 20002}, NODE_NETWORK, current_time};
// Create a peer with a routable IPv4 address (outbound).
in_addr peer_out_in_addr;
@@ -699,7 +702,7 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
// Without the fix peer_us:8333 is chosen instead of the proper peer_us:bind_port.
auto chosen_local_addr = GetLocalAddrForPeer(&peer_out);
BOOST_REQUIRE(chosen_local_addr);
- const CService expected{peer_us_addr, bind_port};
+ const CAddress expected{CService{peer_us_addr, bind_port}, NODE_NETWORK, current_time};
BOOST_CHECK(*chosen_local_addr == expected);
// Create a peer with a routable IPv4 address (inbound).
diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
index 06877898a4..3f66a8fc46 100644
--- a/src/test/policyestimator_tests.cpp
+++ b/src/test/policyestimator_tests.cpp
@@ -12,12 +12,12 @@
#include <boost/test/unit_test.hpp>
-BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup)
+BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, ChainTestingSetup)
BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
{
- CBlockPolicyEstimator feeEst;
- CTxMemPool mpool(&feeEst);
+ CBlockPolicyEstimator& feeEst = *Assert(m_node.fee_estimator);
+ CTxMemPool& mpool = *Assert(m_node.mempool);
LOCK2(cs_main, mpool.cs);
TestMemPoolEntryHelper entry;
CAmount basefee(2000);
diff --git a/src/test/util/net.h b/src/test/util/net.h
index e980fe4967..37d278645a 100644
--- a/src/test/util/net.h
+++ b/src/test/util/net.h
@@ -162,6 +162,15 @@ public:
return true;
}
+ bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override
+ {
+ for (auto& [sock, events] : events_per_sock) {
+ (void)sock;
+ events.occurred = events.requested;
+ }
+ return true;
+ }
+
private:
const std::string m_contents;
mutable size_t m_consumed;
diff --git a/src/test/validation_chainstate_tests.cpp b/src/test/validation_chainstate_tests.cpp
index 98cb713a81..102de74389 100644
--- a/src/test/validation_chainstate_tests.cpp
+++ b/src/test/validation_chainstate_tests.cpp
@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
ChainstateManager manager{chainman_opts};
WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
- CTxMemPool mempool;
+ CTxMemPool& mempool = *Assert(m_node.mempool);
//! Create and add a Coin with DynamicMemoryUsage of 80 bytes to the given view.
auto add_coin = [](CCoinsViewCache& coins_view) -> COutPoint {
diff --git a/src/test/validation_flush_tests.cpp b/src/test/validation_flush_tests.cpp
index a34895d4ae..012169b17e 100644
--- a/src/test/validation_flush_tests.cpp
+++ b/src/test/validation_flush_tests.cpp
@@ -20,7 +20,7 @@ BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, ChainTestingSetup)
//!
BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
{
- CTxMemPool mempool;
+ CTxMemPool& mempool = *Assert(m_node.mempool);
BlockManager blockman{};
CChainState chainstate{&mempool, blockman, *Assert(m_node.chainman)};
chainstate.InitCoinsDB(/*cache_size_bytes=*/1 << 10, /*in_memory=*/true, /*should_wipe=*/false);
diff --git a/src/univalue/.cirrus.yml b/src/univalue/.cirrus.yml
deleted file mode 100644
index f140fee12b..0000000000
--- a/src/univalue/.cirrus.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-env:
- MAKEJOBS: "-j4"
- RUN_TESTS: "true"
- BASE_OUTDIR: "$CIRRUS_WORKING_DIR/out_dir_base"
- DEBIAN_FRONTEND: "noninteractive"
-
-task:
- container:
- image: ubuntu:focal
- cpu: 1
- memory: 1G
- greedy: true # https://medium.com/cirruslabs/introducing-greedy-container-instances-29aad06dc2b4
-
- matrix:
- - name: "gcc"
- env:
- CC: "gcc"
- CXX: "g++"
- APT_PKGS: "gcc"
- - name: "clang"
- env:
- CC: "clang"
- CXX: "clang++"
- APT_PKGS: "clang"
- - name: "mingw"
- env:
- CC: ""
- CXX: ""
- UNIVALUE_CONFIG: "--host=x86_64-w64-mingw32"
- APT_PKGS: "g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64"
- RUN_TESTS: "false"
-
- install_script:
- - apt update
- - apt install -y pkg-config build-essential libtool autotools-dev automake bsdmainutils
- - apt install -y $APT_PKGS
- autogen_script:
- - ./autogen.sh
- configure_script:
- - ./configure --cache-file=config.cache --bindir=$BASE_OUTDIR/bin --libdir=$BASE_OUTDIR/lib $UNIVALUE_CONFIG
- make_script:
- - make $MAKEJOBS V=1
- test_script:
- - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS distcheck; fi
diff --git a/src/univalue/COPYING b/src/univalue/COPYING
deleted file mode 100644
index 1fb429f356..0000000000
--- a/src/univalue/COPYING
+++ /dev/null
@@ -1,19 +0,0 @@
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/src/univalue/Makefile.am b/src/univalue/Makefile.am
deleted file mode 100644
index 476f14b922..0000000000
--- a/src/univalue/Makefile.am
+++ /dev/null
@@ -1,58 +0,0 @@
-include sources.mk
-ACLOCAL_AMFLAGS = -I build-aux/m4
-.PHONY: gen FORCE
-.INTERMEDIATE: $(GENBIN)
-
-include_HEADERS = $(UNIVALUE_DIST_HEADERS_INT)
-noinst_HEADERS = $(UNIVALUE_LIB_HEADERS_INT)
-
-lib_LTLIBRARIES = libunivalue.la
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = pc/libunivalue.pc
-
-libunivalue_la_SOURCES = $(UNIVALUE_LIB_SOURCES_INT)
-
-libunivalue_la_LDFLAGS = \
- -version-info $(LIBUNIVALUE_CURRENT):$(LIBUNIVALUE_REVISION):$(LIBUNIVALUE_AGE) \
- -no-undefined
-libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include
-
-TESTS = test/object test/unitester test/no_nul
-
-GENBIN = gen/gen$(BUILD_EXEEXT)
-GEN_SRCS = gen/gen.cpp
-
-$(GENBIN): $(GEN_SRCS)
- @echo Building $@
- $(AM_V_at)c++ -I$(top_srcdir)/include -o $@ $<
-
-gen: $(GENBIN) FORCE
- @echo Updating lib/univalue_escapes.h
- $(AM_V_at)$(GENBIN) > lib/univalue_escapes.h
-
-noinst_PROGRAMS = $(TESTS) test/test_json
-
-test_unitester_SOURCES = $(UNIVALUE_TEST_UNITESTER_INT)
-test_unitester_LDADD = libunivalue.la
-test_unitester_CXXFLAGS = -I$(top_srcdir)/include -DJSON_TEST_SRC=\"$(srcdir)/$(UNIVALUE_TEST_DATA_DIR_INT)\"
-test_unitester_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
-
-test_test_json_SOURCES = $(UNIVALUE_TEST_JSON_INT)
-test_test_json_LDADD = libunivalue.la
-test_test_json_CXXFLAGS = -I$(top_srcdir)/include
-test_test_json_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
-
-test_no_nul_SOURCES = $(UNIVALUE_TEST_NO_NUL_INT)
-test_no_nul_LDADD = libunivalue.la
-test_no_nul_CXXFLAGS = -I$(top_srcdir)/include
-test_no_nul_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
-
-test_object_SOURCES = $(UNIVALUE_TEST_OBJECT_INT)
-test_object_LDADD = libunivalue.la
-test_object_CXXFLAGS = -I$(top_srcdir)/include
-test_object_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
-
-TEST_FILES = $(UNIVALUE_TEST_FILES_INT)
-
-EXTRA_DIST=$(UNIVALUE_TEST_FILES_INT) $(GEN_SRCS)
diff --git a/src/univalue/README.md b/src/univalue/README.md
deleted file mode 100644
index d622f5b1e0..0000000000
--- a/src/univalue/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# UniValue
-
-## Summary
-
-A universal value class, with JSON encoding and decoding.
-
-UniValue is an abstract data type that may be a null, boolean, string,
-number, array container, or a key/value dictionary container, nested to
-an arbitrary depth.
-
-This class is aligned with the JSON standard, [RFC
-7159](https://tools.ietf.org/html/rfc7159.html).
-
-## Library usage
-
-This is a fork of univalue used by Bitcoin Core. It is not maintained for usage
-by other projects. Notably, the API is broken in non-backward-compatible ways.
-
-Other projects looking for a maintained library should use the upstream
-univalue at https://github.com/jgarzik/univalue.
diff --git a/src/univalue/autogen.sh b/src/univalue/autogen.sh
deleted file mode 100755
index 4b38721faa..0000000000
--- a/src/univalue/autogen.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-set -e
-srcdir="$(dirname $0)"
-cd "$srcdir"
-if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
- LIBTOOLIZE="${GLIBTOOLIZE}"
- export LIBTOOLIZE
-fi
-autoreconf --install --force
diff --git a/src/univalue/build-aux/m4/.gitignore b/src/univalue/build-aux/m4/.gitignore
deleted file mode 100644
index f063686524..0000000000
--- a/src/univalue/build-aux/m4/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/*.m4
diff --git a/src/univalue/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/src/univalue/build-aux/m4/ax_cxx_compile_stdcxx.m4
deleted file mode 100644
index f7e5137003..0000000000
--- a/src/univalue/build-aux/m4/ax_cxx_compile_stdcxx.m4
+++ /dev/null
@@ -1,962 +0,0 @@
-# ===========================================================================
-# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
-#
-# DESCRIPTION
-#
-# Check for baseline language coverage in the compiler for the specified
-# version of the C++ standard. If necessary, add switches to CXX and
-# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
-# or '14' (for the C++14 standard).
-#
-# The second argument, if specified, indicates whether you insist on an
-# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
-# -std=c++11). If neither is specified, you get whatever works, with
-# preference for no added switch, and then for an extended mode.
-#
-# The third argument, if specified 'mandatory' or if left unspecified,
-# indicates that baseline support for the specified C++ standard is
-# required and that the macro should error out if no mode with that
-# support is found. If specified 'optional', then configuration proceeds
-# regardless, after defining HAVE_CXX${VERSION} if and only if a
-# supporting mode is found.
-#
-# LICENSE
-#
-# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
-# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
-# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
-# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
-# Copyright (c) 2015 Paul Norman <penorman@mac.com>
-# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
-# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
-# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
-# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
-#
-# Copying and distribution of this file, with or without modification, are
-# permitted in any medium without royalty provided the copyright notice
-# and this notice are preserved. This file is offered as-is, without any
-# warranty.
-
-#serial 12
-
-dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
-dnl (serial version number 13).
-
-AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
- m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
- [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
- [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
- [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
- m4_if([$2], [], [],
- [$2], [ext], [],
- [$2], [noext], [],
- [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
- m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
- [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
- [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
- [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
- AC_LANG_PUSH([C++])dnl
- ac_success=no
-
- m4_if([$2], [], [dnl
- AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
- ax_cv_cxx_compile_cxx$1,
- [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
- [ax_cv_cxx_compile_cxx$1=yes],
- [ax_cv_cxx_compile_cxx$1=no])])
- if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
- ac_success=yes
- fi])
-
- m4_if([$2], [noext], [], [dnl
- if test x$ac_success = xno; then
- for alternative in ${ax_cxx_compile_alternatives}; do
- switch="-std=gnu++${alternative}"
- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
- AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
- $cachevar,
- [ac_save_CXX="$CXX"
- CXX="$CXX $switch"
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
- [eval $cachevar=yes],
- [eval $cachevar=no])
- CXX="$ac_save_CXX"])
- if eval test x\$$cachevar = xyes; then
- CXX="$CXX $switch"
- if test -n "$CXXCPP" ; then
- CXXCPP="$CXXCPP $switch"
- fi
- ac_success=yes
- break
- fi
- done
- fi])
-
- m4_if([$2], [ext], [], [dnl
- if test x$ac_success = xno; then
- dnl HP's aCC needs +std=c++11 according to:
- dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
- dnl Cray's crayCC needs "-h std=c++11"
- for alternative in ${ax_cxx_compile_alternatives}; do
- for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
- AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
- $cachevar,
- [ac_save_CXX="$CXX"
- CXX="$CXX $switch"
- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
- [eval $cachevar=yes],
- [eval $cachevar=no])
- CXX="$ac_save_CXX"])
- if eval test x\$$cachevar = xyes; then
- CXX="$CXX $switch"
- if test -n "$CXXCPP" ; then
- CXXCPP="$CXXCPP $switch"
- fi
- ac_success=yes
- break
- fi
- done
- if test x$ac_success = xyes; then
- break
- fi
- done
- fi])
- AC_LANG_POP([C++])
- if test x$ax_cxx_compile_cxx$1_required = xtrue; then
- if test x$ac_success = xno; then
- AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
- fi
- fi
- if test x$ac_success = xno; then
- HAVE_CXX$1=0
- AC_MSG_NOTICE([No compiler with C++$1 support was found])
- else
- HAVE_CXX$1=1
- AC_DEFINE(HAVE_CXX$1,1,
- [define if the compiler supports basic C++$1 syntax])
- fi
- AC_SUBST(HAVE_CXX$1)
-])
-
-
-dnl Test body for checking C++11 support
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
- _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-)
-
-
-dnl Test body for checking C++14 support
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
- _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
- _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
-)
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
- _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
- _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
- _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
-)
-
-dnl Tests for new features in C++11
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
-
-// If the compiler admits that it is not ready for C++11, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
-
-#error "This is not a C++ compiler"
-
-#elif __cplusplus < 201103L
-
-#error "This is not a C++11 compiler"
-
-#else
-
-namespace cxx11
-{
-
- namespace test_static_assert
- {
-
- template <typename T>
- struct check
- {
- static_assert(sizeof(int) <= sizeof(T), "not big enough");
- };
-
- }
-
- namespace test_final_override
- {
-
- struct Base
- {
- virtual ~Base() {}
- virtual void f() {}
- };
-
- struct Derived : public Base
- {
- virtual ~Derived() override {}
- virtual void f() override {}
- };
-
- }
-
- namespace test_double_right_angle_brackets
- {
-
- template < typename T >
- struct check {};
-
- typedef check<void> single_type;
- typedef check<check<void>> double_type;
- typedef check<check<check<void>>> triple_type;
- typedef check<check<check<check<void>>>> quadruple_type;
-
- }
-
- namespace test_decltype
- {
-
- int
- f()
- {
- int a = 1;
- decltype(a) b = 2;
- return a + b;
- }
-
- }
-
- namespace test_type_deduction
- {
-
- template < typename T1, typename T2 >
- struct is_same
- {
- static const bool value = false;
- };
-
- template < typename T >
- struct is_same<T, T>
- {
- static const bool value = true;
- };
-
- template < typename T1, typename T2 >
- auto
- add(T1 a1, T2 a2) -> decltype(a1 + a2)
- {
- return a1 + a2;
- }
-
- int
- test(const int c, volatile int v)
- {
- static_assert(is_same<int, decltype(0)>::value == true, "");
- static_assert(is_same<int, decltype(c)>::value == false, "");
- static_assert(is_same<int, decltype(v)>::value == false, "");
- auto ac = c;
- auto av = v;
- auto sumi = ac + av + 'x';
- auto sumf = ac + av + 1.0;
- static_assert(is_same<int, decltype(ac)>::value == true, "");
- static_assert(is_same<int, decltype(av)>::value == true, "");
- static_assert(is_same<int, decltype(sumi)>::value == true, "");
- static_assert(is_same<int, decltype(sumf)>::value == false, "");
- static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
- return (sumf > 0.0) ? sumi : add(c, v);
- }
-
- }
-
- namespace test_noexcept
- {
-
- int f() { return 0; }
- int g() noexcept { return 0; }
-
- static_assert(noexcept(f()) == false, "");
- static_assert(noexcept(g()) == true, "");
-
- }
-
- namespace test_constexpr
- {
-
- template < typename CharT >
- unsigned long constexpr
- strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
- {
- return *s ? strlen_c_r(s + 1, acc + 1) : acc;
- }
-
- template < typename CharT >
- unsigned long constexpr
- strlen_c(const CharT *const s) noexcept
- {
- return strlen_c_r(s, 0UL);
- }
-
- static_assert(strlen_c("") == 0UL, "");
- static_assert(strlen_c("1") == 1UL, "");
- static_assert(strlen_c("example") == 7UL, "");
- static_assert(strlen_c("another\0example") == 7UL, "");
-
- }
-
- namespace test_rvalue_references
- {
-
- template < int N >
- struct answer
- {
- static constexpr int value = N;
- };
-
- answer<1> f(int&) { return answer<1>(); }
- answer<2> f(const int&) { return answer<2>(); }
- answer<3> f(int&&) { return answer<3>(); }
-
- void
- test()
- {
- int i = 0;
- const int c = 0;
- static_assert(decltype(f(i))::value == 1, "");
- static_assert(decltype(f(c))::value == 2, "");
- static_assert(decltype(f(0))::value == 3, "");
- }
-
- }
-
- namespace test_uniform_initialization
- {
-
- struct test
- {
- static const int zero {};
- static const int one {1};
- };
-
- static_assert(test::zero == 0, "");
- static_assert(test::one == 1, "");
-
- }
-
- namespace test_lambdas
- {
-
- void
- test1()
- {
- auto lambda1 = [](){};
- auto lambda2 = lambda1;
- lambda1();
- lambda2();
- }
-
- int
- test2()
- {
- auto a = [](int i, int j){ return i + j; }(1, 2);
- auto b = []() -> int { return '0'; }();
- auto c = [=](){ return a + b; }();
- auto d = [&](){ return c; }();
- auto e = [a, &b](int x) mutable {
- const auto identity = [](int y){ return y; };
- for (auto i = 0; i < a; ++i)
- a += b--;
- return x + identity(a + b);
- }(0);
- return a + b + c + d + e;
- }
-
- int
- test3()
- {
- const auto nullary = [](){ return 0; };
- const auto unary = [](int x){ return x; };
- using nullary_t = decltype(nullary);
- using unary_t = decltype(unary);
- const auto higher1st = [](nullary_t f){ return f(); };
- const auto higher2nd = [unary](nullary_t f1){
- return [unary, f1](unary_t f2){ return f2(unary(f1())); };
- };
- return higher1st(nullary) + higher2nd(nullary)(unary);
- }
-
- }
-
- namespace test_variadic_templates
- {
-
- template <int...>
- struct sum;
-
- template <int N0, int... N1toN>
- struct sum<N0, N1toN...>
- {
- static constexpr auto value = N0 + sum<N1toN...>::value;
- };
-
- template <>
- struct sum<>
- {
- static constexpr auto value = 0;
- };
-
- static_assert(sum<>::value == 0, "");
- static_assert(sum<1>::value == 1, "");
- static_assert(sum<23>::value == 23, "");
- static_assert(sum<1, 2>::value == 3, "");
- static_assert(sum<5, 5, 11>::value == 21, "");
- static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
-
- }
-
- // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
- // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
- // because of this.
- namespace test_template_alias_sfinae
- {
-
- struct foo {};
-
- template<typename T>
- using member = typename T::member_type;
-
- template<typename T>
- void func(...) {}
-
- template<typename T>
- void func(member<T>*) {}
-
- void test();
-
- void test() { func<foo>(0); }
-
- }
-
-} // namespace cxx11
-
-#endif // __cplusplus >= 201103L
-
-]])
-
-
-dnl Tests for new features in C++14
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
-
-// If the compiler admits that it is not ready for C++14, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
-
-#error "This is not a C++ compiler"
-
-#elif __cplusplus < 201402L
-
-#error "This is not a C++14 compiler"
-
-#else
-
-namespace cxx14
-{
-
- namespace test_polymorphic_lambdas
- {
-
- int
- test()
- {
- const auto lambda = [](auto&&... args){
- const auto istiny = [](auto x){
- return (sizeof(x) == 1UL) ? 1 : 0;
- };
- const int aretiny[] = { istiny(args)... };
- return aretiny[0];
- };
- return lambda(1, 1L, 1.0f, '1');
- }
-
- }
-
- namespace test_binary_literals
- {
-
- constexpr auto ivii = 0b0000000000101010;
- static_assert(ivii == 42, "wrong value");
-
- }
-
- namespace test_generalized_constexpr
- {
-
- template < typename CharT >
- constexpr unsigned long
- strlen_c(const CharT *const s) noexcept
- {
- auto length = 0UL;
- for (auto p = s; *p; ++p)
- ++length;
- return length;
- }
-
- static_assert(strlen_c("") == 0UL, "");
- static_assert(strlen_c("x") == 1UL, "");
- static_assert(strlen_c("test") == 4UL, "");
- static_assert(strlen_c("another\0test") == 7UL, "");
-
- }
-
- namespace test_lambda_init_capture
- {
-
- int
- test()
- {
- auto x = 0;
- const auto lambda1 = [a = x](int b){ return a + b; };
- const auto lambda2 = [a = lambda1(x)](){ return a; };
- return lambda2();
- }
-
- }
-
- namespace test_digit_separators
- {
-
- constexpr auto ten_million = 100'000'000;
- static_assert(ten_million == 100000000, "");
-
- }
-
- namespace test_return_type_deduction
- {
-
- auto f(int& x) { return x; }
- decltype(auto) g(int& x) { return x; }
-
- template < typename T1, typename T2 >
- struct is_same
- {
- static constexpr auto value = false;
- };
-
- template < typename T >
- struct is_same<T, T>
- {
- static constexpr auto value = true;
- };
-
- int
- test()
- {
- auto x = 0;
- static_assert(is_same<int, decltype(f(x))>::value, "");
- static_assert(is_same<int&, decltype(g(x))>::value, "");
- return x;
- }
-
- }
-
-} // namespace cxx14
-
-#endif // __cplusplus >= 201402L
-
-]])
-
-
-dnl Tests for new features in C++17
-
-m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
-
-// If the compiler admits that it is not ready for C++17, why torture it?
-// Hopefully, this will speed up the test.
-
-#ifndef __cplusplus
-
-#error "This is not a C++ compiler"
-
-#elif __cplusplus < 201703L
-
-#error "This is not a C++17 compiler"
-
-#else
-
-#include <initializer_list>
-#include <utility>
-#include <type_traits>
-
-namespace cxx17
-{
-
- namespace test_constexpr_lambdas
- {
-
- constexpr int foo = [](){return 42;}();
-
- }
-
- namespace test::nested_namespace::definitions
- {
-
- }
-
- namespace test_fold_expression
- {
-
- template<typename... Args>
- int multiply(Args... args)
- {
- return (args * ... * 1);
- }
-
- template<typename... Args>
- bool all(Args... args)
- {
- return (args && ...);
- }
-
- }
-
- namespace test_extended_static_assert
- {
-
- static_assert (true);
-
- }
-
- namespace test_auto_brace_init_list
- {
-
- auto foo = {5};
- auto bar {5};
-
- static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
- static_assert(std::is_same<int, decltype(bar)>::value);
- }
-
- namespace test_typename_in_template_template_parameter
- {
-
- template<template<typename> typename X> struct D;
-
- }
-
- namespace test_fallthrough_nodiscard_maybe_unused_attributes
- {
-
- int f1()
- {
- return 42;
- }
-
- [[nodiscard]] int f2()
- {
- [[maybe_unused]] auto unused = f1();
-
- switch (f1())
- {
- case 17:
- f1();
- [[fallthrough]];
- case 42:
- f1();
- }
- return f1();
- }
-
- }
-
- namespace test_extended_aggregate_initialization
- {
-
- struct base1
- {
- int b1, b2 = 42;
- };
-
- struct base2
- {
- base2() {
- b3 = 42;
- }
- int b3;
- };
-
- struct derived : base1, base2
- {
- int d;
- };
-
- derived d1 {{1, 2}, {}, 4}; // full initialization
- derived d2 {{}, {}, 4}; // value-initialized bases
-
- }
-
- namespace test_general_range_based_for_loop
- {
-
- struct iter
- {
- int i;
-
- int& operator* ()
- {
- return i;
- }
-
- const int& operator* () const
- {
- return i;
- }
-
- iter& operator++()
- {
- ++i;
- return *this;
- }
- };
-
- struct sentinel
- {
- int i;
- };
-
- bool operator== (const iter& i, const sentinel& s)
- {
- return i.i == s.i;
- }
-
- bool operator!= (const iter& i, const sentinel& s)
- {
- return !(i == s);
- }
-
- struct range
- {
- iter begin() const
- {
- return {0};
- }
-
- sentinel end() const
- {
- return {5};
- }
- };
-
- void f()
- {
- range r {};
-
- for (auto i : r)
- {
- [[maybe_unused]] auto v = i;
- }
- }
-
- }
-
- namespace test_lambda_capture_asterisk_this_by_value
- {
-
- struct t
- {
- int i;
- int foo()
- {
- return [*this]()
- {
- return i;
- }();
- }
- };
-
- }
-
- namespace test_enum_class_construction
- {
-
- enum class byte : unsigned char
- {};
-
- byte foo {42};
-
- }
-
- namespace test_constexpr_if
- {
-
- template <bool cond>
- int f ()
- {
- if constexpr(cond)
- {
- return 13;
- }
- else
- {
- return 42;
- }
- }
-
- }
-
- namespace test_selection_statement_with_initializer
- {
-
- int f()
- {
- return 13;
- }
-
- int f2()
- {
- if (auto i = f(); i > 0)
- {
- return 3;
- }
-
- switch (auto i = f(); i + 4)
- {
- case 17:
- return 2;
-
- default:
- return 1;
- }
- }
-
- }
-
- namespace test_template_argument_deduction_for_class_templates
- {
-
- template <typename T1, typename T2>
- struct pair
- {
- pair (T1 p1, T2 p2)
- : m1 {p1},
- m2 {p2}
- {}
-
- T1 m1;
- T2 m2;
- };
-
- void f()
- {
- [[maybe_unused]] auto p = pair{13, 42u};
- }
-
- }
-
- namespace test_non_type_auto_template_parameters
- {
-
- template <auto n>
- struct B
- {};
-
- B<5> b1;
- B<'a'> b2;
-
- }
-
- namespace test_structured_bindings
- {
-
- int arr[2] = { 1, 2 };
- std::pair<int, int> pr = { 1, 2 };
-
- auto f1() -> int(&)[2]
- {
- return arr;
- }
-
- auto f2() -> std::pair<int, int>&
- {
- return pr;
- }
-
- struct S
- {
- int x1 : 2;
- volatile double y1;
- };
-
- S f3()
- {
- return {};
- }
-
- auto [ x1, y1 ] = f1();
- auto& [ xr1, yr1 ] = f1();
- auto [ x2, y2 ] = f2();
- auto& [ xr2, yr2 ] = f2();
- const auto [ x3, y3 ] = f3();
-
- }
-
- namespace test_exception_spec_type_system
- {
-
- struct Good {};
- struct Bad {};
-
- void g1() noexcept;
- void g2();
-
- template<typename T>
- Bad
- f(T*, T*);
-
- template<typename T1, typename T2>
- Good
- f(T1*, T2*);
-
- static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
-
- }
-
- namespace test_inline_variables
- {
-
- template<class T> void f(T)
- {}
-
- template<class T> inline T g(T)
- {
- return T{};
- }
-
- template<> inline void f<>(int)
- {}
-
- template<> int g<>(int)
- {
- return 5;
- }
-
- }
-
-} // namespace cxx17
-
-#endif // __cplusplus < 201703L
-
-]])
diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac
deleted file mode 100644
index ed9c5f0c5c..0000000000
--- a/src/univalue/configure.ac
+++ /dev/null
@@ -1,72 +0,0 @@
-m4_define([libunivalue_major_version], [1])
-m4_define([libunivalue_minor_version], [1])
-m4_define([libunivalue_micro_version], [4])
-m4_define([libunivalue_interface_age], [4])
-# If you need a modifier for the version number.
-# Normally empty, but can be used to make "fixup" releases.
-m4_define([libunivalue_extraversion], [])
-
-dnl libtool versioning from libunivalue
-m4_define([libunivalue_current], [m4_eval(100 * libunivalue_minor_version + libunivalue_micro_version - libunivalue_interface_age)])
-m4_define([libunivalue_binary_age], [m4_eval(100 * libunivalue_minor_version + libunivalue_micro_version)])
-m4_define([libunivalue_revision], [libunivalue_interface_age])
-m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_interface_age)])
-m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()])
-
-
-AC_INIT([univalue], [1.0.4],
- [http://github.com/jgarzik/univalue/])
-
-dnl make the compilation flags quiet unless V=1 is used
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-AC_PREREQ(2.60)
-AC_CONFIG_SRCDIR([lib/univalue.cpp])
-AC_CONFIG_AUX_DIR([build-aux])
-AC_CONFIG_MACRO_DIR([build-aux/m4])
-AC_CONFIG_HEADERS([univalue-config.h])
-AM_INIT_AUTOMAKE([subdir-objects foreign])
-
-LIBUNIVALUE_MAJOR_VERSION=libunivalue_major_version
-LIBUNIVALUE_MINOR_VERSION=libunivalue_minor_version
-LIBUNIVALUE_MICRO_VERSION=libunivalue_micro_version
-LIBUNIVALUE_INTERFACE_AGE=libunivalue_interface_age
-
-# ABI version
-# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-LIBUNIVALUE_CURRENT=libunivalue_current
-LIBUNIVALUE_REVISION=libunivalue_revision
-LIBUNIVALUE_AGE=libunivalue_age
-
-AC_SUBST(LIBUNIVALUE_CURRENT)
-AC_SUBST(LIBUNIVALUE_REVISION)
-AC_SUBST(LIBUNIVALUE_AGE)
-
-LT_INIT
-LT_LANG([C++])
-
-dnl Require C++17 compiler (no GNU extensions)
-AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory], [nodefault])
-
-case $host in
- *mingw*)
- LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"
- ;;
-esac
-
-BUILD_EXEEXT=
-case $build in
- *mingw*)
- BUILD_EXEEXT=".exe"
- ;;
-esac
-
-AC_CONFIG_FILES([
- Makefile
- pc/libunivalue.pc
- pc/libunivalue-uninstalled.pc])
-
-AC_SUBST(LIBTOOL_APP_LDFLAGS)
-AC_SUBST(BUILD_EXEEXT)
-AC_OUTPUT
-
diff --git a/src/univalue/gen/gen.cpp b/src/univalue/gen/gen.cpp
deleted file mode 100644
index ca5b470ddc..0000000000
--- a/src/univalue/gen/gen.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 BitPay Inc.
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or https://opensource.org/licenses/mit-license.php.
-
-//
-// To re-create univalue_escapes.h:
-// $ g++ -o gen gen.cpp
-// $ ./gen > univalue_escapes.h
-//
-
-#include <univalue.h>
-
-#include <cstdio>
-#include <cstring>
-#include <string>
-
-static bool initEscapes;
-static std::string escapes[256];
-
-static void initJsonEscape()
-{
- // Escape all lower control characters (some get overridden with smaller sequences below)
- for (int ch=0x00; ch<0x20; ++ch) {
- char tmpbuf[20];
- snprintf(tmpbuf, sizeof(tmpbuf), "\\u%04x", ch);
- escapes[ch] = std::string(tmpbuf);
- }
-
- escapes[(int)'"'] = "\\\"";
- escapes[(int)'\\'] = "\\\\";
- escapes[(int)'\b'] = "\\b";
- escapes[(int)'\f'] = "\\f";
- escapes[(int)'\n'] = "\\n";
- escapes[(int)'\r'] = "\\r";
- escapes[(int)'\t'] = "\\t";
- escapes[(int)'\x7f'] = "\\u007f"; // U+007F DELETE
-
- initEscapes = true;
-}
-
-static void outputEscape()
-{
- printf( "// Automatically generated file. Do not modify.\n"
- "#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n"
- "#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n"
- "static const char *escapes[256] = {\n");
-
- for (unsigned int i = 0; i < 256; i++) {
- if (escapes[i].empty()) {
- printf("\tnullptr,\n");
- } else {
- printf("\t\"");
-
- unsigned int si;
- for (si = 0; si < escapes[i].size(); si++) {
- char ch = escapes[i][si];
- switch (ch) {
- case '"':
- printf("\\\"");
- break;
- case '\\':
- printf("\\\\");
- break;
- default:
- printf("%c", escapes[i][si]);
- break;
- }
- }
-
- printf("\",\n");
- }
- }
-
- printf( "};\n"
- "#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n");
-}
-
-int main (int argc, char *argv[])
-{
- initJsonEscape();
- outputEscape();
- return 0;
-}
-
diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h
index f0d4de2035..22be0311e8 100644
--- a/src/univalue/include/univalue.h
+++ b/src/univalue/include/univalue.h
@@ -3,8 +3,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#ifndef __UNIVALUE_H__
-#define __UNIVALUE_H__
+#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
+#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
#include <charconv>
#include <cstdint>
@@ -194,4 +194,4 @@ extern const UniValue NullUniValue;
const UniValue& find_value( const UniValue& obj, const std::string& name);
-#endif // __UNIVALUE_H__
+#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
diff --git a/src/univalue/lib/univalue_escapes.h b/src/univalue/include/univalue_escapes.h
index 3f714f8e5b..83767e8ac5 100644
--- a/src/univalue/lib/univalue_escapes.h
+++ b/src/univalue/include/univalue_escapes.h
@@ -1,6 +1,5 @@
-// Automatically generated file. Do not modify.
-#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
-#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
+#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_ESCAPES_H
+#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_ESCAPES_H
static const char *escapes[256] = {
"\\u0000",
"\\u0001",
@@ -259,4 +258,4 @@ static const char *escapes[256] = {
nullptr,
nullptr,
};
-#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
+#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_ESCAPES_H
diff --git a/src/univalue/lib/univalue_utffilter.h b/src/univalue/include/univalue_utffilter.h
index c24ac58eaf..f688eaaa30 100644
--- a/src/univalue/lib/univalue_utffilter.h
+++ b/src/univalue/include/univalue_utffilter.h
@@ -1,8 +1,8 @@
// Copyright 2016 Wladimir J. van der Laan
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#ifndef UNIVALUE_UTFFILTER_H
-#define UNIVALUE_UTFFILTER_H
+#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
+#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
#include <string>
@@ -116,4 +116,4 @@ private:
}
};
-#endif
+#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp
index a6ed75e57a..2f2385383c 100644
--- a/src/univalue/lib/univalue_read.cpp
+++ b/src/univalue/lib/univalue_read.cpp
@@ -3,7 +3,7 @@
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
-#include "univalue_utffilter.h"
+#include <univalue_utffilter.h>
#include <cstdio>
#include <cstdint>
diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp
index 18833077b7..4a3cbba20f 100644
--- a/src/univalue/lib/univalue_write.cpp
+++ b/src/univalue/lib/univalue_write.cpp
@@ -3,7 +3,7 @@
// file COPYING or https://opensource.org/licenses/mit-license.php.
#include <univalue.h>
-#include "univalue_escapes.h"
+#include <univalue_escapes.h>
#include <memory>
#include <string>
diff --git a/src/univalue/pc/libunivalue-uninstalled.pc.in b/src/univalue/pc/libunivalue-uninstalled.pc.in
deleted file mode 100644
index b7f53e875e..0000000000
--- a/src/univalue/pc/libunivalue-uninstalled.pc.in
+++ /dev/null
@@ -1,9 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libunivalue
-Description: libunivalue, C++ universal value object and JSON library
-Version: @VERSION@
-Libs: ${pc_top_builddir}/${pcfiledir}/libunivalue.la
diff --git a/src/univalue/pc/libunivalue.pc.in b/src/univalue/pc/libunivalue.pc.in
deleted file mode 100644
index 358a2d5f73..0000000000
--- a/src/univalue/pc/libunivalue.pc.in
+++ /dev/null
@@ -1,10 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libunivalue
-Description: libunivalue, C++ universal value object and JSON library
-Version: @VERSION@
-Libs: -L${libdir} -lunivalue
-Cflags: -I${includedir}
diff --git a/src/univalue/sources.mk b/src/univalue/sources.mk
index efab6d277f..e156216378 100644
--- a/src/univalue/sources.mk
+++ b/src/univalue/sources.mk
@@ -12,10 +12,8 @@ UNIVALUE_INCLUDE_DIR_INT = %reldir%/include
UNIVALUE_DIST_HEADERS_INT =
UNIVALUE_DIST_HEADERS_INT += %reldir%/include/univalue.h
-
-UNIVALUE_LIB_HEADERS_INT =
-UNIVALUE_LIB_HEADERS_INT += %reldir%/lib/univalue_utffilter.h
-UNIVALUE_LIB_HEADERS_INT += %reldir%/lib/univalue_escapes.h
+UNIVALUE_DIST_HEADERS_INT += %reldir%/include/univalue_utffilter.h
+UNIVALUE_DIST_HEADERS_INT += %reldir%/include/univalue_escapes.h
UNIVALUE_LIB_SOURCES_INT =
UNIVALUE_LIB_SOURCES_INT += %reldir%/lib/univalue.cpp
diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp
index 81b1c5d3b1..94c149b39f 100644
--- a/src/univalue/test/unitester.cpp
+++ b/src/univalue/test/unitester.cpp
@@ -12,15 +12,7 @@
#error JSON_TEST_SRC must point to test source directory
#endif
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-#endif
-
std::string srcdir(JSON_TEST_SRC);
-static bool test_failed = false;
-
-#define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } }
-#define f_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", __func__); } }
static std::string rtrim(std::string s)
{
@@ -41,9 +33,9 @@ static void runtest(std::string filename, const std::string& jdata)
bool testResult = val.read(jdata);
if (wantPass) {
- d_assert(testResult == true);
+ assert(testResult == true);
} else {
- d_assert(testResult == false);
+ assert(testResult == false);
}
if (wantRoundTrip) {
@@ -141,30 +133,30 @@ void unescape_unicode_test()
bool testResult;
// Escaped ASCII (quote)
testResult = val.read("[\"\\u0022\"]");
- f_assert(testResult);
- f_assert(val[0].get_str() == "\"");
+ assert(testResult);
+ assert(val[0].get_str() == "\"");
// Escaped Basic Plane character, two-byte UTF-8
testResult = val.read("[\"\\u0191\"]");
- f_assert(testResult);
- f_assert(val[0].get_str() == "\xc6\x91");
+ assert(testResult);
+ assert(val[0].get_str() == "\xc6\x91");
// Escaped Basic Plane character, three-byte UTF-8
testResult = val.read("[\"\\u2191\"]");
- f_assert(testResult);
- f_assert(val[0].get_str() == "\xe2\x86\x91");
+ assert(testResult);
+ assert(val[0].get_str() == "\xe2\x86\x91");
// Escaped Supplementary Plane character U+1d161
testResult = val.read("[\"\\ud834\\udd61\"]");
- f_assert(testResult);
- f_assert(val[0].get_str() == "\xf0\x9d\x85\xa1");
+ assert(testResult);
+ assert(val[0].get_str() == "\xf0\x9d\x85\xa1");
}
int main (int argc, char *argv[])
{
- for (unsigned int fidx = 0; fidx < ARRAY_SIZE(filenames); fidx++) {
- runtest_file(filenames[fidx]);
+ for (const auto& f: filenames) {
+ runtest_file(f);
}
unescape_unicode_test();
- return test_failed ? 1 : 0;
+ return 0;
}
diff --git a/src/util/sock.cpp b/src/util/sock.cpp
index 3579af4458..7d5069423a 100644
--- a/src/util/sock.cpp
+++ b/src/util/sock.cpp
@@ -113,63 +113,103 @@ int Sock::SetSockOpt(int level, int opt_name, const void* opt_val, socklen_t opt
bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
{
-#ifdef USE_POLL
- pollfd fd;
- fd.fd = m_socket;
- fd.events = 0;
- if (requested & RECV) {
- fd.events |= POLLIN;
- }
- if (requested & SEND) {
- fd.events |= POLLOUT;
- }
+ // We need a `shared_ptr` owning `this` for `WaitMany()`, but don't want
+ // `this` to be destroyed when the `shared_ptr` goes out of scope at the
+ // end of this function. Create it with a custom noop deleter.
+ std::shared_ptr<const Sock> shared{this, [](const Sock*) {}};
+
+ EventsPerSock events_per_sock{std::make_pair(shared, Events{requested})};
- if (poll(&fd, 1, count_milliseconds(timeout)) == SOCKET_ERROR) {
+ if (!WaitMany(timeout, events_per_sock)) {
return false;
}
if (occurred != nullptr) {
- *occurred = 0;
- if (fd.revents & POLLIN) {
- *occurred |= RECV;
+ *occurred = events_per_sock.begin()->second.occurred;
+ }
+
+ return true;
+}
+
+bool Sock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const
+{
+#ifdef USE_POLL
+ std::vector<pollfd> pfds;
+ for (const auto& [sock, events] : events_per_sock) {
+ pfds.emplace_back();
+ auto& pfd = pfds.back();
+ pfd.fd = sock->m_socket;
+ if (events.requested & RECV) {
+ pfd.events |= POLLIN;
}
- if (fd.revents & POLLOUT) {
- *occurred |= SEND;
+ if (events.requested & SEND) {
+ pfd.events |= POLLOUT;
}
}
- return true;
-#else
- if (!IsSelectableSocket(m_socket)) {
+ if (poll(pfds.data(), pfds.size(), count_milliseconds(timeout)) == SOCKET_ERROR) {
return false;
}
- fd_set fdset_recv;
- fd_set fdset_send;
- FD_ZERO(&fdset_recv);
- FD_ZERO(&fdset_send);
-
- if (requested & RECV) {
- FD_SET(m_socket, &fdset_recv);
+ assert(pfds.size() == events_per_sock.size());
+ size_t i{0};
+ for (auto& [sock, events] : events_per_sock) {
+ assert(sock->m_socket == static_cast<SOCKET>(pfds[i].fd));
+ events.occurred = 0;
+ if (pfds[i].revents & POLLIN) {
+ events.occurred |= RECV;
+ }
+ if (pfds[i].revents & POLLOUT) {
+ events.occurred |= SEND;
+ }
+ if (pfds[i].revents & (POLLERR | POLLHUP)) {
+ events.occurred |= ERR;
+ }
+ ++i;
}
- if (requested & SEND) {
- FD_SET(m_socket, &fdset_send);
+ return true;
+#else
+ fd_set recv;
+ fd_set send;
+ fd_set err;
+ FD_ZERO(&recv);
+ FD_ZERO(&send);
+ FD_ZERO(&err);
+ SOCKET socket_max{0};
+
+ for (const auto& [sock, events] : events_per_sock) {
+ const auto& s = sock->m_socket;
+ if (!IsSelectableSocket(s)) {
+ return false;
+ }
+ if (events.requested & RECV) {
+ FD_SET(s, &recv);
+ }
+ if (events.requested & SEND) {
+ FD_SET(s, &send);
+ }
+ FD_SET(s, &err);
+ socket_max = std::max(socket_max, s);
}
- timeval timeout_struct = MillisToTimeval(timeout);
+ timeval tv = MillisToTimeval(timeout);
- if (select(m_socket + 1, &fdset_recv, &fdset_send, nullptr, &timeout_struct) == SOCKET_ERROR) {
+ if (select(socket_max + 1, &recv, &send, &err, &tv) == SOCKET_ERROR) {
return false;
}
- if (occurred != nullptr) {
- *occurred = 0;
- if (FD_ISSET(m_socket, &fdset_recv)) {
- *occurred |= RECV;
+ for (auto& [sock, events] : events_per_sock) {
+ const auto& s = sock->m_socket;
+ events.occurred = 0;
+ if (FD_ISSET(s, &recv)) {
+ events.occurred |= RECV;
+ }
+ if (FD_ISSET(s, &send)) {
+ events.occurred |= SEND;
}
- if (FD_ISSET(m_socket, &fdset_send)) {
- *occurred |= SEND;
+ if (FD_ISSET(s, &err)) {
+ events.occurred |= ERR;
}
}
diff --git a/src/util/sock.h b/src/util/sock.h
index dd2913a66c..3245820995 100644
--- a/src/util/sock.h
+++ b/src/util/sock.h
@@ -12,6 +12,7 @@
#include <chrono>
#include <memory>
#include <string>
+#include <unordered_map>
/**
* Maximum time to wait for I/O readiness.
@@ -130,26 +131,84 @@ public:
/**
* If passed to `Wait()`, then it will wait for readiness to read from the socket.
*/
- static constexpr Event RECV = 0b01;
+ static constexpr Event RECV = 0b001;
/**
* If passed to `Wait()`, then it will wait for readiness to send to the socket.
*/
- static constexpr Event SEND = 0b10;
+ static constexpr Event SEND = 0b010;
+
+ /**
+ * Ignored if passed to `Wait()`, but could be set in the occurred events if an
+ * exceptional condition has occurred on the socket or if it has been disconnected.
+ */
+ static constexpr Event ERR = 0b100;
/**
* Wait for readiness for input (recv) or output (send).
* @param[in] timeout Wait this much for at least one of the requested events to occur.
* @param[in] requested Wait for those events, bitwise-or of `RECV` and `SEND`.
- * @param[out] occurred If not nullptr and `true` is returned, then upon return this
- * indicates which of the requested events occurred. A timeout is indicated by return
- * value of `true` and `occurred` being set to 0.
- * @return true on success and false otherwise
+ * @param[out] occurred If not nullptr and the function returns `true`, then this
+ * indicates which of the requested events occurred (`ERR` will be added, even if
+ * not requested, if an exceptional event occurs on the socket).
+ * A timeout is indicated by return value of `true` and `occurred` being set to 0.
+ * @return true on success (or timeout, if `occurred` of 0 is returned), false otherwise
*/
[[nodiscard]] virtual bool Wait(std::chrono::milliseconds timeout,
Event requested,
Event* occurred = nullptr) const;
+ /**
+ * Auxiliary requested/occurred events to wait for in `WaitMany()`.
+ */
+ struct Events {
+ explicit Events(Event req) : requested{req}, occurred{0} {}
+ Event requested;
+ Event occurred;
+ };
+
+ struct HashSharedPtrSock {
+ size_t operator()(const std::shared_ptr<const Sock>& s) const
+ {
+ return s ? s->m_socket : std::numeric_limits<SOCKET>::max();
+ }
+ };
+
+ struct EqualSharedPtrSock {
+ bool operator()(const std::shared_ptr<const Sock>& lhs,
+ const std::shared_ptr<const Sock>& rhs) const
+ {
+ if (lhs && rhs) {
+ return lhs->m_socket == rhs->m_socket;
+ }
+ if (!lhs && !rhs) {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ /**
+ * On which socket to wait for what events in `WaitMany()`.
+ * The `shared_ptr` is copied into the map to ensure that the `Sock` object
+ * is not destroyed (its destructor would close the underlying socket).
+ * If this happens shortly before or after we call `poll(2)` and a new
+ * socket gets created under the same file descriptor number then the report
+ * from `WaitMany()` will be bogus.
+ */
+ using EventsPerSock = std::unordered_map<std::shared_ptr<const Sock>, Events, HashSharedPtrSock, EqualSharedPtrSock>;
+
+ /**
+ * Same as `Wait()`, but wait on many sockets within the same timeout.
+ * @param[in] timeout Wait this long for at least one of the requested events to occur.
+ * @param[in,out] events_per_sock Wait for the requested events on these sockets and set
+ * `occurred` for the events that actually occurred.
+ * @return true on success (or timeout, if all `what[].occurred` are returned as 0),
+ * false otherwise
+ */
+ [[nodiscard]] virtual bool WaitMany(std::chrono::milliseconds timeout,
+ EventsPerSock& events_per_sock) const;
+
/* Higher level, convenience, methods. These may throw. */
/**
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 6e2638a5d6..1ae82fbc96 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -62,9 +62,6 @@
#pragma warning(disable:4717)
#endif
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
#include <codecvt>
#include <io.h> /* for _commit */
diff --git a/src/validation.cpp b/src/validation.cpp
index 26ce286c63..b775c85912 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -81,12 +81,6 @@ using node::UnlinkPrunedFiles;
#define MICRO 0.000001
#define MILLI 0.001
-/**
- * An extra transaction can be added to a package, as long as it only has one
- * ancestor and is no larger than this. Not really any reason to make this
- * configurable as it doesn't materially change DoS parameters.
- */
-static const unsigned int EXTRA_DESCENDANT_TX_SIZE_LIMIT = 10000;
/** Maximum kilobytes for transactions to store for processing during reorg */
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE = 20000;
/** Time to wait between writing blocks/block index to disk. */
diff --git a/src/validation.h b/src/validation.h
index 70b6c072e6..3b6cd509c6 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -21,6 +21,7 @@
#include <node/blockstorage.h>
#include <policy/feerate.h>
#include <policy/packages.h>
+#include <policy/policy.h>
#include <script/script_error.h>
#include <sync.h>
#include <txdb.h>
@@ -58,24 +59,6 @@ namespace Consensus {
struct Params;
} // namespace Consensus
-/** Default for -limitancestorcount, max number of in-mempool ancestors */
-static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25;
-/** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */
-static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101;
-/** Default for -limitdescendantcount, max number of in-mempool descendants */
-static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25;
-/** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */
-static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101;
-
-// If a package is submitted, it must be within the mempool's ancestor/descendant limits. Since a
-// submitted package must be child-with-unconfirmed-parents (all of the transactions are an ancestor
-// of the child), package limits are ultimately bounded by mempool package limits. Ensure that the
-// defaults reflect this constraint.
-static_assert(DEFAULT_DESCENDANT_LIMIT >= MAX_PACKAGE_COUNT);
-static_assert(DEFAULT_ANCESTOR_LIMIT >= MAX_PACKAGE_COUNT);
-static_assert(DEFAULT_ANCESTOR_SIZE_LIMIT >= MAX_PACKAGE_SIZE);
-static_assert(DEFAULT_DESCENDANT_SIZE_LIMIT >= MAX_PACKAGE_SIZE);
-
/** Default for -mempoolexpiry, expiration time for mempool transactions in hours */
static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 336;
/** Maximum number of dedicated script-checking threads allowed */
diff --git a/src/wallet/coincontrol.h b/src/wallet/coincontrol.h
index 65a5c83366..d08d3664c4 100644
--- a/src/wallet/coincontrol.h
+++ b/src/wallet/coincontrol.h
@@ -33,12 +33,11 @@ public:
CTxDestination destChange = CNoDestination();
//! Override the default change type if set, ignored if destChange is set
std::optional<OutputType> m_change_type;
- //! If false, only selected inputs are used
- bool m_add_inputs = true;
//! If false, only safe inputs will be used
bool m_include_unsafe_inputs = false;
- //! If false, allows unselected inputs, but requires all selected inputs be used
- bool fAllowOtherInputs = false;
+ //! If true, the selection process can add extra unselected inputs from the wallet
+ //! while requires all selected inputs be used
+ bool m_allow_other_inputs = false;
//! Includes watch only addresses which are solvable
bool fAllowWatchOnly = false;
//! Override automatic min/max checks on fee, m_feerate must be set if true
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index afd2b83971..5e70ed4a30 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -213,7 +213,7 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
for (const auto& inputs : wtx.tx->vin) {
new_coin_control.Select(COutPoint(inputs.prevout));
}
- new_coin_control.fAllowOtherInputs = true;
+ new_coin_control.m_allow_other_inputs = true;
// We cannot source new unconfirmed inputs(bip125 rule 2)
new_coin_control.m_min_depth = 1;
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index e1203817e0..f54b2c83d2 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -110,7 +110,7 @@ WalletTxOut MakeWalletTxOut(const CWallet& wallet,
result.txout = wtx.tx->vout[n];
result.time = wtx.GetTxTime();
result.depth_in_main_chain = depth;
- result.is_spent = wallet.IsSpent(wtx.GetHash(), n);
+ result.is_spent = wallet.IsSpent(COutPoint(wtx.GetHash(), n));
return result;
}
@@ -121,7 +121,7 @@ WalletTxOut MakeWalletTxOut(const CWallet& wallet,
result.txout = output.txout;
result.time = output.time;
result.depth_in_main_chain = output.depth;
- result.is_spent = wallet.IsSpent(output.outpoint.hash, output.outpoint.n);
+ result.is_spent = wallet.IsSpent(output.outpoint);
return result;
}
@@ -245,7 +245,7 @@ public:
bool isLockedCoin(const COutPoint& output) override
{
LOCK(m_wallet->cs_wallet);
- return m_wallet->IsLockedCoin(output.hash, output.n);
+ return m_wallet->IsLockedCoin(output);
}
void listLockedCoins(std::vector<COutPoint>& outputs) override
{
diff --git a/src/wallet/receive.cpp b/src/wallet/receive.cpp
index 8cce07b921..8de4017371 100644
--- a/src/wallet/receive.cpp
+++ b/src/wallet/receive.cpp
@@ -204,10 +204,9 @@ CAmount CachedTxGetAvailableCredit(const CWallet& wallet, const CWalletTx& wtx,
bool allow_used_addresses = (filter & ISMINE_USED) || !wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
CAmount nCredit = 0;
uint256 hashTx = wtx.GetHash();
- for (unsigned int i = 0; i < wtx.tx->vout.size(); i++)
- {
- if (!wallet.IsSpent(hashTx, i) && (allow_used_addresses || !wallet.IsSpentKey(hashTx, i))) {
- const CTxOut &txout = wtx.tx->vout[i];
+ for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
+ const CTxOut& txout = wtx.tx->vout[i];
+ if (!wallet.IsSpent(COutPoint(hashTx, i)) && (allow_used_addresses || !wallet.IsSpentKey(txout.scriptPubKey))) {
nCredit += OutputGetCredit(wallet, txout, filter);
if (!MoneyRange(nCredit))
throw std::runtime_error(std::string(__func__) + " : value out of range");
@@ -371,15 +370,15 @@ std::map<CTxDestination, CAmount> GetAddressBalances(const CWallet& wallet)
if (nDepth < (CachedTxIsFromMe(wallet, wtx, ISMINE_ALL) ? 0 : 1))
continue;
- for (unsigned int i = 0; i < wtx.tx->vout.size(); i++)
- {
+ for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
+ const auto& output = wtx.tx->vout[i];
CTxDestination addr;
- if (!wallet.IsMine(wtx.tx->vout[i]))
+ if (!wallet.IsMine(output))
continue;
- if(!ExtractDestination(wtx.tx->vout[i].scriptPubKey, addr))
+ if(!ExtractDestination(output.scriptPubKey, addr))
continue;
- CAmount n = wallet.IsSpent(walletEntry.first, i) ? 0 : wtx.tx->vout[i].nValue;
+ CAmount n = wallet.IsSpent(COutPoint(walletEntry.first, i)) ? 0 : output.nValue;
balances[addr] += n;
}
}
diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp
index 2649fa586c..ad59cc94ff 100644
--- a/src/wallet/rpc/coins.cpp
+++ b/src/wallet/rpc/coins.cpp
@@ -341,11 +341,11 @@ RPCHelpMan lockunspent()
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");
}
- if (pwallet->IsSpent(outpt.hash, outpt.n)) {
+ if (pwallet->IsSpent(outpt)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");
}
- const bool is_locked = pwallet->IsLockedCoin(outpt.hash, outpt.n);
+ const bool is_locked = pwallet->IsLockedCoin(outpt);
if (fUnlock && !is_locked) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");
@@ -638,7 +638,7 @@ RPCHelpMan listunspent()
cctl.m_max_depth = nMaxDepth;
cctl.m_include_unsafe_inputs = include_unsafe;
LOCK(pwallet->cs_wallet);
- AvailableCoinsListUnspent(*pwallet, vecOutputs, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount);
+ vecOutputs = AvailableCoinsListUnspent(*pwallet, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount).coins;
}
LOCK(pwallet->cs_wallet);
@@ -649,7 +649,7 @@ RPCHelpMan listunspent()
CTxDestination address;
const CScript& scriptPubKey = out.txout.scriptPubKey;
bool fValidAddress = ExtractDestination(scriptPubKey, address);
- bool reused = avoid_reuse && pwallet->IsSpentKey(out.outpoint.hash, out.outpoint.n);
+ bool reused = avoid_reuse && pwallet->IsSpentKey(scriptPubKey);
if (destinations.size() && (!fValidAddress || !destinations.count(address)))
continue;
diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp
index d1a0ba50f6..0e8cee5db8 100644
--- a/src/wallet/rpc/spend.cpp
+++ b/src/wallet/rpc/spend.cpp
@@ -535,8 +535,8 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
},
true, true);
- if (options.exists("add_inputs") ) {
- coinControl.m_add_inputs = options["add_inputs"].get_bool();
+ if (options.exists("add_inputs")) {
+ coinControl.m_allow_other_inputs = options["add_inputs"].get_bool();
}
if (options.exists("changeAddress") || options.exists("change_address")) {
@@ -699,19 +699,6 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
setSubtractFeeFromOutputs.insert(pos);
}
- // Fetch specified UTXOs from the UTXO set to get the scriptPubKeys and values of the outputs being selected
- // and to match with the given solving_data. Only used for non-wallet outputs.
- std::map<COutPoint, Coin> coins;
- for (const CTxIn& txin : tx.vin) {
- coins[txin.prevout]; // Create empty map entry keyed by prevout.
- }
- wallet.chain().findCoins(coins);
- for (const auto& coin : coins) {
- if (!coin.second.out.IsNull()) {
- coinControl.SelectExternal(coin.first, coin.second.out);
- }
- }
-
bilingual_str error;
if (!FundTransaction(wallet, tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
@@ -836,7 +823,7 @@ RPCHelpMan fundrawtransaction()
int change_position;
CCoinControl coin_control;
// Automatically select (additional) coins. Can be overridden by options.add_inputs.
- coin_control.m_add_inputs = true;
+ coin_control.m_allow_other_inputs = true;
FundTransaction(*pwallet, tx, fee, change_position, request.params[1], coin_control, /*override_min_fee=*/true);
UniValue result(UniValue::VOBJ);
@@ -1238,7 +1225,7 @@ RPCHelpMan send()
CCoinControl coin_control;
// Automatically select coins, unless at least one is manually selected. Can
// be overridden by options.add_inputs.
- coin_control.m_add_inputs = rawTx.vin.size() == 0;
+ coin_control.m_allow_other_inputs = rawTx.vin.size() == 0;
SetOptionsInputWeights(options["inputs"], options);
FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control, /*override_min_fee=*/false);
@@ -1380,7 +1367,6 @@ RPCHelpMan sendall()
CMutableTransaction rawTx{ConstructTransaction(options["inputs"], recipient_key_value_pairs, options["locktime"], rbf)};
LOCK(pwallet->cs_wallet);
- std::vector<COutput> all_the_utxos;
CAmount total_input_value(0);
bool send_max{options.exists("send_max") ? options["send_max"].get_bool() : false};
@@ -1388,7 +1374,7 @@ RPCHelpMan sendall()
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine send_max with specific inputs.");
} else if (options.exists("inputs")) {
for (const CTxIn& input : rawTx.vin) {
- if (pwallet->IsSpent(input.prevout.hash, input.prevout.n)) {
+ if (pwallet->IsSpent(input.prevout)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not available. UTXO (%s:%d) was already spent.", input.prevout.hash.ToString(), input.prevout.n));
}
const CWalletTx* tx{pwallet->GetWalletTx(input.prevout.hash)};
@@ -1398,8 +1384,7 @@ RPCHelpMan sendall()
total_input_value += tx->tx->vout[input.prevout.n].nValue;
}
} else {
- AvailableCoins(*pwallet, all_the_utxos, &coin_control, fee_rate, /*nMinimumAmount=*/0);
- for (const COutput& output : all_the_utxos) {
+ for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, /*nMinimumAmount=*/0).coins) {
CHECK_NONFATAL(output.input_bytes > 0);
if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) {
continue;
@@ -1664,7 +1649,7 @@ RPCHelpMan walletcreatefundedpsbt()
CCoinControl coin_control;
// Automatically select coins, unless at least one is manually selected. Can
// be overridden by options.add_inputs.
- coin_control.m_add_inputs = rawTx.vin.size() == 0;
+ coin_control.m_allow_other_inputs = rawTx.vin.size() == 0;
SetOptionsInputWeights(request.params[0], options);
FundTransaction(wallet, rawTx, fee, change_position, options, coin_control, /*override_min_fee=*/true);
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index 6f79ae4e9b..5799a9ff2a 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -84,12 +84,18 @@ TxSize CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *walle
return CalculateMaximumSignedTxSize(tx, wallet, txouts, coin_control);
}
-void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const CCoinControl* coinControl, std::optional<CFeeRate> feerate, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount)
+CoinsResult AvailableCoins(const CWallet& wallet,
+ const CCoinControl* coinControl,
+ std::optional<CFeeRate> feerate,
+ const CAmount& nMinimumAmount,
+ const CAmount& nMaximumAmount,
+ const CAmount& nMinimumSumAmount,
+ const uint64_t nMaximumCount,
+ bool only_spendable)
{
AssertLockHeld(wallet.cs_wallet);
- vCoins.clear();
- CAmount nTotal = 0;
+ CoinsResult result;
// Either the WALLET_FLAG_AVOID_REUSE flag is not set (in which case we always allow), or we default to avoiding, and only in the case where
// a coin control object is provided, and has the avoid address reuse flag set to false, do we allow already used addresses
bool allow_used_addresses = !wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE) || (coinControl && !coinControl->m_avoid_address_reuse);
@@ -159,76 +165,75 @@ void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const C
bool tx_from_me = CachedTxIsFromMe(wallet, wtx, ISMINE_ALL);
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
- // Only consider selected coins if add_inputs is false
- if (coinControl && !coinControl->m_add_inputs && !coinControl->IsSelected(COutPoint(entry.first, i))) {
- continue;
- }
+ const CTxOut& output = wtx.tx->vout[i];
+ const COutPoint outpoint(wtxid, i);
- if (wtx.tx->vout[i].nValue < nMinimumAmount || wtx.tx->vout[i].nValue > nMaximumAmount)
+ if (output.nValue < nMinimumAmount || output.nValue > nMaximumAmount)
continue;
- if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint(entry.first, i)))
+ if (coinControl && coinControl->HasSelected() && !coinControl->m_allow_other_inputs && !coinControl->IsSelected(outpoint))
continue;
- if (wallet.IsLockedCoin(entry.first, i))
+ if (wallet.IsLockedCoin(outpoint))
continue;
- if (wallet.IsSpent(wtxid, i))
+ if (wallet.IsSpent(outpoint))
continue;
- isminetype mine = wallet.IsMine(wtx.tx->vout[i]);
+ isminetype mine = wallet.IsMine(output);
if (mine == ISMINE_NO) {
continue;
}
- if (!allow_used_addresses && wallet.IsSpentKey(wtxid, i)) {
+ if (!allow_used_addresses && wallet.IsSpentKey(output.scriptPubKey)) {
continue;
}
- std::unique_ptr<SigningProvider> provider = wallet.GetSolvingProvider(wtx.tx->vout[i].scriptPubKey);
+ std::unique_ptr<SigningProvider> provider = wallet.GetSolvingProvider(output.scriptPubKey);
- bool solvable = provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey) : false;
+ bool solvable = provider ? IsSolvable(*provider, output.scriptPubKey) : false;
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
- int input_bytes = GetTxSpendSize(wallet, wtx, i, (coinControl && coinControl->fAllowWatchOnly));
- vCoins.emplace_back(COutPoint(wtx.GetHash(), i), wtx.tx->vout.at(i), nDepth, input_bytes, spendable, solvable, safeTx, wtx.GetTxTime(), tx_from_me, feerate);
+ // Filter by spendable outputs only
+ if (!spendable && only_spendable) continue;
+
+ int input_bytes = GetTxSpendSize(wallet, wtx, i, (coinControl && coinControl->fAllowWatchOnly));
+ result.coins.emplace_back(outpoint, output, nDepth, input_bytes, spendable, solvable, safeTx, wtx.GetTxTime(), tx_from_me, feerate);
+ result.total_amount += output.nValue;
// Checks the sum amount of all UTXO's.
if (nMinimumSumAmount != MAX_MONEY) {
- nTotal += wtx.tx->vout[i].nValue;
-
- if (nTotal >= nMinimumSumAmount) {
- return;
+ if (result.total_amount >= nMinimumSumAmount) {
+ return result;
}
}
// Checks the maximum number of UTXO's.
- if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
- return;
+ if (nMaximumCount > 0 && result.coins.size() >= nMaximumCount) {
+ return result;
}
}
}
+
+ return result;
}
-void AvailableCoinsListUnspent(const CWallet& wallet, std::vector<COutput>& vCoins, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount)
+CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount)
{
- AvailableCoins(wallet, vCoins, coinControl, /*feerate=*/ std::nullopt, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount);
+ return AvailableCoins(wallet, coinControl, /*feerate=*/ std::nullopt, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, /*only_spendable=*/false);
}
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl)
{
LOCK(wallet.cs_wallet);
-
- CAmount balance = 0;
- std::vector<COutput> vCoins;
- AvailableCoinsListUnspent(wallet, vCoins, coinControl);
- for (const COutput& out : vCoins) {
- if (out.spendable) {
- balance += out.txout.nValue;
- }
- }
- return balance;
+ return AvailableCoins(wallet, coinControl,
+ /*feerate=*/ std::nullopt,
+ /*nMinimumAmount=*/ 1,
+ /*nMaximumAmount=*/ MAX_MONEY,
+ /*nMinimumSumAmount=*/ MAX_MONEY,
+ /*nMaximumCount=*/ 0
+ ).total_amount;
}
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output)
@@ -260,11 +265,8 @@ std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet)
AssertLockHeld(wallet.cs_wallet);
std::map<CTxDestination, std::vector<COutput>> result;
- std::vector<COutput> availableCoins;
- AvailableCoinsListUnspent(wallet, availableCoins);
-
- for (const COutput& coin : availableCoins) {
+ for (const COutput& coin : AvailableCoinsListUnspent(wallet).coins) {
CTxDestination address;
if ((coin.spendable || (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && coin.solvable)) &&
ExtractDestination(FindNonChangeParentOutput(wallet, coin.outpoint).scriptPubKey, address)) {
@@ -431,23 +433,6 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
OutputGroup preset_inputs(coin_selection_params);
- // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
- if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs)
- {
- for (const COutput& out : vCoins) {
- if (!out.spendable) continue;
- /* Set ancestors and descendants to 0 as these don't matter for preset inputs as no actual selection is being done.
- * positive_only is set to false because we want to include all preset inputs, even if they are dust.
- */
- preset_inputs.Insert(out, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
- }
- SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
- result.AddInput(preset_inputs);
- if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
- result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
- return result;
- }
-
// calculate value from preset inputs and store them
std::set<COutPoint> preset_coins;
@@ -456,15 +441,14 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
for (const COutPoint& outpoint : vPresetInputs) {
int input_bytes = -1;
CTxOut txout;
- std::map<uint256, CWalletTx>::const_iterator it = wallet.mapWallet.find(outpoint.hash);
- if (it != wallet.mapWallet.end()) {
- const CWalletTx& wtx = it->second;
+ auto ptr_wtx = wallet.GetWalletTx(outpoint.hash);
+ if (ptr_wtx) {
// Clearly invalid input, fail
- if (wtx.tx->vout.size() <= outpoint.n) {
+ if (ptr_wtx->tx->vout.size() <= outpoint.n) {
return std::nullopt;
}
- input_bytes = GetTxSpendSize(wallet, wtx, outpoint.n, false);
- txout = wtx.tx->vout.at(outpoint.n);
+ input_bytes = GetTxSpendSize(wallet, *ptr_wtx, outpoint.n, false);
+ txout = ptr_wtx->tx->vout.at(outpoint.n);
} else {
// The input is external. We did not find the tx in mapWallet.
if (!coin_control.GetExternalOutput(outpoint, txout)) {
@@ -495,6 +479,15 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
preset_inputs.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
}
+ // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
+ if (coin_control.HasSelected() && !coin_control.m_allow_other_inputs) {
+ SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
+ result.AddInput(preset_inputs);
+ if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
+ result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
+ return result;
+ }
+
// remove preset inputs from vCoins so that Coin Selection doesn't pick them.
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
{
@@ -791,11 +784,16 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
CAmount selection_target = recipients_sum + not_input_fees;
// Get available coins
- std::vector<COutput> vAvailableCoins;
- AvailableCoins(wallet, vAvailableCoins, &coin_control, coin_selection_params.m_effective_feerate, 1, MAX_MONEY, MAX_MONEY, 0);
+ auto res_available_coins = AvailableCoins(wallet,
+ &coin_control,
+ coin_selection_params.m_effective_feerate,
+ 1, /*nMinimumAmount*/
+ MAX_MONEY, /*nMaximumAmount*/
+ MAX_MONEY, /*nMinimumSumAmount*/
+ 0); /*nMaximumCount*/
// Choose coins to use
- std::optional<SelectionResult> result = SelectCoins(wallet, vAvailableCoins, /*nTargetValue=*/selection_target, coin_control, coin_selection_params);
+ std::optional<SelectionResult> result = SelectCoins(wallet, res_available_coins.coins, /*nTargetValue=*/selection_target, coin_control, coin_selection_params);
if (!result) {
error = _("Insufficient funds");
return std::nullopt;
@@ -1021,15 +1019,27 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet,
vecSend.push_back(recipient);
}
- coinControl.fAllowOtherInputs = true;
+ // Acquire the locks to prevent races to the new locked unspents between the
+ // CreateTransaction call and LockCoin calls (when lockUnspents is true).
+ LOCK(wallet.cs_wallet);
+ // Fetch specified UTXOs from the UTXO set to get the scriptPubKeys and values of the outputs being selected
+ // and to match with the given solving_data. Only used for non-wallet outputs.
+ std::map<COutPoint, Coin> coins;
for (const CTxIn& txin : tx.vin) {
- coinControl.Select(txin.prevout);
+ coins[txin.prevout]; // Create empty map entry keyed by prevout.
}
+ wallet.chain().findCoins(coins);
- // Acquire the locks to prevent races to the new locked unspents between the
- // CreateTransaction call and LockCoin calls (when lockUnspents is true).
- LOCK(wallet.cs_wallet);
+ for (const CTxIn& txin : tx.vin) {
+ // if it's not in the wallet and corresponding UTXO is found than select as external output
+ const auto& outPoint = txin.prevout;
+ if (wallet.mapWallet.find(outPoint.hash) == wallet.mapWallet.end() && !coins[outPoint].out.IsNull()) {
+ coinControl.SelectExternal(outPoint, coins[outPoint].out);
+ } else {
+ coinControl.Select(outPoint);
+ }
+ }
FeeCalculation fee_calc_out;
std::optional<CreatedTransactionResult> txr = CreateTransaction(wallet, vecSend, nChangePosInOut, error, coinControl, fee_calc_out, false);
diff --git a/src/wallet/spend.h b/src/wallet/spend.h
index 988058a25a..cba42d6fae 100644
--- a/src/wallet/spend.h
+++ b/src/wallet/spend.h
@@ -34,16 +34,29 @@ struct TxSize {
TxSize CalculateMaximumSignedTxSize(const CTransaction& tx, const CWallet* wallet, const std::vector<CTxOut>& txouts, const CCoinControl* coin_control = nullptr);
TxSize CalculateMaximumSignedTxSize(const CTransaction& tx, const CWallet* wallet, const CCoinControl* coin_control = nullptr) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet);
+struct CoinsResult {
+ std::vector<COutput> coins;
+ // Sum of all the coins amounts
+ CAmount total_amount{0};
+};
/**
- * populate vCoins with vector of available COutputs.
+ * Return vector of available COutputs.
+ * By default, returns only the spendable coins.
*/
-void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const CCoinControl* coinControl = nullptr, std::optional<CFeeRate> feerate = std::nullopt, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
+CoinsResult AvailableCoins(const CWallet& wallet,
+ const CCoinControl* coinControl = nullptr,
+ std::optional<CFeeRate> feerate = std::nullopt,
+ const CAmount& nMinimumAmount = 1,
+ const CAmount& nMaximumAmount = MAX_MONEY,
+ const CAmount& nMinimumSumAmount = MAX_MONEY,
+ const uint64_t nMaximumCount = 0,
+ bool only_spendable = true) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
/**
* Wrapper function for AvailableCoins which skips the `feerate` parameter. Use this function
* to list all available coins (e.g. listunspent RPC) while not intending to fund a transaction.
*/
-void AvailableCoinsListUnspent(const CWallet& wallet, std::vector<COutput>& vCoins, const CCoinControl* coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
+CoinsResult AvailableCoinsListUnspent(const CWallet& wallet, const CCoinControl* coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinControl = nullptr);
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index 76f28917a4..d6f47e9954 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -336,7 +336,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
add_coin(coins, *wallet, 3 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
add_coin(coins, *wallet, 2 * CENT, coin_selection_params_bnb.m_effective_feerate, 6 * 24, false, 0, true);
CCoinControl coin_control;
- coin_control.fAllowOtherInputs = true;
+ coin_control.m_allow_other_inputs = true;
coin_control.Select(coins.at(0).outpoint);
coin_selection_params_bnb.m_effective_feerate = CFeeRate(0);
const auto result10 = SelectCoins(*wallet, coins, 10 * CENT, coin_control, coin_selection_params_bnb);
@@ -392,7 +392,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
expected_result.Clear();
add_coin(9 * CENT, 2, expected_result);
add_coin(1 * CENT, 2, expected_result);
- coin_control.fAllowOtherInputs = true;
+ coin_control.m_allow_other_inputs = true;
coin_control.Select(coins.at(1).outpoint); // pre select 9 coin
const auto result13 = SelectCoins(*wallet, coins, 10 * CENT, coin_control, coin_selection_params_bnb);
BOOST_CHECK(EquivalentResult(expected_result, *result13));
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 70863f5464..0c03b2f4a2 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -583,9 +583,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup)
// Lock both coins. Confirm number of available coins drops to 0.
{
LOCK(wallet->cs_wallet);
- std::vector<COutput> available;
- AvailableCoinsListUnspent(*wallet, available);
- BOOST_CHECK_EQUAL(available.size(), 2U);
+ BOOST_CHECK_EQUAL(AvailableCoinsListUnspent(*wallet).coins.size(), 2U);
}
for (const auto& group : list) {
for (const auto& coin : group.second) {
@@ -595,9 +593,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup)
}
{
LOCK(wallet->cs_wallet);
- std::vector<COutput> available;
- AvailableCoinsListUnspent(*wallet, available);
- BOOST_CHECK_EQUAL(available.size(), 0U);
+ BOOST_CHECK_EQUAL(AvailableCoinsListUnspent(*wallet).coins.size(), 0U);
}
// Confirm ListCoins still returns same result as before, despite coins
// being locked.
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 910562e669..ea306183ef 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -629,14 +629,12 @@ void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> ran
* Outpoint is spent if any non-conflicted transaction
* spends it:
*/
-bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
+bool CWallet::IsSpent(const COutPoint& outpoint) const
{
- const COutPoint outpoint(hash, n);
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
range = mapTxSpends.equal_range(outpoint);
- for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
- {
+ for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
const uint256& wtxid = it->second;
std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
if (mit != mapWallet.end()) {
@@ -908,35 +906,31 @@ void CWallet::SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned
}
}
-bool CWallet::IsSpentKey(const uint256& hash, unsigned int n) const
+bool CWallet::IsSpentKey(const CScript& scriptPubKey) const
{
AssertLockHeld(cs_wallet);
- const CWalletTx* srctx = GetWalletTx(hash);
- if (srctx) {
- assert(srctx->tx->vout.size() > n);
- CTxDestination dest;
- if (!ExtractDestination(srctx->tx->vout[n].scriptPubKey, dest)) {
- return false;
- }
- if (IsAddressUsed(dest)) {
- return true;
- }
- if (IsLegacy()) {
- LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
- assert(spk_man != nullptr);
- for (const auto& keyid : GetAffectedKeys(srctx->tx->vout[n].scriptPubKey, *spk_man)) {
- WitnessV0KeyHash wpkh_dest(keyid);
- if (IsAddressUsed(wpkh_dest)) {
- return true;
- }
- ScriptHash sh_wpkh_dest(GetScriptForDestination(wpkh_dest));
- if (IsAddressUsed(sh_wpkh_dest)) {
- return true;
- }
- PKHash pkh_dest(keyid);
- if (IsAddressUsed(pkh_dest)) {
- return true;
- }
+ CTxDestination dest;
+ if (!ExtractDestination(scriptPubKey, dest)) {
+ return false;
+ }
+ if (IsAddressUsed(dest)) {
+ return true;
+ }
+ if (IsLegacy()) {
+ LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
+ assert(spk_man != nullptr);
+ for (const auto& keyid : GetAffectedKeys(scriptPubKey, *spk_man)) {
+ WitnessV0KeyHash wpkh_dest(keyid);
+ if (IsAddressUsed(wpkh_dest)) {
+ return true;
+ }
+ ScriptHash sh_wpkh_dest(GetScriptForDestination(wpkh_dest));
+ if (IsAddressUsed(sh_wpkh_dest)) {
+ return true;
+ }
+ PKHash pkh_dest(keyid);
+ if (IsAddressUsed(pkh_dest)) {
+ return true;
}
}
}
@@ -2450,12 +2444,10 @@ bool CWallet::UnlockAllCoins()
return success;
}
-bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
+bool CWallet::IsLockedCoin(const COutPoint& output) const
{
AssertLockHeld(cs_wallet);
- COutPoint outpt(hash, n);
-
- return (setLockedCoins.count(outpt) > 0);
+ return setLockedCoins.count(output) > 0;
}
void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 7da601c3b7..a75b6981e1 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -441,16 +441,16 @@ public:
//! check whether we support the named feature
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return IsFeatureSupported(nWalletVersion, wf); }
- bool IsSpent(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool IsSpent(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- // Whether this or any known UTXO with the same single key has been spent.
- bool IsSpentKey(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ // Whether this or any known scriptPubKey with the same single key has been spent.
+ bool IsSpentKey(const CScript& scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
/** Display address on an external signer. Returns false if external signer support is not compiled */
bool DisplayAddress(const CTxDestination& dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
+ bool IsLockedCoin(const COutPoint& output) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool LockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool UnlockCoin(const COutPoint& output, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index 716ee8f7ef..1ad3fc24c9 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -43,7 +43,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
if self.is_bdb_compiled():
self.final = node2.getnewaddress()
else:
- self.final = getnewdestination()[2]
+ self.final = getnewdestination('bech32')[2]
def run_test(self):
node0, node1, node2 = self.nodes
@@ -66,9 +66,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
# Test mixed compressed and uncompressed pubkeys
self.log.info('Mixed compressed and uncompressed multisigs are not allowed')
- pk0 = getnewdestination()[0].hex()
- pk1 = getnewdestination()[0].hex()
- pk2 = getnewdestination()[0].hex()
+ pk0, pk1, pk2 = [getnewdestination('bech32')[0].hex() for _ in range(3)]
# decompress pk2
pk_obj = ECPubKey()
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 759e43194b..948deaaec4 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -11,6 +11,9 @@ from math import ceil
from test_framework.descriptors import descsum_create
from test_framework.key import ECKey
+from test_framework.messages import (
+ COIN,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_approx,
@@ -103,6 +106,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.generate(self.nodes[2], 1)
self.generate(self.nodes[0], 121)
+ self.test_weight_calculation()
self.test_change_position()
self.test_simple()
self.test_simple_two_coins()
@@ -1069,6 +1073,27 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[2].unloadwallet("extfund")
+ def test_weight_calculation(self):
+ self.log.info("Test weight calculation with external inputs")
+
+ self.nodes[2].createwallet("test_weight_calculation")
+ wallet = self.nodes[2].get_wallet_rpc("test_weight_calculation")
+
+ addr = wallet.getnewaddress()
+ txid = self.nodes[0].sendtoaddress(addr, 5)
+ vout = find_vout_for_address(self.nodes[0], txid, addr)
+
+ self.nodes[0].sendtoaddress(wallet.getnewaddress(), 5)
+ self.generate(self.nodes[0], 1)
+
+ rawtx = wallet.createrawtransaction([{'txid': txid, 'vout': vout}], [{self.nodes[0].getnewaddress(): 9.999}])
+ fundedtx = wallet.fundrawtransaction(rawtx, {'fee_rate': 10})
+ # with 71-byte signatures we should expect following tx size
+ tx_size = 10 + 41*2 + 31*2 + (2 + 107*2)/4
+ assert_equal(fundedtx['fee'] * COIN, tx_size * 10)
+
+ self.nodes[2].unloadwallet("test_weight_calculation")
+
def test_include_unsafe(self):
self.log.info("Test fundrawtxn with unsafe inputs")
diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py
index fcea24655b..92244b5ed8 100644
--- a/test/functional/test_framework/address.py
+++ b/test/functional/test_framework/address.py
@@ -47,8 +47,7 @@ def create_deterministic_address_bcrt1_p2tr_op_true():
Returns a tuple with the generated address and the internal key.
"""
internal_key = (1).to_bytes(32, 'big')
- scriptPubKey = taproot_construct(internal_key, [(None, CScript([OP_TRUE]))]).scriptPubKey
- address = encode_segwit_address("bcrt", 1, scriptPubKey[2:])
+ address = output_key_to_p2tr(taproot_construct(internal_key, [(None, CScript([OP_TRUE]))]).output_pubkey)
assert_equal(address, 'bcrt1p9yfmy5h72durp7zrhlw9lf7jpwjgvwdg0jr0lqmmjtgg83266lqsekaqka')
return (address, internal_key)
@@ -141,6 +140,10 @@ def script_to_p2sh_p2wsh(script, main=False):
p2shscript = CScript([OP_0, sha256(script)])
return script_to_p2sh(p2shscript, main)
+def output_key_to_p2tr(key, main=False):
+ assert len(key) == 32
+ return program_to_witness(1, key, main)
+
def check_key(key):
if (type(key) is str):
key = bytes.fromhex(key) # Assuming this is hex string
diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py
index f7d8422eee..b114002145 100755
--- a/test/functional/test_framework/script_util.py
+++ b/test/functional/test_framework/script_util.py
@@ -105,6 +105,11 @@ def script_to_p2sh_p2wsh_script(script):
return script_to_p2sh_script(p2shscript)
+def output_key_to_p2tr_script(key):
+ assert len(key) == 32
+ return program_to_witness_script(1, key)
+
+
def check_key(key):
if isinstance(key, str):
key = bytes.fromhex(key) # Assuming this is hex string
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index 93f3ea9e81..7249e53676 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -19,9 +19,13 @@ from test_framework.address import (
key_to_p2pkh,
key_to_p2sh_p2wpkh,
key_to_p2wpkh,
+ output_key_to_p2tr,
)
from test_framework.descriptors import descsum_create
-from test_framework.key import ECKey
+from test_framework.key import (
+ ECKey,
+ compute_xonly_pubkey,
+)
from test_framework.messages import (
COIN,
COutPoint,
@@ -38,6 +42,7 @@ from test_framework.script import (
OP_NOP,
OP_TRUE,
SIGHASH_ALL,
+ taproot_construct,
)
from test_framework.script_util import (
key_to_p2pk_script,
@@ -81,8 +86,7 @@ class MiniWallet:
def __init__(self, test_node, *, mode=MiniWalletMode.ADDRESS_OP_TRUE):
self._test_node = test_node
self._utxos = []
- self._priv_key = None
- self._address = None
+ self._mode = mode
assert isinstance(mode, MiniWalletMode)
if mode == MiniWalletMode.RAW_OP_TRUE:
@@ -116,7 +120,7 @@ class MiniWallet:
def sign_tx(self, tx, fixed_length=True):
"""Sign tx that has been created by MiniWallet in P2PK mode"""
- assert self._priv_key is not None
+ assert_equal(self._mode, MiniWalletMode.RAW_P2PK)
(sighash, err) = LegacySignatureHash(CScript(self._scriptPubKey), tx, 0, SIGHASH_ALL)
assert err is None
# for exact fee calculation, create only signatures with fixed size by default (>49.89% probability):
@@ -146,6 +150,7 @@ class MiniWallet:
return descsum_create(f'raw({self._scriptPubKey.hex()})')
def get_address(self):
+ assert_equal(self._mode, MiniWalletMode.ADDRESS_OP_TRUE)
return self._address
def get_utxo(self, *, txid: str = '', vout: Optional[int] = None, mark_as_spent=True) -> dict:
@@ -252,10 +257,12 @@ class MiniWallet:
"""Create and return a tx with the specified fee_rate. Fee may be exact or at most one satoshi higher than needed."""
from_node = from_node or self._test_node
utxo_to_spend = utxo_to_spend or self.get_utxo()
- if self._priv_key is None:
+ if self._mode in (MiniWalletMode.RAW_OP_TRUE, MiniWalletMode.ADDRESS_OP_TRUE):
vsize = Decimal(104) # anyone-can-spend
- else:
+ elif self._mode == MiniWalletMode.RAW_P2PK:
vsize = Decimal(168) # P2PK (73 bytes scriptSig + 35 bytes scriptPubKey + 60 bytes other)
+ else:
+ assert False
send_value = int(COIN * (utxo_to_spend['value'] - fee_rate * (vsize / 1000)))
assert send_value > 0
@@ -263,17 +270,15 @@ class MiniWallet:
tx.vin = [CTxIn(COutPoint(int(utxo_to_spend['txid'], 16), utxo_to_spend['vout']), nSequence=sequence)]
tx.vout = [CTxOut(send_value, self._scriptPubKey)]
tx.nLockTime = locktime
- if not self._address:
- # raw script
- if self._priv_key is not None:
- # P2PK, need to sign
- self.sign_tx(tx)
- else:
- # anyone-can-spend
- tx.vin[0].scriptSig = CScript([OP_NOP] * 43) # pad to identical size
- else:
+ if self._mode == MiniWalletMode.RAW_P2PK:
+ self.sign_tx(tx)
+ elif self._mode == MiniWalletMode.RAW_OP_TRUE:
+ tx.vin[0].scriptSig = CScript([OP_NOP] * 43) # pad to identical size
+ elif self._mode == MiniWalletMode.ADDRESS_OP_TRUE:
tx.wit.vtxinwit = [CTxInWitness()]
tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE]), bytes([LEAF_VERSION_TAPSCRIPT]) + self._internal_key]
+ else:
+ assert False
tx_hex = tx.serialize().hex()
assert_equal(tx.get_vsize(), vsize)
@@ -286,10 +291,10 @@ class MiniWallet:
return txid
-def getnewdestination(address_type='bech32'):
+def getnewdestination(address_type='bech32m'):
"""Generate a random destination of the specified type and return the
corresponding public key, scriptPubKey and address. Supported types are
- 'legacy', 'p2sh-segwit' and 'bech32'. Can be used when a random
+ 'legacy', 'p2sh-segwit', 'bech32' and 'bech32m'. Can be used when a random
destination is needed, but no compiled wallet is available (e.g. as
replacement to the getnewaddress/getaddressinfo RPCs)."""
key = ECKey()
@@ -304,7 +309,11 @@ def getnewdestination(address_type='bech32'):
elif address_type == 'bech32':
scriptpubkey = key_to_p2wpkh_script(pubkey)
address = key_to_p2wpkh(pubkey)
- # TODO: also support bech32m (need to generate x-only-pubkey)
+ elif address_type == 'bech32m':
+ tap = taproot_construct(compute_xonly_pubkey(key.get_bytes())[0])
+ pubkey = tap.output_pubkey
+ scriptpubkey = tap.scriptPubKey
+ address = output_key_to_p2tr(pubkey)
else:
assert False
return pubkey, scriptpubkey, address
diff --git a/test/functional/wallet_taproot.py b/test/functional/wallet_taproot.py
index a4d836c8fe..d238c50bca 100755
--- a/test/functional/wallet_taproot.py
+++ b/test/functional/wallet_taproot.py
@@ -7,19 +7,18 @@
import random
from decimal import Decimal
+from test_framework.address import output_key_to_p2tr
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
from test_framework.descriptors import descsum_create
from test_framework.script import (
CScript,
MAX_PUBKEYS_PER_MULTI_A,
- OP_1,
OP_CHECKSIG,
OP_CHECKSIGADD,
OP_NUMEQUAL,
taproot_construct,
)
-from test_framework.segwit_addr import encode_segwit_address
# xprvs/xpubs, and m/* derived x-only pubkeys (created using independent implementation)
KEYS = [
@@ -183,10 +182,7 @@ def multi_a(k, hex_keys, sort=False):
def compute_taproot_address(pubkey, scripts):
"""Compute the address for a taproot output with given inner key and scripts."""
- tap = taproot_construct(pubkey, scripts)
- assert tap.scriptPubKey[0] == OP_1
- assert tap.scriptPubKey[1] == 0x20
- return encode_segwit_address("bcrt", 1, tap.scriptPubKey[2:])
+ return output_key_to_p2tr(taproot_construct(pubkey, scripts).output_pubkey)
class WalletTaprootTest(BitcoinTestFramework):
"""Test generation and spending of P2TR address outputs."""
diff --git a/test/lint/README.md b/test/lint/README.md
index a23211a72b..8d592c3282 100644
--- a/test/lint/README.md
+++ b/test/lint/README.md
@@ -28,7 +28,6 @@ To do a full check with `-r`, make sure that you have fetched the upstream repos
maintained:
* for `src/secp256k1`: https://github.com/bitcoin-core/secp256k1.git (branch master)
* for `src/leveldb`: https://github.com/bitcoin-core/leveldb-subtree.git (branch bitcoin-fork)
-* for `src/univalue`: https://github.com/bitcoin-core/univalue-subtree.git (branch master)
* for `src/crypto/ctaes`: https://github.com/bitcoin-core/ctaes.git (branch master)
* for `src/crc32c`: https://github.com/bitcoin-core/crc32c-subtree.git (branch bitcoin-fork)
* for `src/minisketch`: https://github.com/sipa/minisketch.git (branch master)
diff --git a/test/lint/lint-files.py b/test/lint/lint-files.py
index dbb51ce54e..123bee2cbc 100755
--- a/test/lint/lint-files.py
+++ b/test/lint/lint-files.py
@@ -21,7 +21,7 @@ ALL_SOURCE_FILENAMES_REGEXP = r"^.*\.(cpp|h|py|sh)$"
ALLOWED_FILENAME_REGEXP = "^[a-zA-Z0-9/_.@][a-zA-Z0-9/_.@-]*$"
ALLOWED_SOURCE_FILENAME_REGEXP = "^[a-z0-9_./-]+$"
ALLOWED_SOURCE_FILENAME_EXCEPTION_REGEXP = (
- "^src/(secp256k1/|minisketch/|univalue/|test/fuzz/FuzzedDataProvider.h)"
+ "^src/(secp256k1/|minisketch/|test/fuzz/FuzzedDataProvider.h)"
)
ALLOWED_PERMISSION_NON_EXECUTABLES = 0o644
ALLOWED_PERMISSION_EXECUTABLES = 0o755
diff --git a/test/lint/lint-format-strings.py b/test/lint/lint-format-strings.py
index 522023e328..f54126e023 100755
--- a/test/lint/lint-format-strings.py
+++ b/test/lint/lint-format-strings.py
@@ -77,7 +77,7 @@ def main():
matching_files_filtered = []
for matching_file in matching_files:
- if not re.search('^src/(leveldb|secp256k1|minisketch|tinyformat|univalue|test/fuzz/strprintf.cpp)', matching_file):
+ if not re.search('^src/(leveldb|secp256k1|minisketch|tinyformat|test/fuzz/strprintf.cpp)', matching_file):
matching_files_filtered.append(matching_file)
matching_files_filtered.sort()
diff --git a/test/lint/lint-include-guards.py b/test/lint/lint-include-guards.py
index 86284517d5..5867aae028 100755
--- a/test/lint/lint-include-guards.py
+++ b/test/lint/lint-include-guards.py
@@ -22,7 +22,6 @@ EXCLUDE_FILES_WITH_PREFIX = ['src/crypto/ctaes',
'src/crc32c',
'src/secp256k1',
'src/minisketch',
- 'src/univalue',
'src/tinyformat.h',
'src/bench/nanobench.h',
'src/test/fuzz/FuzzedDataProvider.h']
diff --git a/test/lint/lint-includes.py b/test/lint/lint-includes.py
index ae62994642..afdca0d418 100755
--- a/test/lint/lint-includes.py
+++ b/test/lint/lint-includes.py
@@ -19,7 +19,7 @@ EXCLUDED_DIRS = ["src/leveldb/",
"src/crc32c/",
"src/secp256k1/",
"src/minisketch/",
- "src/univalue/"]
+ ]
EXPECTED_BOOST_INCLUDES = ["boost/algorithm/string/replace.hpp",
"boost/date_time/posix_time/posix_time.hpp",
diff --git a/test/lint/lint-locale-dependence.py b/test/lint/lint-locale-dependence.py
index 9b2cf4587a..4876ac2e2d 100755
--- a/test/lint/lint-locale-dependence.py
+++ b/test/lint/lint-locale-dependence.py
@@ -60,7 +60,6 @@ REGEXP_EXTERNAL_DEPENDENCIES_EXCLUSIONS = [
"src/secp256k1/",
"src/minisketch/",
"src/tinyformat.h",
- "src/univalue/"
]
LOCALE_DEPENDENT_FUNCTIONS = [
diff --git a/test/lint/lint-shell-locale.py b/test/lint/lint-shell-locale.py
index f3dfe18a95..309c426374 100755
--- a/test/lint/lint-shell-locale.py
+++ b/test/lint/lint-shell-locale.py
@@ -41,7 +41,7 @@ def main():
exit_code = 0
shell_files = get_shell_files_list()
for file_path in shell_files:
- if re.search('src/(secp256k1|minisketch|univalue)/', file_path):
+ if re.search('src/(secp256k1|minisketch)/', file_path):
continue
with open(file_path, 'r', encoding='utf-8') as file_obj:
diff --git a/test/lint/lint-shell.py b/test/lint/lint-shell.py
index f1e4494350..ed95024ef5 100755
--- a/test/lint/lint-shell.py
+++ b/test/lint/lint-shell.py
@@ -68,7 +68,7 @@ def main():
]
files = get_files(files_cmd)
# remove everything that doesn't match this regex
- reg = re.compile(r'src/[leveldb,secp256k1,minisketch,univalue]')
+ reg = re.compile(r'src/[leveldb,secp256k1,minisketch]')
files[:] = [file for file in files if not reg.match(file)]
# build the `shellcheck` command
diff --git a/test/lint/lint-spelling.py b/test/lint/lint-spelling.py
index 5da1b243f7..14d7d13a75 100755
--- a/test/lint/lint-spelling.py
+++ b/test/lint/lint-spelling.py
@@ -12,7 +12,7 @@ Note: Will exit successfully regardless of spelling errors.
from subprocess import check_output, STDOUT, CalledProcessError
IGNORE_WORDS_FILE = 'test/lint/spelling.ignore-words.txt'
-FILES_ARGS = ['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/minisketch/", ":(exclude)src/univalue/", ":(exclude)contrib/builder-keys/keys.txt", ":(exclude)contrib/guix/patches"]
+FILES_ARGS = ['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/minisketch/", ":(exclude)contrib/builder-keys/keys.txt", ":(exclude)contrib/guix/patches"]
def check_codespell_install():
diff --git a/test/lint/lint-whitespace.py b/test/lint/lint-whitespace.py
index d98fc8d9a2..3fb5b80013 100755
--- a/test/lint/lint-whitespace.py
+++ b/test/lint/lint-whitespace.py
@@ -22,7 +22,6 @@ EXCLUDED_DIRS = ["depends/patches/",
"src/crc32c/",
"src/secp256k1/",
"src/minisketch/",
- "src/univalue/",
"doc/release-notes/",
"src/qt/locale"]