mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 19:37:27 -03:00
Compare commits
190 commits
8ed7f6325d
...
99d00833d0
Author | SHA1 | Date | |
---|---|---|---|
|
99d00833d0 | ||
|
66aa6a47bd | ||
|
2fb833e696 | ||
|
7c123c08dd | ||
|
433412fd84 | ||
|
c506f2cee7 | ||
|
41a2ce9b7d | ||
|
6475849c40 | ||
|
49fc2258cf | ||
|
ac918c7cc0 | ||
|
a0f0c48ae2 | ||
|
558783625c | ||
|
3e936789b1 | ||
|
5af642bf48 | ||
|
29bca9713d | ||
|
4036ee3f2b | ||
|
6aa0e70ccb | ||
|
3e0a992a3f | ||
|
604bf2ea37 | ||
|
04249682e3 | ||
|
fa0411ee30 | ||
|
2bdaf52ed1 | ||
|
34e8ee23b8 | ||
|
228aba2c4d | ||
|
9b9752217f | ||
|
87c9ebd889 | ||
|
df5c643f92 | ||
|
fa3de038f7 | ||
|
ba0cb7d5a5 | ||
|
69e35f5c60 | ||
|
17db84dbb8 | ||
|
e6f14241f6 | ||
|
a137b0bd6b | ||
|
67bfe28995 | ||
|
ad174c2817 | ||
|
b29d68f942 | ||
|
9355578a77 | ||
|
f95fb79372 | ||
|
bc43ecaf6d | ||
|
226d03dd61 | ||
|
fa63b8232f | ||
|
fa62c8b1f0 | ||
|
366ae00b77 | ||
|
e366408590 | ||
|
5709718b83 | ||
|
b0b8d96d93 | ||
|
fc7b214847 | ||
|
273440d5c9 | ||
|
4cdf50c4ba | ||
|
faf7eac364 | ||
|
fafa9cc7a5 | ||
|
fa044857ca | ||
|
63b6b638aa | ||
|
ecaa786cc1 | ||
|
e196190a28 | ||
|
bb57017b29 | ||
|
5bbbc0d0ee | ||
|
d9d5bc2e74 | ||
|
fa494a1d53 | ||
|
faaf4800aa | ||
|
faa5391f77 | ||
|
fa86223475 | ||
|
faae6fa5f6 | ||
|
facc4f120b | ||
|
fac3a782ea | ||
|
c1252b14d7 | ||
|
be1a2e5dfb | ||
|
fa0c473d4c | ||
|
ea53568a06 | ||
|
b8710201fb | ||
|
23b8a424fb | ||
|
0a76c292ac | ||
|
fadd568931 | ||
|
fa83bec78e | ||
|
4f06ae05ed | ||
|
366fbf152c | ||
|
c991cea1a0 | ||
|
9a47852d88 | ||
|
bfc4e029d4 | ||
|
477b357460 | ||
|
a60d5702fd | ||
|
a95a8ba3a3 | ||
|
cd3d9fa5ea | ||
|
785486a975 | ||
|
1251a23642 | ||
|
d2136d32bb | ||
|
58436d4af3 | ||
|
38dcf0f982 | ||
|
fae63bf130 | ||
|
81cea5d4ee | ||
|
e058544d0e | ||
|
f86678156a | ||
|
4d57288246 | ||
|
2e81791d90 | ||
|
39d3b538e6 | ||
|
fa18acb457 | ||
|
fa9e0489f5 | ||
|
46e207d329 | ||
|
a10bb400e8 | ||
|
3353d4a5e9 | ||
|
b9766c9977 | ||
|
b042c4f053 | ||
|
e8f0e6efaf | ||
|
facb4d010c | ||
|
2b9ff4a66d | ||
|
fa0e30b93a | ||
|
d73f37dda2 | ||
|
fa7809aeab | ||
|
78f1bff709 | ||
|
84890e0291 | ||
|
d5ab5a47f0 | ||
|
fa0998f0a0 | ||
|
fa9aacf614 | ||
|
beac62e541 | ||
|
5cd9e95eea | ||
|
df27ee9f02 | ||
|
435ad572a1 | ||
|
ea9e64ff3c | ||
|
29ddee1796 | ||
|
e2d3372e55 | ||
|
fa47baa03b | ||
|
015aad8d6a | ||
|
62bd61de11 | ||
|
676936845b | ||
|
8ad2c90274 | ||
|
a582ee681c | ||
|
fa397177ac | ||
|
b6f0593f43 | ||
|
f9cac63523 | ||
|
b7ec69c25c | ||
|
37e49c2c7c | ||
|
62b2d23edb | ||
|
9039d8f1a1 | ||
|
bb7e686341 | ||
|
f6496a8388 | ||
|
35000e34cf | ||
|
18d0cfb194 | ||
|
c93bf0e6e2 | ||
|
76cca4aa6f | ||
|
533013cba2 | ||
|
b81a465995 | ||
|
cdd207c0e4 | ||
|
297a876c98 | ||
|
932cd1e92b | ||
|
41d934c72d | ||
|
c9fb38a590 | ||
|
22723c809a | ||
|
b1f0f3c288 | ||
|
1a35447595 | ||
|
eb2ebe6f30 | ||
|
5b283fa147 | ||
|
37946c0aaf | ||
|
fa6e599cf9 | ||
|
2eccb8bc5e | ||
|
7239ddb7ce | ||
|
6d973f86f7 | ||
|
6a1e613e85 | ||
|
edb41e4814 | ||
|
31e59d94c6 | ||
|
fe9bc5abef | ||
|
083770adbe | ||
|
f6afca46a1 | ||
|
811a65d3c6 | ||
|
fae76393bd | ||
|
f9650e18ea | ||
|
221c789e91 | ||
|
0184d33b3d | ||
|
006e4d1d59 | ||
|
831d2bfcf9 | ||
|
058021969b | ||
|
52fd1511a7 | ||
|
ff41b9e296 | ||
|
7ab733ede4 | ||
|
0f84cdd266 | ||
|
cccca8a77f | ||
|
ee1b9bef00 | ||
|
06443b8f28 | ||
|
1d01ad4d73 | ||
|
937ef9eb40 | ||
|
ad224429f8 | ||
|
988721d37a | ||
|
55347a5018 | ||
|
1dd3af8fbc | ||
|
997757dd2b | ||
|
0e2b12b92a | ||
|
f42ec0f3bf | ||
|
a2c45ae548 | ||
|
97a18c8545 | ||
|
e56fc7ce6a | ||
|
ec777917d6 |
199 changed files with 1849 additions and 1026 deletions
|
@ -298,6 +298,15 @@ if(WIN32)
|
||||||
try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core_interface)
|
try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core_interface)
|
||||||
try_append_linker_flag("-Wl,--minor-subsystem-version,2" TARGET core_interface)
|
try_append_linker_flag("-Wl,--minor-subsystem-version,2" TARGET core_interface)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Workaround producing large object files, which cannot be handled by the assembler.
|
||||||
|
# More likely to happen with no, or lower levels of optimisation.
|
||||||
|
# See discussion in https://github.com/bitcoin/bitcoin/issues/28109.
|
||||||
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
try_append_cxx_flags("/bigobj" TARGET core_interface_debug SKIP_LINK)
|
||||||
|
else()
|
||||||
|
try_append_cxx_flags("-Wa,-mbig-obj" TARGET core_interface_debug SKIP_LINK)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use 64-bit off_t on 32-bit Linux.
|
# Use 64-bit off_t on 32-bit Linux.
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
"BUILD_GUI_TESTS": "ON",
|
"BUILD_GUI_TESTS": "ON",
|
||||||
"BUILD_KERNEL_LIB": "ON",
|
"BUILD_KERNEL_LIB": "ON",
|
||||||
"BUILD_SHARED_LIBS": "ON",
|
"BUILD_SHARED_LIBS": "ON",
|
||||||
"BUILD_TESTING": "ON",
|
|
||||||
"BUILD_TESTS": "ON",
|
"BUILD_TESTS": "ON",
|
||||||
"BUILD_TX": "ON",
|
"BUILD_TX": "ON",
|
||||||
"BUILD_UTIL": "ON",
|
"BUILD_UTIL": "ON",
|
||||||
|
|
|
@ -59,7 +59,7 @@ curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_
|
||||||
tar --xz -xf - --directory /tmp/
|
tar --xz -xf - --directory /tmp/
|
||||||
mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
|
mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
|
||||||
|
|
||||||
MLC_VERSION=v0.18.0
|
MLC_VERSION=v0.19.0
|
||||||
MLC_BIN=mlc-x86_64-linux
|
MLC_BIN=mlc-x86_64-linux
|
||||||
curl -sL "https://github.com/becheran/mlc/releases/download/${MLC_VERSION}/${MLC_BIN}" -o "/usr/bin/mlc"
|
curl -sL "https://github.com/becheran/mlc/releases/download/${MLC_VERSION}/${MLC_BIN}" -o "/usr/bin/mlc"
|
||||||
chmod +x /usr/bin/mlc
|
chmod +x /usr/bin/mlc
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# Copyright (c) 2020-2022 The Bitcoin Core developers
|
# Copyright (c) 2020-present The Bitcoin Core developers
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ export LC_ALL=C.UTF-8
|
||||||
export HOST=i686-pc-linux-gnu
|
export HOST=i686-pc-linux-gnu
|
||||||
export CONTAINER_NAME=ci_i686_centos
|
export CONTAINER_NAME=ci_i686_centos
|
||||||
export CI_IMAGE_NAME_TAG="quay.io/centos/amd64:stream9"
|
export CI_IMAGE_NAME_TAG="quay.io/centos/amd64:stream9"
|
||||||
export CI_BASE_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache make git python3 python3-pip which patch lbzip2 xz procps-ng dash rsync coreutils bison e2fsprogs cmake"
|
export STREAM_GCC_V="12"
|
||||||
|
export CI_BASE_PACKAGES="gcc-toolset-${STREAM_GCC_V}-gcc-c++ glibc-devel.x86_64 gcc-toolset-${STREAM_GCC_V}-libstdc++-devel.x86_64 glibc-devel.i686 gcc-toolset-${STREAM_GCC_V}-libstdc++-devel.i686 ccache make git python3 python3-pip which patch lbzip2 xz procps-ng dash rsync coreutils bison e2fsprogs cmake"
|
||||||
export PIP_PACKAGES="pyzmq"
|
export PIP_PACKAGES="pyzmq"
|
||||||
export GOAL="install"
|
export GOAL="install"
|
||||||
export NO_WERROR=1 # Suppress error: #warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform [-Werror=cpp]
|
|
||||||
export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DBUILD_GUI=ON -DREDUCE_EXPORTS=ON"
|
export BITCOIN_CONFIG="-DWITH_ZMQ=ON -DBUILD_GUI=ON -DREDUCE_EXPORTS=ON"
|
||||||
export CONFIG_SHELL="/bin/dash"
|
export CONFIG_SHELL="/bin/dash"
|
||||||
|
|
|
@ -27,4 +27,3 @@ export BITCOIN_CONFIG="\
|
||||||
-DAPPEND_CPPFLAGS='-U_FORTIFY_SOURCE' \
|
-DAPPEND_CPPFLAGS='-U_FORTIFY_SOURCE' \
|
||||||
"
|
"
|
||||||
export USE_MEMORY_SANITIZER="true"
|
export USE_MEMORY_SANITIZER="true"
|
||||||
export RUN_FUNCTIONAL_TESTS="false"
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ export LC_ALL=C.UTF-8
|
||||||
|
|
||||||
export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04"
|
export CI_IMAGE_NAME_TAG="docker.io/ubuntu:24.04"
|
||||||
export CONTAINER_NAME=ci_native_tidy
|
export CONTAINER_NAME=ci_native_tidy
|
||||||
export TIDY_LLVM_V="18"
|
export TIDY_LLVM_V="19"
|
||||||
|
export APT_LLVM_V="${TIDY_LLVM_V}"
|
||||||
export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq libevent-dev libboost-dev libzmq3-dev systemtap-sdt-dev qtbase5-dev qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev"
|
export PACKAGES="clang-${TIDY_LLVM_V} libclang-${TIDY_LLVM_V}-dev llvm-${TIDY_LLVM_V}-dev libomp-${TIDY_LLVM_V}-dev clang-tidy-${TIDY_LLVM_V} jq libevent-dev libboost-dev libzmq3-dev systemtap-sdt-dev qtbase5-dev qttools5-dev qttools5-dev-tools libqrencode-dev libsqlite3-dev libdb++-dev"
|
||||||
export NO_DEPENDS=1
|
export NO_DEPENDS=1
|
||||||
export RUN_UNIT_TESTS=false
|
export RUN_UNIT_TESTS=false
|
||||||
|
|
|
@ -49,7 +49,7 @@ if [ -n "$PIP_PACKAGES" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
|
if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then
|
||||||
${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-19.1.0" /msan/llvm-project
|
${CI_RETRY_EXE} git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-19.1.6" /msan/llvm-project
|
||||||
|
|
||||||
cmake -G Ninja -B /msan/clang_build/ \
|
cmake -G Ninja -B /msan/clang_build/ \
|
||||||
-DLLVM_ENABLE_PROJECTS="clang" \
|
-DLLVM_ENABLE_PROJECTS="clang" \
|
||||||
|
|
|
@ -93,6 +93,8 @@ fi
|
||||||
if [ -z "$NO_DEPENDS" ]; then
|
if [ -z "$NO_DEPENDS" ]; then
|
||||||
if [[ $CI_IMAGE_NAME_TAG == *centos* ]]; then
|
if [[ $CI_IMAGE_NAME_TAG == *centos* ]]; then
|
||||||
SHELL_OPTS="CONFIG_SHELL=/bin/dash"
|
SHELL_OPTS="CONFIG_SHELL=/bin/dash"
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
source "/opt/rh/gcc-toolset-${STREAM_GCC_V}/enable"
|
||||||
else
|
else
|
||||||
SHELL_OPTS="CONFIG_SHELL="
|
SHELL_OPTS="CONFIG_SHELL="
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -72,7 +72,8 @@ function(try_append_cxx_flags flags)
|
||||||
target_compile_options(${TACXXF_TARGET} INTERFACE ${TACXXF_IF_CHECK_PASSED})
|
target_compile_options(${TACXXF_TARGET} INTERFACE ${TACXXF_IF_CHECK_PASSED})
|
||||||
endif()
|
endif()
|
||||||
if(DEFINED TACXXF_VAR)
|
if(DEFINED TACXXF_VAR)
|
||||||
string(STRIP "${${TACXXF_VAR}} ${TACXXF_IF_CHECK_PASSED}" ${TACXXF_VAR})
|
list(JOIN TACXXF_IF_CHECK_PASSED " " flags_if_check_passed_as_string)
|
||||||
|
string(STRIP "${${TACXXF_VAR}} ${flags_if_check_passed_as_string}" ${TACXXF_VAR})
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
if(DEFINED TACXXF_TARGET)
|
if(DEFINED TACXXF_TARGET)
|
||||||
|
|
|
@ -48,7 +48,8 @@ function(try_append_linker_flag flag)
|
||||||
target_link_options(${TALF_TARGET} INTERFACE ${TALF_IF_CHECK_PASSED})
|
target_link_options(${TALF_TARGET} INTERFACE ${TALF_IF_CHECK_PASSED})
|
||||||
endif()
|
endif()
|
||||||
if(DEFINED TALF_VAR)
|
if(DEFINED TALF_VAR)
|
||||||
string(STRIP "${${TALF_VAR}} ${TALF_IF_CHECK_PASSED}" ${TALF_VAR})
|
list(JOIN TALF_IF_CHECK_PASSED " " flags_if_check_passed_as_string)
|
||||||
|
string(STRIP "${${TALF_VAR}} ${flags_if_check_passed_as_string}" ${TALF_VAR})
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
if(DEFINED TALF_TARGET)
|
if(DEFINED TALF_TARGET)
|
||||||
|
|
|
@ -6,7 +6,7 @@ cmake_path(GET JSON_SOURCE_PATH STEM json_source_basename)
|
||||||
|
|
||||||
file(READ ${JSON_SOURCE_PATH} hex_content HEX)
|
file(READ ${JSON_SOURCE_PATH} hex_content HEX)
|
||||||
string(REGEX REPLACE "................" "\\0\n" formatted_bytes "${hex_content}")
|
string(REGEX REPLACE "................" "\\0\n" formatted_bytes "${hex_content}")
|
||||||
string(REGEX REPLACE "[^\n][^\n]" "0x\\0, " formatted_bytes "${formatted_bytes}")
|
string(REGEX REPLACE "[^\n][^\n]" "'\\\\x\\0'," formatted_bytes "${formatted_bytes}")
|
||||||
|
|
||||||
set(header_content
|
set(header_content
|
||||||
"#include <string_view>
|
"#include <string_view>
|
||||||
|
|
|
@ -6,7 +6,7 @@ cmake_path(GET RAW_SOURCE_PATH STEM raw_source_basename)
|
||||||
|
|
||||||
file(READ ${RAW_SOURCE_PATH} hex_content HEX)
|
file(READ ${RAW_SOURCE_PATH} hex_content HEX)
|
||||||
string(REGEX REPLACE "................" "\\0\n" formatted_bytes "${hex_content}")
|
string(REGEX REPLACE "................" "\\0\n" formatted_bytes "${hex_content}")
|
||||||
string(REGEX REPLACE "[^\n][^\n]" "std::byte{0x\\0}, " formatted_bytes "${formatted_bytes}")
|
string(REGEX REPLACE "[^\n][^\n]" "std::byte{0x\\0}," formatted_bytes "${formatted_bytes}")
|
||||||
|
|
||||||
set(header_content
|
set(header_content
|
||||||
"#include <cstddef>
|
"#include <cstddef>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# Fixups / upstreamed changes
|
# Nothing for now.
|
||||||
[
|
[
|
||||||
{ include: [ "<bits/chrono.h>", private, "<chrono>", public ] },
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -420,6 +420,7 @@ inspecting signatures in Mach-O binaries.")
|
||||||
;; https://gcc.gnu.org/install/configure.html
|
;; https://gcc.gnu.org/install/configure.html
|
||||||
(list "--enable-threads=posix",
|
(list "--enable-threads=posix",
|
||||||
"--enable-default-ssp=yes",
|
"--enable-default-ssp=yes",
|
||||||
|
"--disable-gcov",
|
||||||
building-on)))))))
|
building-on)))))))
|
||||||
|
|
||||||
(define-public linux-base-gcc
|
(define-public linux-base-gcc
|
||||||
|
@ -435,6 +436,7 @@ inspecting signatures in Mach-O binaries.")
|
||||||
"--enable-default-pie=yes",
|
"--enable-default-pie=yes",
|
||||||
"--enable-standard-branch-protection=yes",
|
"--enable-standard-branch-protection=yes",
|
||||||
"--enable-cet=yes",
|
"--enable-cet=yes",
|
||||||
|
"--disable-gcov",
|
||||||
building-on)))
|
building-on)))
|
||||||
((#:phases phases)
|
((#:phases phases)
|
||||||
`(modify-phases ,phases
|
`(modify-phases ,phases
|
||||||
|
@ -449,7 +451,7 @@ inspecting signatures in Mach-O binaries.")
|
||||||
#t))))))))
|
#t))))))))
|
||||||
|
|
||||||
(define-public glibc-2.31
|
(define-public glibc-2.31
|
||||||
(let ((commit "8e30f03744837a85e33d84ccd34ed3abe30d37c3"))
|
(let ((commit "7b27c450c34563a28e634cccb399cd415e71ebfe"))
|
||||||
(package
|
(package
|
||||||
(inherit glibc) ;; 2.35
|
(inherit glibc) ;; 2.35
|
||||||
(version "2.31")
|
(version "2.31")
|
||||||
|
@ -461,7 +463,7 @@ inspecting signatures in Mach-O binaries.")
|
||||||
(file-name (git-file-name "glibc" commit))
|
(file-name (git-file-name "glibc" commit))
|
||||||
(sha256
|
(sha256
|
||||||
(base32
|
(base32
|
||||||
"1zi0s9yy5zkisw823vivn7zlj8w6g9p3mm7lmlqiixcxdkz4dbn6"))
|
"017qdpr5id7ddb4lpkzj2li1abvw916m3fc6n7nw28z4h5qbv2n0"))
|
||||||
(patches (search-our-patches "glibc-guix-prefix.patch"))))
|
(patches (search-our-patches "glibc-guix-prefix.patch"))))
|
||||||
(arguments
|
(arguments
|
||||||
(substitute-keyword-arguments (package-arguments glibc)
|
(substitute-keyword-arguments (package-arguments glibc)
|
||||||
|
@ -472,6 +474,8 @@ inspecting signatures in Mach-O binaries.")
|
||||||
"--enable-cet",
|
"--enable-cet",
|
||||||
"--enable-bind-now",
|
"--enable-bind-now",
|
||||||
"--disable-werror",
|
"--disable-werror",
|
||||||
|
"--disable-timezone-tools",
|
||||||
|
"--disable-profile",
|
||||||
building-on)))
|
building-on)))
|
||||||
((#:phases phases)
|
((#:phases phases)
|
||||||
`(modify-phases ,phases
|
`(modify-phases ,phases
|
||||||
|
|
|
@ -117,9 +117,9 @@ int trace_outbound_message(struct pt_regs *ctx) {
|
||||||
|
|
||||||
|
|
||||||
def print_message(event, inbound):
|
def print_message(event, inbound):
|
||||||
print(f"%s %s msg '%s' from peer %d (%s, %s) with %d bytes: %s" %
|
print("{} {} msg '{}' from peer {} ({}, {}) with {} bytes: {}".format(
|
||||||
(
|
|
||||||
f"Warning: incomplete message (only %d out of %d bytes)!" % (
|
"Warning: incomplete message (only {} out of {} bytes)!".format(
|
||||||
len(event.msg), event.msg_size) if len(event.msg) < event.msg_size else "",
|
len(event.msg), event.msg_size) if len(event.msg) < event.msg_size else "",
|
||||||
"inbound" if inbound else "outbound",
|
"inbound" if inbound else "outbound",
|
||||||
event.msg_type.decode("utf-8"),
|
event.msg_type.decode("utf-8"),
|
||||||
|
|
1
depends/.gitignore
vendored
1
depends/.gitignore
vendored
|
@ -3,6 +3,7 @@ work/
|
||||||
built/
|
built/
|
||||||
sources/
|
sources/
|
||||||
x86_64*
|
x86_64*
|
||||||
|
amd64*
|
||||||
i686*
|
i686*
|
||||||
mips*
|
mips*
|
||||||
arm*
|
arm*
|
||||||
|
|
|
@ -4,7 +4,7 @@ freebsd_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
|
||||||
freebsd_release_CFLAGS=-O2
|
freebsd_release_CFLAGS=-O2
|
||||||
freebsd_release_CXXFLAGS=$(freebsd_release_CFLAGS)
|
freebsd_release_CXXFLAGS=$(freebsd_release_CFLAGS)
|
||||||
|
|
||||||
freebsd_debug_CFLAGS=-O1
|
freebsd_debug_CFLAGS=-O1 -g
|
||||||
freebsd_debug_CXXFLAGS=$(freebsd_debug_CFLAGS)
|
freebsd_debug_CXXFLAGS=$(freebsd_debug_CFLAGS)
|
||||||
|
|
||||||
ifeq (86,$(findstring 86,$(build_arch)))
|
ifeq (86,$(findstring 86,$(build_arch)))
|
||||||
|
|
|
@ -7,12 +7,10 @@ netbsd_NM = $(host_toolchain)gcc-nm
|
||||||
netbsd_RANLIB = $(host_toolchain)gcc-ranlib
|
netbsd_RANLIB = $(host_toolchain)gcc-ranlib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
netbsd_CXXFLAGS=$(netbsd_CFLAGS)
|
|
||||||
|
|
||||||
netbsd_release_CFLAGS=-O2
|
netbsd_release_CFLAGS=-O2
|
||||||
netbsd_release_CXXFLAGS=$(netbsd_release_CFLAGS)
|
netbsd_release_CXXFLAGS=$(netbsd_release_CFLAGS)
|
||||||
|
|
||||||
netbsd_debug_CFLAGS=-O1
|
netbsd_debug_CFLAGS=-O1 -g
|
||||||
netbsd_debug_CXXFLAGS=$(netbsd_debug_CFLAGS)
|
netbsd_debug_CXXFLAGS=$(netbsd_debug_CFLAGS)
|
||||||
|
|
||||||
ifeq (86,$(findstring 86,$(build_arch)))
|
ifeq (86,$(findstring 86,$(build_arch)))
|
||||||
|
|
|
@ -4,7 +4,7 @@ openbsd_CXXFLAGS=-pipe -std=$(CXX_STANDARD)
|
||||||
openbsd_release_CFLAGS=-O2
|
openbsd_release_CFLAGS=-O2
|
||||||
openbsd_release_CXXFLAGS=$(openbsd_release_CFLAGS)
|
openbsd_release_CXXFLAGS=$(openbsd_release_CFLAGS)
|
||||||
|
|
||||||
openbsd_debug_CFLAGS=-O1
|
openbsd_debug_CFLAGS=-O1 -g
|
||||||
openbsd_debug_CXXFLAGS=$(openbsd_debug_CFLAGS)
|
openbsd_debug_CXXFLAGS=$(openbsd_debug_CFLAGS)
|
||||||
|
|
||||||
ifeq (86,$(findstring 86,$(build_arch)))
|
ifeq (86,$(findstring 86,$(build_arch)))
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package=native_capnp
|
package=native_capnp
|
||||||
$(package)_version=1.0.1
|
$(package)_version=1.1.0
|
||||||
$(package)_download_path=https://capnproto.org/
|
$(package)_download_path=https://capnproto.org/
|
||||||
$(package)_download_file=capnproto-c++-$($(package)_version).tar.gz
|
$(package)_download_file=capnproto-c++-$($(package)_version).tar.gz
|
||||||
$(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz
|
$(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz
|
||||||
$(package)_sha256_hash=0f7f4b8a76a2cdb284fddef20de8306450df6dd031a47a15ac95bc43c3358e09
|
$(package)_sha256_hash=07167580e563f5e821e3b2af1c238c16ec7181612650c5901330fa9a0da50939
|
||||||
|
|
||||||
define $(package)_set_vars
|
define $(package)_set_vars
|
||||||
$(package)_config_opts := -DBUILD_TESTING=OFF
|
$(package)_config_opts := -DBUILD_TESTING=OFF
|
||||||
|
|
|
@ -96,7 +96,7 @@ There is an included test suite that is useful for testing code changes when dev
|
||||||
To run the test suite (recommended), you will need to have Python 3 installed:
|
To run the test suite (recommended), you will need to have Python 3 installed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pkg install python3 databases/py-sqlite3
|
pkg install python3 databases/py-sqlite3 net/py-pyzmq
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# NetBSD Build Guide
|
# NetBSD Build Guide
|
||||||
|
|
||||||
**Updated for NetBSD [10.0](https://netbsd.org/releases/formal-10/NetBSD-10.0.html)**
|
**Updated for NetBSD [10.1](https://netbsd.org/releases/formal-10/NetBSD-10.1.html)**
|
||||||
|
|
||||||
This guide describes how to build bitcoind, command-line utilities, and GUI on NetBSD.
|
This guide describes how to build bitcoind, command-line utilities, and GUI on NetBSD.
|
||||||
|
|
||||||
|
@ -83,6 +83,13 @@ pkgin install qrencode
|
||||||
|
|
||||||
Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI.
|
Otherwise, if you don't need QR encoding support, use the `-DWITH_QRENCODE=OFF` option to disable this feature in order to compile the GUI.
|
||||||
|
|
||||||
|
#### Notifications
|
||||||
|
###### ZeroMQ
|
||||||
|
|
||||||
|
Bitcoin Core can provide notifications via ZeroMQ. If the package is installed, support will be compiled in.
|
||||||
|
```bash
|
||||||
|
pkgin zeromq
|
||||||
|
```
|
||||||
|
|
||||||
#### Test Suite Dependencies
|
#### Test Suite Dependencies
|
||||||
|
|
||||||
|
@ -90,10 +97,10 @@ There is an included test suite that is useful for testing code changes when dev
|
||||||
To run the test suite (recommended), you will need to have Python 3 installed:
|
To run the test suite (recommended), you will need to have Python 3 installed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pkgin install python39
|
pkgin install python310 py310-zmq
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building Bitcoin Core
|
## Building Bitcoin Core
|
||||||
|
|
||||||
### 1. Configuration
|
### 1. Configuration
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# OpenBSD Build Guide
|
# OpenBSD Build Guide
|
||||||
|
|
||||||
**Updated for OpenBSD [7.5](https://www.openbsd.org/75.html)**
|
**Updated for OpenBSD [7.6](https://www.openbsd.org/76.html)**
|
||||||
|
|
||||||
This guide describes how to build bitcoind, command-line utilities, and GUI on OpenBSD.
|
This guide describes how to build bitcoind, command-line utilities, and GUI on OpenBSD.
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ There is an included test suite that is useful for testing code changes when dev
|
||||||
To run the test suite (recommended), you will need to have Python 3 installed:
|
To run the test suite (recommended), you will need to have Python 3 installed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pkg_add python # Select the newest version of the package.
|
pkg_add python py3-zmq # Select the newest version of the python package if necessary.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building Bitcoin Core
|
## Building Bitcoin Core
|
||||||
|
|
2
doc/release-notes-28121.md
Normal file
2
doc/release-notes-28121.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
The RPC `testmempoolaccept` response now includes a "reject-details" field in some cases,
|
||||||
|
similar to the complete error messages returned by `sendrawtransaction` (#28121)
|
15
doc/release-notes-31223.md
Normal file
15
doc/release-notes-31223.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
P2P and network changes
|
||||||
|
-----------------------
|
||||||
|
When the `-port` configuration option is used, the default onion listening port will now
|
||||||
|
be derived to be that port + 1 instead of being set to a fixed value (8334 on mainnet).
|
||||||
|
This re-allows setups with multiple local nodes using different `-port` and not using `-bind`,
|
||||||
|
which would lead to a startup failure in v28.0 due to a port collision.
|
||||||
|
|
||||||
|
Note that a `HiddenServicePort` manually configured in `torrc` may need adjustment if used in
|
||||||
|
connection with the `-port` option.
|
||||||
|
For example, if you are using `-port=5555` with a non-standard value and not using `-bind=...=onion`,
|
||||||
|
previously Bitcoin Core would listen for incoming Tor connections on `127.0.0.1:8334`.
|
||||||
|
Now it would listen on `127.0.0.1:5556` (`-port` plus one). If you configured the hidden service manually
|
||||||
|
in torrc now you have to change it from `HiddenServicePort 8333 127.0.0.1:8334` to `HiddenServicePort 8333
|
||||||
|
127.0.0.1:5556`, or configure bitcoind with `-bind=127.0.0.1:8334=onion` to get the previous behavior.
|
||||||
|
(#31223)
|
16
doc/release-notes-31384.md
Normal file
16
doc/release-notes-31384.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
- Node and Mining
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- PR #31384 fixed an issue where the coinbase transaction weight was being reserved in two different places.
|
||||||
|
The fix ensures that the reservation happens in a single place.
|
||||||
|
|
||||||
|
- This PR also introduces a new startup option, `-maxcoinbaseweight` (default: `8,000` weight units).
|
||||||
|
This specifies how many weight units to reserve for the coinbase transaction.
|
||||||
|
- Upgrade note: the default of `-maxcoinbaseweight` ensures backward compatibility for users who did
|
||||||
|
not override `-blockmaxweight`.
|
||||||
|
- If you previously configured `-blockmaxweight=4000000` then you can
|
||||||
|
safely set `-maxcoinbaseweight=4000` to maintain existing behavior.
|
||||||
|
|
||||||
|
- Bitcoin Core will now **fail to start** if the `-blockmaxweight` or `-maxcoinbaseweight` init parameter exceeds
|
||||||
|
the consensus limit of `4,000,000` weight units.
|
|
@ -26,6 +26,7 @@ class base_uint
|
||||||
protected:
|
protected:
|
||||||
static_assert(BITS / 32 > 0 && BITS % 32 == 0, "Template parameter BITS must be a positive multiple of 32.");
|
static_assert(BITS / 32 > 0 && BITS % 32 == 0, "Template parameter BITS must be a positive multiple of 32.");
|
||||||
static constexpr int WIDTH = BITS / 32;
|
static constexpr int WIDTH = BITS / 32;
|
||||||
|
/** Big integer represented with 32-bit digits, least-significant first. */
|
||||||
uint32_t pn[WIDTH];
|
uint32_t pn[WIDTH];
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ std::string EncodeBase58Check(Span<const unsigned char> input)
|
||||||
// add 4-byte hash check to the end
|
// add 4-byte hash check to the end
|
||||||
std::vector<unsigned char> vch(input.begin(), input.end());
|
std::vector<unsigned char> vch(input.begin(), input.end());
|
||||||
uint256 hash = Hash(vch);
|
uint256 hash = Hash(vch);
|
||||||
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
|
vch.insert(vch.end(), hash.data(), hash.data() + 4);
|
||||||
return EncodeBase58(vch);
|
return EncodeBase58(vch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,19 +20,23 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
using node::BlockAssembler;
|
||||||
|
|
||||||
static void AssembleBlock(benchmark::Bench& bench)
|
static void AssembleBlock(benchmark::Bench& bench)
|
||||||
{
|
{
|
||||||
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
|
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
|
||||||
|
|
||||||
CScriptWitness witness;
|
CScriptWitness witness;
|
||||||
witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE);
|
witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE);
|
||||||
|
BlockAssembler::Options options;
|
||||||
|
options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||||
|
|
||||||
// Collect some loose transactions that spend the coinbases of our mined blocks
|
// Collect some loose transactions that spend the coinbases of our mined blocks
|
||||||
constexpr size_t NUM_BLOCKS{200};
|
constexpr size_t NUM_BLOCKS{200};
|
||||||
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
|
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
|
||||||
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
|
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
|
||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
tx.vin.emplace_back(MineBlock(test_setup->m_node, P2WSH_OP_TRUE));
|
tx.vin.emplace_back(MineBlock(test_setup->m_node, options));
|
||||||
tx.vin.back().scriptWitness = witness;
|
tx.vin.back().scriptWitness = witness;
|
||||||
tx.vout.emplace_back(1337, P2WSH_OP_TRUE);
|
tx.vout.emplace_back(1337, P2WSH_OP_TRUE);
|
||||||
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
|
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
|
||||||
|
@ -48,7 +52,7 @@ static void AssembleBlock(benchmark::Bench& bench)
|
||||||
}
|
}
|
||||||
|
|
||||||
bench.run([&] {
|
bench.run([&] {
|
||||||
PrepareBlock(test_setup->m_node, P2WSH_OP_TRUE);
|
PrepareBlock(test_setup->m_node, options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static void BlockAssemblerAddPackageTxns(benchmark::Bench& bench)
|
static void BlockAssemblerAddPackageTxns(benchmark::Bench& bench)
|
||||||
|
@ -56,11 +60,12 @@ static void BlockAssemblerAddPackageTxns(benchmark::Bench& bench)
|
||||||
FastRandomContext det_rand{true};
|
FastRandomContext det_rand{true};
|
||||||
auto testing_setup{MakeNoLogFileContext<TestChain100Setup>()};
|
auto testing_setup{MakeNoLogFileContext<TestChain100Setup>()};
|
||||||
testing_setup->PopulateMempool(det_rand, /*num_transactions=*/1000, /*submit=*/true);
|
testing_setup->PopulateMempool(det_rand, /*num_transactions=*/1000, /*submit=*/true);
|
||||||
node::BlockAssembler::Options assembler_options;
|
BlockAssembler::Options assembler_options;
|
||||||
assembler_options.test_block_validity = false;
|
assembler_options.test_block_validity = false;
|
||||||
|
assembler_options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||||
|
|
||||||
bench.run([&] {
|
bench.run([&] {
|
||||||
PrepareBlock(testing_setup->m_node, P2WSH_OP_TRUE, assembler_options);
|
PrepareBlock(testing_setup->m_node, assembler_options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,15 @@ std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const ChainType chain)
|
||||||
{
|
{
|
||||||
switch (chain) {
|
switch (chain) {
|
||||||
case ChainType::MAIN:
|
case ChainType::MAIN:
|
||||||
return std::make_unique<CBaseChainParams>("", 8332, 8334);
|
return std::make_unique<CBaseChainParams>("", 8332);
|
||||||
case ChainType::TESTNET:
|
case ChainType::TESTNET:
|
||||||
return std::make_unique<CBaseChainParams>("testnet3", 18332, 18334);
|
return std::make_unique<CBaseChainParams>("testnet3", 18332);
|
||||||
case ChainType::TESTNET4:
|
case ChainType::TESTNET4:
|
||||||
return std::make_unique<CBaseChainParams>("testnet4", 48332, 48334);
|
return std::make_unique<CBaseChainParams>("testnet4", 48332);
|
||||||
case ChainType::SIGNET:
|
case ChainType::SIGNET:
|
||||||
return std::make_unique<CBaseChainParams>("signet", 38332, 38334);
|
return std::make_unique<CBaseChainParams>("signet", 38332);
|
||||||
case ChainType::REGTEST:
|
case ChainType::REGTEST:
|
||||||
return std::make_unique<CBaseChainParams>("regtest", 18443, 18445);
|
return std::make_unique<CBaseChainParams>("regtest", 18443);
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,15 +22,13 @@ class CBaseChainParams
|
||||||
public:
|
public:
|
||||||
const std::string& DataDir() const { return strDataDir; }
|
const std::string& DataDir() const { return strDataDir; }
|
||||||
uint16_t RPCPort() const { return m_rpc_port; }
|
uint16_t RPCPort() const { return m_rpc_port; }
|
||||||
uint16_t OnionServiceTargetPort() const { return m_onion_service_target_port; }
|
|
||||||
|
|
||||||
CBaseChainParams() = delete;
|
CBaseChainParams() = delete;
|
||||||
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port, uint16_t onion_service_target_port)
|
CBaseChainParams(const std::string& data_dir, uint16_t rpc_port)
|
||||||
: m_rpc_port(rpc_port), m_onion_service_target_port(onion_service_target_port), strDataDir(data_dir) {}
|
: m_rpc_port(rpc_port), strDataDir(data_dir) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint16_t m_rpc_port;
|
const uint16_t m_rpc_port;
|
||||||
const uint16_t m_onion_service_target_port;
|
|
||||||
std::string strDataDir;
|
std::string strDataDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <consensus/merkle.h>
|
#include <consensus/merkle.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
#include <util/check.h>
|
||||||
|
|
||||||
/* WARNING! If you're reading this because you're learning about crypto
|
/* WARNING! If you're reading this because you're learning about crypto
|
||||||
and/or designing a new system that will use merkle trees, keep in mind
|
and/or designing a new system that will use merkle trees, keep in mind
|
||||||
|
@ -84,8 +85,10 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
|
/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
|
||||||
static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t branchpos, std::vector<uint256>* pbranch) {
|
static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t leaf_pos, std::vector<uint256>* path)
|
||||||
if (pbranch) pbranch->clear();
|
{
|
||||||
|
if (path) path->clear();
|
||||||
|
Assume(leaves.size() <= UINT32_MAX);
|
||||||
if (leaves.size() == 0) {
|
if (leaves.size() == 0) {
|
||||||
if (pmutated) *pmutated = false;
|
if (pmutated) *pmutated = false;
|
||||||
if (proot) *proot = uint256();
|
if (proot) *proot = uint256();
|
||||||
|
@ -105,18 +108,18 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
|
||||||
// First process all leaves into 'inner' values.
|
// First process all leaves into 'inner' values.
|
||||||
while (count < leaves.size()) {
|
while (count < leaves.size()) {
|
||||||
uint256 h = leaves[count];
|
uint256 h = leaves[count];
|
||||||
bool matchh = count == branchpos;
|
bool matchh = count == leaf_pos;
|
||||||
count++;
|
count++;
|
||||||
int level;
|
int level;
|
||||||
// For each of the lower bits in count that are 0, do 1 step. Each
|
// For each of the lower bits in count that are 0, do 1 step. Each
|
||||||
// corresponds to an inner value that existed before processing the
|
// corresponds to an inner value that existed before processing the
|
||||||
// current leaf, and each needs a hash to combine it.
|
// current leaf, and each needs a hash to combine it.
|
||||||
for (level = 0; !(count & ((uint32_t{1}) << level)); level++) {
|
for (level = 0; !(count & ((uint32_t{1}) << level)); level++) {
|
||||||
if (pbranch) {
|
if (path) {
|
||||||
if (matchh) {
|
if (matchh) {
|
||||||
pbranch->push_back(inner[level]);
|
path->push_back(inner[level]);
|
||||||
} else if (matchlevel == level) {
|
} else if (matchlevel == level) {
|
||||||
pbranch->push_back(h);
|
path->push_back(h);
|
||||||
matchh = true;
|
matchh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,8 +147,8 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
|
||||||
// If we reach this point, h is an inner value that is not the top.
|
// If we reach this point, h is an inner value that is not the top.
|
||||||
// We combine it with itself (Bitcoin's special rule for odd levels in
|
// We combine it with itself (Bitcoin's special rule for odd levels in
|
||||||
// the tree) to produce a higher level one.
|
// the tree) to produce a higher level one.
|
||||||
if (pbranch && matchh) {
|
if (path && matchh) {
|
||||||
pbranch->push_back(h);
|
path->push_back(h);
|
||||||
}
|
}
|
||||||
h = Hash(h, h);
|
h = Hash(h, h);
|
||||||
// Increment count to the value it would have if two entries at this
|
// Increment count to the value it would have if two entries at this
|
||||||
|
@ -154,11 +157,11 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
|
||||||
level++;
|
level++;
|
||||||
// And propagate the result upwards accordingly.
|
// And propagate the result upwards accordingly.
|
||||||
while (!(count & ((uint32_t{1}) << level))) {
|
while (!(count & ((uint32_t{1}) << level))) {
|
||||||
if (pbranch) {
|
if (path) {
|
||||||
if (matchh) {
|
if (matchh) {
|
||||||
pbranch->push_back(inner[level]);
|
path->push_back(inner[level]);
|
||||||
} else if (matchlevel == level) {
|
} else if (matchlevel == level) {
|
||||||
pbranch->push_back(h);
|
path->push_back(h);
|
||||||
matchh = true;
|
matchh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,18 +174,18 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
|
||||||
if (proot) *proot = h;
|
if (proot) *proot = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) {
|
static std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& leaves, uint32_t position) {
|
||||||
std::vector<uint256> ret;
|
std::vector<uint256> ret;
|
||||||
MerkleComputation(leaves, nullptr, nullptr, position, &ret);
|
MerkleComputation(leaves, nullptr, nullptr, position, &ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position)
|
std::vector<uint256> TransactionMerklePath(const CBlock& block, uint32_t position)
|
||||||
{
|
{
|
||||||
std::vector<uint256> leaves;
|
std::vector<uint256> leaves;
|
||||||
leaves.resize(block.vtx.size());
|
leaves.resize(block.vtx.size());
|
||||||
for (size_t s = 0; s < block.vtx.size(); s++) {
|
for (size_t s = 0; s < block.vtx.size(); s++) {
|
||||||
leaves[s] = block.vtx[s]->GetHash();
|
leaves[s] = block.vtx[s]->GetHash();
|
||||||
}
|
}
|
||||||
return ComputeMerkleBranch(leaves, position);
|
return ComputeMerklePath(leaves, position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,10 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated = nullptr);
|
||||||
* Compute merkle path to the specified transaction
|
* Compute merkle path to the specified transaction
|
||||||
*
|
*
|
||||||
* @param[in] block the block
|
* @param[in] block the block
|
||||||
* @param[in] position transaction for which to calculate the merkle path, defaults to coinbase
|
* @param[in] position transaction for which to calculate the merkle path (0 is the coinbase)
|
||||||
*
|
*
|
||||||
* @return merkle path ordered from the deepest
|
* @return merkle path ordered from the deepest
|
||||||
*/
|
*/
|
||||||
std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position = 0);
|
std::vector<uint256> TransactionMerklePath(const CBlock& block, uint32_t position);
|
||||||
|
|
||||||
#endif // BITCOIN_CONSENSUS_MERKLE_H
|
#endif // BITCOIN_CONSENSUS_MERKLE_H
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
}
|
}
|
||||||
mapOpNames[strName] = static_cast<opcodetype>(op);
|
mapOpNames[strName] = static_cast<opcodetype>(op);
|
||||||
// Convenience: OP_ADD and just ADD are both recognized:
|
// Convenience: OP_ADD and just ADD are both recognized:
|
||||||
if (strName.compare(0, 3, "OP_") == 0) { // strName starts with "OP_"
|
if (strName.starts_with("OP_")) {
|
||||||
mapOpNames[strName.substr(3)] = static_cast<opcodetype>(op);
|
mapOpNames[strName.substr(3)] = static_cast<opcodetype>(op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2017-2022 The Bitcoin Core developers
|
// Copyright (c) 2017-present The Bitcoin Core developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -25,14 +25,14 @@
|
||||||
void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept
|
void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept
|
||||||
{
|
{
|
||||||
assert(key.size() == KEYLEN);
|
assert(key.size() == KEYLEN);
|
||||||
input[0] = ReadLE32(UCharCast(key.data() + 0));
|
input[0] = ReadLE32(key.data() + 0);
|
||||||
input[1] = ReadLE32(UCharCast(key.data() + 4));
|
input[1] = ReadLE32(key.data() + 4);
|
||||||
input[2] = ReadLE32(UCharCast(key.data() + 8));
|
input[2] = ReadLE32(key.data() + 8);
|
||||||
input[3] = ReadLE32(UCharCast(key.data() + 12));
|
input[3] = ReadLE32(key.data() + 12);
|
||||||
input[4] = ReadLE32(UCharCast(key.data() + 16));
|
input[4] = ReadLE32(key.data() + 16);
|
||||||
input[5] = ReadLE32(UCharCast(key.data() + 20));
|
input[5] = ReadLE32(key.data() + 20);
|
||||||
input[6] = ReadLE32(UCharCast(key.data() + 24));
|
input[6] = ReadLE32(key.data() + 24);
|
||||||
input[7] = ReadLE32(UCharCast(key.data() + 28));
|
input[7] = ReadLE32(key.data() + 28);
|
||||||
input[8] = 0;
|
input[8] = 0;
|
||||||
input[9] = 0;
|
input[9] = 0;
|
||||||
input[10] = 0;
|
input[10] = 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2020 The Bitcoin Core developers
|
// Copyright (c) 2014-present The Bitcoin Core developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -7,82 +7,99 @@
|
||||||
|
|
||||||
#include <compat/endian.h>
|
#include <compat/endian.h>
|
||||||
|
|
||||||
|
#include <concepts>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
template <typename B>
|
||||||
|
concept ByteType = std::same_as<B, unsigned char> || std::same_as<B, std::byte>;
|
||||||
|
|
||||||
|
template <ByteType B>
|
||||||
|
inline uint16_t ReadLE16(const B* ptr)
|
||||||
{
|
{
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
memcpy(&x, ptr, 2);
|
memcpy(&x, ptr, 2);
|
||||||
return le16toh_internal(x);
|
return le16toh_internal(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
template <ByteType B>
|
||||||
|
inline uint32_t ReadLE32(const B* ptr)
|
||||||
{
|
{
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
memcpy(&x, ptr, 4);
|
memcpy(&x, ptr, 4);
|
||||||
return le32toh_internal(x);
|
return le32toh_internal(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
template <ByteType B>
|
||||||
|
inline uint64_t ReadLE64(const B* ptr)
|
||||||
{
|
{
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
memcpy(&x, ptr, 8);
|
memcpy(&x, ptr, 8);
|
||||||
return le64toh_internal(x);
|
return le64toh_internal(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
template <ByteType B>
|
||||||
|
inline void WriteLE16(B* ptr, uint16_t x)
|
||||||
{
|
{
|
||||||
uint16_t v = htole16_internal(x);
|
uint16_t v = htole16_internal(x);
|
||||||
memcpy(ptr, &v, 2);
|
memcpy(ptr, &v, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
template <ByteType B>
|
||||||
|
inline void WriteLE32(B* ptr, uint32_t x)
|
||||||
{
|
{
|
||||||
uint32_t v = htole32_internal(x);
|
uint32_t v = htole32_internal(x);
|
||||||
memcpy(ptr, &v, 4);
|
memcpy(ptr, &v, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
template <ByteType B>
|
||||||
|
inline void WriteLE64(B* ptr, uint64_t x)
|
||||||
{
|
{
|
||||||
uint64_t v = htole64_internal(x);
|
uint64_t v = htole64_internal(x);
|
||||||
memcpy(ptr, &v, 8);
|
memcpy(ptr, &v, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t static inline ReadBE16(const unsigned char* ptr)
|
template <ByteType B>
|
||||||
|
inline uint16_t ReadBE16(const B* ptr)
|
||||||
{
|
{
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
memcpy(&x, ptr, 2);
|
memcpy(&x, ptr, 2);
|
||||||
return be16toh_internal(x);
|
return be16toh_internal(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
template <ByteType B>
|
||||||
|
inline uint32_t ReadBE32(const B* ptr)
|
||||||
{
|
{
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
memcpy(&x, ptr, 4);
|
memcpy(&x, ptr, 4);
|
||||||
return be32toh_internal(x);
|
return be32toh_internal(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
template <ByteType B>
|
||||||
|
inline uint64_t ReadBE64(const B* ptr)
|
||||||
{
|
{
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
memcpy(&x, ptr, 8);
|
memcpy(&x, ptr, 8);
|
||||||
return be64toh_internal(x);
|
return be64toh_internal(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteBE16(unsigned char* ptr, uint16_t x)
|
template <ByteType B>
|
||||||
|
inline void WriteBE16(B* ptr, uint16_t x)
|
||||||
{
|
{
|
||||||
uint16_t v = htobe16_internal(x);
|
uint16_t v = htobe16_internal(x);
|
||||||
memcpy(ptr, &v, 2);
|
memcpy(ptr, &v, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
template <ByteType B>
|
||||||
|
inline void WriteBE32(B* ptr, uint32_t x)
|
||||||
{
|
{
|
||||||
uint32_t v = htobe32_internal(x);
|
uint32_t v = htobe32_internal(x);
|
||||||
memcpy(ptr, &v, 4);
|
memcpy(ptr, &v, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
template <ByteType B>
|
||||||
|
inline void WriteBE64(B* ptr, uint64_t x)
|
||||||
{
|
{
|
||||||
uint64_t v = htobe64_internal(x);
|
uint64_t v = htobe64_internal(x);
|
||||||
memcpy(ptr, &v, 8);
|
memcpy(ptr, &v, 8);
|
||||||
|
|
|
@ -227,7 +227,7 @@ static bool InitHTTPAllowList()
|
||||||
const CSubNet subnet{LookupSubNet(strAllow)};
|
const CSubNet subnet{LookupSubNet(strAllow)};
|
||||||
if (!subnet.IsValid()) {
|
if (!subnet.IsValid()) {
|
||||||
uiInterface.ThreadSafeMessageBox(
|
uiInterface.ThreadSafeMessageBox(
|
||||||
strprintf(Untranslated("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24)."), strAllow),
|
Untranslated(strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow)),
|
||||||
"", CClientUIInterface::MSG_ERROR);
|
"", CClientUIInterface::MSG_ERROR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,17 @@ namespace util {
|
||||||
class SignalInterrupt;
|
class SignalInterrupt;
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|
||||||
static const int DEFAULT_HTTP_THREADS=4;
|
/**
|
||||||
static const int DEFAULT_HTTP_WORKQUEUE=16;
|
* The default value for `-rpcthreads`. This number of threads will be created at startup.
|
||||||
|
*/
|
||||||
|
static const int DEFAULT_HTTP_THREADS=16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for `-rpcworkqueue`. This is the maximum depth of the work queue,
|
||||||
|
* we don't allocate this number of work queue items upfront.
|
||||||
|
*/
|
||||||
|
static const int DEFAULT_HTTP_WORKQUEUE=64;
|
||||||
|
|
||||||
static const int DEFAULT_HTTP_SERVER_TIMEOUT=30;
|
static const int DEFAULT_HTTP_SERVER_TIMEOUT=30;
|
||||||
|
|
||||||
struct evhttp_request;
|
struct evhttp_request;
|
||||||
|
|
|
@ -106,7 +106,7 @@ bool BaseIndex::Init()
|
||||||
// best chain, we will rewind to the fork point during index sync
|
// best chain, we will rewind to the fork point during index sync
|
||||||
const CBlockIndex* locator_index{m_chainstate->m_blockman.LookupBlockIndex(locator.vHave.at(0))};
|
const CBlockIndex* locator_index{m_chainstate->m_blockman.LookupBlockIndex(locator.vHave.at(0))};
|
||||||
if (!locator_index) {
|
if (!locator_index) {
|
||||||
return InitError(strprintf(Untranslated("%s: best block of the index not found. Please rebuild the index."), GetName()));
|
return InitError(Untranslated(strprintf("%s: best block of the index not found. Please rebuild the index.", GetName())));
|
||||||
}
|
}
|
||||||
SetBestBlockIndex(locator_index);
|
SetBestBlockIndex(locator_index);
|
||||||
}
|
}
|
||||||
|
|
42
src/init.cpp
42
src/init.cpp
|
@ -525,7 +525,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
||||||
argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), testnet4BaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultChainParams->GetDefaultPort() + 1, testnetChainParams->GetDefaultPort() + 1, testnet4ChainParams->GetDefaultPort() + 1, signetChainParams->GetDefaultPort() + 1, regtestChainParams->GetDefaultPort() + 1), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-cjdnsreachable", "If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network, see doc/cjdns.md) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-cjdnsreachable", "If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network, see doc/cjdns.md) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
|
@ -552,7 +552,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
||||||
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md). If set to a value x, the default onion listening port will be set to x+1.", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||||
#ifdef HAVE_SOCKADDR_UN
|
#ifdef HAVE_SOCKADDR_UN
|
||||||
argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION);
|
argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION);
|
||||||
#else
|
#else
|
||||||
|
@ -668,7 +668,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
||||||
argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcwhitelist=<whitelist>", "Set a whitelist to filter incoming RPC calls for a specific user. The field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc 2>,...,<rpc n>. If multiple whitelists are set for a given user, they are set-intersected. See -rpcwhitelistdefault documentation for information on default whitelist behavior.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcwhitelist=<whitelist>", "Set a whitelist to filter incoming RPC calls for a specific user. The field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc 2>,...,<rpc n>. If multiple whitelists are set for a given user, they are set-intersected. See -rpcwhitelistdefault documentation for information on default whitelist behavior.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcwhitelistdefault", "Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc server acts as if all rpc users are subject to empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault is set to 1 and no -rpcwhitelist is set, rpc server acts as if all rpc users are subject to empty whitelists.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcwhitelistdefault", "Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc server acts as if all rpc users are subject to empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault is set to 1 and no -rpcwhitelist is set, rpc server acts as if all rpc users are subject to empty whitelists.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the maximum depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-server", "Accept command line and JSON-RPC commands", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-server", "Accept command line and JSON-RPC commands", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
if (can_listen_ipc) {
|
if (can_listen_ipc) {
|
||||||
argsman.AddArg("-ipcbind=<address>", "Bind to Unix socket address and listen for incoming connections. Valid address values are \"unix\" to listen on the default path, <datadir>/node.sock, or \"unix:/custom/path\" to specify a custom path. Can be specified multiple times to listen on multiple paths. Default behavior is not to listen on any path. If relative paths are specified, they are interpreted relative to the network data directory. If paths include any parent directory components and the parent directories do not exist, they will be created.", ArgsManager::ALLOW_ANY, OptionsCategory::IPC);
|
argsman.AddArg("-ipcbind=<address>", "Bind to Unix socket address and listen for incoming connections. Valid address values are \"unix\" to listen on the default path, <datadir>/node.sock, or \"unix:/custom/path\" to specify a custom path. Can be specified multiple times to listen on multiple paths. Default behavior is not to listen on any path. If relative paths are specified, they are interpreted relative to the network data directory. If paths include any parent directory components and the parent directories do not exist, they will be created.", ArgsManager::ALLOW_ANY, OptionsCategory::IPC);
|
||||||
|
@ -889,7 +889,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
||||||
}
|
}
|
||||||
bilingual_str errors;
|
bilingual_str errors;
|
||||||
for (const auto& arg : args.GetUnsuitableSectionOnlyArgs()) {
|
for (const auto& arg : args.GetUnsuitableSectionOnlyArgs()) {
|
||||||
errors += strprintf(_("Config setting for %s only applied on %s network when in [%s] section.") + Untranslated("\n"), arg, ChainTypeToString(chain), ChainTypeToString(chain));
|
errors += strprintf(_("Config setting for %s only applied on %s network when in [%s] section."), arg, ChainTypeToString(chain), ChainTypeToString(chain)) + Untranslated("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errors.empty()) {
|
if (!errors.empty()) {
|
||||||
|
@ -904,7 +904,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
||||||
// Warn if unrecognized section name are present in the config file.
|
// Warn if unrecognized section name are present in the config file.
|
||||||
bilingual_str warnings;
|
bilingual_str warnings;
|
||||||
for (const auto& section : args.GetUnrecognizedSections()) {
|
for (const auto& section : args.GetUnrecognizedSections()) {
|
||||||
warnings += strprintf(Untranslated("%s:%i ") + _("Section [%s] is not recognized.") + Untranslated("\n"), section.m_file, section.m_line, section.m_name);
|
warnings += Untranslated(strprintf("%s:%i ", section.m_file, section.m_line)) + strprintf(_("Section [%s] is not recognized."), section.m_name) + Untranslated("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!warnings.empty()) {
|
if (!warnings.empty()) {
|
||||||
|
@ -1225,7 +1225,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
|
||||||
try {
|
try {
|
||||||
node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown_signal), chainman_opts, blockman_opts);
|
node.chainman = std::make_unique<ChainstateManager>(*Assert(node.shutdown_signal), chainman_opts, blockman_opts);
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
return {ChainstateLoadStatus::FAILURE_FATAL, strprintf(Untranslated("Failed to initialize ChainstateManager: %s"), e.what())};
|
return {ChainstateLoadStatus::FAILURE_FATAL, Untranslated(strprintf("Failed to initialize ChainstateManager: %s", e.what()))};
|
||||||
}
|
}
|
||||||
ChainstateManager& chainman = *node.chainman;
|
ChainstateManager& chainman = *node.chainman;
|
||||||
// This is defined and set here instead of inline in validation.h to avoid a hard
|
// This is defined and set here instead of inline in validation.h to avoid a hard
|
||||||
|
@ -1356,7 +1356,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
try {
|
try {
|
||||||
ipc->listenAddress(address);
|
ipc->listenAddress(address);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
return InitError(strprintf(Untranslated("Unable to bind to IPC address '%s'. %s"), address, e.what()));
|
return InitError(Untranslated(strprintf("Unable to bind to IPC address '%s'. %s", address, e.what())));
|
||||||
}
|
}
|
||||||
LogPrintf("Listening for IPC requests on address %s\n", address);
|
LogPrintf("Listening for IPC requests on address %s\n", address);
|
||||||
}
|
}
|
||||||
|
@ -1787,7 +1787,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
|
|
||||||
node.background_init_thread = std::thread(&util::TraceThread, "initload", [=, &chainman, &args, &node] {
|
node.background_init_thread = std::thread(&util::TraceThread, "initload", [=, &chainman, &args, &node] {
|
||||||
ScheduleBatchPriority();
|
ScheduleBatchPriority();
|
||||||
// Import blocks
|
// Import blocks and ActivateBestChain()
|
||||||
ImportBlocks(chainman, vImportFiles);
|
ImportBlocks(chainman, vImportFiles);
|
||||||
if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
|
if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
|
||||||
LogPrintf("Stopping after block import\n");
|
LogPrintf("Stopping after block import\n");
|
||||||
|
@ -1810,11 +1810,21 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for genesis block to be processed
|
/*
|
||||||
if (WITH_LOCK(chainman.GetMutex(), return chainman.ActiveTip() == nullptr)) {
|
* Wait for genesis block to be processed. Typically kernel_notifications.m_tip_block
|
||||||
|
* has already been set by a call to LoadChainTip() in CompleteChainstateInitialization().
|
||||||
|
* But this is skipped if the chainstate doesn't exist yet or is being wiped:
|
||||||
|
*
|
||||||
|
* 1. first startup with an empty datadir
|
||||||
|
* 2. reindex
|
||||||
|
* 3. reindex-chainstate
|
||||||
|
*
|
||||||
|
* In these case it's connected by a call to ActivateBestChain() in the initload thread.
|
||||||
|
*/
|
||||||
|
{
|
||||||
WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
|
WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
|
||||||
kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {
|
kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {
|
||||||
return !kernel_notifications.m_tip_block.IsNull() || ShutdownRequested(node);
|
return kernel_notifications.TipBlock() || ShutdownRequested(node);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1834,7 +1844,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
if (tip_info) {
|
if (tip_info) {
|
||||||
tip_info->block_height = chain_active_height;
|
tip_info->block_height = chain_active_height;
|
||||||
tip_info->block_time = best_block_time;
|
tip_info->block_time = best_block_time;
|
||||||
tip_info->verification_progress = GuessVerificationProgress(chainman.GetParams().TxData(), &tip);
|
tip_info->verification_progress = chainman.GuessVerificationProgress(&tip);
|
||||||
}
|
}
|
||||||
if (tip_info && chainman.m_best_header) {
|
if (tip_info && chainman.m_best_header) {
|
||||||
tip_info->header_height = chainman.m_best_header->nHeight;
|
tip_info->header_height = chainman.m_best_header->nHeight;
|
||||||
|
@ -1865,6 +1875,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
const uint16_t default_bind_port =
|
const uint16_t default_bind_port =
|
||||||
static_cast<uint16_t>(args.GetIntArg("-port", Params().GetDefaultPort()));
|
static_cast<uint16_t>(args.GetIntArg("-port", Params().GetDefaultPort()));
|
||||||
|
|
||||||
|
const uint16_t default_bind_port_onion = default_bind_port + 1;
|
||||||
|
|
||||||
const auto BadPortWarning = [](const char* prefix, uint16_t port) {
|
const auto BadPortWarning = [](const char* prefix, uint16_t port) {
|
||||||
return strprintf(_("%s request to listen on port %u. This port is considered \"bad\" and "
|
return strprintf(_("%s request to listen on port %u. This port is considered \"bad\" and "
|
||||||
"thus it is unlikely that any peer will connect to it. See "
|
"thus it is unlikely that any peer will connect to it. See "
|
||||||
|
@ -1889,7 +1901,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
const std::string network_type = bind_arg.substr(index + 1);
|
const std::string network_type = bind_arg.substr(index + 1);
|
||||||
if (network_type == "onion") {
|
if (network_type == "onion") {
|
||||||
const std::string truncated_bind_arg = bind_arg.substr(0, index);
|
const std::string truncated_bind_arg = bind_arg.substr(0, index);
|
||||||
bind_addr = Lookup(truncated_bind_arg, BaseParams().OnionServiceTargetPort(), false);
|
bind_addr = Lookup(truncated_bind_arg, default_bind_port_onion, false);
|
||||||
if (bind_addr.has_value()) {
|
if (bind_addr.has_value()) {
|
||||||
connOptions.onion_binds.push_back(bind_addr.value());
|
connOptions.onion_binds.push_back(bind_addr.value());
|
||||||
continue;
|
continue;
|
||||||
|
@ -1925,7 +1937,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
} else if (!connOptions.vBinds.empty()) {
|
} else if (!connOptions.vBinds.empty()) {
|
||||||
onion_service_target = connOptions.vBinds.front();
|
onion_service_target = connOptions.vBinds.front();
|
||||||
} else {
|
} else {
|
||||||
onion_service_target = DefaultOnionServiceTarget();
|
onion_service_target = DefaultOnionServiceTarget(default_bind_port_onion);
|
||||||
connOptions.onion_binds.push_back(onion_service_target);
|
connOptions.onion_binds.push_back(onion_service_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2061,7 +2073,7 @@ bool StartIndexBackgroundSync(NodeContext& node)
|
||||||
const CBlockIndex* start_block = *indexes_start_block;
|
const CBlockIndex* start_block = *indexes_start_block;
|
||||||
if (!start_block) start_block = chainman.ActiveChain().Genesis();
|
if (!start_block) start_block = chainman.ActiveChain().Genesis();
|
||||||
if (!chainman.m_blockman.CheckBlockDataAvailability(*index_chain.Tip(), *Assert(start_block))) {
|
if (!chainman.m_blockman.CheckBlockDataAvailability(*index_chain.Tip(), *Assert(start_block))) {
|
||||||
return InitError(strprintf(Untranslated("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"), older_index_name));
|
return InitError(Untranslated(strprintf("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)", older_index_name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,8 +112,8 @@ bool StartLogging(const ArgsManager& args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!LogInstance().StartLogging()) {
|
if (!LogInstance().StartLogging()) {
|
||||||
return InitError(strprintf(Untranslated("Could not open debug log file %s"),
|
return InitError(Untranslated(strprintf("Could not open debug log file %s",
|
||||||
fs::PathToString(LogInstance().m_file_path)));
|
fs::PathToString(LogInstance().m_file_path))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LogInstance().m_log_timestamps)
|
if (!LogInstance().m_log_timestamps)
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
*
|
*
|
||||||
* @returns if the block was processed, independent of block validity
|
* @returns if the block was processed, independent of block validity
|
||||||
*/
|
*/
|
||||||
virtual bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CMutableTransaction coinbase) = 0;
|
virtual bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Interface giving clients (RPC, Stratum v2 Template Provider in the future)
|
//! Interface giving clients (RPC, Stratum v2 Template Provider in the future)
|
||||||
|
@ -75,8 +75,8 @@ public:
|
||||||
virtual std::optional<BlockRef> getTip() = 0;
|
virtual std::optional<BlockRef> getTip() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for the connected tip to change. If the tip was not connected on
|
* Waits for the connected tip to change. During node initialization, this will
|
||||||
* startup, this will wait.
|
* wait until the tip is connected.
|
||||||
*
|
*
|
||||||
* @param[in] current_tip block hash of the current chain tip. Function waits
|
* @param[in] current_tip block hash of the current chain tip. Function waits
|
||||||
* for the chain tip to differ from this.
|
* for the chain tip to differ from this.
|
||||||
|
@ -88,36 +88,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* Construct a new block template
|
* Construct a new block template
|
||||||
*
|
*
|
||||||
* @param[in] script_pub_key the coinbase output
|
|
||||||
* @param[in] options options for creating the block
|
* @param[in] options options for creating the block
|
||||||
* @returns a block template
|
* @returns a block template
|
||||||
*/
|
*/
|
||||||
virtual std::unique_ptr<BlockTemplate> createNewBlock(const CScript& script_pub_key, const node::BlockCreateOptions& options = {}) = 0;
|
virtual std::unique_ptr<BlockTemplate> createNewBlock(const node::BlockCreateOptions& options = {}) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes new block. A valid new block is automatically relayed to peers.
|
|
||||||
*
|
|
||||||
* @param[in] block The block we want to process.
|
|
||||||
* @param[out] new_block A boolean which is set to indicate if the block was first received via this call
|
|
||||||
* @returns If the block was processed, independently of block validity
|
|
||||||
*/
|
|
||||||
virtual bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) = 0;
|
|
||||||
|
|
||||||
//! Return the number of transaction updates in the mempool,
|
|
||||||
//! used to decide whether to make a new block template.
|
|
||||||
virtual unsigned int getTransactionsUpdated() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check a block is completely valid from start to finish.
|
|
||||||
* Only works on top of our current best block.
|
|
||||||
* Does not check proof-of-work.
|
|
||||||
*
|
|
||||||
* @param[in] block the block to validate
|
|
||||||
* @param[in] check_merkle_root call CheckMerkleRoot()
|
|
||||||
* @param[out] state details of why a block failed to validate
|
|
||||||
* @returns false if it does not build on the current tip, or any of the checks fail
|
|
||||||
*/
|
|
||||||
virtual bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) = 0;
|
|
||||||
|
|
||||||
//! Get internal node context. Useful for RPC and testing,
|
//! Get internal node context. Useful for RPC and testing,
|
||||||
//! but not accessible across processes.
|
//! but not accessible across processes.
|
||||||
|
|
|
@ -17,10 +17,7 @@ interface Mining $Proxy.wrap("interfaces::Mining") {
|
||||||
isInitialBlockDownload @1 (context :Proxy.Context) -> (result: Bool);
|
isInitialBlockDownload @1 (context :Proxy.Context) -> (result: Bool);
|
||||||
getTip @2 (context :Proxy.Context) -> (result: Common.BlockRef, hasResult: Bool);
|
getTip @2 (context :Proxy.Context) -> (result: Common.BlockRef, hasResult: Bool);
|
||||||
waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64) -> (result: Common.BlockRef);
|
waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64) -> (result: Common.BlockRef);
|
||||||
createNewBlock @4 (scriptPubKey: Data, options: BlockCreateOptions) -> (result: BlockTemplate);
|
createNewBlock @4 (options: BlockCreateOptions) -> (result: BlockTemplate);
|
||||||
processNewBlock @5 (context :Proxy.Context, block: Data) -> (newBlock: Bool, result: Bool);
|
|
||||||
getTransactionsUpdated @6 (context :Proxy.Context) -> (result: UInt32);
|
|
||||||
testBlockValidity @7 (context :Proxy.Context, block: Data, checkMerkleRoot: Bool) -> (state: BlockValidationState, result: Bool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {
|
interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {
|
||||||
|
|
|
@ -72,7 +72,7 @@ static bool ParseAddress(std::string& address,
|
||||||
struct sockaddr_un& addr,
|
struct sockaddr_un& addr,
|
||||||
std::string& error)
|
std::string& error)
|
||||||
{
|
{
|
||||||
if (address.compare(0, 4, "unix") == 0 && (address.size() == 4 || address[4] == ':')) {
|
if (address == "unix" || address.starts_with("unix:")) {
|
||||||
fs::path path;
|
fs::path path;
|
||||||
if (address.size() <= 5) {
|
if (address.size() <= 5) {
|
||||||
path = data_dir / fs::PathFromString(strprintf("%s.sock", RemovePrefixView(dest_exe_name, "bitcoin-")));
|
path = data_dir / fs::PathFromString(strprintf("%s.sock", RemovePrefixView(dest_exe_name, "bitcoin-")));
|
||||||
|
|
65
src/net.cpp
65
src/net.cpp
|
@ -558,7 +558,6 @@ void CNode::CloseSocketDisconnect()
|
||||||
fDisconnect = true;
|
fDisconnect = true;
|
||||||
LOCK(m_sock_mutex);
|
LOCK(m_sock_mutex);
|
||||||
if (m_sock) {
|
if (m_sock) {
|
||||||
LogDebug(BCLog::NET, "disconnecting peer=%d\n", id);
|
|
||||||
m_sock.reset();
|
m_sock.reset();
|
||||||
}
|
}
|
||||||
m_i2p_sam_session.reset();
|
m_i2p_sam_session.reset();
|
||||||
|
@ -696,6 +695,18 @@ bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CNode::LogIP(bool log_ip) const
|
||||||
|
{
|
||||||
|
return log_ip ? strprintf(" peeraddr=%s", addr.ToStringAddrPort()) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CNode::DisconnectMsg(bool log_ip) const
|
||||||
|
{
|
||||||
|
return strprintf("disconnecting peer=%d%s",
|
||||||
|
GetId(),
|
||||||
|
LogIP(log_ip));
|
||||||
|
}
|
||||||
|
|
||||||
V1Transport::V1Transport(const NodeId node_id) noexcept
|
V1Transport::V1Transport(const NodeId node_id) noexcept
|
||||||
: m_magic_bytes{Params().MessageStart()}, m_node_id{node_id}
|
: m_magic_bytes{Params().MessageStart()}, m_node_id{node_id}
|
||||||
{
|
{
|
||||||
|
@ -1635,7 +1646,7 @@ std::pair<size_t, bool> CConnman::SocketSendData(CNode& node) const
|
||||||
// error
|
// error
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
|
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
|
||||||
LogDebug(BCLog::NET, "socket send error for peer=%d: %s\n", node.GetId(), NetworkErrorString(nErr));
|
LogDebug(BCLog::NET, "socket send error, %s: %s\n", node.DisconnectMsg(fLogIPs), NetworkErrorString(nErr));
|
||||||
node.CloseSocketDisconnect();
|
node.CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1879,7 +1890,7 @@ void CConnman::DisconnectNodes()
|
||||||
// Disconnect any connected nodes
|
// Disconnect any connected nodes
|
||||||
for (CNode* pnode : m_nodes) {
|
for (CNode* pnode : m_nodes) {
|
||||||
if (!pnode->fDisconnect) {
|
if (!pnode->fDisconnect) {
|
||||||
LogDebug(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
|
LogDebug(BCLog::NET, "Network not active, %s\n", pnode->DisconnectMsg(fLogIPs));
|
||||||
pnode->fDisconnect = true;
|
pnode->fDisconnect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1971,26 +1982,43 @@ bool CConnman::InactivityCheck(const CNode& node) const
|
||||||
|
|
||||||
if (!ShouldRunInactivityChecks(node, now)) return false;
|
if (!ShouldRunInactivityChecks(node, now)) return false;
|
||||||
|
|
||||||
if (last_recv.count() == 0 || last_send.count() == 0) {
|
bool has_received{last_recv.count() != 0};
|
||||||
LogDebug(BCLog::NET, "socket no message in first %i seconds, %d %d peer=%d\n", count_seconds(m_peer_connect_timeout), last_recv.count() != 0, last_send.count() != 0, node.GetId());
|
bool has_sent{last_send.count() != 0};
|
||||||
|
|
||||||
|
if (!has_received || !has_sent) {
|
||||||
|
std::string has_never;
|
||||||
|
if (!has_received) has_never += ", never received from peer";
|
||||||
|
if (!has_sent) has_never += ", never sent to peer";
|
||||||
|
LogDebug(BCLog::NET,
|
||||||
|
"socket no message in first %i seconds%s, %s\n",
|
||||||
|
count_seconds(m_peer_connect_timeout),
|
||||||
|
has_never,
|
||||||
|
node.DisconnectMsg(fLogIPs)
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now > last_send + TIMEOUT_INTERVAL) {
|
if (now > last_send + TIMEOUT_INTERVAL) {
|
||||||
LogDebug(BCLog::NET, "socket sending timeout: %is peer=%d\n", count_seconds(now - last_send), node.GetId());
|
LogDebug(BCLog::NET,
|
||||||
|
"socket sending timeout: %is, %s\n", count_seconds(now - last_send),
|
||||||
|
node.DisconnectMsg(fLogIPs)
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now > last_recv + TIMEOUT_INTERVAL) {
|
if (now > last_recv + TIMEOUT_INTERVAL) {
|
||||||
LogDebug(BCLog::NET, "socket receive timeout: %is peer=%d\n", count_seconds(now - last_recv), node.GetId());
|
LogDebug(BCLog::NET,
|
||||||
|
"socket receive timeout: %is, %s\n", count_seconds(now - last_recv),
|
||||||
|
node.DisconnectMsg(fLogIPs)
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node.fSuccessfullyConnected) {
|
if (!node.fSuccessfullyConnected) {
|
||||||
if (node.m_transport->GetInfo().transport_type == TransportProtocolType::DETECTING) {
|
if (node.m_transport->GetInfo().transport_type == TransportProtocolType::DETECTING) {
|
||||||
LogDebug(BCLog::NET, "V2 handshake timeout peer=%d\n", node.GetId());
|
LogDebug(BCLog::NET, "V2 handshake timeout, %s\n", node.DisconnectMsg(fLogIPs));
|
||||||
} else {
|
} else {
|
||||||
LogDebug(BCLog::NET, "version handshake timeout peer=%d\n", node.GetId());
|
LogDebug(BCLog::NET, "version handshake timeout, %s\n", node.DisconnectMsg(fLogIPs));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2118,6 +2146,10 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
|
||||||
{
|
{
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
if (!pnode->ReceiveMsgBytes({pchBuf, (size_t)nBytes}, notify)) {
|
if (!pnode->ReceiveMsgBytes({pchBuf, (size_t)nBytes}, notify)) {
|
||||||
|
LogDebug(BCLog::NET,
|
||||||
|
"receiving message bytes failed, %s\n",
|
||||||
|
pnode->DisconnectMsg(fLogIPs)
|
||||||
|
);
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
RecordBytesRecv(nBytes);
|
RecordBytesRecv(nBytes);
|
||||||
|
@ -2130,7 +2162,7 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
|
||||||
{
|
{
|
||||||
// socket closed gracefully
|
// socket closed gracefully
|
||||||
if (!pnode->fDisconnect) {
|
if (!pnode->fDisconnect) {
|
||||||
LogDebug(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
|
LogDebug(BCLog::NET, "socket closed, %s\n", pnode->DisconnectMsg(fLogIPs));
|
||||||
}
|
}
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
|
@ -2141,7 +2173,7 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes,
|
||||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||||
{
|
{
|
||||||
if (!pnode->fDisconnect) {
|
if (!pnode->fDisconnect) {
|
||||||
LogDebug(BCLog::NET, "socket recv error for peer=%d: %s\n", pnode->GetId(), NetworkErrorString(nErr));
|
LogDebug(BCLog::NET, "socket recv error, %s: %s\n", pnode->DisconnectMsg(fLogIPs), NetworkErrorString(nErr));
|
||||||
}
|
}
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
|
@ -3058,14 +3090,14 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError,
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
|
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
|
||||||
{
|
{
|
||||||
strError = strprintf(Untranslated("Bind address family for %s not supported"), addrBind.ToStringAddrPort());
|
strError = Untranslated(strprintf("Bind address family for %s not supported", addrBind.ToStringAddrPort()));
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Error, "%s\n", strError.original);
|
LogPrintLevel(BCLog::NET, BCLog::Level::Error, "%s\n", strError.original);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Sock> sock = CreateSock(addrBind.GetSAFamily(), SOCK_STREAM, IPPROTO_TCP);
|
std::unique_ptr<Sock> sock = CreateSock(addrBind.GetSAFamily(), SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (!sock) {
|
if (!sock) {
|
||||||
strError = strprintf(Untranslated("Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError()));
|
strError = Untranslated(strprintf("Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError())));
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Error, "%s\n", strError.original);
|
LogPrintLevel(BCLog::NET, BCLog::Level::Error, "%s\n", strError.original);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3073,7 +3105,7 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError,
|
||||||
// Allow binding if the port is still in TIME_WAIT state after
|
// Allow binding if the port is still in TIME_WAIT state after
|
||||||
// the program was closed and restarted.
|
// the program was closed and restarted.
|
||||||
if (sock->SetSockOpt(SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int)) == SOCKET_ERROR) {
|
if (sock->SetSockOpt(SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int)) == SOCKET_ERROR) {
|
||||||
strError = strprintf(Untranslated("Error setting SO_REUSEADDR on socket: %s, continuing anyway"), NetworkErrorString(WSAGetLastError()));
|
strError = Untranslated(strprintf("Error setting SO_REUSEADDR on socket: %s, continuing anyway", NetworkErrorString(WSAGetLastError())));
|
||||||
LogPrintf("%s\n", strError.original);
|
LogPrintf("%s\n", strError.original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3082,14 +3114,14 @@ bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError,
|
||||||
if (addrBind.IsIPv6()) {
|
if (addrBind.IsIPv6()) {
|
||||||
#ifdef IPV6_V6ONLY
|
#ifdef IPV6_V6ONLY
|
||||||
if (sock->SetSockOpt(IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int)) == SOCKET_ERROR) {
|
if (sock->SetSockOpt(IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int)) == SOCKET_ERROR) {
|
||||||
strError = strprintf(Untranslated("Error setting IPV6_V6ONLY on socket: %s, continuing anyway"), NetworkErrorString(WSAGetLastError()));
|
strError = Untranslated(strprintf("Error setting IPV6_V6ONLY on socket: %s, continuing anyway", NetworkErrorString(WSAGetLastError())));
|
||||||
LogPrintf("%s\n", strError.original);
|
LogPrintf("%s\n", strError.original);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
|
int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
|
||||||
if (sock->SetSockOpt(IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int)) == SOCKET_ERROR) {
|
if (sock->SetSockOpt(IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int)) == SOCKET_ERROR) {
|
||||||
strError = strprintf(Untranslated("Error setting IPV6_PROTECTION_LEVEL on socket: %s, continuing anyway"), NetworkErrorString(WSAGetLastError()));
|
strError = Untranslated(strprintf("Error setting IPV6_PROTECTION_LEVEL on socket: %s, continuing anyway", NetworkErrorString(WSAGetLastError())));
|
||||||
LogPrintf("%s\n", strError.original);
|
LogPrintf("%s\n", strError.original);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3411,6 +3443,7 @@ void CConnman::StopNodes()
|
||||||
std::vector<CNode*> nodes;
|
std::vector<CNode*> nodes;
|
||||||
WITH_LOCK(m_nodes_mutex, nodes.swap(m_nodes));
|
WITH_LOCK(m_nodes_mutex, nodes.swap(m_nodes));
|
||||||
for (CNode* pnode : nodes) {
|
for (CNode* pnode : nodes) {
|
||||||
|
LogDebug(BCLog::NET, "%s\n", pnode->DisconnectMsg(fLogIPs));
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
DeleteNode(pnode);
|
DeleteNode(pnode);
|
||||||
}
|
}
|
||||||
|
|
16
src/net.h
16
src/net.h
|
@ -947,6 +947,22 @@ public:
|
||||||
|
|
||||||
std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); }
|
std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to optionally log the IP address.
|
||||||
|
*
|
||||||
|
* @param[in] log_ip whether to include the IP address
|
||||||
|
* @return " peeraddr=..." or ""
|
||||||
|
*/
|
||||||
|
std::string LogIP(bool log_ip) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to log disconnects.
|
||||||
|
*
|
||||||
|
* @param[in] log_ip whether to include the IP address
|
||||||
|
* @return "disconnecting peer=..." and optionally "peeraddr=..."
|
||||||
|
*/
|
||||||
|
std::string DisconnectMsg(bool log_ip) const;
|
||||||
|
|
||||||
/** A ping-pong round trip has completed successfully. Update latest and minimum ping times. */
|
/** A ping-pong round trip has completed successfully. Update latest and minimum ping times. */
|
||||||
void PongReceived(std::chrono::microseconds ping_time) {
|
void PongReceived(std::chrono::microseconds ping_time) {
|
||||||
m_last_ping_time = ping_time;
|
m_last_ping_time = ping_time;
|
||||||
|
|
|
@ -2238,7 +2238,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||||
(((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) &&
|
(((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) &&
|
||||||
!pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target
|
!pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target
|
||||||
) {
|
) {
|
||||||
LogDebug(BCLog::NET, "historical block serving limit reached, disconnect peer=%d\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "historical block serving limit reached, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2247,7 +2247,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||||
if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && (
|
if (!pfrom.HasPermission(NetPermissionFlags::NoBan) && (
|
||||||
(((peer.m_our_services & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((peer.m_our_services & NODE_NETWORK) != NODE_NETWORK) && (tip->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
|
(((peer.m_our_services & NODE_NETWORK_LIMITED) == NODE_NETWORK_LIMITED) && ((peer.m_our_services & NODE_NETWORK) != NODE_NETWORK) && (tip->nHeight - pindex->nHeight > (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2 /* add two blocks buffer extension for possible races */) )
|
||||||
)) {
|
)) {
|
||||||
LogDebug(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold, disconnect peer=%d\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "Ignore block request below NODE_NETWORK_LIMITED threshold, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
//disconnect node and prevent it from stalling (would otherwise wait for the missing block)
|
//disconnect node and prevent it from stalling (would otherwise wait for the missing block)
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
|
@ -2270,9 +2270,9 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||||
std::vector<uint8_t> block_data;
|
std::vector<uint8_t> block_data;
|
||||||
if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, block_pos)) {
|
if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, block_pos)) {
|
||||||
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
|
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
|
||||||
LogDebug(BCLog::NET, "Block was pruned before it could be read, disconnect peer=%s\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "Block was pruned before it could be read, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
} else {
|
} else {
|
||||||
LogError("Cannot load block from disk, disconnect peer=%d\n", pfrom.GetId());
|
LogError("Cannot load block from disk, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
}
|
}
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
|
@ -2284,9 +2284,9 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
|
||||||
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
|
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
|
||||||
if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos)) {
|
if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos)) {
|
||||||
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
|
if (WITH_LOCK(m_chainman.GetMutex(), return m_chainman.m_blockman.IsBlockPruned(*pindex))) {
|
||||||
LogDebug(BCLog::NET, "Block was pruned before it could be read, disconnect peer=%s\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "Block was pruned before it could be read, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
} else {
|
} else {
|
||||||
LogError("Cannot load block from disk, disconnect peer=%d\n", pfrom.GetId());
|
LogError("Cannot load block from disk, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
}
|
}
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
|
@ -2788,7 +2788,7 @@ void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer
|
||||||
// the minimum chain work, even if a peer has a chain past our tip,
|
// the minimum chain work, even if a peer has a chain past our tip,
|
||||||
// as an anti-DoS measure.
|
// as an anti-DoS measure.
|
||||||
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
||||||
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
|
LogInfo("outbound peer headers chain has insufficient work, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3111,8 +3111,8 @@ bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& node, Peer& peer,
|
||||||
(filter_type == BlockFilterType::BASIC &&
|
(filter_type == BlockFilterType::BASIC &&
|
||||||
(peer.m_our_services & NODE_COMPACT_FILTERS));
|
(peer.m_our_services & NODE_COMPACT_FILTERS));
|
||||||
if (!supported_filter_type) {
|
if (!supported_filter_type) {
|
||||||
LogDebug(BCLog::NET, "peer %d requested unsupported block filter type: %d\n",
|
LogDebug(BCLog::NET, "peer requested unsupported block filter type: %d, %s\n",
|
||||||
node.GetId(), static_cast<uint8_t>(filter_type));
|
static_cast<uint8_t>(filter_type), node.DisconnectMsg(fLogIPs));
|
||||||
node.fDisconnect = true;
|
node.fDisconnect = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3123,8 +3123,8 @@ bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& node, Peer& peer,
|
||||||
|
|
||||||
// Check that the stop block exists and the peer would be allowed to fetch it.
|
// Check that the stop block exists and the peer would be allowed to fetch it.
|
||||||
if (!stop_index || !BlockRequestAllowed(stop_index)) {
|
if (!stop_index || !BlockRequestAllowed(stop_index)) {
|
||||||
LogDebug(BCLog::NET, "peer %d requested invalid block hash: %s\n",
|
LogDebug(BCLog::NET, "peer requested invalid block hash: %s, %s\n",
|
||||||
node.GetId(), stop_hash.ToString());
|
stop_hash.ToString(), node.DisconnectMsg(fLogIPs));
|
||||||
node.fDisconnect = true;
|
node.fDisconnect = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3132,15 +3132,15 @@ bool PeerManagerImpl::PrepareBlockFilterRequest(CNode& node, Peer& peer,
|
||||||
|
|
||||||
uint32_t stop_height = stop_index->nHeight;
|
uint32_t stop_height = stop_index->nHeight;
|
||||||
if (start_height > stop_height) {
|
if (start_height > stop_height) {
|
||||||
LogDebug(BCLog::NET, "peer %d sent invalid getcfilters/getcfheaders with "
|
LogDebug(BCLog::NET, "peer sent invalid getcfilters/getcfheaders with "
|
||||||
"start height %d and stop height %d\n",
|
"start height %d and stop height %d, %s\n",
|
||||||
node.GetId(), start_height, stop_height);
|
start_height, stop_height, node.DisconnectMsg(fLogIPs));
|
||||||
node.fDisconnect = true;
|
node.fDisconnect = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (stop_height - start_height >= max_height_diff) {
|
if (stop_height - start_height >= max_height_diff) {
|
||||||
LogDebug(BCLog::NET, "peer %d requested too many cfilters/cfheaders: %d / %d\n",
|
LogDebug(BCLog::NET, "peer requested too many cfilters/cfheaders: %d / %d, %s\n",
|
||||||
node.GetId(), stop_height - start_height + 1, max_height_diff);
|
stop_height - start_height + 1, max_height_diff, node.DisconnectMsg(fLogIPs));
|
||||||
node.fDisconnect = true;
|
node.fDisconnect = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3407,14 +3407,17 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
}
|
}
|
||||||
if (pfrom.ExpectServicesFromConn() && !HasAllDesirableServiceFlags(nServices))
|
if (pfrom.ExpectServicesFromConn() && !HasAllDesirableServiceFlags(nServices))
|
||||||
{
|
{
|
||||||
LogDebug(BCLog::NET, "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom.GetId(), nServices, GetDesirableServiceFlags(nServices));
|
LogDebug(BCLog::NET, "peer does not offer the expected services (%08x offered, %08x expected), %s\n",
|
||||||
|
nServices,
|
||||||
|
GetDesirableServiceFlags(nServices),
|
||||||
|
pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nVersion < MIN_PEER_PROTO_VERSION) {
|
if (nVersion < MIN_PEER_PROTO_VERSION) {
|
||||||
// disconnect from peers older than this proto version
|
// disconnect from peers older than this proto version
|
||||||
LogDebug(BCLog::NET, "peer=%d using obsolete version %i; disconnecting\n", pfrom.GetId(), nVersion);
|
LogDebug(BCLog::NET, "peer using obsolete version %i, %s\n", nVersion, pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3565,15 +3568,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
m_addrman.Good(pfrom.addr);
|
m_addrman.Good(pfrom.addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string remoteAddr;
|
|
||||||
if (fLogIPs)
|
|
||||||
remoteAddr = ", peeraddr=" + pfrom.addr.ToStringAddrPort();
|
|
||||||
|
|
||||||
const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
|
const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
|
||||||
LogDebug(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s\n",
|
LogDebug(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s\n",
|
||||||
cleanSubVer, pfrom.nVersion,
|
cleanSubVer, pfrom.nVersion,
|
||||||
peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
|
peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
|
||||||
remoteAddr, (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
pfrom.LogIP(fLogIPs), (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
||||||
|
|
||||||
peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
|
peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
|
||||||
if (!pfrom.IsInboundConn()) {
|
if (!pfrom.IsInboundConn()) {
|
||||||
|
@ -3591,7 +3590,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
// Feeler connections exist only to verify if address is online.
|
// Feeler connections exist only to verify if address is online.
|
||||||
if (pfrom.IsFeelerConn()) {
|
if (pfrom.IsFeelerConn()) {
|
||||||
LogDebug(BCLog::NET, "feeler connection completed peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "feeler connection completed, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -3617,7 +3616,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
pfrom.ConnectionTypeAsString(),
|
pfrom.ConnectionTypeAsString(),
|
||||||
TransportTypeAsString(pfrom.m_transport->GetInfo().transport_type),
|
TransportTypeAsString(pfrom.m_transport->GetInfo().transport_type),
|
||||||
pfrom.nVersion.load(), peer->m_starting_height,
|
pfrom.nVersion.load(), peer->m_starting_height,
|
||||||
pfrom.GetId(), (fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToStringAddrPort()) : ""),
|
pfrom.GetId(), pfrom.LogIP(fLogIPs),
|
||||||
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
(mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3695,7 +3694,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
if (msg_type == NetMsgType::WTXIDRELAY) {
|
if (msg_type == NetMsgType::WTXIDRELAY) {
|
||||||
if (pfrom.fSuccessfullyConnected) {
|
if (pfrom.fSuccessfullyConnected) {
|
||||||
// Disconnect peers that send a wtxidrelay message after VERACK.
|
// Disconnect peers that send a wtxidrelay message after VERACK.
|
||||||
LogDebug(BCLog::NET, "wtxidrelay received after verack from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "wtxidrelay received after verack, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3717,7 +3716,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
if (msg_type == NetMsgType::SENDADDRV2) {
|
if (msg_type == NetMsgType::SENDADDRV2) {
|
||||||
if (pfrom.fSuccessfullyConnected) {
|
if (pfrom.fSuccessfullyConnected) {
|
||||||
// Disconnect peers that send a SENDADDRV2 message after VERACK.
|
// Disconnect peers that send a SENDADDRV2 message after VERACK.
|
||||||
LogDebug(BCLog::NET, "sendaddrv2 received after verack from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "sendaddrv2 received after verack, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3730,19 +3729,19 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
// from switching announcement protocols after the connection is up.
|
// from switching announcement protocols after the connection is up.
|
||||||
if (msg_type == NetMsgType::SENDTXRCNCL) {
|
if (msg_type == NetMsgType::SENDTXRCNCL) {
|
||||||
if (!m_txreconciliation) {
|
if (!m_txreconciliation) {
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl from peer=%d ignored, as our node does not have txreconciliation enabled\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "sendtxrcncl from peer=%d ignored, as our node does not have txreconciliation enabled\n", pfrom.GetId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfrom.fSuccessfullyConnected) {
|
if (pfrom.fSuccessfullyConnected) {
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received after verack from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "sendtxrcncl received after verack, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peer must not offer us reconciliations if we specified no tx relay support in VERSION.
|
// Peer must not offer us reconciliations if we specified no tx relay support in VERSION.
|
||||||
if (RejectIncomingTxs(pfrom)) {
|
if (RejectIncomingTxs(pfrom)) {
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received from peer=%d to which we indicated no tx relay; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "sendtxrcncl received to which we indicated no tx relay, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3752,7 +3751,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
// eliminates them, so that this flag fully represents what we are looking for.
|
// eliminates them, so that this flag fully represents what we are looking for.
|
||||||
const auto* tx_relay = peer->GetTxRelay();
|
const auto* tx_relay = peer->GetTxRelay();
|
||||||
if (!tx_relay || !WITH_LOCK(tx_relay->m_bloom_filter_mutex, return tx_relay->m_relay_txs)) {
|
if (!tx_relay || !WITH_LOCK(tx_relay->m_bloom_filter_mutex, return tx_relay->m_relay_txs)) {
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "sendtxrcncl received from peer=%d which indicated no tx relay to us; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "sendtxrcncl received which indicated no tx relay to us, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3765,16 +3764,16 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
peer_txreconcl_version, remote_salt);
|
peer_txreconcl_version, remote_salt);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case ReconciliationRegisterResult::NOT_FOUND:
|
case ReconciliationRegisterResult::NOT_FOUND:
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "Ignore unexpected txreconciliation signal from peer=%d\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "Ignore unexpected txreconciliation signal from peer=%d\n", pfrom.GetId());
|
||||||
break;
|
break;
|
||||||
case ReconciliationRegisterResult::SUCCESS:
|
case ReconciliationRegisterResult::SUCCESS:
|
||||||
break;
|
break;
|
||||||
case ReconciliationRegisterResult::ALREADY_REGISTERED:
|
case ReconciliationRegisterResult::ALREADY_REGISTERED:
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "txreconciliation protocol violation from peer=%d (sendtxrcncl received from already registered peer); disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "txreconciliation protocol violation (sendtxrcncl received from already registered peer), %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
case ReconciliationRegisterResult::PROTOCOL_VIOLATION:
|
case ReconciliationRegisterResult::PROTOCOL_VIOLATION:
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "txreconciliation protocol violation from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "txreconciliation protocol violation, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3877,7 +3876,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
// AddrFetch: Require multiple addresses to avoid disconnecting on self-announcements
|
// AddrFetch: Require multiple addresses to avoid disconnecting on self-announcements
|
||||||
if (pfrom.IsAddrFetchConn() && vAddr.size() > 1) {
|
if (pfrom.IsAddrFetchConn() && vAddr.size() > 1) {
|
||||||
LogDebug(BCLog::NET, "addrfetch connection completed peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "addrfetch connection completed, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -3927,7 +3926,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
}
|
}
|
||||||
} else if (inv.IsGenTxMsg()) {
|
} else if (inv.IsGenTxMsg()) {
|
||||||
if (reject_tx_invs) {
|
if (reject_tx_invs) {
|
||||||
LogDebug(BCLog::NET, "transaction (%s) inv sent in violation of protocol, disconnecting peer=%d\n", inv.hash.ToString(), pfrom.GetId());
|
LogDebug(BCLog::NET, "transaction (%s) inv sent in violation of protocol, %s\n", inv.hash.ToString(), pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4004,7 +4003,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
vRecv >> locator >> hashStop;
|
vRecv >> locator >> hashStop;
|
||||||
|
|
||||||
if (locator.vHave.size() > MAX_LOCATOR_SZ) {
|
if (locator.vHave.size() > MAX_LOCATOR_SZ) {
|
||||||
LogDebug(BCLog::NET, "getblocks locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom.GetId());
|
LogDebug(BCLog::NET, "getblocks locator size %lld > %d, %s\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4126,7 +4125,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
vRecv >> locator >> hashStop;
|
vRecv >> locator >> hashStop;
|
||||||
|
|
||||||
if (locator.vHave.size() > MAX_LOCATOR_SZ) {
|
if (locator.vHave.size() > MAX_LOCATOR_SZ) {
|
||||||
LogDebug(BCLog::NET, "getheaders locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom.GetId());
|
LogDebug(BCLog::NET, "getheaders locator size %lld > %d, %s\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4667,7 +4666,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
{
|
{
|
||||||
if (!pfrom.HasPermission(NetPermissionFlags::NoBan))
|
if (!pfrom.HasPermission(NetPermissionFlags::NoBan))
|
||||||
{
|
{
|
||||||
LogDebug(BCLog::NET, "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "mempool request with bloom filters disabled, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -4677,7 +4676,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
{
|
{
|
||||||
if (!pfrom.HasPermission(NetPermissionFlags::NoBan))
|
if (!pfrom.HasPermission(NetPermissionFlags::NoBan))
|
||||||
{
|
{
|
||||||
LogDebug(BCLog::NET, "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "mempool request with bandwidth limit reached, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -4767,7 +4766,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
if (msg_type == NetMsgType::FILTERLOAD) {
|
if (msg_type == NetMsgType::FILTERLOAD) {
|
||||||
if (!(peer->m_our_services & NODE_BLOOM)) {
|
if (!(peer->m_our_services & NODE_BLOOM)) {
|
||||||
LogDebug(BCLog::NET, "filterload received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "filterload received despite not offering bloom services, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4792,7 +4791,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
if (msg_type == NetMsgType::FILTERADD) {
|
if (msg_type == NetMsgType::FILTERADD) {
|
||||||
if (!(peer->m_our_services & NODE_BLOOM)) {
|
if (!(peer->m_our_services & NODE_BLOOM)) {
|
||||||
LogDebug(BCLog::NET, "filteradd received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "filteradd received despite not offering bloom services, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4820,7 +4819,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
|
|
||||||
if (msg_type == NetMsgType::FILTERCLEAR) {
|
if (msg_type == NetMsgType::FILTERCLEAR) {
|
||||||
if (!(peer->m_our_services & NODE_BLOOM)) {
|
if (!(peer->m_our_services & NODE_BLOOM)) {
|
||||||
LogDebug(BCLog::NET, "filterclear received despite not offering bloom services from peer=%d; disconnecting\n", pfrom.GetId());
|
LogDebug(BCLog::NET, "filterclear received despite not offering bloom services, %s\n", pfrom.DisconnectMsg(fLogIPs));
|
||||||
pfrom.fDisconnect = true;
|
pfrom.fDisconnect = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5041,7 +5040,7 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, Peer& peer, std::chrono::seco
|
||||||
// message to give the peer a chance to update us.
|
// message to give the peer a chance to update us.
|
||||||
if (state.m_chain_sync.m_sent_getheaders) {
|
if (state.m_chain_sync.m_sent_getheaders) {
|
||||||
// They've run out of time to catch up!
|
// They've run out of time to catch up!
|
||||||
LogPrintf("Disconnecting outbound peer %d for old chain, best known block = %s\n", pto.GetId(), state.pindexBestKnownBlock != nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() : "<none>");
|
LogInfo("Outbound peer has old chain, best known block = %s, %s\n", state.pindexBestKnownBlock != nullptr ? state.pindexBestKnownBlock->GetBlockHash().ToString() : "<none>", pto.DisconnectMsg(fLogIPs));
|
||||||
pto.fDisconnect = true;
|
pto.fDisconnect = true;
|
||||||
} else {
|
} else {
|
||||||
assert(state.m_chain_sync.m_work_header);
|
assert(state.m_chain_sync.m_work_header);
|
||||||
|
@ -5442,7 +5441,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||||
const auto current_time{GetTime<std::chrono::microseconds>()};
|
const auto current_time{GetTime<std::chrono::microseconds>()};
|
||||||
|
|
||||||
if (pto->IsAddrFetchConn() && current_time - pto->m_connected > 10 * AVG_ADDRESS_BROADCAST_INTERVAL) {
|
if (pto->IsAddrFetchConn() && current_time - pto->m_connected > 10 * AVG_ADDRESS_BROADCAST_INTERVAL) {
|
||||||
LogDebug(BCLog::NET, "addrfetch connection timeout; disconnecting peer=%d\n", pto->GetId());
|
LogDebug(BCLog::NET, "addrfetch connection timeout, %s\n", pto->DisconnectMsg(fLogIPs));
|
||||||
pto->fDisconnect = true;
|
pto->fDisconnect = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5786,7 +5785,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||||
// Stalling only triggers when the block download window cannot move. During normal steady state,
|
// Stalling only triggers when the block download window cannot move. During normal steady state,
|
||||||
// the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
|
// the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
|
||||||
// should only happen during initial block download.
|
// should only happen during initial block download.
|
||||||
LogPrintf("Peer=%d%s is stalling block download, disconnecting\n", pto->GetId(), fLogIPs ? strprintf(" peeraddr=%s", pto->addr.ToStringAddrPort()) : "");
|
LogInfo("Peer is stalling block download, %s\n", pto->DisconnectMsg(fLogIPs));
|
||||||
pto->fDisconnect = true;
|
pto->fDisconnect = true;
|
||||||
// Increase timeout for the next peer so that we don't disconnect multiple peers if our own
|
// Increase timeout for the next peer so that we don't disconnect multiple peers if our own
|
||||||
// bandwidth is insufficient.
|
// bandwidth is insufficient.
|
||||||
|
@ -5805,7 +5804,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||||
QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
|
QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
|
||||||
int nOtherPeersWithValidatedDownloads = m_peers_downloading_from - 1;
|
int nOtherPeersWithValidatedDownloads = m_peers_downloading_from - 1;
|
||||||
if (current_time > state.m_downloading_since + std::chrono::seconds{consensusParams.nPowTargetSpacing} * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
|
if (current_time > state.m_downloading_since + std::chrono::seconds{consensusParams.nPowTargetSpacing} * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
|
||||||
LogPrintf("Timeout downloading block %s from peer=%d%s, disconnecting\n", queuedBlock.pindex->GetBlockHash().ToString(), pto->GetId(), fLogIPs ? strprintf(" peeraddr=%s", pto->addr.ToStringAddrPort()) : "");
|
LogInfo("Timeout downloading block %s, %s\n", queuedBlock.pindex->GetBlockHash().ToString(), pto->DisconnectMsg(fLogIPs));
|
||||||
pto->fDisconnect = true;
|
pto->fDisconnect = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5821,11 +5820,11 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
||||||
// disconnect our sync peer for stalling; we have bigger
|
// disconnect our sync peer for stalling; we have bigger
|
||||||
// problems if we can't get any outbound peers.
|
// problems if we can't get any outbound peers.
|
||||||
if (!pto->HasPermission(NetPermissionFlags::NoBan)) {
|
if (!pto->HasPermission(NetPermissionFlags::NoBan)) {
|
||||||
LogPrintf("Timeout downloading headers from peer=%d%s, disconnecting\n", pto->GetId(), fLogIPs ? strprintf(" peeraddr=%s", pto->addr.ToStringAddrPort()) : "");
|
LogInfo("Timeout downloading headers, %s\n", pto->DisconnectMsg(fLogIPs));
|
||||||
pto->fDisconnect = true;
|
pto->fDisconnect = true;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("Timeout downloading headers from noban peer=%d%s, not disconnecting\n", pto->GetId(), fLogIPs ? strprintf(" peeraddr=%s", pto->addr.ToStringAddrPort()) : "");
|
LogInfo("Timeout downloading headers from noban peer, not %s\n", pto->DisconnectMsg(fLogIPs));
|
||||||
// Reset the headers sync state so that we have a
|
// Reset the headers sync state so that we have a
|
||||||
// chance to try downloading from a different peer.
|
// chance to try downloading from a different peer.
|
||||||
// Note: this will also result in at least one more
|
// Note: this will also result in at least one more
|
||||||
|
|
|
@ -430,6 +430,7 @@ public:
|
||||||
void CleanupBlockRevFiles() const;
|
void CleanupBlockRevFiles() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Calls ActivateBestChain() even if no blocks are imported.
|
||||||
void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_paths);
|
void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_paths);
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManage
|
||||||
if (auto min_work{uint256::FromUserHex(*value)}) {
|
if (auto min_work{uint256::FromUserHex(*value)}) {
|
||||||
opts.minimum_chain_work = UintToArith256(*min_work);
|
opts.minimum_chain_work = UintToArith256(*min_work);
|
||||||
} else {
|
} else {
|
||||||
return util::Error{strprintf(Untranslated("Invalid minimum work specified (%s), must be up to %d hex digits"), *value, uint256::size() * 2)};
|
return util::Error{Untranslated(strprintf("Invalid minimum work specified (%s), must be up to %d hex digits", *value, uint256::size() * 2))};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, ChainstateManage
|
||||||
if (auto block_hash{uint256::FromUserHex(*value)}) {
|
if (auto block_hash{uint256::FromUserHex(*value)}) {
|
||||||
opts.assumed_valid_block = *block_hash;
|
opts.assumed_valid_block = *block_hash;
|
||||||
} else {
|
} else {
|
||||||
return util::Error{strprintf(Untranslated("Invalid assumevalid block hash specified (%s), must be up to %d hex digits (or 0 to disable)"), *value, uint256::size() * 2)};
|
return util::Error{Untranslated(strprintf("Invalid assumevalid block hash specified (%s), must be up to %d hex digits (or 0 to disable)", *value, uint256::size() * 2))};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ bool InitError(const bilingual_str& str, const std::vector<std::string>& details
|
||||||
// functions which provide error details are ones that run during early init
|
// functions which provide error details are ones that run during early init
|
||||||
// before the GUI uiInterface is registered, so there's no point passing
|
// before the GUI uiInterface is registered, so there's no point passing
|
||||||
// main messages and details separately to uiInterface yet.
|
// main messages and details separately to uiInterface yet.
|
||||||
return InitError(details.empty() ? str : strprintf(Untranslated("%s:\n%s"), str, MakeUnorderedList(details)));
|
return InitError(details.empty() ? str : str + Untranslated(strprintf(":\n%s", MakeUnorderedList(details))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitWarning(const bilingual_str& str)
|
void InitWarning(const bilingual_str& str)
|
||||||
|
|
|
@ -324,7 +324,7 @@ public:
|
||||||
}
|
}
|
||||||
double getVerificationProgress() override
|
double getVerificationProgress() override
|
||||||
{
|
{
|
||||||
return GuessVerificationProgress(chainman().GetParams().TxData(), WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()));
|
return chainman().GuessVerificationProgress(WITH_LOCK(chainman().GetMutex(), return chainman().ActiveChain().Tip()));
|
||||||
}
|
}
|
||||||
bool isInitialBlockDownload() override
|
bool isInitialBlockDownload() override
|
||||||
{
|
{
|
||||||
|
@ -406,9 +406,9 @@ public:
|
||||||
}
|
}
|
||||||
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
|
std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
|
||||||
{
|
{
|
||||||
return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
|
return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn, this](SynchronizationState sync_state, const CBlockIndex* block) {
|
||||||
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
|
fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
|
||||||
GuessVerificationProgress(Params().TxData(), block));
|
chainman().GuessVerificationProgress(block));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
|
std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
|
||||||
|
@ -639,8 +639,8 @@ public:
|
||||||
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
|
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
|
||||||
double guessVerificationProgress(const uint256& block_hash) override
|
double guessVerificationProgress(const uint256& block_hash) override
|
||||||
{
|
{
|
||||||
LOCK(::cs_main);
|
LOCK(chainman().GetMutex());
|
||||||
return GuessVerificationProgress(chainman().GetParams().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash));
|
return chainman().GuessVerificationProgress(chainman().m_blockman.LookupBlockIndex(block_hash));
|
||||||
}
|
}
|
||||||
bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
|
bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
|
||||||
{
|
{
|
||||||
|
@ -913,19 +913,17 @@ public:
|
||||||
|
|
||||||
std::vector<uint256> getCoinbaseMerklePath() override
|
std::vector<uint256> getCoinbaseMerklePath() override
|
||||||
{
|
{
|
||||||
return BlockMerkleBranch(m_block_template->block);
|
return TransactionMerklePath(m_block_template->block, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CMutableTransaction coinbase) override
|
bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase) override
|
||||||
{
|
{
|
||||||
CBlock block{m_block_template->block};
|
CBlock block{m_block_template->block};
|
||||||
|
|
||||||
auto cb = MakeTransactionRef(std::move(coinbase));
|
|
||||||
|
|
||||||
if (block.vtx.size() == 0) {
|
if (block.vtx.size() == 0) {
|
||||||
block.vtx.push_back(cb);
|
block.vtx.push_back(coinbase);
|
||||||
} else {
|
} else {
|
||||||
block.vtx[0] = cb;
|
block.vtx[0] = coinbase;
|
||||||
}
|
}
|
||||||
|
|
||||||
block.nVersion = version;
|
block.nVersion = version;
|
||||||
|
@ -973,7 +971,9 @@ public:
|
||||||
{
|
{
|
||||||
WAIT_LOCK(notifications().m_tip_block_mutex, lock);
|
WAIT_LOCK(notifications().m_tip_block_mutex, lock);
|
||||||
notifications().m_tip_block_cv.wait_for(lock, timeout, [&]() EXCLUSIVE_LOCKS_REQUIRED(notifications().m_tip_block_mutex) {
|
notifications().m_tip_block_cv.wait_for(lock, timeout, [&]() EXCLUSIVE_LOCKS_REQUIRED(notifications().m_tip_block_mutex) {
|
||||||
return (notifications().m_tip_block != current_tip && notifications().m_tip_block != uint256::ZERO) || chainman().m_interrupt;
|
// We need to wait for m_tip_block to be set AND for the value
|
||||||
|
// to differ from the current_tip value.
|
||||||
|
return (notifications().TipBlock() && notifications().TipBlock() != current_tip) || chainman().m_interrupt;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks.
|
// Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks.
|
||||||
|
@ -981,34 +981,11 @@ public:
|
||||||
return BlockRef{chainman().ActiveChain().Tip()->GetBlockHash(), chainman().ActiveChain().Tip()->nHeight};
|
return BlockRef{chainman().ActiveChain().Tip()->GetBlockHash(), chainman().ActiveChain().Tip()->nHeight};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) override
|
std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options) override
|
||||||
{
|
|
||||||
return chainman().ProcessNewBlock(block, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/new_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int getTransactionsUpdated() override
|
|
||||||
{
|
|
||||||
return context()->mempool->GetTransactionsUpdated();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) override
|
|
||||||
{
|
|
||||||
LOCK(cs_main);
|
|
||||||
CBlockIndex* tip{chainman().ActiveChain().Tip()};
|
|
||||||
// Fail if the tip updated before the lock was taken
|
|
||||||
if (block.hashPrevBlock != tip->GetBlockHash()) {
|
|
||||||
state.Error("Block does not connect to current chain tip.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, tip, /*fCheckPOW=*/false, check_merkle_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<BlockTemplate> createNewBlock(const CScript& script_pub_key, const BlockCreateOptions& options) override
|
|
||||||
{
|
{
|
||||||
BlockAssembler::Options assemble_options{options};
|
BlockAssembler::Options assemble_options{options};
|
||||||
ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
|
ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
|
||||||
return std::make_unique<BlockTemplateImpl>(BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(script_pub_key), m_node);
|
return std::make_unique<BlockTemplateImpl>(BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(), m_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeContext* context() override { return &m_node; }
|
NodeContext* context() override { return &m_node; }
|
||||||
|
|
|
@ -52,6 +52,7 @@ kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(m_tip_block_mutex);
|
LOCK(m_tip_block_mutex);
|
||||||
|
Assume(index.GetBlockHash() != uint256::ZERO);
|
||||||
m_tip_block = index.GetBlockHash();
|
m_tip_block = index.GetBlockHash();
|
||||||
m_tip_block_cv.notify_all();
|
m_tip_block_cv.notify_all();
|
||||||
}
|
}
|
||||||
|
@ -99,6 +100,13 @@ void KernelNotifications::fatalError(const bilingual_str& message)
|
||||||
m_exit_status, message, &m_warnings);
|
m_exit_status, message, &m_warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<uint256> KernelNotifications::TipBlock()
|
||||||
|
{
|
||||||
|
AssertLockHeld(m_tip_block_mutex);
|
||||||
|
return m_tip_block;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications)
|
void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications)
|
||||||
{
|
{
|
||||||
if (auto value{args.GetIntArg("-stopatheight")}) notifications.m_stop_at_height = *value;
|
if (auto value{args.GetIntArg("-stopatheight")}) notifications.m_stop_at_height = *value;
|
||||||
|
|
|
@ -56,15 +56,17 @@ public:
|
||||||
|
|
||||||
Mutex m_tip_block_mutex;
|
Mutex m_tip_block_mutex;
|
||||||
std::condition_variable m_tip_block_cv GUARDED_BY(m_tip_block_mutex);
|
std::condition_variable m_tip_block_cv GUARDED_BY(m_tip_block_mutex);
|
||||||
//! The block for which the last blockTip notification was received for.
|
//! The block for which the last blockTip notification was received.
|
||||||
//! The initial ZERO means that no block has been connected yet, which may
|
//! It's first set when the tip is connected during node initialization.
|
||||||
//! be true even long after startup, until shutdown.
|
//! Might be unset during an early shutdown.
|
||||||
uint256 m_tip_block GUARDED_BY(m_tip_block_mutex){uint256::ZERO};
|
std::optional<uint256> TipBlock() EXCLUSIVE_LOCKS_REQUIRED(m_tip_block_mutex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::function<bool()>& m_shutdown_request;
|
const std::function<bool()>& m_shutdown_request;
|
||||||
std::atomic<int>& m_exit_status;
|
std::atomic<int>& m_exit_status;
|
||||||
node::Warnings& m_warnings;
|
node::Warnings& m_warnings;
|
||||||
|
|
||||||
|
std::optional<uint256> m_tip_block GUARDED_BY(m_tip_block_mutex);
|
||||||
};
|
};
|
||||||
|
|
||||||
void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications);
|
void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications);
|
||||||
|
|
|
@ -89,7 +89,7 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP
|
||||||
|
|
||||||
mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", DEFAULT_ACCEPT_NON_STD_TXN);
|
mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", DEFAULT_ACCEPT_NON_STD_TXN);
|
||||||
if (!chainparams.IsTestChain() && !mempool_opts.require_standard) {
|
if (!chainparams.IsTestChain() && !mempool_opts.require_standard) {
|
||||||
return util::Error{strprintf(Untranslated("acceptnonstdtxn is not currently supported for %s chain"), chainparams.GetChainTypeString())};
|
return util::Error{Untranslated(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.GetChainTypeString()))};
|
||||||
}
|
}
|
||||||
|
|
||||||
mempool_opts.persist_v1_dat = argsman.GetBoolArg("-persistmempoolv1", mempool_opts.persist_v1_dat);
|
mempool_opts.persist_v1_dat = argsman.GetBoolArg("-persistmempoolv1", mempool_opts.persist_v1_dat);
|
||||||
|
|
|
@ -105,7 +105,7 @@ void BlockAssembler::resetBlock()
|
||||||
nFees = 0;
|
nFees = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
|
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
|
||||||
{
|
{
|
||||||
const auto time_start{SteadyClock::now()};
|
const auto time_start{SteadyClock::now()};
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||||
coinbaseTx.vin.resize(1);
|
coinbaseTx.vin.resize(1);
|
||||||
coinbaseTx.vin[0].prevout.SetNull();
|
coinbaseTx.vin[0].prevout.SetNull();
|
||||||
coinbaseTx.vout.resize(1);
|
coinbaseTx.vout.resize(1);
|
||||||
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
|
coinbaseTx.vout[0].scriptPubKey = m_options.coinbase_output_script;
|
||||||
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
|
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
|
||||||
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||||
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
|
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
|
||||||
|
@ -422,6 +422,7 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
|
||||||
}
|
}
|
||||||
|
|
||||||
++nPackagesSelected;
|
++nPackagesSelected;
|
||||||
|
pblocktemplate->m_package_feerates.emplace_back(packageFees, static_cast<int32_t>(packageSize));
|
||||||
|
|
||||||
// Update transactions that depend on each of these
|
// Update transactions that depend on each of these
|
||||||
nDescendantsUpdated += UpdatePackagesForAdded(mempool, ancestors, mapModifiedTx);
|
nDescendantsUpdated += UpdatePackagesForAdded(mempool, ancestors, mapModifiedTx);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <node/types.h>
|
#include <node/types.h>
|
||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
#include <txmempool.h>
|
#include <txmempool.h>
|
||||||
|
#include <util/feefrac.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -39,6 +40,9 @@ struct CBlockTemplate
|
||||||
std::vector<CAmount> vTxFees;
|
std::vector<CAmount> vTxFees;
|
||||||
std::vector<int64_t> vTxSigOpsCost;
|
std::vector<int64_t> vTxSigOpsCost;
|
||||||
std::vector<unsigned char> vchCoinbaseCommitment;
|
std::vector<unsigned char> vchCoinbaseCommitment;
|
||||||
|
/* A vector of package fee rates, ordered by the sequence in which
|
||||||
|
* packages are selected for inclusion in the block template.*/
|
||||||
|
std::vector<FeeFrac> m_package_feerates;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Container for tracking updates to ancestor feerate as we include (parent)
|
// Container for tracking updates to ancestor feerate as we include (parent)
|
||||||
|
@ -169,8 +173,8 @@ public:
|
||||||
|
|
||||||
explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
|
explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
|
||||||
|
|
||||||
/** Construct a new block template with coinbase to scriptPubKeyIn */
|
/** Construct a new block template */
|
||||||
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
|
std::unique_ptr<CBlockTemplate> CreateNewBlock();
|
||||||
|
|
||||||
/** The number of transactions in the last assembled block (excluding coinbase transaction) */
|
/** The number of transactions in the last assembled block (excluding coinbase transaction) */
|
||||||
inline static std::optional<int64_t> m_last_block_num_txs{};
|
inline static std::optional<int64_t> m_last_block_num_txs{};
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
//! @file node/types.h is a home for public enum and struct type definitions
|
//! @file node/types.h is a home for public enum and struct type definitions
|
||||||
//! that are used by internally by node code, but also used externally by wallet
|
//! that are used internally by node code, but also used externally by wallet,
|
||||||
//! or GUI code.
|
//! mining or GUI code.
|
||||||
//!
|
//!
|
||||||
//! This file is intended to define only simple types that do not have external
|
//! This file is intended to define only simple types that do not have external
|
||||||
//! dependencies. More complicated types should be defined in dedicated header
|
//! dependencies. More complicated types should be defined in dedicated header
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#define BITCOIN_NODE_TYPES_H
|
#define BITCOIN_NODE_TYPES_H
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <script/script.h>
|
||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
enum class TransactionError {
|
enum class TransactionError {
|
||||||
|
@ -43,6 +44,22 @@ struct BlockCreateOptions {
|
||||||
* transaction outputs.
|
* transaction outputs.
|
||||||
*/
|
*/
|
||||||
size_t coinbase_output_max_additional_sigops{400};
|
size_t coinbase_output_max_additional_sigops{400};
|
||||||
|
/**
|
||||||
|
* Script to put in the coinbase transaction. The default is an
|
||||||
|
* anyone-can-spend dummy.
|
||||||
|
*
|
||||||
|
* Should only be used for tests, when the default doesn't suffice.
|
||||||
|
*
|
||||||
|
* Note that higher level code like the getblocktemplate RPC may omit the
|
||||||
|
* coinbase transaction entirely. It's instead constructed by pool software
|
||||||
|
* using fields like coinbasevalue, coinbaseaux and default_witness_commitment.
|
||||||
|
* This software typically also controls the payout outputs, even for solo
|
||||||
|
* mining.
|
||||||
|
*
|
||||||
|
* The size and sigops are not checked against
|
||||||
|
* coinbase_max_additional_weight and coinbase_output_max_additional_sigops.
|
||||||
|
*/
|
||||||
|
CScript coinbase_output_script{CScript() << OP_TRUE};
|
||||||
};
|
};
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
|
|
|
@ -89,8 +89,9 @@ bool IsChildWithParents(const Package& package);
|
||||||
*/
|
*/
|
||||||
bool IsChildWithParentsTree(const Package& package);
|
bool IsChildWithParentsTree(const Package& package);
|
||||||
|
|
||||||
/** Get the hash of these transactions' wtxids, concatenated in lexicographical order (treating the
|
/** Get the hash of the concatenated wtxids of transactions, with wtxids
|
||||||
* wtxids as little endian encoded uint256, smallest to largest). */
|
* treated as a little-endian numbers and sorted in ascending numeric order.
|
||||||
|
*/
|
||||||
uint256 GetPackageHash(const std::vector<CTransactionRef>& transactions);
|
uint256 GetPackageHash(const std::vector<CTransactionRef>& transactions);
|
||||||
|
|
||||||
#endif // BITCOIN_POLICY_PACKAGES_H
|
#endif // BITCOIN_POLICY_PACKAGES_H
|
||||||
|
|
|
@ -71,7 +71,7 @@ std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
|
||||||
// descendants (i.e. if multiple conflicts share a descendant, it will be counted multiple
|
// descendants (i.e. if multiple conflicts share a descendant, it will be counted multiple
|
||||||
// times), but we just want to be conservative to avoid doing too much work.
|
// times), but we just want to be conservative to avoid doing too much work.
|
||||||
if (nConflictingCount > MAX_REPLACEMENT_CANDIDATES) {
|
if (nConflictingCount > MAX_REPLACEMENT_CANDIDATES) {
|
||||||
return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
|
return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)",
|
||||||
txid.ToString(),
|
txid.ToString(),
|
||||||
nConflictingCount,
|
nConflictingCount,
|
||||||
MAX_REPLACEMENT_CANDIDATES);
|
MAX_REPLACEMENT_CANDIDATES);
|
||||||
|
|
|
@ -192,7 +192,10 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned
|
||||||
* For an example script for calculating H, refer to the unit tests in
|
* For an example script for calculating H, refer to the unit tests in
|
||||||
* ./test/functional/test_framework/crypto/secp256k1.py
|
* ./test/functional/test_framework/crypto/secp256k1.py
|
||||||
*/
|
*/
|
||||||
constexpr XOnlyPubKey XOnlyPubKey::NUMS_H{"50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"_hex_u8};
|
constexpr XOnlyPubKey XOnlyPubKey::NUMS_H{
|
||||||
|
// Use immediate lambda to work around GCC-14 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117966
|
||||||
|
[]() consteval { return XOnlyPubKey{"50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0"_hex_u8}; }(),
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
|
std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -529,7 +529,7 @@ int GuiMain(int argc, char* argv[])
|
||||||
SetupUIArgs(gArgs);
|
SetupUIArgs(gArgs);
|
||||||
std::string error;
|
std::string error;
|
||||||
if (!gArgs.ParseParameters(argc, argv, error)) {
|
if (!gArgs.ParseParameters(argc, argv, error)) {
|
||||||
InitError(strprintf(Untranslated("Error parsing command line arguments: %s"), error));
|
InitError(Untranslated(strprintf("Error parsing command line arguments: %s", error)));
|
||||||
// Create a message box, because the gui has neither been created nor has subscribed to core signals
|
// Create a message box, because the gui has neither been created nor has subscribed to core signals
|
||||||
QMessageBox::critical(nullptr, CLIENT_NAME,
|
QMessageBox::critical(nullptr, CLIENT_NAME,
|
||||||
// message cannot be translated because translations have not been initialized
|
// message cannot be translated because translations have not been initialized
|
||||||
|
|
|
@ -671,9 +671,11 @@ void MakeRandDeterministicDANGEROUS(const uint256& seed) noexcept
|
||||||
{
|
{
|
||||||
GetRNGState().MakeDeterministic(seed);
|
GetRNGState().MakeDeterministic(seed);
|
||||||
}
|
}
|
||||||
|
std::atomic<bool> g_used_g_prng{false}; // Only accessed from tests
|
||||||
|
|
||||||
void GetRandBytes(Span<unsigned char> bytes) noexcept
|
void GetRandBytes(Span<unsigned char> bytes) noexcept
|
||||||
{
|
{
|
||||||
|
g_used_g_prng = true;
|
||||||
ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST, /*always_use_real_rng=*/false);
|
ProcRand(bytes.data(), bytes.size(), RNGLevel::FAST, /*always_use_real_rng=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1307,6 +1307,7 @@ RPCHelpMan getblockchaininfo()
|
||||||
{RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "height of the last block pruned, plus one (only present if pruning is enabled)"},
|
{RPCResult::Type::NUM, "pruneheight", /*optional=*/true, "height of the last block pruned, plus one (only present if pruning is enabled)"},
|
||||||
{RPCResult::Type::BOOL, "automatic_pruning", /*optional=*/true, "whether automatic pruning is enabled (only present if pruning is enabled)"},
|
{RPCResult::Type::BOOL, "automatic_pruning", /*optional=*/true, "whether automatic pruning is enabled (only present if pruning is enabled)"},
|
||||||
{RPCResult::Type::NUM, "prune_target_size", /*optional=*/true, "the target size used by pruning (only present if automatic pruning is enabled)"},
|
{RPCResult::Type::NUM, "prune_target_size", /*optional=*/true, "the target size used by pruning (only present if automatic pruning is enabled)"},
|
||||||
|
{RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "the block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
|
||||||
(IsDeprecatedRPCEnabled("warnings") ?
|
(IsDeprecatedRPCEnabled("warnings") ?
|
||||||
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
|
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
|
||||||
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
|
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
|
||||||
|
@ -1336,7 +1337,7 @@ RPCHelpMan getblockchaininfo()
|
||||||
obj.pushKV("difficulty", GetDifficulty(tip));
|
obj.pushKV("difficulty", GetDifficulty(tip));
|
||||||
obj.pushKV("time", tip.GetBlockTime());
|
obj.pushKV("time", tip.GetBlockTime());
|
||||||
obj.pushKV("mediantime", tip.GetMedianTimePast());
|
obj.pushKV("mediantime", tip.GetMedianTimePast());
|
||||||
obj.pushKV("verificationprogress", GuessVerificationProgress(chainman.GetParams().TxData(), &tip));
|
obj.pushKV("verificationprogress", chainman.GuessVerificationProgress(&tip));
|
||||||
obj.pushKV("initialblockdownload", chainman.IsInitialBlockDownload());
|
obj.pushKV("initialblockdownload", chainman.IsInitialBlockDownload());
|
||||||
obj.pushKV("chainwork", tip.nChainWork.GetHex());
|
obj.pushKV("chainwork", tip.nChainWork.GetHex());
|
||||||
obj.pushKV("size_on_disk", chainman.m_blockman.CalculateCurrentUsage());
|
obj.pushKV("size_on_disk", chainman.m_blockman.CalculateCurrentUsage());
|
||||||
|
@ -1351,6 +1352,11 @@ RPCHelpMan getblockchaininfo()
|
||||||
obj.pushKV("prune_target_size", chainman.m_blockman.GetPruneTarget());
|
obj.pushKV("prune_target_size", chainman.m_blockman.GetPruneTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (chainman.GetParams().GetChainType() == ChainType::SIGNET) {
|
||||||
|
const std::vector<uint8_t>& signet_challenge =
|
||||||
|
chainman.GetParams().GetConsensus().signet_challenge;
|
||||||
|
obj.pushKV("signet_challenge", HexStr(signet_challenge));
|
||||||
|
}
|
||||||
|
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
|
obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
|
||||||
|
@ -2942,7 +2948,7 @@ static RPCHelpMan dumptxoutset()
|
||||||
return RPCHelpMan{
|
return RPCHelpMan{
|
||||||
"dumptxoutset",
|
"dumptxoutset",
|
||||||
"Write the serialized UTXO set to a file. This can be used in loadtxoutset afterwards if this snapshot height is supported in the chainparams as well.\n\n"
|
"Write the serialized UTXO set to a file. This can be used in loadtxoutset afterwards if this snapshot height is supported in the chainparams as well.\n\n"
|
||||||
"Unless the the \"latest\" type is requested, the node will roll back to the requested height and network activity will be suspended during this process. "
|
"Unless the \"latest\" type is requested, the node will roll back to the requested height and network activity will be suspended during this process. "
|
||||||
"Because of this it is discouraged to interact with the node in any other way during the execution of this call to avoid inconsistent results and race conditions, particularly RPCs that interact with blockstorage.\n\n"
|
"Because of this it is discouraged to interact with the node in any other way during the execution of this call to avoid inconsistent results and race conditions, particularly RPCs that interact with blockstorage.\n\n"
|
||||||
"This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
|
"This call may take several minutes. Make sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",
|
||||||
{
|
{
|
||||||
|
@ -3338,7 +3344,7 @@ return RPCHelpMan{
|
||||||
data.pushKV("blocks", (int)chain.Height());
|
data.pushKV("blocks", (int)chain.Height());
|
||||||
data.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
|
data.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
|
||||||
data.pushKV("difficulty", GetDifficulty(*tip));
|
data.pushKV("difficulty", GetDifficulty(*tip));
|
||||||
data.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
|
data.pushKV("verificationprogress", chainman.GuessVerificationProgress(tip));
|
||||||
data.pushKV("coins_db_cache_bytes", cs.m_coinsdb_cache_size_bytes);
|
data.pushKV("coins_db_cache_bytes", cs.m_coinsdb_cache_size_bytes);
|
||||||
data.pushKV("coins_tip_cache_bytes", cs.m_coinstip_cache_size_bytes);
|
data.pushKV("coins_tip_cache_bytes", cs.m_coinstip_cache_size_bytes);
|
||||||
if (cs.m_from_snapshot_blockhash) {
|
if (cs.m_from_snapshot_blockhash) {
|
||||||
|
|
|
@ -146,7 +146,8 @@ static RPCHelpMan testmempoolaccept()
|
||||||
{RPCResult{RPCResult::Type::STR_HEX, "", "transaction wtxid in hex"},
|
{RPCResult{RPCResult::Type::STR_HEX, "", "transaction wtxid in hex"},
|
||||||
}},
|
}},
|
||||||
}},
|
}},
|
||||||
{RPCResult::Type::STR, "reject-reason", /*optional=*/true, "Rejection string (only present when 'allowed' is false)"},
|
{RPCResult::Type::STR, "reject-reason", /*optional=*/true, "Rejection reason (only present when 'allowed' is false)"},
|
||||||
|
{RPCResult::Type::STR, "reject-details", /*optional=*/true, "Rejection details (only present when 'allowed' is false and rejection details exist)"},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -245,6 +246,7 @@ static RPCHelpMan testmempoolaccept()
|
||||||
result_inner.pushKV("reject-reason", "missing-inputs");
|
result_inner.pushKV("reject-reason", "missing-inputs");
|
||||||
} else {
|
} else {
|
||||||
result_inner.pushKV("reject-reason", state.GetRejectReason());
|
result_inner.pushKV("reject-reason", state.GetRejectReason());
|
||||||
|
result_inner.pushKV("reject-details", state.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpc_result.push_back(std::move(result_inner));
|
rpc_result.push_back(std::move(result_inner));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2010 Satoshi Nakamoto
|
// Copyright (c) 2010 Satoshi Nakamoto
|
||||||
// Copyright (c) 2009-2022 The Bitcoin Core developers
|
// Copyright (c) 2009-present The Bitcoin Core developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ static RPCHelpMan getnetworkhashps()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GenerateBlock(ChainstateManager& chainman, Mining& miner, CBlock&& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block)
|
static bool GenerateBlock(ChainstateManager& chainman, CBlock&& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block)
|
||||||
{
|
{
|
||||||
block_out.reset();
|
block_out.reset();
|
||||||
block.hashMerkleRoot = BlockMerkleRoot(block);
|
block.hashMerkleRoot = BlockMerkleRoot(block);
|
||||||
|
@ -151,22 +151,22 @@ static bool GenerateBlock(ChainstateManager& chainman, Mining& miner, CBlock&& b
|
||||||
|
|
||||||
if (!process_new_block) return true;
|
if (!process_new_block) return true;
|
||||||
|
|
||||||
if (!miner.processNewBlock(block_out, nullptr)) {
|
if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries)
|
static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CScript& coinbase_output_script, int nGenerate, uint64_t nMaxTries)
|
||||||
{
|
{
|
||||||
UniValue blockHashes(UniValue::VARR);
|
UniValue blockHashes(UniValue::VARR);
|
||||||
while (nGenerate > 0 && !chainman.m_interrupt) {
|
while (nGenerate > 0 && !chainman.m_interrupt) {
|
||||||
std::unique_ptr<BlockTemplate> block_template(miner.createNewBlock(coinbase_script));
|
std::unique_ptr<BlockTemplate> block_template(miner.createNewBlock({ .coinbase_output_script = coinbase_output_script }));
|
||||||
CHECK_NONFATAL(block_template);
|
CHECK_NONFATAL(block_template);
|
||||||
|
|
||||||
std::shared_ptr<const CBlock> block_out;
|
std::shared_ptr<const CBlock> block_out;
|
||||||
if (!GenerateBlock(chainman, miner, block_template->getBlock(), nMaxTries, block_out, /*process_new_block=*/true)) {
|
if (!GenerateBlock(chainman, block_template->getBlock(), nMaxTries, block_out, /*process_new_block=*/true)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,9 +236,9 @@ static RPCHelpMan generatetodescriptor()
|
||||||
const auto num_blocks{self.Arg<int>("num_blocks")};
|
const auto num_blocks{self.Arg<int>("num_blocks")};
|
||||||
const auto max_tries{self.Arg<uint64_t>("maxtries")};
|
const auto max_tries{self.Arg<uint64_t>("maxtries")};
|
||||||
|
|
||||||
CScript coinbase_script;
|
CScript coinbase_output_script;
|
||||||
std::string error;
|
std::string error;
|
||||||
if (!getScriptFromDescriptor(self.Arg<std::string>("descriptor"), coinbase_script, error)) {
|
if (!getScriptFromDescriptor(self.Arg<std::string>("descriptor"), coinbase_output_script, error)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ static RPCHelpMan generatetodescriptor()
|
||||||
Mining& miner = EnsureMining(node);
|
Mining& miner = EnsureMining(node);
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
|
|
||||||
return generateBlocks(chainman, miner, coinbase_script, num_blocks, max_tries);
|
return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -292,9 +292,9 @@ static RPCHelpMan generatetoaddress()
|
||||||
Mining& miner = EnsureMining(node);
|
Mining& miner = EnsureMining(node);
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
|
|
||||||
CScript coinbase_script = GetScriptForDestination(destination);
|
CScript coinbase_output_script = GetScriptForDestination(destination);
|
||||||
|
|
||||||
return generateBlocks(chainman, miner, coinbase_script, num_blocks, max_tries);
|
return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -328,16 +328,16 @@ static RPCHelpMan generateblock()
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
const auto address_or_descriptor = request.params[0].get_str();
|
const auto address_or_descriptor = request.params[0].get_str();
|
||||||
CScript coinbase_script;
|
CScript coinbase_output_script;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|
||||||
if (!getScriptFromDescriptor(address_or_descriptor, coinbase_script, error)) {
|
if (!getScriptFromDescriptor(address_or_descriptor, coinbase_output_script, error)) {
|
||||||
const auto destination = DecodeDestination(address_or_descriptor);
|
const auto destination = DecodeDestination(address_or_descriptor);
|
||||||
if (!IsValidDestination(destination)) {
|
if (!IsValidDestination(destination)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address or descriptor");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address or descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
coinbase_script = GetScriptForDestination(destination);
|
coinbase_output_script = GetScriptForDestination(destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
|
@ -371,29 +371,30 @@ static RPCHelpMan generateblock()
|
||||||
|
|
||||||
ChainstateManager& chainman = EnsureChainman(node);
|
ChainstateManager& chainman = EnsureChainman(node);
|
||||||
{
|
{
|
||||||
std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock(coinbase_script, {.use_mempool = false})};
|
LOCK(chainman.GetMutex());
|
||||||
CHECK_NONFATAL(block_template);
|
{
|
||||||
|
std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script})};
|
||||||
|
CHECK_NONFATAL(block_template);
|
||||||
|
|
||||||
block = block_template->getBlock();
|
block = block_template->getBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_NONFATAL(block.vtx.size() == 1);
|
CHECK_NONFATAL(block.vtx.size() == 1);
|
||||||
|
|
||||||
// Add transactions
|
// Add transactions
|
||||||
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
|
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
|
||||||
RegenerateCommitments(block, chainman);
|
RegenerateCommitments(block, chainman);
|
||||||
|
|
||||||
{
|
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
if (!miner.testBlockValidity(block, /*check_merkle_root=*/false, state)) {
|
if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/false)) {
|
||||||
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString()));
|
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const CBlock> block_out;
|
std::shared_ptr<const CBlock> block_out;
|
||||||
uint64_t max_tries{DEFAULT_MAX_TRIES};
|
uint64_t max_tries{DEFAULT_MAX_TRIES};
|
||||||
|
|
||||||
if (!GenerateBlock(chainman, miner, std::move(block), max_tries, block_out, process_new_block) || !block_out) {
|
if (!GenerateBlock(chainman, std::move(block), max_tries, block_out, process_new_block) || !block_out) {
|
||||||
throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
|
throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,6 +425,7 @@ static RPCHelpMan getmininginfo()
|
||||||
{RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
|
{RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
|
||||||
{RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
|
{RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
|
||||||
{RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},
|
{RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},
|
||||||
|
{RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
|
||||||
(IsDeprecatedRPCEnabled("warnings") ?
|
(IsDeprecatedRPCEnabled("warnings") ?
|
||||||
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
|
RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
|
||||||
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
|
RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
|
||||||
|
@ -453,6 +455,11 @@ static RPCHelpMan getmininginfo()
|
||||||
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
|
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
|
||||||
obj.pushKV("pooledtx", (uint64_t)mempool.size());
|
obj.pushKV("pooledtx", (uint64_t)mempool.size());
|
||||||
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
|
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
|
||||||
|
if (chainman.GetParams().GetChainType() == ChainType::SIGNET) {
|
||||||
|
const std::vector<uint8_t>& signet_challenge =
|
||||||
|
chainman.GetParams().GetConsensus().signet_challenge;
|
||||||
|
obj.pushKV("signet_challenge", HexStr(signet_challenge));
|
||||||
|
}
|
||||||
obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
|
obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
@ -626,8 +633,8 @@ static RPCHelpMan getblocktemplate()
|
||||||
{RPCResult::Type::OBJ, "", "",
|
{RPCResult::Type::OBJ, "", "",
|
||||||
{
|
{
|
||||||
{RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
|
{RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
|
||||||
{RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"},
|
{RPCResult::Type::STR_HEX, "txid", "transaction hash excluding witness data, shown in byte-reversed hex"},
|
||||||
{RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal (including witness data)"},
|
{RPCResult::Type::STR_HEX, "hash", "transaction hash including witness data, shown in byte-reversed hex"},
|
||||||
{RPCResult::Type::ARR, "depends", "array of numbers",
|
{RPCResult::Type::ARR, "depends", "array of numbers",
|
||||||
{
|
{
|
||||||
{RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
|
{RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
|
||||||
|
@ -709,12 +716,12 @@ static RPCHelpMan getblocktemplate()
|
||||||
return "duplicate-inconclusive";
|
return "duplicate-inconclusive";
|
||||||
}
|
}
|
||||||
|
|
||||||
// testBlockValidity only supports blocks built on the current Tip
|
// TestBlockValidity only supports blocks built on the current Tip
|
||||||
if (block.hashPrevBlock != tip) {
|
if (block.hashPrevBlock != tip) {
|
||||||
return "inconclusive-not-best-prevblk";
|
return "inconclusive-not-best-prevblk";
|
||||||
}
|
}
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
miner.testBlockValidity(block, /*check_merkle_root=*/true, state);
|
TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/true);
|
||||||
return BIP22ValidationResult(state);
|
return BIP22ValidationResult(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,6 +749,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int nTransactionsUpdatedLast;
|
static unsigned int nTransactionsUpdatedLast;
|
||||||
|
const CTxMemPool& mempool = EnsureMemPool(node);
|
||||||
|
|
||||||
if (!lpval.isNull())
|
if (!lpval.isNull())
|
||||||
{
|
{
|
||||||
|
@ -772,7 +780,7 @@ static RPCHelpMan getblocktemplate()
|
||||||
tip = miner.waitTipChanged(hashWatchedChain, checktxtime).hash;
|
tip = miner.waitTipChanged(hashWatchedChain, checktxtime).hash;
|
||||||
// Timeout: Check transactions for update
|
// Timeout: Check transactions for update
|
||||||
// without holding the mempool lock to avoid deadlocks
|
// without holding the mempool lock to avoid deadlocks
|
||||||
if (miner.getTransactionsUpdated() != nTransactionsUpdatedLastLP)
|
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
|
||||||
break;
|
break;
|
||||||
checktxtime = std::chrono::seconds(10);
|
checktxtime = std::chrono::seconds(10);
|
||||||
}
|
}
|
||||||
|
@ -803,19 +811,18 @@ static RPCHelpMan getblocktemplate()
|
||||||
static int64_t time_start;
|
static int64_t time_start;
|
||||||
static std::unique_ptr<BlockTemplate> block_template;
|
static std::unique_ptr<BlockTemplate> block_template;
|
||||||
if (!pindexPrev || pindexPrev->GetBlockHash() != tip ||
|
if (!pindexPrev || pindexPrev->GetBlockHash() != tip ||
|
||||||
(miner.getTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
|
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
|
||||||
{
|
{
|
||||||
// Clear pindexPrev so future calls make a new block, despite any failures from here on
|
// Clear pindexPrev so future calls make a new block, despite any failures from here on
|
||||||
pindexPrev = nullptr;
|
pindexPrev = nullptr;
|
||||||
|
|
||||||
// Store the pindexBest used before createNewBlock, to avoid races
|
// Store the pindexBest used before createNewBlock, to avoid races
|
||||||
nTransactionsUpdatedLast = miner.getTransactionsUpdated();
|
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
||||||
CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip);
|
CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip);
|
||||||
time_start = GetTime();
|
time_start = GetTime();
|
||||||
|
|
||||||
// Create new block
|
// Create new block
|
||||||
CScript scriptDummy = CScript() << OP_TRUE;
|
block_template = miner.createNewBlock();
|
||||||
block_template = miner.createNewBlock(scriptDummy);
|
|
||||||
CHECK_NONFATAL(block_template);
|
CHECK_NONFATAL(block_template);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1033,13 +1040,10 @@ static RPCHelpMan submitblock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeContext& node = EnsureAnyNodeContext(request.context);
|
|
||||||
Mining& miner = EnsureMining(node);
|
|
||||||
|
|
||||||
bool new_block;
|
bool new_block;
|
||||||
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
||||||
CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);
|
CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);
|
||||||
bool accepted = miner.processNewBlock(blockptr, /*new_block=*/&new_block);
|
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
|
||||||
CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);
|
CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);
|
||||||
if (!new_block && accepted) {
|
if (!new_block && accepted) {
|
||||||
return "duplicate";
|
return "duplicate";
|
||||||
|
|
|
@ -1761,7 +1761,7 @@ struct KeyParser {
|
||||||
std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
|
std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
|
||||||
{
|
{
|
||||||
using namespace script;
|
using namespace script;
|
||||||
|
Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
|
||||||
std::vector<std::unique_ptr<DescriptorImpl>> ret;
|
std::vector<std::unique_ptr<DescriptorImpl>> ret;
|
||||||
auto expr = Expr(sp);
|
auto expr = Expr(sp);
|
||||||
if (Func("pk", expr)) {
|
if (Func("pk", expr)) {
|
||||||
|
@ -1787,10 +1787,6 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index
|
||||||
ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
|
ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} else if (ctx != ParseScriptContext::P2TR && Func("pkh", expr)) {
|
|
||||||
// Under Taproot, always the Miniscript parser deal with it.
|
|
||||||
error = "Can only have pkh at top level, in sh(), wsh(), or in tr()";
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
|
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
|
||||||
auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
|
auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
|
||||||
|
|
|
@ -1798,7 +1798,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
|
||||||
// Get threshold
|
// Get threshold
|
||||||
int next_comma = FindNextChar(in, ',');
|
int next_comma = FindNextChar(in, ',');
|
||||||
if (next_comma < 1) return false;
|
if (next_comma < 1) return false;
|
||||||
const auto k_to_integral{ToIntegral<int64_t>(std::string_view(in.begin(), next_comma))};
|
const auto k_to_integral{ToIntegral<int64_t>(std::string_view(in.data(), next_comma))};
|
||||||
if (!k_to_integral.has_value()) return false;
|
if (!k_to_integral.has_value()) return false;
|
||||||
const int64_t k{k_to_integral.value()};
|
const int64_t k{k_to_integral.value()};
|
||||||
in = in.subspan(next_comma + 1);
|
in = in.subspan(next_comma + 1);
|
||||||
|
@ -1954,7 +1954,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
|
||||||
} else if (Const("after(", in)) {
|
} else if (Const("after(", in)) {
|
||||||
int arg_size = FindNextChar(in, ')');
|
int arg_size = FindNextChar(in, ')');
|
||||||
if (arg_size < 1) return {};
|
if (arg_size < 1) return {};
|
||||||
const auto num{ToIntegral<int64_t>(std::string_view(in.begin(), arg_size))};
|
const auto num{ToIntegral<int64_t>(std::string_view(in.data(), arg_size))};
|
||||||
if (!num.has_value() || *num < 1 || *num >= 0x80000000L) return {};
|
if (!num.has_value() || *num < 1 || *num >= 0x80000000L) return {};
|
||||||
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::AFTER, *num));
|
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::AFTER, *num));
|
||||||
in = in.subspan(arg_size + 1);
|
in = in.subspan(arg_size + 1);
|
||||||
|
@ -1962,7 +1962,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
|
||||||
} else if (Const("older(", in)) {
|
} else if (Const("older(", in)) {
|
||||||
int arg_size = FindNextChar(in, ')');
|
int arg_size = FindNextChar(in, ')');
|
||||||
if (arg_size < 1) return {};
|
if (arg_size < 1) return {};
|
||||||
const auto num{ToIntegral<int64_t>(std::string_view(in.begin(), arg_size))};
|
const auto num{ToIntegral<int64_t>(std::string_view(in.data(), arg_size))};
|
||||||
if (!num.has_value() || *num < 1 || *num >= 0x80000000L) return {};
|
if (!num.has_value() || *num < 1 || *num >= 0x80000000L) return {};
|
||||||
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::OLDER, *num));
|
constructed.push_back(MakeNodeRef<Key>(internal::NoDupCheck{}, ctx.MsContext(), Fragment::OLDER, *num));
|
||||||
in = in.subspan(arg_size + 1);
|
in = in.subspan(arg_size + 1);
|
||||||
|
@ -1974,7 +1974,7 @@ inline NodeRef<Key> Parse(Span<const char> in, const Ctx& ctx)
|
||||||
} else if (Const("thresh(", in)) {
|
} else if (Const("thresh(", in)) {
|
||||||
int next_comma = FindNextChar(in, ',');
|
int next_comma = FindNextChar(in, ',');
|
||||||
if (next_comma < 1) return {};
|
if (next_comma < 1) return {};
|
||||||
const auto k{ToIntegral<int64_t>(std::string_view(in.begin(), next_comma))};
|
const auto k{ToIntegral<int64_t>(std::string_view(in.data(), next_comma))};
|
||||||
if (!k.has_value() || *k < 1) return {};
|
if (!k.has_value() || *k < 1) return {};
|
||||||
in = in.subspan(next_comma + 1);
|
in = in.subspan(next_comma + 1);
|
||||||
// n = 1 here because we read the first WRAPPED_EXPR before reaching THRESH
|
// n = 1 here because we read the first WRAPPED_EXPR before reaching THRESH
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <attributes.h>
|
#include <attributes.h>
|
||||||
#include <script/script.h>
|
#include <script/script.h>
|
||||||
|
#include <span.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -17,7 +18,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class CPubKey;
|
class CPubKey;
|
||||||
template <typename C> class Span;
|
|
||||||
|
|
||||||
enum class TxoutType {
|
enum class TxoutType {
|
||||||
NONSTANDARD,
|
NONSTANDARD,
|
||||||
|
|
|
@ -264,6 +264,7 @@ template<typename Stream> inline void Serialize(Stream& s, int64_t a ) { ser_wri
|
||||||
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
|
template<typename Stream> inline void Serialize(Stream& s, uint64_t a) { ser_writedata64(s, a); }
|
||||||
template <typename Stream, BasicByte B, int N> void Serialize(Stream& s, const B (&a)[N]) { s.write(MakeByteSpan(a)); }
|
template <typename Stream, BasicByte B, int N> void Serialize(Stream& s, const B (&a)[N]) { s.write(MakeByteSpan(a)); }
|
||||||
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, const std::array<B, N>& a) { s.write(MakeByteSpan(a)); }
|
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, const std::array<B, N>& a) { s.write(MakeByteSpan(a)); }
|
||||||
|
template <typename Stream, BasicByte B, std::size_t N> void Serialize(Stream& s, std::span<B, N> span) { s.write(std::as_bytes(span)); }
|
||||||
template <typename Stream, BasicByte B> void Serialize(Stream& s, Span<B> span) { s.write(AsBytes(span)); }
|
template <typename Stream, BasicByte B> void Serialize(Stream& s, Span<B> span) { s.write(AsBytes(span)); }
|
||||||
|
|
||||||
template <typename Stream, CharNotInt8 V> void Unserialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
|
template <typename Stream, CharNotInt8 V> void Unserialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
|
||||||
|
@ -278,6 +279,7 @@ template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a =
|
||||||
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
|
template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
|
||||||
template <typename Stream, BasicByte B, int N> void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
|
template <typename Stream, BasicByte B, int N> void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
|
||||||
template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::array<B, N>& a) { s.read(MakeWritableByteSpan(a)); }
|
template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::array<B, N>& a) { s.read(MakeWritableByteSpan(a)); }
|
||||||
|
template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::span<B, N> span) { s.read(std::as_writable_bytes(span)); }
|
||||||
template <typename Stream, BasicByte B> void Unserialize(Stream& s, Span<B> span) { s.read(AsWritableBytes(span)); }
|
template <typename Stream, BasicByte B> void Unserialize(Stream& s, Span<B> span) { s.read(AsWritableBytes(span)); }
|
||||||
|
|
||||||
template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); }
|
template <typename Stream> inline void Serialize(Stream& s, bool a) { uint8_t f = a; ser_writedata8(s, f); }
|
||||||
|
|
|
@ -248,9 +248,8 @@ template <typename T>
|
||||||
T& SpanPopBack(Span<T>& span)
|
T& SpanPopBack(Span<T>& span)
|
||||||
{
|
{
|
||||||
size_t size = span.size();
|
size_t size = span.size();
|
||||||
ASSERT_IF_DEBUG(size > 0);
|
T& back = span.back();
|
||||||
T& back = span[size - 1];
|
span = span.first(size - 1);
|
||||||
span = Span<T>(span.data(), size - 1);
|
|
||||||
return back;
|
return back;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ public:
|
||||||
memcpy(vchData.data() + nPos, src.data(), nOverwrite);
|
memcpy(vchData.data() + nPos, src.data(), nOverwrite);
|
||||||
}
|
}
|
||||||
if (nOverwrite < src.size()) {
|
if (nOverwrite < src.size()) {
|
||||||
vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.end()));
|
vchData.insert(vchData.end(), UCharCast(src.data()) + nOverwrite, UCharCast(src.data() + src.size()));
|
||||||
}
|
}
|
||||||
nPos += src.size();
|
nPos += src.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
// Copyright (c) 2009-2021 The Bitcoin Core developers
|
// Copyright (c) 2009-present The Bitcoin Core developers
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ secure_unique_ptr<T> make_secure_unique(Args&&... as)
|
||||||
|
|
||||||
// initialize in place, and return as secure_unique_ptr
|
// initialize in place, and return as secure_unique_ptr
|
||||||
try {
|
try {
|
||||||
return secure_unique_ptr<T>(new (p) T(std::forward(as)...));
|
return secure_unique_ptr<T>(new (p) T(std::forward<Args>(as)...));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
secure_allocator<T>().deallocate(p, 1);
|
secure_allocator<T>().deallocate(p, 1);
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -18,7 +18,6 @@ generate_header_from_raw(data/asmap.raw test::data)
|
||||||
# SOURCES property is processed to gather test suite macros.
|
# SOURCES property is processed to gather test suite macros.
|
||||||
add_executable(test_bitcoin
|
add_executable(test_bitcoin
|
||||||
main.cpp
|
main.cpp
|
||||||
$<TARGET_OBJECTS:bitcoin_consensus>
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/data/asmap.raw.h
|
${CMAKE_CURRENT_BINARY_DIR}/data/asmap.raw.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/data/base58_encode_decode.json.h
|
${CMAKE_CURRENT_BINARY_DIR}/data/base58_encode_decode.json.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/data/bip341_wallet_vectors.json.h
|
${CMAKE_CURRENT_BINARY_DIR}/data/bip341_wallet_vectors.json.h
|
||||||
|
@ -151,6 +150,7 @@ target_link_libraries(test_bitcoin
|
||||||
test_util
|
test_util
|
||||||
bitcoin_cli
|
bitcoin_cli
|
||||||
bitcoin_node
|
bitcoin_node
|
||||||
|
bitcoin_consensus
|
||||||
minisketch
|
minisketch
|
||||||
secp256k1
|
secp256k1
|
||||||
Boost::headers
|
Boost::headers
|
||||||
|
|
|
@ -67,8 +67,9 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
|
||||||
const std::vector<CMutableTransaction>& txns,
|
const std::vector<CMutableTransaction>& txns,
|
||||||
const CScript& scriptPubKey)
|
const CScript& scriptPubKey)
|
||||||
{
|
{
|
||||||
BlockAssembler::Options options;
|
BlockAssembler::Options options;
|
||||||
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock(scriptPubKey);
|
options.coinbase_output_script = scriptPubKey;
|
||||||
|
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||||
CBlock& block = pblocktemplate->block;
|
CBlock& block = pblocktemplate->block;
|
||||||
block.hashPrevBlock = prev->GetBlockHash();
|
block.hashPrevBlock = prev->GetBlockHash();
|
||||||
block.nTime = prev->nTime + 1;
|
block.nTime = prev->nTime + 1;
|
||||||
|
|
|
@ -161,7 +161,8 @@ void DoCheck(std::string prv, std::string pub, const std::string& norm_pub, int
|
||||||
// We must be able to estimate the max satisfaction size for any solvable descriptor top descriptor (but combo).
|
// We must be able to estimate the max satisfaction size for any solvable descriptor top descriptor (but combo).
|
||||||
const bool is_nontop_or_nonsolvable{!parse_priv->IsSolvable() || !parse_priv->GetOutputType()};
|
const bool is_nontop_or_nonsolvable{!parse_priv->IsSolvable() || !parse_priv->GetOutputType()};
|
||||||
const auto max_sat_maxsig{parse_priv->MaxSatisfactionWeight(true)};
|
const auto max_sat_maxsig{parse_priv->MaxSatisfactionWeight(true)};
|
||||||
const auto max_sat_nonmaxsig{parse_priv->MaxSatisfactionWeight(true)};
|
const auto max_sat_nonmaxsig{parse_priv->MaxSatisfactionWeight(false)};
|
||||||
|
BOOST_CHECK(max_sat_nonmaxsig <= max_sat_maxsig);
|
||||||
const auto max_elems{parse_priv->MaxSatisfactionElems()};
|
const auto max_elems{parse_priv->MaxSatisfactionElems()};
|
||||||
const bool is_input_size_info_set{max_sat_maxsig && max_sat_nonmaxsig && max_elems};
|
const bool is_input_size_info_set{max_sat_maxsig && max_sat_nonmaxsig && max_elems};
|
||||||
BOOST_CHECK_MESSAGE(is_input_size_info_set || is_nontop_or_nonsolvable, prv);
|
BOOST_CHECK_MESSAGE(is_input_size_info_set || is_nontop_or_nonsolvable, prv);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
|
@ -41,6 +41,7 @@ void initialize_addrman()
|
||||||
|
|
||||||
FUZZ_TARGET(data_stream_addr_man, .init = initialize_addrman)
|
FUZZ_TARGET(data_stream_addr_man, .init = initialize_addrman)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
DataStream data_stream = ConsumeDataStream(fuzzed_data_provider);
|
DataStream data_stream = ConsumeDataStream(fuzzed_data_provider);
|
||||||
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
|
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
|
||||||
|
@ -113,6 +114,7 @@ void FillAddrman(AddrMan& addrman, FuzzedDataProvider& fuzzed_data_provider)
|
||||||
|
|
||||||
FUZZ_TARGET(addrman, .init = initialize_addrman)
|
FUZZ_TARGET(addrman, .init = initialize_addrman)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
|
NetGroupManager netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
|
||||||
|
@ -197,6 +199,7 @@ FUZZ_TARGET(addrman, .init = initialize_addrman)
|
||||||
// Check that serialize followed by unserialize produces the same addrman.
|
// Check that serialize followed by unserialize produces the same addrman.
|
||||||
FUZZ_TARGET(addrman_serdeser, .init = initialize_addrman)
|
FUZZ_TARGET(addrman_serdeser, .init = initialize_addrman)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs)
|
||||||
|
|
||||||
FUZZ_TARGET(banman, .init = initialize_banman)
|
FUZZ_TARGET(banman, .init = initialize_banman)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
|
fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
|
|
||||||
FUZZ_TARGET(blockfilter)
|
FUZZ_TARGET(blockfilter)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
const std::optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider);
|
const std::optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider);
|
||||||
if (!block_filter) {
|
if (!block_filter) {
|
||||||
|
|
|
@ -36,6 +36,7 @@ void initialize_connman()
|
||||||
|
|
||||||
FUZZ_TARGET(connman, .init = initialize_connman)
|
FUZZ_TARGET(connman, .init = initialize_connman)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
|
auto netgroupman{ConsumeNetGroupManager(fuzzed_data_provider)};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <netaddress.h>
|
#include <netaddress.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
|
#include <test/fuzz/util/check_globals.h>
|
||||||
#include <test/util/random.h>
|
#include <test/util/random.h>
|
||||||
#include <test/util/setup_common.h>
|
#include <test/util/setup_common.h>
|
||||||
#include <util/check.h>
|
#include <util/check.h>
|
||||||
|
@ -78,6 +79,12 @@ void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target,
|
||||||
static std::string_view g_fuzz_target;
|
static std::string_view g_fuzz_target;
|
||||||
static const TypeTestOneInput* g_test_one_input{nullptr};
|
static const TypeTestOneInput* g_test_one_input{nullptr};
|
||||||
|
|
||||||
|
inline void test_one_input(FuzzBufferType buffer)
|
||||||
|
{
|
||||||
|
CheckGlobals check{};
|
||||||
|
(*Assert(g_test_one_input))(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
const std::function<std::string()> G_TEST_GET_FULL_NAME{[]{
|
const std::function<std::string()> G_TEST_GET_FULL_NAME{[]{
|
||||||
return std::string{g_fuzz_target};
|
return std::string{g_fuzz_target};
|
||||||
}};
|
}};
|
||||||
|
@ -210,7 +217,6 @@ void signal_handler(int signal)
|
||||||
// This function is used by libFuzzer
|
// This function is used by libFuzzer
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||||
{
|
{
|
||||||
static const auto& test_one_input = *Assert(g_test_one_input);
|
|
||||||
test_one_input({data, size});
|
test_one_input({data, size});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -227,7 +233,6 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
initialize();
|
initialize();
|
||||||
static const auto& test_one_input = *Assert(g_test_one_input);
|
|
||||||
#ifdef __AFL_LOOP
|
#ifdef __AFL_LOOP
|
||||||
// Enable AFL persistent mode. Requires compilation using afl-clang-fast++.
|
// Enable AFL persistent mode. Requires compilation using afl-clang-fast++.
|
||||||
// See fuzzing.md for details.
|
// See fuzzing.md for details.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
#include <util/bytevectorhash.h>
|
#include <util/bytevectorhash.h>
|
||||||
#include <util/golombrice.h>
|
#include <util/golombrice.h>
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@ std::vector<uint64_t> BuildHashedSet(const std::unordered_set<std::vector<uint8_
|
||||||
|
|
||||||
FUZZ_TARGET(golomb_rice)
|
FUZZ_TARGET(golomb_rice)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
std::vector<uint8_t> golomb_rice_data;
|
std::vector<uint8_t> golomb_rice_data;
|
||||||
std::vector<uint64_t> encoded_deltas;
|
std::vector<uint64_t> encoded_deltas;
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
|
|
||||||
FUZZ_TARGET(headers_sync_state, .init = initialize_headers_sync_state_fuzz)
|
FUZZ_TARGET(headers_sync_state, .init = initialize_headers_sync_state_fuzz)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
auto mock_time{ConsumeTime(fuzzed_data_provider)};
|
auto mock_time{ConsumeTime(fuzzed_data_provider)};
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ void initialize_i2p()
|
||||||
|
|
||||||
FUZZ_TARGET(i2p, .init = initialize_i2p)
|
FUZZ_TARGET(i2p, .init = initialize_i2p)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
|
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
#include <util/chaintype.h>
|
#include <util/chaintype.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ void initialize_key()
|
||||||
|
|
||||||
FUZZ_TARGET(key, .init = initialize_key)
|
FUZZ_TARGET(key, .init = initialize_key)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
const CKey key = [&] {
|
const CKey key = [&] {
|
||||||
CKey k;
|
CKey k;
|
||||||
k.Set(buffer.begin(), buffer.end(), true);
|
k.Set(buffer.begin(), buffer.end(), true);
|
||||||
|
|
|
@ -35,6 +35,7 @@ void initialize_miner()
|
||||||
// Test that the MiniMiner can run with various outpoints and feerates.
|
// Test that the MiniMiner can run with various outpoints and feerates.
|
||||||
FUZZ_TARGET(mini_miner, .init = initialize_miner)
|
FUZZ_TARGET(mini_miner, .init = initialize_miner)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
bilingual_str error;
|
bilingual_str error;
|
||||||
CTxMemPool pool{CTxMemPool::Options{}, error};
|
CTxMemPool pool{CTxMemPool::Options{}, error};
|
||||||
|
@ -113,6 +114,7 @@ FUZZ_TARGET(mini_miner, .init = initialize_miner)
|
||||||
// Test that MiniMiner and BlockAssembler build the same block given the same transactions and constraints.
|
// Test that MiniMiner and BlockAssembler build the same block given the same transactions and constraints.
|
||||||
FUZZ_TARGET(mini_miner_selection, .init = initialize_miner)
|
FUZZ_TARGET(mini_miner_selection, .init = initialize_miner)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
bilingual_str error;
|
bilingual_str error;
|
||||||
CTxMemPool pool{CTxMemPool::Options{}, error};
|
CTxMemPool pool{CTxMemPool::Options{}, error};
|
||||||
|
@ -176,15 +178,15 @@ FUZZ_TARGET(mini_miner_selection, .init = initialize_miner)
|
||||||
miner_options.blockMinFeeRate = target_feerate;
|
miner_options.blockMinFeeRate = target_feerate;
|
||||||
miner_options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
|
miner_options.nBlockMaxWeight = MAX_BLOCK_WEIGHT;
|
||||||
miner_options.test_block_validity = false;
|
miner_options.test_block_validity = false;
|
||||||
|
miner_options.coinbase_output_script = CScript() << OP_0;
|
||||||
|
|
||||||
node::BlockAssembler miner{g_setup->m_node.chainman->ActiveChainstate(), &pool, miner_options};
|
node::BlockAssembler miner{g_setup->m_node.chainman->ActiveChainstate(), &pool, miner_options};
|
||||||
node::MiniMiner mini_miner{pool, outpoints};
|
node::MiniMiner mini_miner{pool, outpoints};
|
||||||
assert(mini_miner.IsReadyToCalculate());
|
assert(mini_miner.IsReadyToCalculate());
|
||||||
|
|
||||||
CScript spk_placeholder = CScript() << OP_0;
|
|
||||||
// Use BlockAssembler as oracle. BlockAssembler and MiniMiner should select the same
|
// Use BlockAssembler as oracle. BlockAssembler and MiniMiner should select the same
|
||||||
// transactions, stopping once packages do not meet target_feerate.
|
// transactions, stopping once packages do not meet target_feerate.
|
||||||
const auto blocktemplate{miner.CreateNewBlock(spk_placeholder)};
|
const auto blocktemplate{miner.CreateNewBlock()};
|
||||||
mini_miner.BuildMockTemplate(target_feerate);
|
mini_miner.BuildMockTemplate(target_feerate);
|
||||||
assert(!mini_miner.IsReadyToCalculate());
|
assert(!mini_miner.IsReadyToCalculate());
|
||||||
auto mock_template_txids = mini_miner.GetMockTemplateTxids();
|
auto mock_template_txids = mini_miner.GetMockTemplateTxids();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util/net.h>
|
#include <test/fuzz/util/net.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
|
|
||||||
FUZZ_TARGET(netaddress)
|
FUZZ_TARGET(netaddress)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
const CNetAddr net_addr = ConsumeNetAddr(fuzzed_data_provider);
|
const CNetAddr net_addr = ConsumeNetAddr(fuzzed_data_provider);
|
||||||
|
|
|
@ -39,6 +39,7 @@ void initialize()
|
||||||
|
|
||||||
FUZZ_TARGET(p2p_handshake, .init = ::initialize)
|
FUZZ_TARGET(p2p_handshake, .init = ::initialize)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
ConnmanTestMsg& connman = static_cast<ConnmanTestMsg&>(*g_setup->m_node.connman);
|
ConnmanTestMsg& connman = static_cast<ConnmanTestMsg&>(*g_setup->m_node.connman);
|
||||||
|
|
|
@ -153,6 +153,7 @@ void initialize()
|
||||||
|
|
||||||
FUZZ_TARGET(p2p_headers_presync, .init = initialize)
|
FUZZ_TARGET(p2p_headers_presync, .init = initialize)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
ChainstateManager& chainman = *g_testing_setup->m_node.chainman;
|
ChainstateManager& chainman = *g_testing_setup->m_node.chainman;
|
||||||
|
|
||||||
LOCK(NetEventsInterface::g_msgproc_mutex);
|
LOCK(NetEventsInterface::g_msgproc_mutex);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
|
|
||||||
|
using node::BlockAssembler;
|
||||||
using node::NodeContext;
|
using node::NodeContext;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -42,8 +43,11 @@ void initialize_tx_pool()
|
||||||
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
|
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
|
||||||
g_setup = testing_setup.get();
|
g_setup = testing_setup.get();
|
||||||
|
|
||||||
|
BlockAssembler::Options options;
|
||||||
|
options.coinbase_output_script = P2WSH_EMPTY;
|
||||||
|
|
||||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||||
COutPoint prevout{MineBlock(g_setup->m_node, P2WSH_EMPTY)};
|
COutPoint prevout{MineBlock(g_setup->m_node, options)};
|
||||||
if (i < COINBASE_MATURITY) {
|
if (i < COINBASE_MATURITY) {
|
||||||
// Remember the txids to avoid expensive disk access later on
|
// Remember the txids to avoid expensive disk access later on
|
||||||
g_outpoints_coinbase_init_mature.push_back(prevout);
|
g_outpoints_coinbase_init_mature.push_back(prevout);
|
||||||
|
@ -188,6 +192,7 @@ std::optional<COutPoint> GetChildEvictingPrevout(const CTxMemPool& tx_pool)
|
||||||
|
|
||||||
FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool)
|
FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
const auto& node = g_setup->m_node;
|
const auto& node = g_setup->m_node;
|
||||||
auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())};
|
auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())};
|
||||||
|
@ -342,6 +347,7 @@ FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool)
|
||||||
|
|
||||||
FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
const auto& node = g_setup->m_node;
|
const auto& node = g_setup->m_node;
|
||||||
auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())};
|
auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())};
|
||||||
|
|
|
@ -44,6 +44,7 @@ PartiallyDownloadedBlock::CheckBlockFn FuzzedCheckBlock(std::optional<BlockValid
|
||||||
|
|
||||||
FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb)
|
FUZZ_TARGET(partially_downloaded_block, .init = initialize_pdb)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
|
|
||||||
auto block{ConsumeDeserializable<CBlock>(fuzzed_data_provider, TX_WITH_WITNESS)};
|
auto block{ConsumeDeserializable<CBlock>(fuzzed_data_provider, TX_WITH_WITNESS)};
|
||||||
|
|
|
@ -45,13 +45,14 @@ void initialize_process_message()
|
||||||
{.extra_args = {"-txreconciliation"}});
|
{.extra_args = {"-txreconciliation"}});
|
||||||
g_setup = testing_setup.get();
|
g_setup = testing_setup.get();
|
||||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||||
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
|
MineBlock(g_setup->m_node, {});
|
||||||
}
|
}
|
||||||
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
FUZZ_TARGET(process_message, .init = initialize_process_message)
|
FUZZ_TARGET(process_message, .init = initialize_process_message)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
ConnmanTestMsg& connman = *static_cast<ConnmanTestMsg*>(g_setup->m_node.connman.get());
|
ConnmanTestMsg& connman = *static_cast<ConnmanTestMsg*>(g_setup->m_node.connman.get());
|
||||||
|
|
|
@ -35,13 +35,14 @@ void initialize_process_messages()
|
||||||
{.extra_args = {"-txreconciliation"}});
|
{.extra_args = {"-txreconciliation"}});
|
||||||
g_setup = testing_setup.get();
|
g_setup = testing_setup.get();
|
||||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||||
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
|
MineBlock(g_setup->m_node, {});
|
||||||
}
|
}
|
||||||
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
ConnmanTestMsg& connman = *static_cast<ConnmanTestMsg*>(g_setup->m_node.connman.get());
|
ConnmanTestMsg& connman = *static_cast<ConnmanTestMsg*>(g_setup->m_node.connman.get());
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
|
||||||
#include <test/fuzz/fuzz.h>
|
|
||||||
|
|
||||||
#include <node/psbt.h>
|
#include <node/psbt.h>
|
||||||
#include <psbt.h>
|
#include <psbt.h>
|
||||||
#include <pubkey.h>
|
#include <pubkey.h>
|
||||||
#include <script/script.h>
|
#include <script/script.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
|
#include <test/fuzz/fuzz.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
#include <util/check.h>
|
#include <util/check.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -23,6 +23,7 @@ using node::PSBTInputAnalysis;
|
||||||
|
|
||||||
FUZZ_TARGET(psbt)
|
FUZZ_TARGET(psbt)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
PartiallySignedTransaction psbt_mut;
|
PartiallySignedTransaction psbt_mut;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|
|
@ -51,6 +51,7 @@ void initialize_package_rbf()
|
||||||
|
|
||||||
FUZZ_TARGET(rbf, .init = initialize_rbf)
|
FUZZ_TARGET(rbf, .init = initialize_rbf)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
|
std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
|
||||||
|
@ -92,6 +93,7 @@ FUZZ_TARGET(rbf, .init = initialize_rbf)
|
||||||
|
|
||||||
FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
|
FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
|
|
||||||
FUZZ_TARGET(rolling_bloom_filter)
|
FUZZ_TARGET(rolling_bloom_filter)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
CRollingBloomFilter rolling_bloom_filter{
|
CRollingBloomFilter rolling_bloom_filter{
|
||||||
|
|
|
@ -365,6 +365,7 @@ void initialize_rpc()
|
||||||
|
|
||||||
FUZZ_TARGET(rpc, .init = initialize_rpc)
|
FUZZ_TARGET(rpc, .init = initialize_rpc)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
bool good_data{true};
|
bool good_data{true};
|
||||||
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
SetMockTime(ConsumeTime(fuzzed_data_provider));
|
||||||
|
|
|
@ -25,6 +25,7 @@ void initialize_script_sigcache()
|
||||||
|
|
||||||
FUZZ_TARGET(script_sigcache, .init = initialize_script_sigcache)
|
FUZZ_TARGET(script_sigcache, .init = initialize_script_sigcache)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
|
|
||||||
const auto max_sigcache_bytes{fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, DEFAULT_SIGNATURE_CACHE_BYTES)};
|
const auto max_sigcache_bytes{fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, DEFAULT_SIGNATURE_CACHE_BYTES)};
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <test/fuzz/FuzzedDataProvider.h>
|
#include <test/fuzz/FuzzedDataProvider.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
#include <test/fuzz/util.h>
|
#include <test/fuzz/util.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -16,6 +17,7 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned
|
||||||
|
|
||||||
FUZZ_TARGET(secp256k1_ecdsa_signature_parse_der_lax)
|
FUZZ_TARGET(secp256k1_ecdsa_signature_parse_der_lax)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
|
||||||
const std::vector<uint8_t> signature_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
const std::vector<uint8_t> signature_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
||||||
if (signature_bytes.data() == nullptr) {
|
if (signature_bytes.data() == nullptr) {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <test/fuzz/fuzz.h>
|
#include <test/fuzz/fuzz.h>
|
||||||
|
#include <test/util/random.h>
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
#include <util/chaintype.h>
|
#include <util/chaintype.h>
|
||||||
#include <util/rbf.h>
|
#include <util/rbf.h>
|
||||||
|
@ -28,6 +29,7 @@ void initialize_transaction()
|
||||||
|
|
||||||
FUZZ_TARGET(transaction, .init = initialize_transaction)
|
FUZZ_TARGET(transaction, .init = initialize_transaction)
|
||||||
{
|
{
|
||||||
|
SeedRandomStateForTest(SeedRand::ZEROS);
|
||||||
DataStream ds{buffer};
|
DataStream ds{buffer};
|
||||||
bool valid_tx = true;
|
bool valid_tx = true;
|
||||||
const CTransaction tx = [&] {
|
const CTransaction tx = [&] {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue