mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #5818 from knst/bp-v21-p10
backport: bitcoin#20211, #20380, #20884, #20941, #20944, #21028, #21064, #21110, #21117, bitcon-core/gui#204
This commit is contained in:
commit
9d464558eb
@ -5,7 +5,7 @@ environment:
|
||||
- CXXFLAGS=-fcoverage-mapping -fno-omit-frame-pointer -fprofile-instr-generate -gline-tables-only -O1
|
||||
setup:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -y autoconf bsdmainutils clang git libboost-all-dev libc++1 libc++abi1 libc++abi-dev libc++-dev libclang1 libclang-dev libdb5.3++ libevent-dev libllvm-ocaml-dev libomp5 libomp-dev libqt5core5a libqt5dbus5 libqt5gui5 libtool llvm llvm-dev llvm-runtime pkg-config qttools5-dev qttools5-dev-tools software-properties-common
|
||||
- sudo apt-get install -y autoconf bsdmainutils clang git libboost-system-dev libboost-filesystem-dev libboost-test-dev libc++1 libc++abi1 libc++abi-dev libc++-dev libclang1 libclang-dev libdb5.3++ libevent-dev libllvm-ocaml-dev libomp5 libomp-dev libqt5core5a libqt5dbus5 libqt5gui5 libtool llvm llvm-dev llvm-runtime pkg-config qttools5-dev qttools5-dev-tools software-properties-common
|
||||
- ./autogen.sh
|
||||
- CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined --enable-danger-fuzz-link-all
|
||||
- make
|
||||
|
@ -1,187 +0,0 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_boost_thread.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_BOOST_THREAD
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Test for Thread library from the Boost C++ libraries. The macro requires
|
||||
# a preceding call to AX_BOOST_BASE. Further documentation is available at
|
||||
# <http://randspringer.de/boost/index.html>.
|
||||
#
|
||||
# This macro calls:
|
||||
#
|
||||
# AC_SUBST(BOOST_THREAD_LIB)
|
||||
#
|
||||
# And sets:
|
||||
#
|
||||
# HAVE_BOOST_THREAD
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
|
||||
# Copyright (c) 2009 Michael Tindal
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 33
|
||||
|
||||
AC_DEFUN([AX_BOOST_THREAD],
|
||||
[
|
||||
AC_ARG_WITH([boost-thread],
|
||||
AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@],
|
||||
[use the Thread library from boost -
|
||||
it is possible to specify a certain library for the linker
|
||||
e.g. --with-boost-thread=boost_thread-gcc-mt ]),
|
||||
[
|
||||
if test "$withval" = "yes"; then
|
||||
want_boost="yes"
|
||||
ax_boost_user_thread_lib=""
|
||||
else
|
||||
want_boost="yes"
|
||||
ax_boost_user_thread_lib="$withval"
|
||||
fi
|
||||
],
|
||||
[want_boost="yes"]
|
||||
)
|
||||
|
||||
if test "x$want_boost" = "xyes"; then
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_BUILD])
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
|
||||
LDFLAGS_SAVED="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_CACHE_CHECK(whether the Boost::Thread library is available,
|
||||
ax_cv_boost_thread,
|
||||
[AC_LANG_PUSH([C++])
|
||||
CXXFLAGS_SAVE=$CXXFLAGS
|
||||
|
||||
case "x$host_os" in
|
||||
xsolaris )
|
||||
CXXFLAGS="-pthreads $CXXFLAGS"
|
||||
break;
|
||||
;;
|
||||
xmingw32 )
|
||||
CXXFLAGS="-mthreads $CXXFLAGS"
|
||||
break;
|
||||
;;
|
||||
*android* )
|
||||
break;
|
||||
;;
|
||||
* )
|
||||
CXXFLAGS="-pthread $CXXFLAGS"
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM(
|
||||
[[@%:@include <boost/thread/thread.hpp>]],
|
||||
[[boost::thread_group thrds;
|
||||
return 0;]])],
|
||||
ax_cv_boost_thread=yes, ax_cv_boost_thread=no)
|
||||
CXXFLAGS=$CXXFLAGS_SAVE
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
if test "x$ax_cv_boost_thread" = "xyes"; then
|
||||
case "x$host_os" in
|
||||
xsolaris )
|
||||
BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS"
|
||||
break;
|
||||
;;
|
||||
xmingw32 )
|
||||
BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS"
|
||||
break;
|
||||
;;
|
||||
*android* )
|
||||
break;
|
||||
;;
|
||||
* )
|
||||
BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS"
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(BOOST_CPPFLAGS)
|
||||
|
||||
AC_DEFINE(HAVE_BOOST_THREAD,,
|
||||
[define if the Boost::Thread library is available])
|
||||
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
|
||||
|
||||
LDFLAGS_SAVE=$LDFLAGS
|
||||
case "x$host_os" in
|
||||
*bsd* )
|
||||
LDFLAGS="-pthread $LDFLAGS"
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
if test "x$ax_boost_user_thread_lib" = "x"; then
|
||||
for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do
|
||||
ax_lib=${libextension}
|
||||
AC_CHECK_LIB($ax_lib, exit,
|
||||
[link_thread="yes"; break],
|
||||
[link_thread="no"])
|
||||
done
|
||||
if test "x$link_thread" != "xyes"; then
|
||||
for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do
|
||||
ax_lib=${libextension}
|
||||
AC_CHECK_LIB($ax_lib, exit,
|
||||
[link_thread="yes"; break],
|
||||
[link_thread="no"])
|
||||
done
|
||||
fi
|
||||
|
||||
else
|
||||
for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do
|
||||
AC_CHECK_LIB($ax_lib, exit,
|
||||
[link_thread="yes"; break],
|
||||
[link_thread="no"])
|
||||
done
|
||||
|
||||
fi
|
||||
if test "x$ax_lib" = "x"; then
|
||||
AC_MSG_ERROR(Could not find a version of the Boost::Thread library!)
|
||||
fi
|
||||
if test "x$link_thread" = "xno"; then
|
||||
AC_MSG_ERROR(Could not link against $ax_lib !)
|
||||
else
|
||||
BOOST_THREAD_LIB="-l$ax_lib"
|
||||
case "x$host_os" in
|
||||
*bsd* )
|
||||
BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS"
|
||||
break;
|
||||
;;
|
||||
xsolaris )
|
||||
BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread"
|
||||
break;
|
||||
;;
|
||||
xmingw32 )
|
||||
break;
|
||||
;;
|
||||
*android* )
|
||||
break;
|
||||
;;
|
||||
* )
|
||||
BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread"
|
||||
break;
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(BOOST_THREAD_LIB)
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
LDFLAGS="$LDFLAGS_SAVED"
|
||||
fi
|
||||
])
|
@ -6,7 +6,7 @@
|
||||
|
||||
export LC_ALL=C.UTF-8
|
||||
|
||||
export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev"
|
||||
export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-filesystem-dev libboost-test-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev"
|
||||
export NO_DEPENDS=1
|
||||
export FUNCTIONAL_TESTS_CONFIG="--exclude wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163)
|
||||
export RUN_BENCH=true
|
||||
|
@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8
|
||||
|
||||
export DOCKER_NAME_TAG="ubuntu:20.04"
|
||||
export CONTAINER_NAME=ci_native_fuzz
|
||||
export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-filesystem-dev libboost-test-dev libboost-thread-dev"
|
||||
export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-filesystem-dev libboost-test-dev"
|
||||
export DEP_OPTS="NO_UPNP=1 DEBUG=1"
|
||||
export CPPFLAGS="-DDEBUG_LOCKORDER -DENABLE_DASH_DEBUG -DARENA_DEBUG"
|
||||
export CXXFLAGS="-Werror -Wno-unused-command-line-argument -Wno-unused-value -Wno-deprecated-builtins"
|
||||
|
@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8
|
||||
|
||||
export DOCKER_NAME_TAG="ubuntu:20.04"
|
||||
export CONTAINER_NAME=ci_native_fuzz_valgrind
|
||||
export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev valgrind"
|
||||
export PACKAGES="clang llvm python3 libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev valgrind"
|
||||
export NO_DEPENDS=1
|
||||
export RUN_UNIT_TESTS=false
|
||||
export RUN_FUNCTIONAL_TESTS=false
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
export LC_ALL=C.UTF-8
|
||||
|
||||
export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev"
|
||||
export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev"
|
||||
export USE_VALGRIND=1
|
||||
export NO_DEPENDS=1
|
||||
export TEST_RUNNER_EXTRA="--exclude rpc_bind" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
|
||||
|
@ -693,7 +693,7 @@ case $host in
|
||||
AC_MSG_ERROR("windres not found")
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN"
|
||||
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN"
|
||||
|
||||
dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against.
|
||||
dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override
|
||||
@ -1421,7 +1421,6 @@ if test x$want_boost = xno; then
|
||||
AC_MSG_ERROR([[only libdashconsensus can be built without boost]])
|
||||
fi
|
||||
AX_BOOST_FILESYSTEM
|
||||
AX_BOOST_THREAD
|
||||
|
||||
if test x$suppress_external_warnings != xno; then
|
||||
dnl Prevent use of std::unary_function, which was removed in C++17,
|
||||
@ -1432,7 +1431,7 @@ if test x$suppress_external_warnings != xno; then
|
||||
BOOST_CPPFLAGS=SUPPRESS_WARNINGS($BOOST_CPPFLAGS)
|
||||
fi
|
||||
|
||||
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_THREAD_LIB"
|
||||
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB"
|
||||
fi
|
||||
|
||||
if test x$use_reduce_exports = xyes; then
|
||||
|
@ -1,6 +1,6 @@
|
||||
Sample configuration files for:
|
||||
```
|
||||
SystemD: dashd.service
|
||||
systemd: dashd.service
|
||||
Upstart: dashd.conf
|
||||
OpenRC: dashd.openrc
|
||||
dashd.openrcconf
|
||||
@ -9,4 +9,4 @@ macOS: org.dash.dashd.plist
|
||||
```
|
||||
have been made available to assist packagers in creating node packages here.
|
||||
|
||||
See doc/init.md for more information.
|
||||
See [doc/init.md](../../doc/init.md) for more information.
|
||||
|
@ -11,7 +11,11 @@
|
||||
|
||||
[Unit]
|
||||
Description=Dash daemon
|
||||
After=network.target
|
||||
Documentation=https://github.com/dashpay/dash/blob/master/doc/init.md
|
||||
|
||||
# https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/dashd -daemon \
|
||||
|
@ -30,7 +30,7 @@ endif
|
||||
else
|
||||
$(package)_toolset_$(host_os)=gcc
|
||||
endif
|
||||
$(package)_config_libraries=filesystem,thread,test
|
||||
$(package)_config_libraries=filesystem,test
|
||||
$(package)_cxxflags=-std=c++17 -fvisibility=hidden
|
||||
$(package)_cxxflags_linux=-fPIC
|
||||
$(package)_cxxflags_freebsd=-fPIC
|
||||
|
@ -112,12 +112,7 @@ $ curl localhost:19998/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff76
|
||||
|
||||
Returns various information about the TX mempool.
|
||||
Only supports JSON as output format.
|
||||
* loaded : (boolean) if the mempool is fully loaded
|
||||
* size : (numeric) the number of transactions in the TX mempool
|
||||
* bytes : (numeric) size of the TX mempool in bytes
|
||||
* usage : (numeric) total TX mempool memory usage
|
||||
* maxmempool : (numeric) maximum memory usage for the mempool in bytes
|
||||
* mempoolminfee : (numeric) minimum feerate (DASH per KB) for tx to be accepted
|
||||
Refer to the `getmempoolinfo` RPC for documentation of the fields.
|
||||
|
||||
`GET /rest/mempool/contents.json`
|
||||
|
||||
|
@ -15,6 +15,9 @@ BIPs that are implemented by Dash Core (up-to-date up to **v18.0**):
|
||||
* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)). As of **v0.13.0**, this is only available for `NODE_BLOOM` (BIP 111) peers.
|
||||
* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial Merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)).
|
||||
* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)).
|
||||
* [`BIP 43`](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki): The experimental descriptor wallets introduced in **v0.21.0** by default use the Hierarchical Deterministic Wallet derivation proposed by BIP 43. ([PR #16528](https://github.com/bitcoin/bitcoin/pull/16528))
|
||||
* [`BIP 44`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki): The experimental descriptor wallets introduced in **v0.21.0** by default use the Hierarchical Deterministic Wallet derivation proposed by BIP 44. ([PR #16528](https://github.com/bitcoin/bitcoin/pull/16528))
|
||||
* [`BIP 49`](https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki): The experimental descriptor wallets introduced in **v0.21.0** by default use the Hierarchical Deterministic Wallet derivation proposed by BIP 49. ([PR #16528](https://github.com/bitcoin/bitcoin/pull/16528))
|
||||
* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)). Starting *v0.16.0*, whether to send reject messages can be configured with the `-enablebip61` option. Support was removed in **v0.20.0** ([PR #15437](https://github.com/bitcoin/bitcoin/pull/15437)).
|
||||
* [`BIP 65`](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki): The CHECKLOCKTIMEVERIFY softfork was merged in **v0.12.0** ([PR #6351](https://github.com/bitcoin/bitcoin/pull/6351)), and backported to **v0.11.2** and **v0.10.4**. Mempool-only CLTV was added in [PR #6124](https://github.com/bitcoin/bitcoin/pull/6124).
|
||||
* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)).
|
||||
@ -24,6 +27,7 @@ BIPs that are implemented by Dash Core (up-to-date up to **v18.0**):
|
||||
Support can be optionally disabled at build time since **v0.18.0** ([PR 14451](https://github.com/bitcoin/bitcoin/pull/14451)),
|
||||
and it is disabled by default at build time since **v0.19.0** ([PR #15584](https://github.com/bitcoin/bitcoin/pull/15584)).
|
||||
It has been removed as of **v0.20.0** ([PR 17165](https://github.com/bitcoin/bitcoin/pull/17165)).
|
||||
* [`BIP 84`](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki): The experimental descriptor wallets introduced in **v0.21.0** by default use the Hierarchical Deterministic Wallet derivation proposed by BIP 84. ([PR #16528](https://github.com/bitcoin/bitcoin/pull/16528))
|
||||
* [`BIP 90`](https://github.com/bitcoin/bips/blob/master/bip-0090.mediawiki): Trigger mechanism for activation of BIPs 34, 65, and 66 has been simplified to block height checks since **v0.14.0** ([PR #8391](https://github.com/bitcoin/bitcoin/pull/8391)).
|
||||
* [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, and enforced for all peer versions as of **v0.13.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579) and [PR #6641](https://github.com/bitcoin/bitcoin/pull/6641)).
|
||||
* [`BIP 112`](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki): The CHECKSEQUENCEVERIFY opcode has been implemented since **v0.12.1** ([PR #7524](https://github.com/bitcoin/bitcoin/pull/7524)), and has been *buried* since **v0.19.0** ([PR #16060](https://github.com/bitcoin/bitcoin/pull/16060)).
|
||||
|
@ -74,7 +74,7 @@ Build requirements:
|
||||
|
||||
Now, you can either build from self-compiled [depends](/depends/README.md) or install the required dependencies:
|
||||
|
||||
sudo apt-get libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev
|
||||
sudo apt-get libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev
|
||||
|
||||
Berkeley DB is required for the wallet.
|
||||
|
||||
|
@ -176,3 +176,77 @@ $ FUZZ=process_message honggfuzz/honggfuzz -i inputs/ -- src/test/fuzz/fuzz
|
||||
```
|
||||
|
||||
Read the [Honggfuzz documentation](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more information.
|
||||
|
||||
## Fuzzing the Dash Core P2P layer using Honggfuzz NetDriver
|
||||
|
||||
Honggfuzz NetDriver allows for very easy fuzzing of TCP servers such as Dash
|
||||
Core without having to write any custom fuzzing harness. The `dashd` server
|
||||
process is largely fuzzed without modification.
|
||||
|
||||
This makes the fuzzing highly realistic: a bug reachable by the fuzzer is likely
|
||||
also remotely triggerable by an untrusted peer.
|
||||
|
||||
To quickly get started fuzzing the P2P layer using Honggfuzz NetDriver:
|
||||
|
||||
```sh
|
||||
$ mkdir bitcoin-honggfuzz-p2p/
|
||||
$ cd bitcoin-honggfuzz-p2p/
|
||||
$ git clone https://github.com/dashpay/dash/
|
||||
$ cd dash/
|
||||
$ ./autogen.sh
|
||||
$ git clone https://github.com/google/honggfuzz
|
||||
$ cd honggfuzz/
|
||||
$ make
|
||||
$ cd ..
|
||||
$ CC=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang \
|
||||
CXX=$(pwd)/honggfuzz/hfuzz_cc/hfuzz-clang++ \
|
||||
./configure --disable-wallet --with-gui=no \
|
||||
--with-sanitizers=address,undefined
|
||||
$ git apply << "EOF"
|
||||
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
|
||||
index 455a82e39..2faa3f80f 100644
|
||||
--- a/src/bitcoind.cpp
|
||||
+++ b/src/bitcoind.cpp
|
||||
@@ -158,7 +158,11 @@ static bool AppInit(int argc, char* argv[])
|
||||
return fRet;
|
||||
}
|
||||
|
||||
+#ifdef HFND_FUZZING_ENTRY_FUNCTION_CXX
|
||||
+HFND_FUZZING_ENTRY_FUNCTION_CXX(int argc, char* argv[])
|
||||
+#else
|
||||
int main(int argc, char* argv[])
|
||||
+#endif
|
||||
{
|
||||
#ifdef WIN32
|
||||
util::WinCmdLineArgs winArgs;
|
||||
diff --git a/src/net.cpp b/src/net.cpp
|
||||
index cf987b699..636a4176a 100644
|
||||
--- a/src/net.cpp
|
||||
+++ b/src/net.cpp
|
||||
@@ -709,7 +709,7 @@ int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
|
||||
}
|
||||
|
||||
// Check start string, network magic
|
||||
- if (memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) {
|
||||
+ if (false && memcmp(hdr.pchMessageStart, m_chain_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) { // skip network magic checking
|
||||
LogPrint(BCLog::NET, "HEADER ERROR - MESSAGESTART (%s, %u bytes), received %s, peer=%d\n", hdr.GetCommand(), hdr.nMessageSize, HexStr(hdr.pchMessageStart), m_node_id);
|
||||
return -1;
|
||||
}
|
||||
@@ -768,7 +768,7 @@ Optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::mic
|
||||
RandAddEvent(ReadLE32(hash.begin()));
|
||||
|
||||
// Check checksum and header command string
|
||||
- if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
|
||||
+ if (false && memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) { // skip checksum checking
|
||||
LogPrint(BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s, peer=%d\n",
|
||||
SanitizeString(msg->m_command), msg->m_message_size,
|
||||
HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
|
||||
EOF
|
||||
$ make -C src/ dashd
|
||||
$ mkdir -p inputs/
|
||||
$ honggfuzz/honggfuzz --exit_upon_crash --quiet --timeout 4 -n 1 -Q \
|
||||
-E HFND_TCP_PORT=18444 -f inputs/ -- \
|
||||
src/dashd -regtest -discover=0 -dns=0 -dnsseed=0 -listenonion=0 \
|
||||
-nodebuglogfile -bind=127.0.0.1:18444 -logthreadnames \
|
||||
-debug
|
||||
```
|
||||
|
@ -949,6 +949,10 @@ static bool InitSanityCheck()
|
||||
return InitError(Untranslated("OS cryptographic RNG sanity check failure. Aborting."));
|
||||
}
|
||||
|
||||
if (!ChronoSanityCheck()) {
|
||||
return InitError(Untranslated("Clock epoch mismatch. Aborting."));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -694,120 +694,6 @@ bool LabelOutOfFocusEventFilter::eventFilter(QObject* watched, QEvent* event)
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void TableViewLastColumnResizingFixer::connectViewHeadersSignals()
|
||||
{
|
||||
connect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized);
|
||||
connect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged);
|
||||
}
|
||||
|
||||
// We need to disconnect these while handling the resize events, otherwise we can enter infinite loops.
|
||||
void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals()
|
||||
{
|
||||
disconnect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized);
|
||||
disconnect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged);
|
||||
}
|
||||
|
||||
// Setup the resize mode, handles compatibility for Qt5 and below as the method signatures changed.
|
||||
// Refactored here for readability.
|
||||
void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
|
||||
{
|
||||
tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
|
||||
}
|
||||
|
||||
void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex, int width)
|
||||
{
|
||||
tableView->setColumnWidth(nColumnIndex, width);
|
||||
tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
|
||||
}
|
||||
|
||||
int TableViewLastColumnResizingFixer::getColumnsWidth()
|
||||
{
|
||||
int nColumnsWidthSum = 0;
|
||||
for (int i = 0; i < columnCount; i++)
|
||||
{
|
||||
nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
|
||||
}
|
||||
return nColumnsWidthSum;
|
||||
}
|
||||
|
||||
int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column)
|
||||
{
|
||||
int nResult = lastColumnMinimumWidth;
|
||||
int nTableWidth = tableView->horizontalHeader()->width();
|
||||
|
||||
if (nTableWidth > 0)
|
||||
{
|
||||
int nOtherColsWidth = getColumnsWidth() - tableView->horizontalHeader()->sectionSize(column);
|
||||
nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
|
||||
}
|
||||
|
||||
return nResult;
|
||||
}
|
||||
|
||||
// Make sure we don't make the columns wider than the table's viewport width.
|
||||
void TableViewLastColumnResizingFixer::adjustTableColumnsWidth()
|
||||
{
|
||||
disconnectViewHeadersSignals();
|
||||
resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
|
||||
connectViewHeadersSignals();
|
||||
|
||||
int nTableWidth = tableView->horizontalHeader()->width();
|
||||
int nColsWidth = getColumnsWidth();
|
||||
if (nColsWidth > nTableWidth)
|
||||
{
|
||||
resizeColumn(secondToLastColumnIndex,getAvailableWidthForColumn(secondToLastColumnIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// Make column use all the space available, useful during window resizing.
|
||||
void TableViewLastColumnResizingFixer::stretchColumnWidth(int column)
|
||||
{
|
||||
disconnectViewHeadersSignals();
|
||||
resizeColumn(column, getAvailableWidthForColumn(column));
|
||||
connectViewHeadersSignals();
|
||||
}
|
||||
|
||||
// When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
|
||||
void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex, int oldSize, int newSize)
|
||||
{
|
||||
adjustTableColumnsWidth();
|
||||
int remainingWidth = getAvailableWidthForColumn(logicalIndex);
|
||||
if (newSize > remainingWidth)
|
||||
{
|
||||
resizeColumn(logicalIndex, remainingWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// When the table's geometry is ready, we manually perform the stretch of the "Message" column,
|
||||
// as the "Stretch" resize mode does not allow for interactive resizing.
|
||||
void TableViewLastColumnResizingFixer::on_geometriesChanged()
|
||||
{
|
||||
if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) != 0)
|
||||
{
|
||||
disconnectViewHeadersSignals();
|
||||
resizeColumn(secondToLastColumnIndex, getAvailableWidthForColumn(secondToLastColumnIndex));
|
||||
connectViewHeadersSignals();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all internal variables and prepares the
|
||||
* the resize modes of the last 2 columns of the table and
|
||||
*/
|
||||
TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent) :
|
||||
QObject(parent),
|
||||
tableView(table),
|
||||
lastColumnMinimumWidth(lastColMinimumWidth),
|
||||
allColumnsMinimumWidth(allColsMinimumWidth)
|
||||
{
|
||||
columnCount = tableView->horizontalHeader()->count();
|
||||
lastColumnIndex = columnCount - 1;
|
||||
secondToLastColumnIndex = columnCount - 2;
|
||||
tableView->horizontalHeader()->setMinimumSectionSize(allColumnsMinimumWidth);
|
||||
setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
|
||||
setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
fs::path static StartupShortcutPath()
|
||||
{
|
||||
|
@ -248,45 +248,6 @@ namespace GUIUtil
|
||||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Makes a QTableView last column feel as if it was being resized from its left border.
|
||||
* Also makes sure the column widths are never larger than the table's viewport.
|
||||
* In Qt, all columns are resizable from the right, but it's not intuitive resizing the last column from the right.
|
||||
* Usually our second to last columns behave as if stretched, and when on stretch mode, columns aren't resizable
|
||||
* interactively or programmatically.
|
||||
*
|
||||
* This helper object takes care of this issue.
|
||||
*
|
||||
*/
|
||||
class TableViewLastColumnResizingFixer: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent);
|
||||
void stretchColumnWidth(int column);
|
||||
|
||||
private:
|
||||
QTableView* tableView;
|
||||
int lastColumnMinimumWidth;
|
||||
int allColumnsMinimumWidth;
|
||||
int lastColumnIndex;
|
||||
int columnCount;
|
||||
int secondToLastColumnIndex;
|
||||
|
||||
void adjustTableColumnsWidth();
|
||||
int getAvailableWidthForColumn(int column);
|
||||
int getColumnsWidth();
|
||||
void connectViewHeadersSignals();
|
||||
void disconnectViewHeadersSignals();
|
||||
void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode);
|
||||
void resizeColumn(int nColumnIndex, int width);
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_sectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
void on_geometriesChanged();
|
||||
};
|
||||
|
||||
bool GetStartOnSystemStartup();
|
||||
bool SetStartOnSystemStartup(bool fAutoStart);
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget* parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::ReceiveCoinsDialog),
|
||||
columnResizingFixer(nullptr),
|
||||
model(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -70,7 +69,6 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
|
||||
QTableView* tableView = ui->recentRequestsView;
|
||||
|
||||
tableView->verticalHeader()->hide();
|
||||
tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
tableView->setModel(_model->getRecentRequestsTableModel());
|
||||
tableView->setAlternatingRowColors(true);
|
||||
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
@ -78,12 +76,12 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
|
||||
tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
|
||||
tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
|
||||
tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
|
||||
tableView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
|
||||
tableView->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
connect(tableView->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged, this,
|
||||
&ReceiveCoinsDialog::recentRequestsView_selectionChanged);
|
||||
// Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
|
||||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
|
||||
|
||||
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
|
||||
ui->receiveButton->setEnabled(model->wallet().canGetAddresses());
|
||||
@ -189,14 +187,6 @@ void ReceiveCoinsDialog::on_removeRequestButton_clicked()
|
||||
model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
|
||||
}
|
||||
|
||||
// We override the virtual resizeEvent of the QWidget to adjust tables column
|
||||
// sizes as the tables width is proportional to the dialogs width.
|
||||
void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
|
||||
}
|
||||
|
||||
QModelIndex ReceiveCoinsDialog::selectedRow()
|
||||
{
|
||||
if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
|
||||
|
@ -50,13 +50,11 @@ public Q_SLOTS:
|
||||
|
||||
private:
|
||||
Ui::ReceiveCoinsDialog *ui;
|
||||
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
|
||||
WalletModel *model;
|
||||
QMenu *contextMenu;
|
||||
|
||||
QModelIndex selectedRow();
|
||||
void copyColumnToClipboard(int column);
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void on_receiveButton_clicked();
|
||||
|
@ -218,7 +218,6 @@ void TransactionView::setModel(WalletModel *_model)
|
||||
|
||||
transactionProxyModel->setSortRole(Qt::EditRole);
|
||||
|
||||
transactionView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
transactionView->setModel(transactionProxyModel);
|
||||
transactionView->setAlternatingRowColors(true);
|
||||
transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
@ -236,7 +235,8 @@ void TransactionView::setModel(WalletModel *_model)
|
||||
// Note: it's a good idea to connect this signal AFTER the model is set
|
||||
connect(transactionView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TransactionView::computeSum);
|
||||
|
||||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this);
|
||||
transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
|
||||
transactionView->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
if (_model->getOptionsModel())
|
||||
{
|
||||
@ -709,14 +709,6 @@ void TransactionView::focusTransaction(const uint256& txid)
|
||||
}
|
||||
}
|
||||
|
||||
// We override the virtual resizeEvent of the QWidget to adjust tables column
|
||||
// sizes as the tables width is proportional to the dialogs width.
|
||||
void TransactionView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
columnResizingFixer->stretchColumnWidth(TransactionTableModel::ToAddress);
|
||||
}
|
||||
|
||||
void TransactionView::changeEvent(QEvent* e)
|
||||
{
|
||||
QWidget::changeEvent(e);
|
||||
|
@ -82,9 +82,6 @@ private:
|
||||
QWidget *createDateRangeWidget();
|
||||
void updateCalendarWidgets();
|
||||
|
||||
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer{nullptr};
|
||||
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
void changeEvent(QEvent* e) override;
|
||||
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <node/coinstats.h>
|
||||
#include <node/context.h>
|
||||
#include <node/utxo_snapshot.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/fees.h>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
@ -1916,6 +1917,7 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool, llmq::CInstantSendManager& is
|
||||
ret.pushKV("size", (int64_t)pool.size());
|
||||
ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
|
||||
ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
|
||||
ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee()));
|
||||
size_t maxmempool = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
|
||||
ret.pushKV("maxmempool", (int64_t) maxmempool);
|
||||
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(maxmempool), ::minRelayTxFee).GetFeePerK()));
|
||||
@ -1937,6 +1939,7 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
|
||||
{RPCResult::Type::NUM, "size", "Current tx count"},
|
||||
{RPCResult::Type::NUM, "bytes", "Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted"},
|
||||
{RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
|
||||
{RPCResult::Type::STR_AMOUNT, "total_fee", "Total fees for the mempool in " + CURRENCY_UNIT + ", ignoring modified fees through prioritizetransaction"},
|
||||
{RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
|
||||
{RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
|
||||
{RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
|
||||
|
@ -991,10 +991,11 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
||||
UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
RPCHelpMan{"sendrawtransaction", "\nSubmit a raw transaction (serialized, hex-encoded) to local node and network.\n"
|
||||
"\nNote that the transaction will be sent unconditionally to all peers, so using this\n"
|
||||
"\nThe transaction will be sent unconditionally to all peers, so using sendrawtransaction\n"
|
||||
"for manual rebroadcast may degrade privacy by leaking the transaction's origin, as\n"
|
||||
"nodes will normally not rebroadcast non-wallet transactions already in their mempool.\n"
|
||||
"\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
|
||||
"\nA specific exception, RPC_TRANSACTION_ALREADY_IN_CHAIN, may throw if the transaction cannot be added to the mempool.\n"
|
||||
"\nRelated RPCs: createrawtransaction, signrawtransactionwithkey\n",
|
||||
{
|
||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
|
||||
{"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK()),
|
||||
|
@ -99,8 +99,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
||||
std::vector<valtype> vSolutions;
|
||||
whichTypeRet = Solver(scriptPubKey, vSolutions);
|
||||
|
||||
switch (whichTypeRet)
|
||||
{
|
||||
switch (whichTypeRet) {
|
||||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::NULL_DATA:
|
||||
return false;
|
||||
@ -151,10 +150,8 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
|
||||
static CScript PushAll(const std::vector<valtype>& values)
|
||||
|
@ -31,8 +31,7 @@ CKeyID ToKeyID(const PKHash& key_hash)
|
||||
|
||||
std::string GetTxnOutputType(TxoutType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
switch (t) {
|
||||
case TxoutType::NONSTANDARD: return "nonstandard";
|
||||
case TxoutType::PUBKEY: return "pubkey";
|
||||
case TxoutType::PUBKEYHASH: return "pubkeyhash";
|
||||
@ -140,7 +139,8 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
std::vector<valtype> vSolutions;
|
||||
TxoutType whichType = Solver(scriptPubKey, vSolutions);
|
||||
|
||||
if (whichType == TxoutType::PUBKEY) {
|
||||
switch (whichType) {
|
||||
case TxoutType::PUBKEY: {
|
||||
CPubKey pubKey(vSolutions[0]);
|
||||
if (!pubKey.IsValid())
|
||||
return false;
|
||||
@ -148,18 +148,21 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
addressRet = PKHash(pubKey);
|
||||
return true;
|
||||
}
|
||||
else if (whichType == TxoutType::PUBKEYHASH)
|
||||
{
|
||||
case TxoutType::PUBKEYHASH: {
|
||||
addressRet = PKHash(uint160(vSolutions[0]));
|
||||
return true;
|
||||
}
|
||||
else if (whichType == TxoutType::SCRIPTHASH)
|
||||
{
|
||||
case TxoutType::SCRIPTHASH: {
|
||||
addressRet = ScriptHash(uint160(vSolutions[0]));
|
||||
return true;
|
||||
}
|
||||
// Multisig txns have more than one address...
|
||||
return false;
|
||||
case TxoutType::MULTISIG:
|
||||
// Multisig txns have more than one address...
|
||||
case TxoutType::NULL_DATA:
|
||||
case TxoutType::NONSTANDARD:
|
||||
return false;
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
|
||||
bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <key.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@ -12,6 +13,7 @@ BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup)
|
||||
BOOST_AUTO_TEST_CASE(basic_sanity)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "secp256k1 sanity test");
|
||||
BOOST_CHECK_MESSAGE(ChronoSanityCheck() == true, "chrono epoch test");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -8,16 +8,16 @@
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <validation.h>
|
||||
#include <policy/policy.h>
|
||||
#include <hash.h>
|
||||
#include <policy/fees.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/settings.h>
|
||||
#include <reverse_iterator.h>
|
||||
#include <util/check.h>
|
||||
#include <util/system.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/system.h>
|
||||
#include <util/time.h>
|
||||
#include <hash.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <evo/specialtx.h>
|
||||
@ -400,7 +400,10 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
|
||||
|
||||
nTransactionsUpdated++;
|
||||
totalTxSize += entry.GetTxSize();
|
||||
if (minerPolicyEstimator) {minerPolicyEstimator->processTransaction(entry, validFeeEstimate);}
|
||||
m_total_fee += entry.GetFee();
|
||||
if (minerPolicyEstimator) {
|
||||
minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
|
||||
}
|
||||
|
||||
vTxHashes.emplace_back(entry.GetTx().GetHash(), newit);
|
||||
newit->vTxHashesIdx = vTxHashes.size() - 1;
|
||||
@ -645,6 +648,7 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
|
||||
}
|
||||
|
||||
totalTxSize -= it->GetTxSize();
|
||||
m_total_fee -= it->GetFee();
|
||||
cachedInnerUsage -= it->DynamicMemoryUsage();
|
||||
cachedInnerUsage -= memusage::DynamicUsage(mapLinks[it].parents) + memusage::DynamicUsage(mapLinks[it].children);
|
||||
mapLinks.erase(it);
|
||||
@ -990,6 +994,7 @@ void CTxMemPool::_clear()
|
||||
mapProTxAddresses.clear();
|
||||
mapProTxPubKeyIDs.clear();
|
||||
totalTxSize = 0;
|
||||
m_total_fee = 0;
|
||||
cachedInnerUsage = 0;
|
||||
lastRollingFeeUpdate = GetTime();
|
||||
blockSinceLastRollingFeeBump = false;
|
||||
@ -1023,6 +1028,7 @@ void CTxMemPool::check(CChainState& active_chainstate) const
|
||||
LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
|
||||
|
||||
uint64_t checkTotal = 0;
|
||||
CAmount check_total_fee{0};
|
||||
uint64_t innerUsage = 0;
|
||||
|
||||
CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip();
|
||||
@ -1035,6 +1041,7 @@ void CTxMemPool::check(CChainState& active_chainstate) const
|
||||
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
|
||||
unsigned int i = 0;
|
||||
checkTotal += it->GetTxSize();
|
||||
check_total_fee += it->GetFee();
|
||||
innerUsage += it->DynamicMemoryUsage();
|
||||
const CTransaction& tx = it->GetTx();
|
||||
txlinksMap::const_iterator linksiter = mapLinks.find(it);
|
||||
@ -1127,6 +1134,7 @@ void CTxMemPool::check(CChainState& active_chainstate) const
|
||||
}
|
||||
|
||||
assert(totalTxSize == checkTotal);
|
||||
assert(m_total_fee == check_total_fee);
|
||||
assert(innerUsage == cachedInnerUsage);
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,10 @@
|
||||
#include <indirectmap.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <sync.h>
|
||||
#include <random.h>
|
||||
#include <netaddress.h>
|
||||
#include <pubkey.h>
|
||||
#include <sync.h>
|
||||
#include <util/epochguard.h>
|
||||
#include <util/hasher.h>
|
||||
|
||||
@ -447,8 +447,9 @@ private:
|
||||
std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
|
||||
CBlockPolicyEstimator* minerPolicyEstimator;
|
||||
|
||||
uint64_t totalTxSize; //!< sum of all mempool tx' byte sizes
|
||||
uint64_t cachedInnerUsage; //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
|
||||
uint64_t totalTxSize GUARDED_BY(cs); //!< sum of all mempool tx' byte sizes
|
||||
CAmount m_total_fee GUARDED_BY(cs); //!< sum of all mempool tx's fees (NOT modified fee)
|
||||
uint64_t cachedInnerUsage GUARDED_BY(cs); //!< sum of dynamic memory usage of all the map elements (NOT the maps themselves)
|
||||
|
||||
mutable int64_t lastRollingFeeUpdate;
|
||||
mutable bool blockSinceLastRollingFeeBump;
|
||||
@ -728,6 +729,12 @@ public:
|
||||
return totalTxSize;
|
||||
}
|
||||
|
||||
CAmount GetTotalFee() const EXCLUSIVE_LOCKS_REQUIRED(cs)
|
||||
{
|
||||
AssertLockHeld(cs);
|
||||
return m_total_fee;
|
||||
}
|
||||
|
||||
bool exists(const uint256& hash) const
|
||||
{
|
||||
LOCK(cs);
|
||||
|
@ -33,6 +33,49 @@ int64_t GetTime()
|
||||
return now;
|
||||
}
|
||||
|
||||
bool ChronoSanityCheck()
|
||||
{
|
||||
// std::chrono::system_clock.time_since_epoch and time_t(0) are not guaranteed
|
||||
// to use the Unix epoch timestamp, prior to C++20, but in practice they almost
|
||||
// certainly will. Any differing behavior will be assumed to be an error, unless
|
||||
// certain platforms prove to consistently deviate, at which point we'll cope
|
||||
// with it by adding offsets.
|
||||
|
||||
// Create a new clock from time_t(0) and make sure that it represents 0
|
||||
// seconds from the system_clock's time_since_epoch. Then convert that back
|
||||
// to a time_t and verify that it's the same as before.
|
||||
const time_t time_t_epoch{};
|
||||
auto clock = std::chrono::system_clock::from_time_t(time_t_epoch);
|
||||
if (std::chrono::duration_cast<std::chrono::seconds>(clock.time_since_epoch()).count() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
time_t time_val = std::chrono::system_clock::to_time_t(clock);
|
||||
if (time_val != time_t_epoch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the above zero time is actually equal to the known unix timestamp.
|
||||
struct tm epoch;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
if (gmtime_r(&time_val, &epoch) == nullptr) {
|
||||
#else
|
||||
if (gmtime_s(&epoch, &time_val) != 0) {
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((epoch.tm_sec != 0) ||
|
||||
(epoch.tm_min != 0) ||
|
||||
(epoch.tm_hour != 0) ||
|
||||
(epoch.tm_mday != 1) ||
|
||||
(epoch.tm_mon != 0) ||
|
||||
(epoch.tm_year != 70)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T GetTime()
|
||||
{
|
||||
@ -47,6 +90,14 @@ template std::chrono::seconds GetTime();
|
||||
template std::chrono::milliseconds GetTime();
|
||||
template std::chrono::microseconds GetTime();
|
||||
|
||||
template <typename T>
|
||||
static T GetSystemTime()
|
||||
{
|
||||
const auto now = std::chrono::duration_cast<T>(std::chrono::system_clock::now().time_since_epoch());
|
||||
assert(now.count() > 0);
|
||||
return now;
|
||||
}
|
||||
|
||||
void SetMockTime(int64_t nMockTimeIn)
|
||||
{
|
||||
Assert(nMockTimeIn >= 0);
|
||||
@ -60,21 +111,17 @@ int64_t GetMockTime()
|
||||
|
||||
int64_t GetTimeMillis()
|
||||
{
|
||||
int64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
assert(now > 0);
|
||||
return now;
|
||||
return int64_t{GetSystemTime<std::chrono::milliseconds>().count()};
|
||||
}
|
||||
|
||||
int64_t GetTimeMicros()
|
||||
{
|
||||
int64_t now = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
assert(now > 0);
|
||||
return now;
|
||||
return int64_t{GetSystemTime<std::chrono::microseconds>().count()};
|
||||
}
|
||||
|
||||
int64_t GetSystemTimeInSeconds()
|
||||
{
|
||||
return GetTimeMicros()/1000000;
|
||||
return int64_t{GetSystemTime<std::chrono::seconds>().count()};
|
||||
}
|
||||
|
||||
std::string FormatISO8601DateTime(int64_t nTime) {
|
||||
|
@ -85,4 +85,7 @@ struct timeval MillisToTimeval(int64_t nTimeout);
|
||||
*/
|
||||
struct timeval MillisToTimeval(std::chrono::milliseconds ms);
|
||||
|
||||
/** Sanity check epoch match normal Unix epoch */
|
||||
bool ChronoSanityCheck();
|
||||
|
||||
#endif // BITCOIN_UTIL_TIME_H
|
||||
|
@ -1114,9 +1114,9 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
|
||||
case TxoutType::NULL_DATA:
|
||||
return "unspendable script";
|
||||
case TxoutType::NONSTANDARD:
|
||||
default:
|
||||
return "unrecognized script";
|
||||
}
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
CHECK_NONFATAL(false);
|
||||
}
|
||||
|
||||
static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)
|
||||
|
@ -89,8 +89,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
||||
TxoutType whichType = Solver(scriptPubKey, vSolutions);
|
||||
|
||||
CKeyID keyID;
|
||||
switch (whichType)
|
||||
{
|
||||
switch (whichType) {
|
||||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::NULL_DATA:
|
||||
break;
|
||||
@ -153,7 +152,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
|
||||
if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) {
|
||||
ret = std::max(ret, IsMineResult::WATCH_ONLY);
|
||||
|
@ -29,9 +29,12 @@ Start three nodes:
|
||||
block 200. node2 will reject block 102 since it's assumed valid, but it
|
||||
isn't buried by at least two weeks' work.
|
||||
"""
|
||||
import time
|
||||
|
||||
from test_framework.blocktools import (COINBASE_MATURITY,create_block, create_coinbase)
|
||||
from test_framework.blocktools import (
|
||||
COINBASE_MATURITY,
|
||||
create_block,
|
||||
create_coinbase,
|
||||
)
|
||||
from test_framework.key import ECKey
|
||||
from test_framework.messages import (
|
||||
CBlockHeader,
|
||||
@ -45,7 +48,7 @@ from test_framework.messages import (
|
||||
from test_framework.mininode import P2PInterface
|
||||
from test_framework.script import (CScript, OP_TRUE)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (assert_equal, set_node_times)
|
||||
from test_framework.util import (assert_equal, set_node_times, wait_until)
|
||||
|
||||
|
||||
class BaseNode(P2PInterface):
|
||||
@ -80,24 +83,6 @@ class AssumeValidTest(BitcoinTestFramework):
|
||||
assert not p2p_conn.is_connected
|
||||
break
|
||||
|
||||
def assert_blockchain_height(self, node, height):
|
||||
"""Wait until the blockchain is no longer advancing and verify it's reached the expected height."""
|
||||
last_height = node.getblock(node.getbestblockhash())['height']
|
||||
timeout = 10
|
||||
while True:
|
||||
time.sleep(0.25)
|
||||
current_height = node.getblock(node.getbestblockhash())['height']
|
||||
if current_height != last_height:
|
||||
last_height = current_height
|
||||
if timeout < 0:
|
||||
assert False, "blockchain too short after timeout: %d" % current_height
|
||||
timeout -= 0.25
|
||||
continue
|
||||
elif current_height > height:
|
||||
assert False, "blockchain too long: %d" % current_height
|
||||
elif current_height == height:
|
||||
break
|
||||
|
||||
def run_test(self):
|
||||
p2p0 = self.nodes[0].add_p2p_connection(BaseNode())
|
||||
|
||||
@ -187,7 +172,8 @@ class AssumeValidTest(BitcoinTestFramework):
|
||||
|
||||
# Send blocks to node0. Block 102 will be rejected.
|
||||
self.send_blocks_until_disconnected(p2p0)
|
||||
self.assert_blockchain_height(self.nodes[0], COINBASE_MATURITY + 1)
|
||||
wait_until(lambda: self.nodes[0].getblockcount() >= COINBASE_MATURITY + 1)
|
||||
assert_equal(self.nodes[0].getblockcount(), COINBASE_MATURITY + 1)
|
||||
|
||||
# Send 200 blocks to node1. All blocks, including block 102, will be accepted.
|
||||
for i in range(200):
|
||||
@ -198,7 +184,8 @@ class AssumeValidTest(BitcoinTestFramework):
|
||||
|
||||
# Send blocks to node2. Block 102 will be rejected.
|
||||
self.send_blocks_until_disconnected(p2p2)
|
||||
self.assert_blockchain_height(self.nodes[2], COINBASE_MATURITY + 1)
|
||||
wait_until(lambda: self.nodes[2].getblockcount() >= COINBASE_MATURITY + 1)
|
||||
assert_equal(self.nodes[2].getblockcount(), COINBASE_MATURITY + 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -67,6 +67,8 @@ class MempoolPersistTest(BitcoinTestFramework):
|
||||
assert_equal(len(self.nodes[0].getrawmempool()), 5)
|
||||
assert_equal(len(self.nodes[1].getrawmempool()), 5)
|
||||
|
||||
total_fee_old = self.nodes[0].getmempoolinfo()['total_fee']
|
||||
|
||||
self.log.debug("Prioritize a transaction on node0")
|
||||
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
|
||||
assert_equal(fees['base'], fees['modified'])
|
||||
@ -74,6 +76,10 @@ class MempoolPersistTest(BitcoinTestFramework):
|
||||
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
|
||||
assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified'])
|
||||
|
||||
self.log.info('Check the total base fee is unchanged after prioritisetransaction')
|
||||
assert_equal(total_fee_old, self.nodes[0].getmempoolinfo()['total_fee'])
|
||||
assert_equal(total_fee_old, sum(v['fees']['base'] for k, v in self.nodes[0].getrawmempool(verbose=True).items()))
|
||||
|
||||
tx_creation_time = self.nodes[0].getmempoolentry(txid=last_txid)['time']
|
||||
assert_greater_than_or_equal(tx_creation_time, tx_creation_time_lower)
|
||||
assert_greater_than_or_equal(tx_creation_time_higher, tx_creation_time)
|
||||
|
Loading…
Reference in New Issue
Block a user