Fix rebase issues
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
This commit is contained in:
parent
423e158876
commit
eac4f02348
101 changed files with 2761 additions and 993 deletions
|
@ -175,9 +175,6 @@ $(BITCOIN_CLI_BIN): FORCE
|
||||||
$(BITCOIN_TX_BIN): FORCE
|
$(BITCOIN_TX_BIN): FORCE
|
||||||
$(MAKE) -C src $(@F)
|
$(MAKE) -C src $(@F)
|
||||||
|
|
||||||
$(BITCOIN_TX_BIN): FORCE
|
|
||||||
$(MAKE) -C src $(@F)
|
|
||||||
|
|
||||||
$(BITCOIN_WALLET_BIN): FORCE
|
$(BITCOIN_WALLET_BIN): FORCE
|
||||||
$(MAKE) -C src $(@F)
|
$(MAKE) -C src $(@F)
|
||||||
|
|
||||||
|
|
58
configure.ac
58
configure.ac
|
@ -8,7 +8,7 @@ define(_CLIENT_VERSION_RC, 1)
|
||||||
define(_COPYRIGHT_YEAR, 2019)
|
define(_COPYRIGHT_YEAR, 2019)
|
||||||
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
||||||
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[LBRYcrd Core]])
|
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[LBRYcrd Core]])
|
||||||
AC_INIT([LBRYcrd Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/lbryio/lbrycrd/issues],[lbrycrd],[https://lbry.com/])
|
AC_INIT([LBRYcrd Core],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_REVISION, m4_if(_CLIENT_VERSION_BUILD, [0], [], _CLIENT_VERSION_BUILD))m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/lbryio/lbrycrd/issues],[lbrycrd],[https://lbry.com/])
|
||||||
AC_CONFIG_SRCDIR([src/validation.cpp])
|
AC_CONFIG_SRCDIR([src/validation.cpp])
|
||||||
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
|
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
@ -438,23 +438,29 @@ fi
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
||||||
|
|
||||||
|
AC_ARG_WITH([utils],
|
||||||
|
[AS_HELP_STRING([--with-utils],
|
||||||
|
[build lbrycrd-cli lbrycrd-tx lbrycrd-wallet (default=yes)])],
|
||||||
|
[build_lbrycrd_utils=$withval],
|
||||||
|
[build_lbrycrd_utils=yes])
|
||||||
|
|
||||||
AC_ARG_ENABLE([util-cli],
|
AC_ARG_ENABLE([util-cli],
|
||||||
[AS_HELP_STRING([--enable-util-cli],
|
[AS_HELP_STRING([--enable-util-cli],
|
||||||
[build lbrycrd-cli])],
|
[build lbrycrd-cli])],
|
||||||
[build_lbrycrd_cli=$enableval],
|
[build_lbrycrd_cli=$enableval],
|
||||||
[build_lbrycrd_cli=$build_bitcoin_utils])
|
[build_lbrycrd_cli=$build_lbrycrd_utils])
|
||||||
|
|
||||||
AC_ARG_ENABLE([util-tx],
|
AC_ARG_ENABLE([util-tx],
|
||||||
[AS_HELP_STRING([--enable-util-tx],
|
[AS_HELP_STRING([--enable-util-tx],
|
||||||
[build lbrycrd-tx])],
|
[build lbrycrd-tx])],
|
||||||
[build_lbrycrd_tx=$enableval],
|
[build_lbrycrd_tx=$enableval],
|
||||||
[build_lbrycrd_tx=$build_bitcoin_utils])
|
[build_lbrycrd_tx=$build_lbrycrd_utils])
|
||||||
|
|
||||||
AC_ARG_ENABLE([util-wallet],
|
AC_ARG_ENABLE([util-wallet],
|
||||||
[AS_HELP_STRING([--enable-util-wallet],
|
[AS_HELP_STRING([--enable-util-wallet],
|
||||||
[build lbrycrd-wallet])],
|
[build lbrycrd-wallet])],
|
||||||
[build_lbrycrd_wallet=$enableval],
|
[build_lbrycrd_wallet=$enableval],
|
||||||
[build_lbrycrd_wallet=$build_bitcoin_utils])
|
[build_lbrycrd_wallet=$build_lbrycrd_utils])
|
||||||
|
|
||||||
AC_ARG_WITH([libs],
|
AC_ARG_WITH([libs],
|
||||||
[AS_HELP_STRING([--with-libs],
|
[AS_HELP_STRING([--with-libs],
|
||||||
|
@ -511,7 +517,6 @@ case $host in
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601"
|
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601"
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_WINDOWS"
|
|
||||||
if test "x$CXXFLAGS_overridden" = "xno"; then
|
if test "x$CXXFLAGS_overridden" = "xno"; then
|
||||||
CXXFLAGS="$CXXFLAGS -w"
|
CXXFLAGS="$CXXFLAGS -w"
|
||||||
fi
|
fi
|
||||||
|
@ -533,7 +538,6 @@ case $host in
|
||||||
;;
|
;;
|
||||||
*darwin*)
|
*darwin*)
|
||||||
TARGET_OS=darwin
|
TARGET_OS=darwin
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_MACOSX"
|
|
||||||
if test x$cross_compiling != xyes; then
|
if test x$cross_compiling != xyes; then
|
||||||
BUILD_OS=darwin
|
BUILD_OS=darwin
|
||||||
AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert)
|
AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert)
|
||||||
|
@ -587,37 +591,8 @@ case $host in
|
||||||
CPPFLAGS="$CPPFLAGS -DMAC_OSX -DOBJC_OLD_DISPATCH_PROTOTYPES=0"
|
CPPFLAGS="$CPPFLAGS -DMAC_OSX -DOBJC_OLD_DISPATCH_PROTOTYPES=0"
|
||||||
OBJCXXFLAGS="$CXXFLAGS"
|
OBJCXXFLAGS="$CXXFLAGS"
|
||||||
;;
|
;;
|
||||||
*android*)
|
|
||||||
dnl make sure android stays above linux for hosts like *linux-android*
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_ANDROID"
|
|
||||||
;;
|
|
||||||
*linux*)
|
*linux*)
|
||||||
TARGET_OS=linux
|
TARGET_OS=linux
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_LINUX"
|
|
||||||
;;
|
|
||||||
*kfreebsd*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_KFREEBSD"
|
|
||||||
;;
|
|
||||||
*freebsd*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_FREEBSD"
|
|
||||||
;;
|
|
||||||
*openbsd*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_OPENBSD"
|
|
||||||
;;
|
|
||||||
*netbsd*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_NETBSD"
|
|
||||||
;;
|
|
||||||
*dragonfly*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_DRAGONFLYBSD"
|
|
||||||
;;
|
|
||||||
*solaris*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_SOLARIS"
|
|
||||||
;;
|
|
||||||
*hpux*)
|
|
||||||
LEVELDB_TARGET_FLAGS="-DOS_HPUX"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
AC_MSG_ERROR(Cannot build leveldb for $host. Please file a bug report.)
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -986,18 +961,10 @@ AC_LINK_IFELSE(
|
||||||
# Define to 1 if std::system or ::wsystem (Windows) is available
|
# Define to 1 if std::system or ::wsystem (Windows) is available
|
||||||
AC_DEFINE([HAVE_SYSTEM], [HAVE_STD__SYSTEM || HAVE_WSYSTEM], [std::system or ::wsystem])
|
AC_DEFINE([HAVE_SYSTEM], [HAVE_STD__SYSTEM || HAVE_WSYSTEM], [std::system or ::wsystem])
|
||||||
|
|
||||||
LEVELDB_CPPFLAGS=
|
|
||||||
LIBLEVELDB=
|
|
||||||
LIBMEMENV=
|
|
||||||
AM_CONDITIONAL([EMBEDDED_LEVELDB],[true])
|
|
||||||
AC_SUBST(LEVELDB_CPPFLAGS)
|
|
||||||
AC_SUBST(LIBLEVELDB)
|
|
||||||
AC_SUBST(LIBMEMENV)
|
|
||||||
|
|
||||||
dnl enable-fuzz should disable all other targets
|
dnl enable-fuzz should disable all other targets
|
||||||
if test "x$enable_fuzz" = "xyes"; then
|
if test "x$enable_fuzz" = "xyes"; then
|
||||||
AC_MSG_WARN(enable-fuzz will disable all other targets)
|
AC_MSG_WARN(enable-fuzz will disable all other targets)
|
||||||
build_bitcoin_utils=no
|
build_lbrycrd_utils=no
|
||||||
build_lbrycrd_cli=no
|
build_lbrycrd_cli=no
|
||||||
build_lbrycrd_tx=no
|
build_lbrycrd_tx=no
|
||||||
build_lbrycrd_wallet=no
|
build_lbrycrd_wallet=no
|
||||||
|
@ -1412,7 +1379,7 @@ if test x$have_protobuf != xno &&
|
||||||
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
|
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to build bitcoind])
|
AC_MSG_CHECKING([whether to build lbrycrdd])
|
||||||
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_lbrycrdd = xyes])
|
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_lbrycrdd = xyes])
|
||||||
AC_MSG_RESULT($build_lbrycrdd)
|
AC_MSG_RESULT($build_lbrycrdd)
|
||||||
|
|
||||||
|
@ -1646,7 +1613,6 @@ AC_SUBST(BOOST_LIBS)
|
||||||
AC_SUBST(ICU_CPPFLAGS)
|
AC_SUBST(ICU_CPPFLAGS)
|
||||||
AC_SUBST(ICU_LIBS)
|
AC_SUBST(ICU_LIBS)
|
||||||
AC_SUBST(TESTDEFS)
|
AC_SUBST(TESTDEFS)
|
||||||
AC_SUBST(LEVELDB_TARGET_FLAGS)
|
|
||||||
AC_SUBST(MINIUPNPC_CPPFLAGS)
|
AC_SUBST(MINIUPNPC_CPPFLAGS)
|
||||||
AC_SUBST(MINIUPNPC_LIBS)
|
AC_SUBST(MINIUPNPC_LIBS)
|
||||||
AC_SUBST(CRYPTO_LIBS)
|
AC_SUBST(CRYPTO_LIBS)
|
||||||
|
|
|
@ -114,6 +114,8 @@ endif
|
||||||
|
|
||||||
ifeq ($(rapidcheck_packages_),)
|
ifeq ($(rapidcheck_packages_),)
|
||||||
packages += $(rapidcheck_packages)
|
packages += $(rapidcheck_packages)
|
||||||
|
endif
|
||||||
|
|
||||||
all_packages = $(packages) $(native_packages)
|
all_packages = $(packages) $(native_packages)
|
||||||
|
|
||||||
meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
|
meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk
|
||||||
|
|
|
@ -137,6 +137,7 @@ BITCOIN_CORE_H = \
|
||||||
fs.h \
|
fs.h \
|
||||||
httprpc.h \
|
httprpc.h \
|
||||||
httpserver.h \
|
httpserver.h \
|
||||||
|
index/base.h \
|
||||||
index/blockfilterindex.h \
|
index/blockfilterindex.h \
|
||||||
indirectmap.h \
|
indirectmap.h \
|
||||||
init.h \
|
init.h \
|
||||||
|
@ -275,13 +276,13 @@ libbitcoin_server_a_SOURCES = \
|
||||||
flatfile.cpp \
|
flatfile.cpp \
|
||||||
httprpc.cpp \
|
httprpc.cpp \
|
||||||
httpserver.cpp \
|
httpserver.cpp \
|
||||||
|
index/base.cpp \
|
||||||
index/blockfilterindex.cpp \
|
index/blockfilterindex.cpp \
|
||||||
interfaces/chain.cpp \
|
interfaces/chain.cpp \
|
||||||
interfaces/node.cpp \
|
interfaces/node.cpp \
|
||||||
init.cpp \
|
init.cpp \
|
||||||
lbry.cpp \
|
lbry.cpp \
|
||||||
miner.cpp \
|
miner.cpp \
|
||||||
nameclaim.cpp \
|
|
||||||
net.cpp \
|
net.cpp \
|
||||||
net_processing.cpp \
|
net_processing.cpp \
|
||||||
node/coin.cpp \
|
node/coin.cpp \
|
||||||
|
@ -309,7 +310,6 @@ libbitcoin_server_a_SOURCES = \
|
||||||
txmempool.cpp \
|
txmempool.cpp \
|
||||||
ui_interface.cpp \
|
ui_interface.cpp \
|
||||||
uint256.cpp \
|
uint256.cpp \
|
||||||
utilstrencodings.cpp \
|
|
||||||
validation.cpp \
|
validation.cpp \
|
||||||
validationinterface.cpp \
|
validationinterface.cpp \
|
||||||
versionbits.cpp \
|
versionbits.cpp \
|
||||||
|
@ -362,7 +362,7 @@ libbitcoin_wallet_tool_a_SOURCES = \
|
||||||
$(BITCOIN_CORE_H)
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
# crypto primitives library
|
# crypto primitives library
|
||||||
crypto_libbitcoin_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS)
|
crypto_libbitcoin_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
crypto_libbitcoin_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
crypto_libbitcoin_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
crypto_libbitcoin_crypto_base_a_SOURCES = \
|
crypto_libbitcoin_crypto_base_a_SOURCES = \
|
||||||
crypto/aes.cpp \
|
crypto/aes.cpp \
|
||||||
|
@ -573,7 +573,6 @@ lbrycrdd_LDADD = \
|
||||||
$(LIBBITCOIN_ZMQ) \
|
$(LIBBITCOIN_ZMQ) \
|
||||||
$(LIBBITCOIN_CONSENSUS) \
|
$(LIBBITCOIN_CONSENSUS) \
|
||||||
$(LIBBITCOIN_CRYPTO) \
|
$(LIBBITCOIN_CRYPTO) \
|
||||||
$(LIBMEMENV) \
|
|
||||||
$(LIBSECP256K1)
|
$(LIBSECP256K1)
|
||||||
|
|
||||||
lbrycrdd_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
|
lbrycrdd_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
|
||||||
|
@ -630,15 +629,14 @@ endif
|
||||||
|
|
||||||
lbrycrd_wallet_LDADD = \
|
lbrycrd_wallet_LDADD = \
|
||||||
$(LIBBITCOIN_WALLET_TOOL) \
|
$(LIBBITCOIN_WALLET_TOOL) \
|
||||||
|
$(LIBBITCOIN_SERVER) \
|
||||||
$(LIBBITCOIN_WALLET) \
|
$(LIBBITCOIN_WALLET) \
|
||||||
|
$(LIBBITCOIN_SERVER) \
|
||||||
$(LIBBITCOIN_COMMON) \
|
$(LIBBITCOIN_COMMON) \
|
||||||
$(LIBBITCOIN_CONSENSUS) \
|
$(LIBBITCOIN_CONSENSUS) \
|
||||||
$(LIBBITCOIN_UTIL) \
|
$(LIBBITCOIN_UTIL) \
|
||||||
$(LIBBITCOIN_CRYPTO) \
|
$(LIBBITCOIN_CRYPTO) \
|
||||||
$(LIBBITCOIN_ZMQ) \
|
$(LIBBITCOIN_ZMQ) \
|
||||||
$(LIBLEVELDB) \
|
|
||||||
$(LIBLEVELDB_SSE42) \
|
|
||||||
$(LIBMEMENV) \
|
|
||||||
$(LIBSECP256K1) \
|
$(LIBSECP256K1) \
|
||||||
$(LIBUNIVALUE)
|
$(LIBUNIVALUE)
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,6 @@ bench_bench_bitcoin_LDADD = \
|
||||||
$(LIBBITCOIN_UTIL) \
|
$(LIBBITCOIN_UTIL) \
|
||||||
$(LIBBITCOIN_CONSENSUS) \
|
$(LIBBITCOIN_CONSENSUS) \
|
||||||
$(LIBBITCOIN_CRYPTO) \
|
$(LIBBITCOIN_CRYPTO) \
|
||||||
$(LIBMEMENV) \
|
|
||||||
$(LIBSECP256K1) \
|
$(LIBSECP256K1) \
|
||||||
$(LIBUNIVALUE) \
|
$(LIBUNIVALUE) \
|
||||||
$(EVENT_PTHREADS_LIBS) \
|
$(EVENT_PTHREADS_LIBS) \
|
||||||
|
|
|
@ -334,7 +334,7 @@ endif
|
||||||
if ENABLE_ZMQ
|
if ENABLE_ZMQ
|
||||||
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||||
endif
|
endif
|
||||||
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBMEMENV) \
|
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
||||||
$(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
$(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||||
if ENABLE_BIP70
|
if ENABLE_BIP70
|
||||||
|
|
|
@ -58,7 +58,7 @@ qt_test_test_lbrycrd_qt_SOURCES += \
|
||||||
qt/test/wallettests.cpp \
|
qt/test/wallettests.cpp \
|
||||||
wallet/test/wallet_test_fixture.cpp
|
wallet/test/wallet_test_fixture.cpp
|
||||||
if ENABLE_BIP70
|
if ENABLE_BIP70
|
||||||
qt_test_test_bitcoin_qt_SOURCES += \
|
qt_test_test_lbrycrd_qt_SOURCES += \
|
||||||
qt/test/paymentservertests.cpp
|
qt/test/paymentservertests.cpp
|
||||||
endif # ENABLE_BIP70
|
endif # ENABLE_BIP70
|
||||||
endif # ENABLE_WALLET
|
endif # ENABLE_WALLET
|
||||||
|
@ -73,7 +73,7 @@ if ENABLE_ZMQ
|
||||||
qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||||
endif
|
endif
|
||||||
qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
||||||
$(LIBMEMENV) $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
$(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
$(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||||
qt_test_test_lbrycrd_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
qt_test_test_lbrycrd_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||||
|
|
|
@ -68,15 +68,12 @@ FUZZ_SUITE_LD_COMMON = \
|
||||||
$(LIBBITCOIN_CONSENSUS) \
|
$(LIBBITCOIN_CONSENSUS) \
|
||||||
$(LIBBITCOIN_CRYPTO) \
|
$(LIBBITCOIN_CRYPTO) \
|
||||||
$(LIBUNIVALUE) \
|
$(LIBUNIVALUE) \
|
||||||
$(LIBLEVELDB) \
|
|
||||||
$(LIBLEVELDB_SSE42) \
|
|
||||||
$(BOOST_LIBS) \
|
$(BOOST_LIBS) \
|
||||||
$(LIBMEMENV) \
|
|
||||||
$(LIBSECP256K1) \
|
$(LIBSECP256K1) \
|
||||||
$(EVENT_LIBS) \
|
$(EVENT_LIBS) \
|
||||||
$(CRYPTO_LIBS) \
|
$(CRYPTO_LIBS) \
|
||||||
$(EVENT_PTHREADS_LIBS)
|
$(EVENT_PTHREADS_LIBS) \
|
||||||
$(LIBCLAIMTRIE)
|
$(LIBCLAIMTRIE) \
|
||||||
$(BOOST_LOCALE_LIB)
|
$(BOOST_LOCALE_LIB)
|
||||||
|
|
||||||
# test_bitcoin binary #
|
# test_bitcoin binary #
|
||||||
|
@ -96,7 +93,6 @@ BITCOIN_TESTS =\
|
||||||
test/blockfilter_tests.cpp \
|
test/blockfilter_tests.cpp \
|
||||||
test/blockfilter_index_tests.cpp \
|
test/blockfilter_index_tests.cpp \
|
||||||
test/bloom_tests.cpp \
|
test/bloom_tests.cpp \
|
||||||
test/Checkpoints_tests.cpp \
|
|
||||||
test/bswap_tests.cpp \
|
test/bswap_tests.cpp \
|
||||||
test/checkqueue_tests.cpp \
|
test/checkqueue_tests.cpp \
|
||||||
test/coins_tests.cpp \
|
test/coins_tests.cpp \
|
||||||
|
@ -173,7 +169,6 @@ if ENABLE_WALLET
|
||||||
BITCOIN_TESTS += \
|
BITCOIN_TESTS += \
|
||||||
wallet/test/db_tests.cpp \
|
wallet/test/db_tests.cpp \
|
||||||
wallet/test/claim_rpc_tests.cpp \
|
wallet/test/claim_rpc_tests.cpp \
|
||||||
wallet/test/db_tests.cpp \
|
|
||||||
wallet/test/psbt_wallet_tests.cpp \
|
wallet/test/psbt_wallet_tests.cpp \
|
||||||
wallet/test/wallet_tests.cpp \
|
wallet/test/wallet_tests.cpp \
|
||||||
wallet/test/wallet_crypto_tests.cpp \
|
wallet/test/wallet_crypto_tests.cpp \
|
||||||
|
@ -196,7 +191,7 @@ test_test_lbrycrd_LDADD += $(LIBBITCOIN_WALLET)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
test_test_lbrycrd_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
test_test_lbrycrd_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
||||||
$(LIBMEMENV) $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
$(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||||
test_test_lbrycrd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
test_test_lbrycrd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
|
||||||
test_test_lbrycrd_LDADD += $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS)
|
test_test_lbrycrd_LDADD += $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(RAPIDCHECK_LIBS)
|
||||||
|
|
|
@ -110,7 +110,7 @@ bool DeserializeFileDB(const fs::path& path, Data& data)
|
||||||
FILE *file = fsbridge::fopen(path, "rb");
|
FILE *file = fsbridge::fopen(path, "rb");
|
||||||
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
|
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
|
||||||
if (filein.IsNull())
|
if (filein.IsNull())
|
||||||
return false;
|
return error("%s: Failed to open file %s", __func__, path.string());
|
||||||
|
|
||||||
return DeserializeDB(filein, data);
|
return DeserializeDB(filein, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <bench/bench.h>
|
#include <bench/bench.h>
|
||||||
|
#include <chainparams.h>
|
||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
#include <crypto/sha256.h>
|
#include <crypto/sha256.h>
|
||||||
#include <test/util.h>
|
#include <test/util.h>
|
||||||
#include <txmempool.h>
|
#include <txmempool.h>
|
||||||
#include <util.h>
|
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -58,22 +58,24 @@ CDataStream getTestBlockStream()
|
||||||
static void DeserializeBlockTest(benchmark::State& state)
|
static void DeserializeBlockTest(benchmark::State& state)
|
||||||
{
|
{
|
||||||
auto stream = getTestBlockStream();
|
auto stream = getTestBlockStream();
|
||||||
|
auto size = stream.size() - 1;
|
||||||
while (state.KeepRunning()) {
|
while (state.KeepRunning()) {
|
||||||
CBlock block;
|
CBlock block;
|
||||||
stream >> block;
|
stream >> block;
|
||||||
assert(stream.Rewind(block.size()));
|
assert(stream.Rewind(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeserializeAndCheckBlockTest(benchmark::State& state)
|
static void DeserializeAndCheckBlockTest(benchmark::State& state)
|
||||||
{
|
{
|
||||||
auto stream = getTestBlockStream();
|
auto stream = getTestBlockStream();
|
||||||
|
auto size = stream.size() - 1;
|
||||||
const auto chainParams = CreateChainParams(CBaseChainParams::REGTEST);
|
const auto chainParams = CreateChainParams(CBaseChainParams::REGTEST);
|
||||||
|
|
||||||
while (state.KeepRunning()) {
|
while (state.KeepRunning()) {
|
||||||
CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
|
CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
|
||||||
stream >> block;
|
stream >> block;
|
||||||
assert(stream.Rewind(block.size()));
|
assert(stream.Rewind(size));
|
||||||
|
|
||||||
CValidationState validationState;
|
CValidationState validationState;
|
||||||
bool checked = CheckBlock(block, validationState, chainParams->GetConsensus());
|
bool checked = CheckBlock(block, validationState, chainParams->GetConsensus());
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <bloom.h>
|
#include <bloom.h>
|
||||||
#include <nameclaim.h>
|
|
||||||
|
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
@ -156,8 +155,7 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
|
||||||
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
|
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<unsigned char> > vSolutions;
|
std::vector<std::vector<unsigned char> > vSolutions;
|
||||||
const CScript& scriptPubKey = txout.scriptPubKey;
|
txnouttype type = Solver(txout.scriptPubKey, vSolutions);
|
||||||
txnouttype type = Solver(scriptPubKey, vSolutions);
|
|
||||||
if (type == TX_PUBKEY || type == TX_MULTISIG) {
|
if (type == TX_PUBKEY || type == TX_MULTISIG) {
|
||||||
insert(COutPoint(hash, i));
|
insert(COutPoint(hash, i));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// 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 <arith_uint256.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
|
||||||
#include <chainparamsseeds.h>
|
#include <chainparamsseeds.h>
|
||||||
#include <consensus/merkle.h>
|
#include <consensus/merkle.h>
|
||||||
#include <tinyformat.h>
|
#include <tinyformat.h>
|
||||||
|
@ -125,9 +125,9 @@ public:
|
||||||
consensus.BIP66Height = 200000;
|
consensus.BIP66Height = 200000;
|
||||||
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
consensus.nPowTargetTimespan = 150; //retarget every block
|
consensus.nPowTargetTimespan = 150; //retarget every block
|
||||||
consensus.CSVHeight = 419328; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5
|
consensus.CSVHeight = 200000;
|
||||||
consensus.SegwitHeight = 481824; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893
|
consensus.SegwitHeight = 680770;
|
||||||
consensus.MinBIP9WarningHeight = 483840; // segwit activation height + miner confirmation window
|
consensus.MinBIP9WarningHeight = 682786; // segwit activation height + miner confirmation window
|
||||||
consensus.nPowTargetSpacing = 150;
|
consensus.nPowTargetSpacing = 150;
|
||||||
consensus.nOriginalClaimExpirationTime = 262974;
|
consensus.nOriginalClaimExpirationTime = 262974;
|
||||||
consensus.nExtendedClaimExpirationTime = 2102400;
|
consensus.nExtendedClaimExpirationTime = 2102400;
|
||||||
|
@ -137,7 +137,6 @@ public:
|
||||||
consensus.nNormalizedNameForkHeight = 539940; // targeting 21 March 2019
|
consensus.nNormalizedNameForkHeight = 539940; // targeting 21 March 2019
|
||||||
consensus.nMinRemovalWorkaroundHeight = 297706;
|
consensus.nMinRemovalWorkaroundHeight = 297706;
|
||||||
consensus.nMaxRemovalWorkaroundHeight = 100000000;
|
consensus.nMaxRemovalWorkaroundHeight = 100000000;
|
||||||
consensus.nWitnessForkHeight = 680770; // targeting 11 Dec 2019
|
|
||||||
consensus.nAllClaimsInMerkleForkHeight = 658310; // targeting 30 Oct 2019
|
consensus.nAllClaimsInMerkleForkHeight = 658310; // targeting 30 Oct 2019
|
||||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||||
consensus.fPowNoRetargeting = false;
|
consensus.fPowNoRetargeting = false;
|
||||||
|
@ -236,9 +235,9 @@ public:
|
||||||
consensus.BIP66Height = 1200000;
|
consensus.BIP66Height = 1200000;
|
||||||
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
consensus.nPowTargetTimespan = 150;
|
consensus.nPowTargetTimespan = 150;
|
||||||
consensus.CSVHeight = 770112; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb
|
consensus.CSVHeight = 1200000;
|
||||||
consensus.SegwitHeight = 834624; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca
|
consensus.SegwitHeight = 1198600;
|
||||||
consensus.MinBIP9WarningHeight = 836640; // segwit activation height + miner confirmation window
|
consensus.MinBIP9WarningHeight = 1200616; // segwit activation height + miner confirmation window
|
||||||
consensus.nPowTargetSpacing = 150;
|
consensus.nPowTargetSpacing = 150;
|
||||||
consensus.nOriginalClaimExpirationTime = 262974;
|
consensus.nOriginalClaimExpirationTime = 262974;
|
||||||
consensus.nExtendedClaimExpirationTime = 2102400;
|
consensus.nExtendedClaimExpirationTime = 2102400;
|
||||||
|
@ -248,7 +247,6 @@ public:
|
||||||
consensus.nNormalizedNameForkHeight = 993380; // targeting, 21 Feb 2019
|
consensus.nNormalizedNameForkHeight = 993380; // targeting, 21 Feb 2019
|
||||||
consensus.nMinRemovalWorkaroundHeight = 99;
|
consensus.nMinRemovalWorkaroundHeight = 99;
|
||||||
consensus.nMaxRemovalWorkaroundHeight = 100000000;
|
consensus.nMaxRemovalWorkaroundHeight = 100000000;
|
||||||
consensus.nWitnessForkHeight = 1198600;
|
|
||||||
consensus.nAllClaimsInMerkleForkHeight = 1198560; // targeting 30 Sep 2019
|
consensus.nAllClaimsInMerkleForkHeight = 1198560; // targeting 30 Sep 2019
|
||||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||||
consensus.fPowNoRetargeting = false;
|
consensus.fPowNoRetargeting = false;
|
||||||
|
@ -334,8 +332,8 @@ public:
|
||||||
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
|
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
|
||||||
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
|
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
|
||||||
consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests)
|
consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests)
|
||||||
consensus.SegwitHeight = 0; // SEGWIT is always activated on regtest unless overridden
|
consensus.SegwitHeight = 150; // SEGWIT is always activated on regtest unless overridden
|
||||||
consensus.MinBIP9WarningHeight = 0;
|
consensus.MinBIP9WarningHeight = 294;
|
||||||
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
consensus.nPowTargetTimespan = 1;//14 * 24 * 60 * 60; // two weeks
|
consensus.nPowTargetTimespan = 1;//14 * 24 * 60 * 60; // two weeks
|
||||||
consensus.nPowTargetSpacing = 1;
|
consensus.nPowTargetSpacing = 1;
|
||||||
|
@ -347,7 +345,6 @@ public:
|
||||||
consensus.nNormalizedNameForkHeight = 250; // SDK depends upon this number
|
consensus.nNormalizedNameForkHeight = 250; // SDK depends upon this number
|
||||||
consensus.nMinRemovalWorkaroundHeight = -1;
|
consensus.nMinRemovalWorkaroundHeight = -1;
|
||||||
consensus.nMaxRemovalWorkaroundHeight = -1;
|
consensus.nMaxRemovalWorkaroundHeight = -1;
|
||||||
consensus.nWitnessForkHeight = 150;
|
|
||||||
consensus.nAllClaimsInMerkleForkHeight = 350;
|
consensus.nAllClaimsInMerkleForkHeight = 350;
|
||||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||||
consensus.fPowNoRetargeting = false;
|
consensus.fPowNoRetargeting = false;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
#include <claimscriptop.h>
|
#include <claimscriptop.h>
|
||||||
|
#include <logging.h>
|
||||||
#include <nameclaim.h>
|
#include <nameclaim.h>
|
||||||
|
|
||||||
CClaimScriptAddOp::CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight)
|
CClaimScriptAddOp::CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight)
|
||||||
|
|
|
@ -5,13 +5,11 @@
|
||||||
#ifndef CLAIMSCRIPTOP_H
|
#ifndef CLAIMSCRIPTOP_H
|
||||||
#define CLAIMSCRIPTOP_H
|
#define CLAIMSCRIPTOP_H
|
||||||
|
|
||||||
#include "amount.h"
|
#include <amount.h>
|
||||||
#include "claimtrie/forks.h"
|
#include <claimtrie/forks.h>
|
||||||
#include "hash.h"
|
#include <claimtrie/uints.h>
|
||||||
#include "primitives/transaction.h"
|
#include <primitives/transaction.h>
|
||||||
#include "script/script.h"
|
#include <script/script.h>
|
||||||
#include "uint256.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -112,7 +112,7 @@ void CBaseBlob<BITS>::SetHex(const char* psz)
|
||||||
template<uint32_t BITS>
|
template<uint32_t BITS>
|
||||||
uint64_t CBaseBlob<BITS>::GetUint64(int pos) const
|
uint64_t CBaseBlob<BITS>::GetUint64(int pos) const
|
||||||
{
|
{
|
||||||
assert((pos + 1) * 8 <= size());
|
assert(uint32_t(pos + 1) * 8 <= size());
|
||||||
const uint8_t* ptr = begin() + pos * 8;
|
const uint8_t* ptr = begin() + pos * 8;
|
||||||
uint64_t res = 0;
|
uint64_t res = 0;
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
|
|
|
@ -203,7 +203,7 @@ bool CClaimTrieCacheNormalizationFork::getProofForName(const std::string& name,
|
||||||
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), claim, proof);
|
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), claim, proof);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim, int offsetHeight) const
|
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim, int offsetHeight)
|
||||||
{
|
{
|
||||||
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim, offsetHeight);
|
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim, offsetHeight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,8 @@ public:
|
||||||
bool decrementBlock() override;
|
bool decrementBlock() override;
|
||||||
|
|
||||||
bool getProofForName(const std::string& name, const uint160& claim, CClaimTrieProof& proof) override;
|
bool getProofForName(const std::string& name, const uint160& claim, CClaimTrieProof& proof) override;
|
||||||
bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const override;
|
bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) override;
|
||||||
|
|
||||||
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
||||||
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
||||||
|
|
||||||
|
|
|
@ -402,11 +402,11 @@ namespace sqlite {
|
||||||
database(std::shared_ptr<sqlite3> db):
|
database(std::shared_ptr<sqlite3> db):
|
||||||
_db(db) {}
|
_db(db) {}
|
||||||
|
|
||||||
database_binder operator<<(str_ref sql) {
|
database_binder operator<<(str_ref sql) const {
|
||||||
return database_binder(_db, sql);
|
return database_binder(_db, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
database_binder operator<<(u16str_ref sql) {
|
database_binder operator<<(u16str_ref sql) const {
|
||||||
return database_binder(_db, sql);
|
return database_binder(_db, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -355,7 +355,7 @@ int64_t CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset) const
|
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset)
|
||||||
{
|
{
|
||||||
auto ret = false;
|
auto ret = false;
|
||||||
auto nextHeight = nNextHeight + heightOffset;
|
auto nextHeight = nNextHeight + heightOffset;
|
||||||
|
@ -509,10 +509,11 @@ extern const std::string proofClaimQuery_s =
|
||||||
"ORDER BY n.name";
|
"ORDER BY n.name";
|
||||||
|
|
||||||
CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
||||||
: base(base), db(base->dbFile, sharedConfig), transacting(false),
|
: base(base), db(base->dbFile, sharedConfig),
|
||||||
childHashQuery(db << childHashQuery_s),
|
childHashQuery(db << childHashQuery_s),
|
||||||
claimHashQuery(db << claimHashQuery_s),
|
claimHashQuery(db << claimHashQuery_s),
|
||||||
claimHashQueryLimit(db << claimHashQueryLimit_s)
|
claimHashQueryLimit(db << claimHashQueryLimit_s),
|
||||||
|
transacting(false)
|
||||||
{
|
{
|
||||||
assert(base);
|
assert(base);
|
||||||
nNextHeight = base->nNextHeight;
|
nNextHeight = base->nNextHeight;
|
||||||
|
@ -900,7 +901,8 @@ void CClaimTrieCacheBase::getNamesInTrie(std::function<void(const std::string&)>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint160> CClaimTrieCacheBase::getActivatedClaims(int height) {
|
std::vector<uint160> CClaimTrieCacheBase::getActivatedClaims(int height) const
|
||||||
|
{
|
||||||
std::vector<uint160> ret;
|
std::vector<uint160> ret;
|
||||||
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE activationHeight = ?1 AND blockHeight < ?1" << height;
|
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE activationHeight = ?1 AND blockHeight < ?1" << height;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
|
@ -909,7 +911,9 @@ std::vector<uint160> CClaimTrieCacheBase::getActivatedClaims(int height) {
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::vector<uint160> CClaimTrieCacheBase::getClaimsWithActivatedSupports(int height) {
|
|
||||||
|
std::vector<uint160> CClaimTrieCacheBase::getClaimsWithActivatedSupports(int height) const
|
||||||
|
{
|
||||||
std::vector<uint160> ret;
|
std::vector<uint160> ret;
|
||||||
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE activationHeight = ?1 AND blockHeight < ?1" << height;
|
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE activationHeight = ?1 AND blockHeight < ?1" << height;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
|
@ -918,7 +922,9 @@ std::vector<uint160> CClaimTrieCacheBase::getClaimsWithActivatedSupports(int hei
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::vector<uint160> CClaimTrieCacheBase::getExpiredClaims(int height) {
|
|
||||||
|
std::vector<uint160> CClaimTrieCacheBase::getExpiredClaims(int height) const
|
||||||
|
{
|
||||||
std::vector<uint160> ret;
|
std::vector<uint160> ret;
|
||||||
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE expirationHeight = ?1 AND blockHeight < ?1" << height;
|
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE expirationHeight = ?1 AND blockHeight < ?1" << height;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
|
@ -927,7 +933,9 @@ std::vector<uint160> CClaimTrieCacheBase::getExpiredClaims(int height) {
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::vector<uint160> CClaimTrieCacheBase::getClaimsWithExpiredSupports(int height) {
|
|
||||||
|
std::vector<uint160> CClaimTrieCacheBase::getClaimsWithExpiredSupports(int height) const
|
||||||
|
{
|
||||||
std::vector<uint160> ret;
|
std::vector<uint160> ret;
|
||||||
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE expirationHeight = ?1 AND blockHeight < ?1" << height;
|
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE expirationHeight = ?1 AND blockHeight < ?1" << height;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
|
|
|
@ -52,7 +52,8 @@ protected:
|
||||||
const int nProportionalDelayFactor;
|
const int nProportionalDelayFactor;
|
||||||
|
|
||||||
const int nNormalizedNameForkHeight;
|
const int nNormalizedNameForkHeight;
|
||||||
const int nMinRemovalWorkaroundHeight, nMaxRemovalWorkaroundHeight;
|
const int nMinRemovalWorkaroundHeight;
|
||||||
|
const int nMaxRemovalWorkaroundHeight;
|
||||||
const int64_t nOriginalClaimExpirationTime;
|
const int64_t nOriginalClaimExpirationTime;
|
||||||
const int64_t nExtendedClaimExpirationTime;
|
const int64_t nExtendedClaimExpirationTime;
|
||||||
const int64_t nExtendedClaimExpirationForkHeight;
|
const int64_t nExtendedClaimExpirationForkHeight;
|
||||||
|
@ -95,8 +96,8 @@ public:
|
||||||
|
|
||||||
virtual int expirationTime() const;
|
virtual int expirationTime() const;
|
||||||
|
|
||||||
|
virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0);
|
||||||
virtual bool getProofForName(const std::string& name, const uint160& claim, CClaimTrieProof& proof);
|
virtual bool getProofForName(const std::string& name, const uint160& claim, CClaimTrieProof& proof);
|
||||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const;
|
|
||||||
|
|
||||||
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
||||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||||
|
@ -105,18 +106,17 @@ public:
|
||||||
bool getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const;
|
bool getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const;
|
||||||
bool findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name) const;
|
bool findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name) const;
|
||||||
|
|
||||||
std::vector<uint160> getActivatedClaims(int height);
|
std::vector<uint160> getActivatedClaims(int height) const;
|
||||||
std::vector<uint160> getClaimsWithActivatedSupports(int height);
|
std::vector<uint160> getClaimsWithActivatedSupports(int height) const;
|
||||||
std::vector<uint160> getExpiredClaims(int height);
|
std::vector<uint160> getExpiredClaims(int height) const;
|
||||||
std::vector<uint160> getClaimsWithExpiredSupports(int height);
|
std::vector<uint160> getClaimsWithExpiredSupports(int height) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int nNextHeight; // Height of the block that is being worked on, which is
|
int nNextHeight; // Height of the block that is being worked on, which is
|
||||||
CClaimTrie* base;
|
CClaimTrie* base;
|
||||||
mutable sqlite::database db;
|
sqlite::database db;
|
||||||
mutable std::unordered_set<std::string> removalWorkaround;
|
mutable std::unordered_set<std::string> removalWorkaround;
|
||||||
|
sqlite::database_binder childHashQuery, claimHashQuery, claimHashQueryLimit;
|
||||||
mutable sqlite::database_binder claimHashQuery, childHashQuery, claimHashQueryLimit;
|
|
||||||
|
|
||||||
virtual uint256 computeNodeHash(const std::string& name, int takeoverHeight);
|
virtual uint256 computeNodeHash(const std::string& name, int takeoverHeight);
|
||||||
supportEntryType getSupportsForName(const std::string& name) const;
|
supportEntryType getSupportsForName(const std::string& name) const;
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
|
|
||||||
#include <txoutpoint.h>
|
#include <txoutpoint.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
COutPoint::COutPoint() noexcept
|
||||||
|
{
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
COutPoint::COutPoint(uint256 hashIn, uint32_t nIn) : hash(std::move(hashIn)), n(nIn)
|
COutPoint::COutPoint(uint256 hashIn, uint32_t nIn) : hash(std::move(hashIn)), n(nIn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -10,12 +16,12 @@ COutPoint::COutPoint(uint256 hashIn, uint32_t nIn) : hash(std::move(hashIn)), n(
|
||||||
void COutPoint::SetNull()
|
void COutPoint::SetNull()
|
||||||
{
|
{
|
||||||
hash.SetNull();
|
hash.SetNull();
|
||||||
n = uint32_t(-1);
|
n = std::numeric_limits<uint32_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool COutPoint::IsNull() const
|
bool COutPoint::IsNull() const
|
||||||
{
|
{
|
||||||
return hash.IsNull() && n == uint32_t(-1);
|
return hash.IsNull() && n == std::numeric_limits<uint32_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool COutPoint::operator<(const COutPoint& b) const
|
bool COutPoint::operator<(const COutPoint& b) const
|
||||||
|
|
|
@ -15,9 +15,9 @@ class COutPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
uint32_t n = uint32_t(-1);
|
uint32_t n;
|
||||||
|
|
||||||
COutPoint() = default;
|
COutPoint() noexcept;
|
||||||
COutPoint(COutPoint&&) = default;
|
COutPoint(COutPoint&&) = default;
|
||||||
COutPoint(const COutPoint&) = default;
|
COutPoint(const COutPoint&) = default;
|
||||||
COutPoint(uint256 hashIn, uint32_t nIn);
|
COutPoint(uint256 hashIn, uint32_t nIn);
|
||||||
|
|
|
@ -40,8 +40,8 @@ public:
|
||||||
uint32_t nHeight : 31;
|
uint32_t nHeight : 31;
|
||||||
|
|
||||||
//! construct a Coin from a CTxOut and height/coinbase information.
|
//! construct a Coin from a CTxOut and height/coinbase information.
|
||||||
Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn) {}
|
Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn) : out(std::move(outIn)), fCoinBase(fCoinBaseIn), nHeight(nHeightIn) {}
|
||||||
Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn) : out(outIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn) {}
|
Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn) : out(outIn), fCoinBase(fCoinBaseIn),nHeight(nHeightIn) {}
|
||||||
|
|
||||||
void Clear() {
|
void Clear() {
|
||||||
out.SetNull();
|
out.SetNull();
|
||||||
|
@ -133,7 +133,6 @@ typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CC
|
||||||
/** Cursor for iterating over CoinsView state */
|
/** Cursor for iterating over CoinsView state */
|
||||||
class CCoinsViewCursor
|
class CCoinsViewCursor
|
||||||
{
|
{
|
||||||
uint256 hashBlock;
|
|
||||||
public:
|
public:
|
||||||
CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {}
|
CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {}
|
||||||
virtual ~CCoinsViewCursor() noexcept {}
|
virtual ~CCoinsViewCursor() noexcept {}
|
||||||
|
@ -146,6 +145,8 @@ public:
|
||||||
|
|
||||||
//! Get best block at the time this cursor was created
|
//! Get best block at the time this cursor was created
|
||||||
const uint256 &GetBestBlock() const { return hashBlock; }
|
const uint256 &GetBestBlock() const { return hashBlock; }
|
||||||
|
private:
|
||||||
|
uint256 hashBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Abstract view on the open txout dataset. */
|
/** Abstract view on the open txout dataset. */
|
||||||
|
|
|
@ -88,8 +88,6 @@ struct Params {
|
||||||
int nMinRemovalWorkaroundHeight;
|
int nMinRemovalWorkaroundHeight;
|
||||||
int nMaxRemovalWorkaroundHeight;
|
int nMaxRemovalWorkaroundHeight;
|
||||||
|
|
||||||
int nWitnessForkHeight;
|
|
||||||
|
|
||||||
int64_t nPowTargetSpacing;
|
int64_t nPowTargetSpacing;
|
||||||
int64_t nPowTargetTimespan;
|
int64_t nPowTargetTimespan;
|
||||||
/** how long it took claims to expire before the hard fork */
|
/** how long it took claims to expire before the hard fork */
|
||||||
|
|
|
@ -65,6 +65,7 @@ enum class ValidationInvalidReason {
|
||||||
*/
|
*/
|
||||||
TX_CONFLICT,
|
TX_CONFLICT,
|
||||||
TX_MEMPOOL_POLICY, //!< violated mempool's fee/size/descendant/RBF/etc limits
|
TX_MEMPOOL_POLICY, //!< violated mempool's fee/size/descendant/RBF/etc limits
|
||||||
|
CLAIMTRIE_HASH = 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsTransactionReason(ValidationInvalidReason r)
|
inline bool IsTransactionReason(ValidationInvalidReason r)
|
||||||
|
|
|
@ -191,7 +191,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||||
else
|
else
|
||||||
out.pushKV("type", GetTxnOutputType(type));
|
out.pushKV("type", GetTxnOutputType(type));
|
||||||
|
|
||||||
if (extracted || type == TX_PUBLIC) {
|
if (extracted) {
|
||||||
UniValue a(UniValue::VARR);
|
UniValue a(UniValue::VARR);
|
||||||
for (const CTxDestination &addr : addresses) {
|
for (const CTxDestination &addr : addresses) {
|
||||||
a.push_back(EncodeDestination(addr));
|
a.push_back(EncodeDestination(addr));
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// 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 <cassert>
|
||||||
#include <crypto/siphash.h>
|
#include <crypto/siphash.h>
|
||||||
|
|
||||||
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
||||||
|
|
371
src/index/base.cpp
Normal file
371
src/index/base.cpp
Normal file
|
@ -0,0 +1,371 @@
|
||||||
|
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <chainparams.h>
|
||||||
|
#include <index/base.h>
|
||||||
|
#include <shutdown.h>
|
||||||
|
#include <tinyformat.h>
|
||||||
|
#include <ui_interface.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
#include <validation.h>
|
||||||
|
#include <warnings.h>
|
||||||
|
|
||||||
|
constexpr int64_t SYNC_LOG_INTERVAL = 30; // seconds
|
||||||
|
constexpr int64_t SYNC_LOCATOR_WRITE_INTERVAL = 30; // seconds
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
static void FatalError(const char* fmt, const Args&... args)
|
||||||
|
{
|
||||||
|
std::string strMessage = tfm::format(fmt, args...);
|
||||||
|
SetMiscWarning(strMessage);
|
||||||
|
LogPrintf("*** %s\n", strMessage);
|
||||||
|
uiInterface.ThreadSafeMessageBox(
|
||||||
|
"Error: A fatal internal error occurred, see debug.log for details",
|
||||||
|
"", CClientUIInterface::MSG_ERROR);
|
||||||
|
StartShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const sqlite::sqlite_config sharedConfig {
|
||||||
|
sqlite::OpenFlags::READWRITE | sqlite::OpenFlags::CREATE,
|
||||||
|
nullptr, sqlite::Encoding::UTF8
|
||||||
|
};
|
||||||
|
|
||||||
|
BaseIndex::DB::DB(const fs::path& path, size_t n_cache_size, bool fMemory, bool fWipe)
|
||||||
|
: sqlite::database(fMemory ? ":memory:" : (path / "index.sqlite").string(), sharedConfig)
|
||||||
|
{
|
||||||
|
(*this) << "PRAGMA cache_size=-" + std::to_string(n_cache_size >> 10); // in -KB
|
||||||
|
(*this) << "PRAGMA synchronous=OFF"; // don't disk sync after transaction commit
|
||||||
|
(*this) << "PRAGMA journal_mode=MEMORY";
|
||||||
|
(*this) << "PRAGMA temp_store=MEMORY";
|
||||||
|
(*this) << "PRAGMA case_sensitive_like=true";
|
||||||
|
|
||||||
|
(*this) << "CREATE TABLE IF NOT EXISTS locator (branch BLOB NOT NULL COLLATE BINARY);";
|
||||||
|
(*this) << "CREATE TABLE IF NOT EXISTS file_pos (file INTEGER NOT NULL, pos INTEGER NOT NULL);";
|
||||||
|
|
||||||
|
(*this) << "CREATE TABLE IF NOT EXISTS block (height INTEGER, hash BLOB NOT NULL COLLATE BINARY, "
|
||||||
|
"filter_hash BLOB NOT NULL COLLATE BINARY, header BLOB NOT NULL COLLATE BINARY, "
|
||||||
|
"file INTEGER NOT NULL, pos INTEGER NOT NULL, "
|
||||||
|
"PRIMARY KEY(height, hash), UNIQUE(filter_hash, header, file, pos));";
|
||||||
|
|
||||||
|
if (fWipe) {
|
||||||
|
(*this) << "DELETE FROM locator";
|
||||||
|
(*this) << "DELETE FROM file_pos";
|
||||||
|
(*this) << "DELETE FROM block";
|
||||||
|
}
|
||||||
|
(*this) << "begin";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::DB::ReadBestBlock(CBlockLocator& locator) const
|
||||||
|
{
|
||||||
|
locator.SetNull();
|
||||||
|
bool success = false;
|
||||||
|
auto& branches = locator.vHave;
|
||||||
|
for (auto&& row : (*this) << "SELECT branch FROM locator") {
|
||||||
|
row >> *branches.insert(branches.end(), uint256{});
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::DB::WriteBestBlock(const CBlockLocator& locator)
|
||||||
|
{
|
||||||
|
(*this) << "DELETE FROM locator";
|
||||||
|
for (auto& branch : locator.vHave)
|
||||||
|
(*this) << "INSERT INTO locator VALUES(?)" << branch;
|
||||||
|
return (*this).rows_modified() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::DB::ReadFilePos(FlatFilePos& file) const
|
||||||
|
{
|
||||||
|
file.SetNull();
|
||||||
|
bool success = false;
|
||||||
|
for (auto&& row : (*this) << "SELECT file, pos FROM file_pos") {
|
||||||
|
row >> file.nFile >> file.nPos;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::DB::WriteFilePos(const FlatFilePos& file)
|
||||||
|
{
|
||||||
|
(*this) << "DELETE FROM file_pos";
|
||||||
|
(*this) << "INSERT INTO file_pos VALUES(?, ?)" << file.nFile << file.nPos;
|
||||||
|
return rows_modified() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseIndex::~BaseIndex()
|
||||||
|
{
|
||||||
|
Interrupt();
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::Init()
|
||||||
|
{
|
||||||
|
CBlockLocator locator;
|
||||||
|
if (!GetDB().ReadBestBlock(locator)) {
|
||||||
|
locator.SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(cs_main);
|
||||||
|
if (locator.IsNull()) {
|
||||||
|
m_best_block_index = nullptr;
|
||||||
|
} else {
|
||||||
|
m_best_block_index = FindForkInGlobalIndex(::ChainActive(), locator);
|
||||||
|
}
|
||||||
|
m_synced = m_best_block_index.load() == ::ChainActive().Tip();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||||
|
{
|
||||||
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
|
if (!pindex_prev) {
|
||||||
|
return ::ChainActive().Genesis();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CBlockIndex* pindex = ::ChainActive().Next(pindex_prev);
|
||||||
|
if (pindex) {
|
||||||
|
return pindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ::ChainActive().Next(::ChainActive().FindFork(pindex_prev));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIndex::ThreadSync()
|
||||||
|
{
|
||||||
|
const CBlockIndex* pindex = m_best_block_index.load();
|
||||||
|
if (!m_synced) {
|
||||||
|
auto& consensus_params = Params().GetConsensus();
|
||||||
|
|
||||||
|
int64_t last_log_time = 0;
|
||||||
|
int64_t last_locator_write_time = 0;
|
||||||
|
while (true) {
|
||||||
|
if (m_interrupt) {
|
||||||
|
m_best_block_index = pindex;
|
||||||
|
// No need to handle errors in Commit. If it fails, the error will be already be
|
||||||
|
// logged. The best way to recover is to continue, as index cannot be corrupted by
|
||||||
|
// a missed commit to disk for an advanced index state.
|
||||||
|
Commit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
const CBlockIndex* pindex_next = NextSyncBlock(pindex);
|
||||||
|
if (!pindex_next) {
|
||||||
|
m_best_block_index = pindex;
|
||||||
|
m_synced = true;
|
||||||
|
// No need to handle errors in Commit. See rationale above.
|
||||||
|
Commit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pindex_next->pprev != pindex && !Rewind(pindex, pindex_next->pprev)) {
|
||||||
|
FatalError("%s: Failed to rewind index %s to a previous chain tip",
|
||||||
|
__func__, GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pindex = pindex_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t current_time = GetTime();
|
||||||
|
if (last_log_time + SYNC_LOG_INTERVAL < current_time) {
|
||||||
|
LogPrintf("Syncing %s with block chain from height %d\n",
|
||||||
|
GetName(), pindex->nHeight);
|
||||||
|
last_log_time = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_locator_write_time + SYNC_LOCATOR_WRITE_INTERVAL < current_time) {
|
||||||
|
m_best_block_index = pindex;
|
||||||
|
last_locator_write_time = current_time;
|
||||||
|
// No need to handle errors in Commit. See rationale above.
|
||||||
|
Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
CBlock block;
|
||||||
|
if (!ReadBlockFromDisk(block, pindex, consensus_params)) {
|
||||||
|
FatalError("%s: Failed to read block %s from disk",
|
||||||
|
__func__, pindex->GetBlockHash().ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!WriteBlock(block, pindex)) {
|
||||||
|
FatalError("%s: Failed to write block %s to index database",
|
||||||
|
__func__, pindex->GetBlockHash().ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pindex) {
|
||||||
|
LogPrintf("%s is enabled at height %d\n", GetName(), pindex->nHeight);
|
||||||
|
} else {
|
||||||
|
LogPrintf("%s is enabled\n", GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::Commit()
|
||||||
|
{
|
||||||
|
if (!CommitInternal() || sqlite::commit(GetDB()) != SQLITE_OK) {
|
||||||
|
GetDB() << "rollback; begin";
|
||||||
|
return error("%s: Failed to commit latest %s state", __func__, GetName());
|
||||||
|
}
|
||||||
|
GetDB() << "begin";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::CommitInternal()
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
return GetDB().WriteBestBlock(::ChainActive().GetLocator(m_best_block_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip)
|
||||||
|
{
|
||||||
|
assert(current_tip == m_best_block_index);
|
||||||
|
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip);
|
||||||
|
|
||||||
|
// In the case of a reorg, ensure persisted block locator is not stale.
|
||||||
|
m_best_block_index = new_tip;
|
||||||
|
if (!Commit()) {
|
||||||
|
// If commit fails, revert the best block index to avoid corruption.
|
||||||
|
m_best_block_index = current_tip;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
|
||||||
|
const std::vector<CTransactionRef>& txn_conflicted)
|
||||||
|
{
|
||||||
|
if (!m_synced) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CBlockIndex* best_block_index = m_best_block_index.load();
|
||||||
|
if (!best_block_index) {
|
||||||
|
if (pindex->nHeight != 0) {
|
||||||
|
FatalError("%s: First block connected is not the genesis block (height=%d)",
|
||||||
|
__func__, pindex->nHeight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Ensure block connects to an ancestor of the current best block. This should be the case
|
||||||
|
// most of the time, but may not be immediately after the sync thread catches up and sets
|
||||||
|
// m_synced. Consider the case where there is a reorg and the blocks on the stale branch are
|
||||||
|
// in the ValidationInterface queue backlog even after the sync thread has caught up to the
|
||||||
|
// new chain tip. In this unlikely event, log a warning and let the queue clear.
|
||||||
|
if (best_block_index->GetAncestor(pindex->nHeight - 1) != pindex->pprev) {
|
||||||
|
LogPrintf("%s: WARNING: Block %s does not connect to an ancestor of " /* Continued */
|
||||||
|
"known best chain (tip=%s); not updating index\n",
|
||||||
|
__func__, pindex->GetBlockHash().ToString(),
|
||||||
|
best_block_index->GetBlockHash().ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (best_block_index != pindex->pprev && !Rewind(best_block_index, pindex->pprev)) {
|
||||||
|
FatalError("%s: Failed to rewind index %s to a previous chain tip",
|
||||||
|
__func__, GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WriteBlock(*block, pindex)) {
|
||||||
|
m_best_block_index = pindex;
|
||||||
|
} else {
|
||||||
|
FatalError("%s: Failed to write block %s to index",
|
||||||
|
__func__, pindex->GetBlockHash().ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIndex::ChainStateFlushed(const CBlockLocator& locator)
|
||||||
|
{
|
||||||
|
if (!m_synced) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint256& locator_tip_hash = locator.vHave.front();
|
||||||
|
const CBlockIndex* locator_tip_index;
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
locator_tip_index = LookupBlockIndex(locator_tip_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!locator_tip_index) {
|
||||||
|
FatalError("%s: First block (hash=%s) in locator was not found",
|
||||||
|
__func__, locator_tip_hash.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This checks that ChainStateFlushed callbacks are received after BlockConnected. The check may fail
|
||||||
|
// immediately after the sync thread catches up and sets m_synced. Consider the case where
|
||||||
|
// there is a reorg and the blocks on the stale branch are in the ValidationInterface queue
|
||||||
|
// backlog even after the sync thread has caught up to the new chain tip. In this unlikely
|
||||||
|
// event, log a warning and let the queue clear.
|
||||||
|
const CBlockIndex* best_block_index = m_best_block_index.load();
|
||||||
|
if (best_block_index->GetAncestor(locator_tip_index->nHeight) != locator_tip_index) {
|
||||||
|
LogPrintf("%s: WARNING: Locator contains block (hash=%s) not on known best " /* Continued */
|
||||||
|
"chain (tip=%s); not writing index locator\n",
|
||||||
|
__func__, locator_tip_hash.ToString(),
|
||||||
|
best_block_index->GetBlockHash().ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need to handle errors in Commit. If it fails, the error will be already be logged. The
|
||||||
|
// best way to recover is to continue, as index cannot be corrupted by a missed commit to disk
|
||||||
|
// for an advanced index state.
|
||||||
|
Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::BlockUntilSyncedToCurrentChain()
|
||||||
|
{
|
||||||
|
AssertLockNotHeld(cs_main);
|
||||||
|
|
||||||
|
if (!m_synced) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Skip the queue-draining stuff if we know we're caught up with
|
||||||
|
// ::ChainActive().Tip().
|
||||||
|
LOCK(cs_main);
|
||||||
|
const CBlockIndex* chain_tip = ::ChainActive().Tip();
|
||||||
|
const CBlockIndex* best_block_index = m_best_block_index.load();
|
||||||
|
if (best_block_index->GetAncestor(chain_tip->nHeight) == chain_tip) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrintf("%s: %s is catching up on block notifications\n", __func__, GetName());
|
||||||
|
SyncWithValidationInterfaceQueue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIndex::Interrupt()
|
||||||
|
{
|
||||||
|
m_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIndex::Start()
|
||||||
|
{
|
||||||
|
// Need to register this ValidationInterface before running Init(), so that
|
||||||
|
// callbacks are not missed if Init sets m_synced to true.
|
||||||
|
RegisterValidationInterface(this);
|
||||||
|
if (!Init()) {
|
||||||
|
FatalError("%s: %s failed to initialize", __func__, GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_thread_sync = std::thread(&TraceThread<std::function<void()>>, GetName(),
|
||||||
|
std::bind(&BaseIndex::ThreadSync, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseIndex::Stop()
|
||||||
|
{
|
||||||
|
UnregisterValidationInterface(this);
|
||||||
|
|
||||||
|
if (m_thread_sync.joinable()) {
|
||||||
|
m_thread_sync.join();
|
||||||
|
}
|
||||||
|
}
|
117
src/index/base.h
Normal file
117
src/index/base.h
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_INDEX_BASE_H
|
||||||
|
#define BITCOIN_INDEX_BASE_H
|
||||||
|
|
||||||
|
#include <flatfile.h>
|
||||||
|
#include <primitives/block.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
|
#include <sqlite.h>
|
||||||
|
#include <threadinterrupt.h>
|
||||||
|
#include <uint256.h>
|
||||||
|
#include <validationinterface.h>
|
||||||
|
|
||||||
|
class CBlockIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for indices of blockchain data. This implements
|
||||||
|
* CValidationInterface and ensures blocks are indexed sequentially according
|
||||||
|
* to their position in the active chain.
|
||||||
|
*/
|
||||||
|
class BaseIndex : public CValidationInterface
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
class DB : public sqlite::database
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DB(const fs::path& path, size_t n_cache_size, bool fMemory, bool fWipe);
|
||||||
|
|
||||||
|
/// Read block locator of the chain that the txindex is in sync with.
|
||||||
|
bool ReadBestBlock(CBlockLocator& locator) const;
|
||||||
|
|
||||||
|
/// Write block locator of the chain that the txindex is in sync with.
|
||||||
|
bool WriteBestBlock(const CBlockLocator& locator);
|
||||||
|
|
||||||
|
bool ReadFilePos(FlatFilePos& file) const;
|
||||||
|
|
||||||
|
bool WriteFilePos(const FlatFilePos& file);
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Whether the index is in sync with the main chain. The flag is flipped
|
||||||
|
/// from false to true once, after which point this starts processing
|
||||||
|
/// ValidationInterface notifications to stay in sync.
|
||||||
|
std::atomic<bool> m_synced{false};
|
||||||
|
|
||||||
|
/// The last block in the chain that the index is in sync with.
|
||||||
|
std::atomic<const CBlockIndex*> m_best_block_index{nullptr};
|
||||||
|
|
||||||
|
std::thread m_thread_sync;
|
||||||
|
CThreadInterrupt m_interrupt;
|
||||||
|
|
||||||
|
/// Sync the index with the block index starting from the current best block.
|
||||||
|
/// Intended to be run in its own thread, m_thread_sync, and can be
|
||||||
|
/// interrupted with m_interrupt. Once the index gets in sync, the m_synced
|
||||||
|
/// flag is set and the BlockConnected ValidationInterface callback takes
|
||||||
|
/// over and the sync thread exits.
|
||||||
|
void ThreadSync();
|
||||||
|
|
||||||
|
/// Write the current index state (eg. chain block locator and subclass-specific items) to disk.
|
||||||
|
///
|
||||||
|
/// Recommendations for error handling:
|
||||||
|
/// If called on a successor of the previous committed best block in the index, the index can
|
||||||
|
/// continue processing without risk of corruption, though the index state will need to catch up
|
||||||
|
/// from further behind on reboot. If the new state is not a successor of the previous state (due
|
||||||
|
/// to a chain reorganization), the index must halt until Commit succeeds or else it could end up
|
||||||
|
/// getting corrupted.
|
||||||
|
bool Commit();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
|
||||||
|
const std::vector<CTransactionRef>& txn_conflicted) override;
|
||||||
|
|
||||||
|
void ChainStateFlushed(const CBlockLocator& locator) override;
|
||||||
|
|
||||||
|
/// Initialize internal state from the database and block index.
|
||||||
|
virtual bool Init();
|
||||||
|
|
||||||
|
/// Write update index entries for a newly connected block.
|
||||||
|
virtual bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) { return true; }
|
||||||
|
|
||||||
|
/// Virtual method called internally by Commit that can be overridden to atomically
|
||||||
|
/// commit more index state.
|
||||||
|
virtual bool CommitInternal();
|
||||||
|
|
||||||
|
/// Rewind index to an earlier chain tip during a chain reorg. The tip must
|
||||||
|
/// be an ancestor of the current best block.
|
||||||
|
virtual bool Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip);
|
||||||
|
|
||||||
|
virtual DB& GetDB() const = 0;
|
||||||
|
|
||||||
|
/// Get the name of the index for display in logs.
|
||||||
|
virtual const char* GetName() const = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Destructor interrupts sync thread if running and blocks until it exits.
|
||||||
|
virtual ~BaseIndex();
|
||||||
|
|
||||||
|
/// Blocks the current thread until the index is caught up to the current
|
||||||
|
/// state of the block chain. This only blocks if the index has gotten in
|
||||||
|
/// sync once and only needs to process blocks in the ValidationInterface
|
||||||
|
/// queue. If the index is catching up from far behind, this method does
|
||||||
|
/// not block and immediately returns false.
|
||||||
|
bool BlockUntilSyncedToCurrentChain();
|
||||||
|
|
||||||
|
void Interrupt();
|
||||||
|
|
||||||
|
/// Start initializes the sync state and registers the instance as a
|
||||||
|
/// ValidationInterface so that it stays in sync with blockchain updates.
|
||||||
|
void Start();
|
||||||
|
|
||||||
|
/// Stops the instance from staying in sync with blockchain updates.
|
||||||
|
void Stop();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BITCOIN_INDEX_BASE_H
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <dbwrapper.h>
|
#include <clientversion.h>
|
||||||
#include <index/blockfilterindex.h>
|
#include <index/blockfilterindex.h>
|
||||||
|
#include <streams.h>
|
||||||
|
#include <sqlite.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
|
@ -14,19 +16,7 @@
|
||||||
* height, and those belonging to blocks that have been reorganized out of the active chain are
|
* height, and those belonging to blocks that have been reorganized out of the active chain are
|
||||||
* indexed by block hash. This ensures that filter data for any block that becomes part of the
|
* indexed by block hash. This ensures that filter data for any block that becomes part of the
|
||||||
* active chain can always be retrieved, alleviating timing concerns.
|
* active chain can always be retrieved, alleviating timing concerns.
|
||||||
*
|
|
||||||
* The filters themselves are stored in flat files and referenced by the LevelDB entries. This
|
|
||||||
* minimizes the amount of data written to LevelDB and keeps the database values constant size. The
|
|
||||||
* disk location of the next block filter to be written (represented as a FlatFilePos) is stored
|
|
||||||
* under the DB_FILTER_POS key.
|
|
||||||
*
|
|
||||||
* Keys for the height index have the type [DB_BLOCK_HEIGHT, uint32 (BE)]. The height is represented
|
|
||||||
* as big-endian so that sequential reads of filters by height are fast.
|
|
||||||
* Keys for the hash index have the type [DB_BLOCK_HASH, uint256].
|
|
||||||
*/
|
*/
|
||||||
constexpr char DB_BLOCK_HASH = 's';
|
|
||||||
constexpr char DB_BLOCK_HEIGHT = 't';
|
|
||||||
constexpr char DB_FILTER_POS = 'P';
|
|
||||||
|
|
||||||
constexpr unsigned int MAX_FLTR_FILE_SIZE = 0x1000000; // 16 MiB
|
constexpr unsigned int MAX_FLTR_FILE_SIZE = 0x1000000; // 16 MiB
|
||||||
/** The pre-allocation chunk size for fltr?????.dat files */
|
/** The pre-allocation chunk size for fltr?????.dat files */
|
||||||
|
@ -49,50 +39,7 @@ struct DBVal {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DBHeightKey {
|
} // namespace
|
||||||
int height;
|
|
||||||
|
|
||||||
DBHeightKey() : height(0) {}
|
|
||||||
explicit DBHeightKey(int height_in) : height(height_in) {}
|
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
void Serialize(Stream& s) const
|
|
||||||
{
|
|
||||||
ser_writedata8(s, DB_BLOCK_HEIGHT);
|
|
||||||
ser_writedata32be(s, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Stream>
|
|
||||||
void Unserialize(Stream& s)
|
|
||||||
{
|
|
||||||
char prefix = ser_readdata8(s);
|
|
||||||
if (prefix != DB_BLOCK_HEIGHT) {
|
|
||||||
throw std::ios_base::failure("Invalid format for block filter index DB height key");
|
|
||||||
}
|
|
||||||
height = ser_readdata32be(s);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DBHashKey {
|
|
||||||
uint256 hash;
|
|
||||||
|
|
||||||
explicit DBHashKey(const uint256& hash_in) : hash(hash_in) {}
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
||||||
char prefix = DB_BLOCK_HASH;
|
|
||||||
READWRITE(prefix);
|
|
||||||
if (prefix != DB_BLOCK_HASH) {
|
|
||||||
throw std::ios_base::failure("Invalid format for block filter index DB hash key");
|
|
||||||
}
|
|
||||||
|
|
||||||
READWRITE(hash);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace
|
|
||||||
|
|
||||||
static std::map<BlockFilterType, BlockFilterIndex> g_filter_indexes;
|
static std::map<BlockFilterType, BlockFilterIndex> g_filter_indexes;
|
||||||
|
|
||||||
|
@ -113,23 +60,11 @@ BlockFilterIndex::BlockFilterIndex(BlockFilterType filter_type,
|
||||||
|
|
||||||
bool BlockFilterIndex::Init()
|
bool BlockFilterIndex::Init()
|
||||||
{
|
{
|
||||||
if (!m_db->Read(DB_FILTER_POS, m_next_filter_pos)) {
|
m_db->ReadFilePos(m_next_filter_pos);
|
||||||
// Check that the cause of the read failure is that the key does not exist. Any other errors
|
|
||||||
// indicate database corruption or a disk failure, and starting the index would cause
|
|
||||||
// further corruption.
|
|
||||||
if (m_db->Exists(DB_FILTER_POS)) {
|
|
||||||
return error("%s: Cannot read current %s state; index may be corrupted",
|
|
||||||
__func__, GetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the DB_FILTER_POS is not set, then initialize to the first location.
|
|
||||||
m_next_filter_pos.nFile = 0;
|
|
||||||
m_next_filter_pos.nPos = 0;
|
|
||||||
}
|
|
||||||
return BaseIndex::Init();
|
return BaseIndex::Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockFilterIndex::CommitInternal(CDBBatch& batch)
|
bool BlockFilterIndex::CommitInternal()
|
||||||
{
|
{
|
||||||
const FlatFilePos& pos = m_next_filter_pos;
|
const FlatFilePos& pos = m_next_filter_pos;
|
||||||
|
|
||||||
|
@ -142,8 +77,7 @@ bool BlockFilterIndex::CommitInternal(CDBBatch& batch)
|
||||||
return error("%s: Failed to commit filter file %d", __func__, pos.nFile);
|
return error("%s: Failed to commit filter file %d", __func__, pos.nFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.Write(DB_FILTER_POS, pos);
|
return BaseIndex::CommitInternal();
|
||||||
return BaseIndex::CommitInternal(batch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, BlockFilter& filter) const
|
bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, BlockFilter& filter) const
|
||||||
|
@ -222,18 +156,20 @@ bool BlockFilterIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint256, DBVal> read_out;
|
uint256 block_hash;
|
||||||
if (!m_db->Read(DBHeightKey(pindex->nHeight - 1), read_out)) {
|
auto query = (*m_db) << "SELECT hash, header FROM block WHERE height = ?"
|
||||||
|
<< pindex->nHeight - 1;
|
||||||
|
auto it = query.begin();
|
||||||
|
if (it == query.end())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
*it >> block_hash >> prev_header;
|
||||||
|
|
||||||
uint256 expected_block_hash = pindex->pprev->GetBlockHash();
|
uint256 expected_block_hash = pindex->pprev->GetBlockHash();
|
||||||
if (read_out.first != expected_block_hash) {
|
if (block_hash != expected_block_hash) {
|
||||||
return error("%s: previous block header belongs to unexpected block %s; expected %s",
|
return error("%s: previous block header belongs to unexpected block %s; expected %s",
|
||||||
__func__, read_out.first.ToString(), expected_block_hash.ToString());
|
__func__, block_hash.ToString(), expected_block_hash.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_header = read_out.second.header;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockFilter filter(m_filter_type, block, block_undo);
|
BlockFilter filter(m_filter_type, block, block_undo);
|
||||||
|
@ -241,13 +177,15 @@ bool BlockFilterIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex
|
||||||
size_t bytes_written = WriteFilterToDisk(m_next_filter_pos, filter);
|
size_t bytes_written = WriteFilterToDisk(m_next_filter_pos, filter);
|
||||||
if (bytes_written == 0) return false;
|
if (bytes_written == 0) return false;
|
||||||
|
|
||||||
std::pair<uint256, DBVal> value;
|
(*m_db) << "INSERT INTO block VALUES(?, ?, ?, ?, ?, ?)"
|
||||||
value.first = pindex->GetBlockHash();
|
<< pindex->nHeight
|
||||||
value.second.hash = filter.GetHash();
|
<< pindex->GetBlockHash()
|
||||||
value.second.header = filter.ComputeHeader(prev_header);
|
<< filter.GetHash()
|
||||||
value.second.pos = m_next_filter_pos;
|
<< filter.ComputeHeader(prev_header)
|
||||||
|
<< m_next_filter_pos.nFile
|
||||||
|
<< m_next_filter_pos.nPos;
|
||||||
|
|
||||||
if (!m_db->Write(DBHeightKey(pindex->nHeight), value)) {
|
if (!(m_db->rows_modified() > 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,74 +193,49 @@ bool BlockFilterIndex::WriteBlock(const CBlock& block, const CBlockIndex* pindex
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CopyHeightIndexToHashIndex(CDBIterator& db_it, CDBBatch& batch,
|
static bool CopyHeightIndexToHashIndex(sqlite::database& db,
|
||||||
const std::string& index_name,
|
|
||||||
int start_height, int stop_height)
|
int start_height, int stop_height)
|
||||||
{
|
{
|
||||||
DBHeightKey key(start_height);
|
db << "UPDATE block SET height = NULL WHERE height >= ? and height <= ?"
|
||||||
db_it.Seek(key);
|
<< start_height << stop_height;
|
||||||
|
return db.rows_modified() > 0;
|
||||||
for (int height = start_height; height <= stop_height; ++height) {
|
|
||||||
if (!db_it.GetKey(key) || key.height != height) {
|
|
||||||
return error("%s: unexpected key in %s: expected (%c, %d)",
|
|
||||||
__func__, index_name, DB_BLOCK_HEIGHT, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<uint256, DBVal> value;
|
|
||||||
if (!db_it.GetValue(value)) {
|
|
||||||
return error("%s: unable to read value in %s at key (%c, %d)",
|
|
||||||
__func__, index_name, DB_BLOCK_HEIGHT, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.Write(DBHashKey(value.first), std::move(value.second));
|
|
||||||
|
|
||||||
db_it.Next();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockFilterIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip)
|
bool BlockFilterIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip)
|
||||||
{
|
{
|
||||||
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip);
|
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip);
|
||||||
|
|
||||||
CDBBatch batch(*m_db);
|
|
||||||
std::unique_ptr<CDBIterator> db_it(m_db->NewIterator());
|
|
||||||
|
|
||||||
// During a reorg, we need to copy all filters for blocks that are getting disconnected from the
|
// During a reorg, we need to copy all filters for blocks that are getting disconnected from the
|
||||||
// height index to the hash index so we can still find them when the height index entries are
|
// height index to the hash index so we can still find them when the height index entries are
|
||||||
// overwritten.
|
// overwritten.
|
||||||
if (!CopyHeightIndexToHashIndex(*db_it, batch, m_name, new_tip->nHeight, current_tip->nHeight)) {
|
if (!CopyHeightIndexToHashIndex(*m_db, new_tip->nHeight, current_tip->nHeight)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The latest filter position gets written in Commit by the call to the BaseIndex::Rewind.
|
// The latest filter position gets written in Commit by the call to the BaseIndex::Rewind.
|
||||||
// But since this creates new references to the filter, the position should get updated here
|
// But since this creates new references to the filter, the position should get updated here
|
||||||
// atomically as well in case Commit fails.
|
// atomically as well in case Commit fails.
|
||||||
batch.Write(DB_FILTER_POS, m_next_filter_pos);
|
if (!m_db->WriteFilePos(m_next_filter_pos)) return false;
|
||||||
if (!m_db->WriteBatch(batch)) return false;
|
|
||||||
|
|
||||||
return BaseIndex::Rewind(current_tip, new_tip);
|
return BaseIndex::Rewind(current_tip, new_tip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LookupOne(const CDBWrapper& db, const CBlockIndex* block_index, DBVal& result)
|
static bool LookupOne(sqlite::database& db, const CBlockIndex* block_index, DBVal& result)
|
||||||
{
|
{
|
||||||
// First check if the result is stored under the height index and the value there matches the
|
// First check if the result is stored under the height index and the value there matches the
|
||||||
// block hash. This should be the case if the block is on the active chain.
|
// block hash. This should be the case if the block is on the active chain.
|
||||||
std::pair<uint256, DBVal> read_out;
|
auto query = db << "SELECT filter_hash, header, file, pos FROM block WHERE (height = ? "
|
||||||
if (!db.Read(DBHeightKey(block_index->nHeight), read_out)) {
|
<< "OR height IS NULL) AND hash = ? LIMIT 1"
|
||||||
return false;
|
<< block_index->nHeight << block_index->GetBlockHash();
|
||||||
}
|
|
||||||
if (read_out.first == block_index->GetBlockHash()) {
|
for (auto&& row : query) {
|
||||||
result = std::move(read_out.second);
|
row >> result.hash >> result.header >> result.pos.nFile >> result.pos.nPos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
// If value at the height index corresponds to an different block, the result will be stored in
|
|
||||||
// the hash index.
|
|
||||||
return db.Read(DBHashKey(block_index->GetBlockHash()), result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start_height,
|
static bool LookupRange(sqlite::database& db, const std::string& index_name, int start_height,
|
||||||
const CBlockIndex* stop_index, std::vector<DBVal>& results)
|
const CBlockIndex* stop_index, std::vector<DBVal>& results)
|
||||||
{
|
{
|
||||||
if (start_height < 0) {
|
if (start_height < 0) {
|
||||||
|
@ -334,25 +247,6 @@ static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t results_size = static_cast<size_t>(stop_index->nHeight - start_height + 1);
|
size_t results_size = static_cast<size_t>(stop_index->nHeight - start_height + 1);
|
||||||
std::vector<std::pair<uint256, DBVal>> values(results_size);
|
|
||||||
|
|
||||||
DBHeightKey key(start_height);
|
|
||||||
std::unique_ptr<CDBIterator> db_it(db.NewIterator());
|
|
||||||
db_it->Seek(DBHeightKey(start_height));
|
|
||||||
for (int height = start_height; height <= stop_index->nHeight; ++height) {
|
|
||||||
if (!db_it->Valid() || !db_it->GetKey(key) || key.height != height) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t i = static_cast<size_t>(height - start_height);
|
|
||||||
if (!db_it->GetValue(values[i])) {
|
|
||||||
return error("%s: unable to read value in %s at key (%c, %d)",
|
|
||||||
__func__, index_name, DB_BLOCK_HEIGHT, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
db_it->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
results.resize(results_size);
|
results.resize(results_size);
|
||||||
|
|
||||||
// Iterate backwards through block indexes collecting results in order to access the block hash
|
// Iterate backwards through block indexes collecting results in order to access the block hash
|
||||||
|
@ -360,17 +254,10 @@ static bool LookupRange(CDBWrapper& db, const std::string& index_name, int start
|
||||||
for (const CBlockIndex* block_index = stop_index;
|
for (const CBlockIndex* block_index = stop_index;
|
||||||
block_index && block_index->nHeight >= start_height;
|
block_index && block_index->nHeight >= start_height;
|
||||||
block_index = block_index->pprev) {
|
block_index = block_index->pprev) {
|
||||||
uint256 block_hash = block_index->GetBlockHash();
|
|
||||||
|
|
||||||
size_t i = static_cast<size_t>(block_index->nHeight - start_height);
|
size_t i = static_cast<size_t>(block_index->nHeight - start_height);
|
||||||
if (block_hash == values[i].first) {
|
if (!LookupOne(db, block_index, results[i])) {
|
||||||
results[i] = std::move(values[i].second);
|
return error("%s: unable to read value in %s at key %s", __func__,
|
||||||
continue;
|
index_name, block_index->GetBlockHash().ToString());
|
||||||
}
|
|
||||||
|
|
||||||
if (!db.Read(DBHashKey(block_hash), results[i])) {
|
|
||||||
return error("%s: unable to read value in %s at key (%c, %s)",
|
|
||||||
__func__, index_name, DB_BLOCK_HASH, block_hash.ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
protected:
|
protected:
|
||||||
bool Init() override;
|
bool Init() override;
|
||||||
|
|
||||||
bool CommitInternal(CDBBatch& batch) override;
|
bool CommitInternal() override;
|
||||||
|
|
||||||
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
|
bool WriteBlock(const CBlock& block, const CBlockIndex* pindex) override;
|
||||||
|
|
||||||
|
|
14
src/init.cpp
14
src/init.cpp
|
@ -52,7 +52,9 @@
|
||||||
#include <ui_interface.h>
|
#include <ui_interface.h>
|
||||||
#include <util/moneystr.h>
|
#include <util/moneystr.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
|
#include <util/strencodings.h>
|
||||||
#include <util/threadnames.h>
|
#include <util/threadnames.h>
|
||||||
|
#include <util/translation.h>
|
||||||
#include <util/validation.h>
|
#include <util/validation.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
|
@ -286,7 +288,6 @@ void Shutdown(InitInterfaces& interfaces)
|
||||||
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
|
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
|
||||||
}
|
}
|
||||||
interfaces.chain_clients.clear();
|
interfaces.chain_clients.clear();
|
||||||
g_wallet_init_interface.Close();
|
|
||||||
UnregisterAllValidationInterfaces();
|
UnregisterAllValidationInterfaces();
|
||||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
||||||
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
||||||
|
@ -1213,7 +1214,6 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||||
// Detailed error printed inside CreatePidFile().
|
// Detailed error printed inside CreatePidFile().
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!LogInstance().StartLogging()) {
|
if (!LogInstance().StartLogging()) {
|
||||||
return InitError(strprintf("Could not open debug log file %s",
|
return InitError(strprintf("Could not open debug log file %s",
|
||||||
LogInstance().m_file_path.string()));
|
LogInstance().m_file_path.string()));
|
||||||
|
@ -1505,7 +1505,7 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||||
// From here on out fReindex and fReset mean something different!
|
// From here on out fReindex and fReset mean something different!
|
||||||
if (!LoadBlockIndex(chainparams)) {
|
if (!LoadBlockIndex(chainparams)) {
|
||||||
if (ShutdownRequested()) break;
|
if (ShutdownRequested()) break;
|
||||||
strLoadError = _("Error loading block index database");
|
strLoadError = _("Error loading block index database").translated;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1546,8 +1546,8 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||||
"", CClientUIInterface::MSG_ERROR);
|
"", CClientUIInterface::MSG_ERROR);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (g_logger->Enabled() && LogAcceptCategory(BCLog::CLAIMS))
|
if (LogInstance().Enabled() && LogAcceptCategory(BCLog::CLAIMS))
|
||||||
CLogPrint::global().setLogger(g_logger);
|
CLogPrint::global().setLogger(&LogInstance());
|
||||||
|
|
||||||
delete pclaimTrie;
|
delete pclaimTrie;
|
||||||
auto& consensus = chainparams.GetConsensus();
|
auto& consensus = chainparams.GetConsensus();
|
||||||
|
@ -1588,9 +1588,9 @@ bool AppInitMain(InitInterfaces& interfaces)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tip = chainActive.Tip();
|
auto tip = ::ChainActive().Tip();
|
||||||
if (tip && !CClaimTrieCache(pclaimTrie).validateDb(tip->nHeight, tip->hashClaimTrie)) {
|
if (tip && !CClaimTrieCache(pclaimTrie).validateDb(tip->nHeight, tip->hashClaimTrie)) {
|
||||||
strLoadError = _("Error validating the claim trie from disk");
|
strLoadError = _("Error validating the claim trie from disk").translated;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ public:
|
||||||
if (try_lock && result && !*result) return {};
|
if (try_lock && result && !*result) return {};
|
||||||
// std::move necessary on some compilers due to conversion from
|
// std::move necessary on some compilers due to conversion from
|
||||||
// LockImpl to Lock pointer
|
// LockImpl to Lock pointer
|
||||||
return std::move(result);
|
return std::unique_ptr<Chain::Lock>{std::move(result)};
|
||||||
}
|
}
|
||||||
bool findBlock(const uint256& hash, CBlock* block, int64_t* time, int64_t* time_max) override
|
bool findBlock(const uint256& hash, CBlock* block, int64_t* time, int64_t* time_max) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <script/standard.h>
|
#include <script/standard.h>
|
||||||
#include <timedata.h>
|
#include <timedata.h>
|
||||||
|
#include <validation.h>
|
||||||
#include <util/moneystr.h>
|
#include <util/moneystr.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <util/validation.h>
|
#include <util/validation.h>
|
||||||
|
@ -58,7 +59,7 @@ void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
||||||
|
|
||||||
trieCache.initializeIncrement();
|
trieCache.initializeIncrement();
|
||||||
|
|
||||||
CCoinsViewCache view(pcoinsTip.get());
|
CCoinsViewCache view(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
for (auto& tx : pblock->vtx)
|
for (auto& tx : pblock->vtx)
|
||||||
if (!tx->IsCoinBase())
|
if (!tx->IsCoinBase())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "nameclaim.h"
|
#include <nameclaim.h>
|
||||||
#include "hash.h"
|
#include <hash.h>
|
||||||
#include "util.h"
|
#include <logging.h>
|
||||||
|
|
||||||
std::vector<unsigned char> uint32_t_to_vch(uint32_t n)
|
std::vector<unsigned char> uint32_t_to_vch(uint32_t n)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +164,7 @@ size_t ClaimNameSize(const CScript& scriptIn)
|
||||||
return vvchParams[0].size();
|
return vvchParams[0].size();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount CalcMinClaimTrieFee(const CTransaction& tx, const CAmount &minFeePerNameClaimChar)
|
CAmount CalcMinClaimTrieFee(const CMutableTransaction& tx, const CAmount &minFeePerNameClaimChar)
|
||||||
{
|
{
|
||||||
if (minFeePerNameClaimChar == 0)
|
if (minFeePerNameClaimChar == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#ifndef BITCOIN_NAMECLAIM_H
|
#ifndef BITCOIN_NAMECLAIM_H
|
||||||
#define BITCOIN_NAMECLAIM_H
|
#define BITCOIN_NAMECLAIM_H
|
||||||
|
|
||||||
#include "amount.h"
|
#include <amount.h>
|
||||||
#include "script/script.h"
|
#include <script/script.h>
|
||||||
#include "primitives/transaction.h"
|
#include <primitives/transaction.h>
|
||||||
#include "uint256.h"
|
#include <uint256.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -40,6 +40,6 @@ size_t ClaimScriptSize(const CScript& scriptIn);
|
||||||
// get size of the name in a claim script, returns 0 if scriptin is not a claimetrie transaction
|
// get size of the name in a claim script, returns 0 if scriptin is not a claimetrie transaction
|
||||||
size_t ClaimNameSize(const CScript& scriptIn);
|
size_t ClaimNameSize(const CScript& scriptIn);
|
||||||
// calculate the minimum fee (mempool rule) required for transaction
|
// calculate the minimum fee (mempool rule) required for transaction
|
||||||
CAmount CalcMinClaimTrieFee(const CTransaction& tx, const CAmount &minFeePerNameClaimChar);
|
CAmount CalcMinClaimTrieFee(const CMutableTransaction& tx, const CAmount &minFeePerNameClaimChar);
|
||||||
|
|
||||||
#endif // BITCOIN_NAMECLAIM_H
|
#endif // BITCOIN_NAMECLAIM_H
|
||||||
|
|
|
@ -1015,6 +1015,7 @@ static bool MaybePunishNode(NodeId nodeid, const CValidationState& state, bool v
|
||||||
// The node is providing invalid data:
|
// The node is providing invalid data:
|
||||||
case ValidationInvalidReason::CONSENSUS:
|
case ValidationInvalidReason::CONSENSUS:
|
||||||
case ValidationInvalidReason::BLOCK_MUTATED:
|
case ValidationInvalidReason::BLOCK_MUTATED:
|
||||||
|
case ValidationInvalidReason::CLAIMTRIE_HASH:
|
||||||
if (!via_compact_block) {
|
if (!via_compact_block) {
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
Misbehaving(nodeid, 100, message);
|
Misbehaving(nodeid, 100, message);
|
||||||
|
|
|
@ -128,20 +128,12 @@ bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: After we fork, we can require these service bits
|
|
||||||
//
|
|
||||||
/* ServiceFlags GetDesirableServiceFlags(ServiceFlags services) { */
|
|
||||||
/* if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) { */
|
|
||||||
/* return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS); */
|
|
||||||
/* } */
|
|
||||||
/* return ServiceFlags(NODE_NETWORK | NODE_WITNESS); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
|
ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
|
||||||
if ((services & NODE_NETWORK) && g_initial_block_download_completed) {
|
if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
|
||||||
return ServiceFlags(NODE_NETWORK | NODE_BLOOM);
|
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
|
||||||
}
|
}
|
||||||
return ServiceFlags(NODE_NETWORK | NODE_BLOOM);
|
return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetServiceFlagsIBDCache(bool state) {
|
void SetServiceFlagsIBDCache(bool state) {
|
||||||
|
|
|
@ -773,12 +773,6 @@ void BitcoinGUI::macosDockIconActivated()
|
||||||
show();
|
show();
|
||||||
activateWindow();
|
activateWindow();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
void BitcoinGUI::macosDockIconActivated()
|
|
||||||
{
|
|
||||||
show();
|
|
||||||
activateWindow();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void BitcoinGUI::optionsClicked()
|
void BitcoinGUI::optionsClicked()
|
||||||
|
|
|
@ -384,9 +384,6 @@ void bringToFront(QWidget* w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void openDebugLogfile()
|
void openDebugLogfile()
|
||||||
{
|
{
|
||||||
fs::path pathDebug = GetDataDir() / "debug.log";
|
fs::path pathDebug = GetDataDir() / "debug.log";
|
||||||
|
|
|
@ -3381,10 +3381,6 @@ Note: Siden gebyret er kalkuleret på en per-byte basis, et gebyr på "100 satos
|
||||||
<source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
|
<source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
|
||||||
<translation>Fejl under læsning af %s! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte.</translation>
|
<translation>Fejl under læsning af %s! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u)</source>
|
|
||||||
<translation>Gruppér output efter adresse og vælg alle eller ingen, i stedet for at vælge på per-output-basis. Højere sikring af privatliv, da en adresse kun bruges én gang (med mindre nogen sender til en adresse efter den er brugt), men kan resultere i en anelse højere gebyrer, da ikke-optimal valg af output-adresser kan forekomme på grund af den tilføjede begrænsning (standard: %u)</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.</source>
|
<source>Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.</source>
|
||||||
<translation>Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet! Hvis der er fejl i disse, vil %s ikke fungere korrekt.</translation>
|
<translation>Undersøg venligst at din computers dato og klokkeslet er korrekt indstillet! Hvis der er fejl i disse, vil %s ikke fungere korrekt.</translation>
|
||||||
|
@ -3687,7 +3683,11 @@ Note: Siden gebyret er kalkuleret på en per-byte basis, et gebyr på "100 satos
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Den specificerede konfigurationsfil %s eksisterer ikke.
|
<translation>Den specificerede konfigurationsfil %s eksisterer ikke.
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Transaktionsbeløbet er for lille til at betale gebyret</translation>
|
<translation>Transaktionsbeløbet er for lille til at betale gebyret</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3685,7 +3685,11 @@ Hinweis: Eine Gebühr von "100 Satoshis pro kB" bei einer Größe der Transaktio
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Die spezifische Konfigurationsdatei %s existiert nicht.
|
<translation>Die spezifische Konfigurationsdatei %s existiert nicht.
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Der Transaktionsbetrag ist zu niedrig, um die Gebühr zu bezahlen.</translation>
|
<translation>Der Transaktionsbetrag ist zu niedrig, um die Gebühr zu bezahlen.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -1600,10 +1600,6 @@
|
||||||
<source>Copy fee</source>
|
<source>Copy fee</source>
|
||||||
<translation>Αντιγραφή τελών</translation>
|
<translation>Αντιγραφή τελών</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Copy fee</source>
|
|
||||||
<translation>Αντιγραφή τελών</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>or</source>
|
<source>or</source>
|
||||||
<translation>ή</translation>
|
<translation>ή</translation>
|
||||||
|
|
|
@ -3675,7 +3675,11 @@ Nota: Dado que la comisión se calcula por byte, una comisión de "100 satoshis
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>El fichero de configuración %s especificado no existe
|
<translation>El fichero de configuración %s especificado no existe
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>El monto de la transacción es muy pequeño para pagar la comisión</translation>
|
<translation>El monto de la transacción es muy pequeño para pagar la comisión</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -337,14 +337,6 @@
|
||||||
<source>Wallet:</source>
|
<source>Wallet:</source>
|
||||||
<translation>Lompakko:</translation>
|
<translation>Lompakko:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Wallet:</source>
|
|
||||||
<translation>Lompakko:</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>default wallet</source>
|
|
||||||
<translation>oletuslompakko</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Click to disable network activity.</source>
|
<source>Click to disable network activity.</source>
|
||||||
<translation>Paina poistaaksesi verkkoyhteysilmaisin käytöstä.</translation>
|
<translation>Paina poistaaksesi verkkoyhteysilmaisin käytöstä.</translation>
|
||||||
|
@ -1968,10 +1960,6 @@
|
||||||
<source>&Unban</source>
|
<source>&Unban</source>
|
||||||
<translation>&Poista esto</translation>
|
<translation>&Poista esto</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>default wallet</source>
|
|
||||||
<translation>oletuslompakko</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Welcome to the %1 RPC console.</source>
|
<source>Welcome to the %1 RPC console.</source>
|
||||||
<translation>Tervetuloa %1 RPC-konsoliin.</translation>
|
<translation>Tervetuloa %1 RPC-konsoliin.</translation>
|
||||||
|
|
|
@ -3683,7 +3683,11 @@ Note : Les frais étant calculés par octet, des frais de « 100 satoshis par
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Le fichier de configuration indiqué %s n’existe pas
|
<translation>Le fichier de configuration indiqué %s n’existe pas
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Le montant de la transaction est trop bas pour que les frais soient payés</translation>
|
<translation>Le montant de la transaction est trop bas pour que les frais soient payés</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3382,10 +3382,6 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p
|
||||||
<source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
|
<source>Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source>
|
||||||
<translation>%s の読み込み中にエラーが発生しました! 全ての鍵は正しく読み込めましたが、取引データやアドレス帳の項目が失われたか、正しくない可能性があります。</translation>
|
<translation>%s の読み込み中にエラーが発生しました! 全ての鍵は正しく読み込めましたが、取引データやアドレス帳の項目が失われたか、正しくない可能性があります。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Group outputs by address, selecting all or none, instead of selecting on a per-output basis. Privacy is improved as an address is only used once (unless someone sends to it after spending from it), but may result in slightly higher fees as suboptimal coin selection may result due to the added limitation (default: %u)</source>
|
|
||||||
<translation>出力ごとではなく、アドレス単位に出力をまとめて選択します。(後からまたそのアドレスに支払われない限り)アドレスが一度しか使用されないためプライバシーが向上します。ただし追加の制限により最適ではないコイン選択が発生した場合に、わずかに高い手数料となる可能性があります。(初期値: %u)</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.</source>
|
<source>Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.</source>
|
||||||
<translation>お使いのコンピューターの日付と時刻が正しいことを確認してください! PCの時計が正しくない場合 %s は正確に動作しません。</translation>
|
<translation>お使いのコンピューターの日付と時刻が正しいことを確認してください! PCの時計が正しくない場合 %s は正確に動作しません。</translation>
|
||||||
|
@ -3538,10 +3534,6 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p
|
||||||
<source>Unknown change type '%s'</source>
|
<source>Unknown change type '%s'</source>
|
||||||
<translation>未知のおつり用アドレス形式 '%s' です</translation>
|
<translation>未知のおつり用アドレス形式 '%s' です</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Specified blocks directory "%s" does not exist.</source>
|
|
||||||
<translation>指定のブロックディレクトリ"%s"は存在しません。</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Upgrading txindex database</source>
|
<source>Upgrading txindex database</source>
|
||||||
<translation>txindex データベースの更新中</translation>
|
<translation>txindex データベースの更新中</translation>
|
||||||
|
@ -3692,7 +3684,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>指定された設定ファイル %s が存在しません。
|
<translation>指定された設定ファイル %s が存在しません。
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>取引の手数料差引後金額が小さすぎるため、送金できません。</translation>
|
<translation>取引の手数料差引後金額が小さすぎるため、送金できません。</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3531,8 +3531,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>지정한 설정 파일 "%s"는 존재하지 않습니다
|
<translation>지정한 설정 파일 "%s"는 존재하지 않습니다
|
||||||
</translation>
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>거래액이 수수료를 지불하기엔 너무 작습니다</translation>
|
<translation>거래액이 수수료를 지불하기엔 너무 작습니다</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3684,7 +3684,11 @@ Notitie: Omdat de vergoeding per byte wordt gerekend, zal een vergoeding van "10
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Het opgegeven configuratiebestand %s bestaat niet
|
<translation>Het opgegeven configuratiebestand %s bestaat niet
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Het transactiebedrag is te klein om transactiekosten in rekening te brengen</translation>
|
<translation>Het transactiebedrag is te klein om transactiekosten in rekening te brengen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3686,7 +3686,11 @@ Zwróć uwagę, że poprawnie zweryfikowana wiadomość potwierdza to, że nadaw
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Podany plik konfiguracyjny %s nie istnieje
|
<translation>Podany plik konfiguracyjny %s nie istnieje
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation>
|
<translation>Zbyt niska kwota transakcji by zapłacić opłatę</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3684,7 +3684,11 @@ Diretório de blocos especificados "%s" não existe.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>O Arquivo de configuração especificado %s não existe
|
<translation>O Arquivo de configuração especificado %s não existe
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>A quantidade da transação é pequena demais para pagar a taxa</translation>
|
<translation>A quantidade da transação é pequena demais para pagar a taxa</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -297,10 +297,6 @@
|
||||||
<source>Wallet:</source>
|
<source>Wallet:</source>
|
||||||
<translation>Portofel:</translation>
|
<translation>Portofel:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>default wallet</source>
|
|
||||||
<translation>portofel implicit</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Click to disable network activity.</source>
|
<source>Click to disable network activity.</source>
|
||||||
<translation>Click pentru a opri activitatea retelei.</translation>
|
<translation>Click pentru a opri activitatea retelei.</translation>
|
||||||
|
@ -1792,10 +1788,6 @@
|
||||||
<source>&Unban</source>
|
<source>&Unban</source>
|
||||||
<translation>&Unban</translation>
|
<translation>&Unban</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>default wallet</source>
|
|
||||||
<translation>portofel implicit</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Welcome to the %1 RPC console.</source>
|
<source>Welcome to the %1 RPC console.</source>
|
||||||
<translation>Bun venit la consola %1 RPC.</translation>
|
<translation>Bun venit la consola %1 RPC.</translation>
|
||||||
|
|
|
@ -3684,7 +3684,11 @@ Poznámka: Keďže poplatok je počítaný za bajt, poplatok o hodnote "100 sato
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Zadaný konfiguračný súbor %s neexistuje
|
<translation>Zadaný konfiguračný súbor %s neexistuje
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Suma transakcie je príliš malá na zaplatenie poplatku</translation>
|
<translation>Suma transakcie je príliš malá na zaplatenie poplatku</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3605,7 +3605,10 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>Зазначений файл конфігурації %s не існує</translation>
|
<translation>Зазначений файл конфігурації %s не існує</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>Неможливо сплатити комісію із-за малої суми транзакції</translation>
|
<translation>Неможливо сплатити комісію із-за малої суми транзакції</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -3567,7 +3567,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The specified config file %s does not exist
|
<source>The specified config file %s does not exist
|
||||||
|
</source>
|
||||||
<translation>指定的配置文件 %s 不存在
|
<translation>指定的配置文件 %s 不存在
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
<source>The transaction amount is too small to pay the fee</source>
|
<source>The transaction amount is too small to pay the fee</source>
|
||||||
<translation>交易金額太少而付不起手續費</translation>
|
<translation>交易金額太少而付不起手續費</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -214,13 +214,13 @@ static bool rest_block(HTTPRequest* req,
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
tip = ::ChainActive().Tip();
|
tip = ::ChainActive().Tip();
|
||||||
if (blockHeight < 0) // negative block heights take us back from current tip
|
if (blockHeight < 0) // negative block heights take us back from current tip
|
||||||
blockHeight += chainActive.Height();
|
blockHeight += tip->nHeight;
|
||||||
if (blockHeight > 0 && blockHeight <= chainActive.Height())
|
if (blockHeight > 0 && blockHeight <= tip->nHeight)
|
||||||
pblockindex = chainActive[blockHeight];
|
pblockindex = ::ChainActive()[blockHeight];
|
||||||
else if (blockHeight != 0)
|
else if (blockHeight != 0)
|
||||||
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash or block height: " + hashStr);
|
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash or block height: " + hashStr);
|
||||||
else if (hashStr == "tip")
|
else if (hashStr == "tip")
|
||||||
pblockindex = chainActive.Tip();
|
pblockindex = tip;
|
||||||
else
|
else
|
||||||
pblockindex = LookupBlockIndex(hash);
|
pblockindex = LookupBlockIndex(hash);
|
||||||
if (!pblockindex) {
|
if (!pblockindex) {
|
||||||
|
|
|
@ -6,14 +6,16 @@
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <nameclaim.h>
|
#include <nameclaim.h>
|
||||||
#include <rpc/claimrpchelp.h>
|
#include <rpc/claimrpchelp.h>
|
||||||
|
#include <rpc/protocol.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
|
#include <rpc/util.h>
|
||||||
#include <script/standard.h>
|
#include <script/standard.h>
|
||||||
#include <shutdown.h>
|
#include <shutdown.h>
|
||||||
#include <txdb.h>
|
#include <txdb.h>
|
||||||
#include <txmempool.h>
|
#include <txmempool.h>
|
||||||
#include <undo.h>
|
#include <undo.h>
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
#include <utilstrencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
#include <boost/locale.hpp>
|
#include <boost/locale.hpp>
|
||||||
|
@ -35,11 +37,10 @@ static CBlockIndex* BlockHashIndex(const uint256& blockHash)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
if (mapBlockIndex.count(blockHash) == 0)
|
CBlockIndex* pblockIndex = LookupBlockIndex(blockHash);
|
||||||
|
if (!pblockIndex)
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||||
|
if (!::ChainActive().Contains(pblockIndex))
|
||||||
CBlockIndex* pblockIndex = mapBlockIndex[blockHash];
|
|
||||||
if (!chainActive.Contains(pblockIndex))
|
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not in main chain");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not in main chain");
|
||||||
|
|
||||||
return pblockIndex;
|
return pblockIndex;
|
||||||
|
@ -47,17 +48,17 @@ static CBlockIndex* BlockHashIndex(const uint256& blockHash)
|
||||||
|
|
||||||
#define MAX_RPC_BLOCK_DECREMENTS 500
|
#define MAX_RPC_BLOCK_DECREMENTS 500
|
||||||
|
|
||||||
extern CChainState g_chainstate;
|
|
||||||
void RollBackTo(const CBlockIndex* targetIndex, CCoinsViewCache& coinsCache, CClaimTrieCache& trieCache)
|
void RollBackTo(const CBlockIndex* targetIndex, CCoinsViewCache& coinsCache, CClaimTrieCache& trieCache)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
|
|
||||||
const CBlockIndex* activeIndex = chainActive.Tip();
|
const CBlockIndex* activeIndex = ::ChainActive().Tip();
|
||||||
|
|
||||||
if (activeIndex->nHeight > (targetIndex->nHeight + MAX_RPC_BLOCK_DECREMENTS))
|
if (activeIndex->nHeight > (targetIndex->nHeight + MAX_RPC_BLOCK_DECREMENTS))
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block is too deep");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block is too deep");
|
||||||
|
|
||||||
const size_t currentMemoryUsage = pcoinsTip->DynamicMemoryUsage();
|
auto& chainstate = ::ChainstateActive();
|
||||||
|
const size_t currentMemoryUsage = chainstate.CoinsTip().DynamicMemoryUsage();
|
||||||
|
|
||||||
for (; activeIndex && activeIndex != targetIndex; activeIndex = activeIndex->pprev) {
|
for (; activeIndex && activeIndex != targetIndex; activeIndex = activeIndex->pprev) {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
@ -72,7 +73,7 @@ void RollBackTo(const CBlockIndex* targetIndex, CCoinsViewCache& coinsCache, CCl
|
||||||
if (ShutdownRequested())
|
if (ShutdownRequested())
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested");
|
||||||
|
|
||||||
if (g_chainstate.DisconnectBlock(block, activeIndex, coinsCache, trieCache) != DisconnectResult::DISCONNECT_OK)
|
if (chainstate.DisconnectBlock(block, activeIndex, coinsCache, trieCache) != DisconnectResult::DISCONNECT_OK)
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Failed to disconnect %s", block.ToString()));
|
throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Failed to disconnect %s", block.ToString()));
|
||||||
}
|
}
|
||||||
trieCache.getMerkleHash(); // update the hash tree
|
trieCache.getMerkleHash(); // update the hash tree
|
||||||
|
@ -246,8 +247,8 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETNAMESINTRIE, 0, 1);
|
validateRequest(request, GETNAMESINTRIE, 0, 1);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
if (!request.params.empty()) {
|
if (!request.params.empty()) {
|
||||||
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter 1)"));
|
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter 1)"));
|
||||||
|
@ -271,8 +272,8 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETVALUEFORNAME, 1, 2);
|
validateRequest(request, GETVALUEFORNAME, 1, 2);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
if (request.params.size() > 1) {
|
if (request.params.size() > 1) {
|
||||||
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
|
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
|
||||||
|
@ -319,8 +320,8 @@ UniValue getclaimsforname(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETCLAIMSFORNAME, 1, 1);
|
validateRequest(request, GETCLAIMSFORNAME, 1, 1);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
if (request.params.size() > 1) {
|
if (request.params.size() > 1) {
|
||||||
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
|
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
|
||||||
|
@ -359,8 +360,8 @@ UniValue getclaimbybid(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETCLAIMBYBID, 1, 2);
|
validateRequest(request, GETCLAIMBYBID, 1, 2);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
int bid = 0;
|
int bid = 0;
|
||||||
if (request.params.size() > 1)
|
if (request.params.size() > 1)
|
||||||
|
@ -402,8 +403,8 @@ UniValue getclaimbyseq(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETCLAIMBYSEQ, 1, 2);
|
validateRequest(request, GETCLAIMBYSEQ, 1, 2);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
int seq = 0;
|
int seq = 0;
|
||||||
if (request.params.size() > 1)
|
if (request.params.size() > 1)
|
||||||
|
@ -448,7 +449,7 @@ UniValue getclaimbyid(const JSONRPCRequest& request)
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
std::string claimId;
|
std::string claimId;
|
||||||
ParseClaimtrieId(request.params[0], claimId, T_CLAIMID " (parameter 1)");
|
ParseClaimtrieId(request.params[0], claimId, T_CLAIMID " (parameter 1)");
|
||||||
|
@ -524,7 +525,8 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
|
||||||
std::vector<std::vector<unsigned char> > vvchParams;
|
std::vector<std::vector<unsigned char> > vvchParams;
|
||||||
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
CCoinsViewCache view(pcoinsTip.get());
|
CCoinsViewCache view(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
const Coin& coin = AccessByTxid(view, hash);
|
const Coin& coin = AccessByTxid(view, hash);
|
||||||
std::vector<CTxOut> txouts{ coin.out };
|
std::vector<CTxOut> txouts{ coin.out };
|
||||||
int nHeight = coin.nHeight;
|
int nHeight = coin.nHeight;
|
||||||
|
@ -551,7 +553,7 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
|
||||||
o.pushKV(T_VALUE, HexStr(vvchParams[2].begin(), vvchParams[2].end()));
|
o.pushKV(T_VALUE, HexStr(vvchParams[2].begin(), vvchParams[2].end()));
|
||||||
}
|
}
|
||||||
if (nHeight > 0) {
|
if (nHeight > 0) {
|
||||||
o.pushKV(T_DEPTH, chainActive.Height() - nHeight);
|
o.pushKV(T_DEPTH, ::ChainActive().Height() - nHeight);
|
||||||
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) {
|
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) {
|
||||||
bool inClaimTrie = trieCache.haveClaim(sName, COutPoint(hash, i));
|
bool inClaimTrie = trieCache.haveClaim(sName, COutPoint(hash, i));
|
||||||
o.pushKV(T_INCLAIMTRIE, inClaimTrie);
|
o.pushKV(T_INCLAIMTRIE, inClaimTrie);
|
||||||
|
@ -564,7 +566,7 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
|
||||||
int nValidAtHeight;
|
int nValidAtHeight;
|
||||||
if (trieCache.haveClaimInQueue(sName, COutPoint(hash, i), nValidAtHeight)) {
|
if (trieCache.haveClaimInQueue(sName, COutPoint(hash, i), nValidAtHeight)) {
|
||||||
o.pushKV(T_INQUEUE, true);
|
o.pushKV(T_INQUEUE, true);
|
||||||
o.pushKV(T_BLOCKSTOVALID, nValidAtHeight - chainActive.Height());
|
o.pushKV(T_BLOCKSTOVALID, nValidAtHeight - ::ChainActive().Height());
|
||||||
} else
|
} else
|
||||||
o.pushKV(T_INQUEUE, false);
|
o.pushKV(T_INQUEUE, false);
|
||||||
}
|
}
|
||||||
|
@ -575,7 +577,7 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
|
||||||
int nValidAtHeight;
|
int nValidAtHeight;
|
||||||
if (trieCache.haveSupportInQueue(sName, COutPoint(hash, i), nValidAtHeight)) {
|
if (trieCache.haveSupportInQueue(sName, COutPoint(hash, i), nValidAtHeight)) {
|
||||||
o.pushKV(T_INQUEUE, true);
|
o.pushKV(T_INQUEUE, true);
|
||||||
o.pushKV(T_BLOCKSTOVALID, nValidAtHeight - chainActive.Height());
|
o.pushKV(T_BLOCKSTOVALID, nValidAtHeight - ::ChainActive().Height());
|
||||||
} else
|
} else
|
||||||
o.pushKV(T_INQUEUE, false);
|
o.pushKV(T_INQUEUE, false);
|
||||||
}
|
}
|
||||||
|
@ -617,19 +619,19 @@ UniValue proofToJSON(const CClaimTrieProof& proof)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nodes.empty())
|
if (!nodes.empty())
|
||||||
result.push_back(Pair(T_NODES, nodes));
|
result.pushKV(T_NODES, nodes);
|
||||||
|
|
||||||
UniValue pairs(UniValue::VARR);
|
UniValue pairs(UniValue::VARR);
|
||||||
|
|
||||||
for (const auto& itPair : proof.pairs) {
|
for (const auto& itPair : proof.pairs) {
|
||||||
UniValue child(UniValue::VOBJ);
|
UniValue child(UniValue::VOBJ);
|
||||||
child.push_back(Pair(T_ODD, itPair.first));
|
child.pushKV(T_ODD, itPair.first);
|
||||||
child.push_back(Pair(T_HASH, itPair.second.GetHex()));
|
child.pushKV(T_HASH, itPair.second.GetHex());
|
||||||
pairs.push_back(child);
|
pairs.push_back(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pairs.empty())
|
if (!pairs.empty())
|
||||||
result.push_back(Pair(T_PAIRS, pairs));
|
result.pushKV(T_PAIRS, pairs);
|
||||||
|
|
||||||
if (proof.hasValue) {
|
if (proof.hasValue) {
|
||||||
result.pushKV(T_TXID, proof.outPoint.hash.GetHex());
|
result.pushKV(T_TXID, proof.outPoint.hash.GetHex());
|
||||||
|
@ -644,10 +646,10 @@ UniValue getnameproof(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETNAMEPROOF, 1, 2);
|
validateRequest(request, GETNAMEPROOF, 1, 2);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
int validHeight = chainActive.Tip()->nHeight;
|
int validHeight = ::ChainActive().Tip()->nHeight;
|
||||||
if (request.params.size() > 1) {
|
if (request.params.size() > 1) {
|
||||||
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
|
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
|
||||||
RollBackTo(pblockIndex, coinsCache, trieCache);
|
RollBackTo(pblockIndex, coinsCache, trieCache);
|
||||||
|
@ -681,8 +683,8 @@ UniValue getclaimproofbybid(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETCLAIMPROOFBYBID, 1, 2);
|
validateRequest(request, GETCLAIMPROOFBYBID, 1, 2);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
int bid = 0;
|
int bid = 0;
|
||||||
if (request.params.size() > 1)
|
if (request.params.size() > 1)
|
||||||
|
@ -715,8 +717,8 @@ UniValue getclaimproofbyseq(const JSONRPCRequest& request)
|
||||||
validateRequest(request, GETCLAIMPROOFBYSEQ, 1, 2);
|
validateRequest(request, GETCLAIMPROOFBYSEQ, 1, 2);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
int seq = 0;
|
int seq = 0;
|
||||||
if (request.params.size() > 1)
|
if (request.params.size() > 1)
|
||||||
|
@ -752,7 +754,7 @@ UniValue getchangesinblock(const JSONRPCRequest& request)
|
||||||
CBlock block;
|
CBlock block;
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
bool allowSupportMetadata;
|
bool allowSupportMetadata;
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
CCoinsViewCache coinsCache(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
UniValue claimsAddUp(UniValue::VARR),
|
UniValue claimsAddUp(UniValue::VARR),
|
||||||
claimsRm(UniValue::VARR),
|
claimsRm(UniValue::VARR),
|
||||||
|
@ -760,7 +762,7 @@ UniValue getchangesinblock(const JSONRPCRequest& request)
|
||||||
supportsRm(UniValue::VARR);
|
supportsRm(UniValue::VARR);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto index = chainActive.Tip();
|
auto index = ::ChainActive().Tip();
|
||||||
if (request.params.size() > 0)
|
if (request.params.size() > 0)
|
||||||
index = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter)"));
|
index = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter)"));
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,6 @@
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
#include <versionbitsinfo.h>
|
#include <versionbitsinfo.h>
|
||||||
#include <warnings.h>
|
#include <warnings.h>
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
#include <wallet/rpcwallet.h>
|
|
||||||
#include <wallet/wallet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -369,8 +364,6 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
UniValue lpval = NullUniValue;
|
UniValue lpval = NullUniValue;
|
||||||
std::set<std::string> setClientRules;
|
std::set<std::string> setClientRules;
|
||||||
int64_t nMaxVersionPreVB = -1;
|
int64_t nMaxVersionPreVB = -1;
|
||||||
UniValue aMutable(UniValue::VARR);
|
|
||||||
bool wantsCoinbaseTxn = false;
|
|
||||||
if (!request.params[0].isNull())
|
if (!request.params[0].isNull())
|
||||||
{
|
{
|
||||||
const UniValue& oparam = request.params[0].get_obj();
|
const UniValue& oparam = request.params[0].get_obj();
|
||||||
|
@ -385,17 +378,6 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
||||||
lpval = find_value(oparam, "longpollid");
|
lpval = find_value(oparam, "longpollid");
|
||||||
|
|
||||||
const UniValue& capval = find_value(oparam, "capabilities");
|
|
||||||
if (capval.isArray()) {
|
|
||||||
for (std::size_t i = 0; i < capval.size(); ++i)
|
|
||||||
if (capval[i].get_str() == "coinbase/append") // should be coinbase/* ? we dont' care what they do to the coinbase
|
|
||||||
aMutable.push_back(capval[i]);
|
|
||||||
#ifdef ENABLE_WALLET
|
|
||||||
else if (capval[i].get_str() == "coinbasetxn")
|
|
||||||
wantsCoinbaseTxn = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strMode == "proposal")
|
if (strMode == "proposal")
|
||||||
{
|
{
|
||||||
const UniValue& dataval = find_value(oparam, "data");
|
const UniValue& dataval = find_value(oparam, "data");
|
||||||
|
@ -524,20 +506,8 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
nStart = GetTime();
|
nStart = GetTime();
|
||||||
|
|
||||||
// Create new block
|
// Create new block
|
||||||
CScript newBlockScript = CScript() << OP_TRUE;
|
CScript scriptDummy = CScript() << OP_TRUE;
|
||||||
#ifdef ENABLE_WALLET
|
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy);
|
||||||
if (wantsCoinbaseTxn) {
|
|
||||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
|
||||||
if (!wallet)
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMS, "No wallet to comply with coinbasetxn request.");
|
|
||||||
std::shared_ptr<CReserveScript> coinbase_script;
|
|
||||||
wallet->GetScriptForMining(coinbase_script); // tops up and locks inside
|
|
||||||
if (!coinbase_script)
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMS, "Unable to acquire address for coinbasetxn request.");
|
|
||||||
newBlockScript = coinbase_script->reserveScript;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(newBlockScript);
|
|
||||||
if (!pblocktemplate)
|
if (!pblocktemplate)
|
||||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
||||||
|
|
||||||
|
@ -554,11 +524,10 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
|
|
||||||
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
|
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
|
||||||
const bool fPreSegWit = (pindexPrev->nHeight + 1 < consensusParams.SegwitHeight);
|
const bool fPreSegWit = (pindexPrev->nHeight + 1 < consensusParams.SegwitHeight);
|
||||||
if (!fPreSegWit && !fSupportsSegwit)
|
if (!fPreSegWit)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Segwit support is now required. Please include \"segwit\" in the client's rules.");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Segwit support is now required. Please include \"segwit\" in the client's rules.");
|
||||||
|
|
||||||
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
|
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
|
||||||
UniValue result(UniValue::VOBJ);
|
|
||||||
|
|
||||||
UniValue transactions(UniValue::VARR);
|
UniValue transactions(UniValue::VARR);
|
||||||
std::map<uint256, int64_t> setTxIndex;
|
std::map<uint256, int64_t> setTxIndex;
|
||||||
|
@ -568,8 +537,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
uint256 txHash = tx.GetHash();
|
uint256 txHash = tx.GetHash();
|
||||||
setTxIndex[txHash] = i++;
|
setTxIndex[txHash] = i++;
|
||||||
|
|
||||||
auto isCoinbase = tx.IsCoinBase();
|
if (tx.IsCoinBase())
|
||||||
if (isCoinbase && !wantsCoinbaseTxn)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
UniValue entry(UniValue::VOBJ);
|
UniValue entry(UniValue::VOBJ);
|
||||||
|
@ -596,10 +564,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
entry.pushKV("sigops", nTxSigOps);
|
entry.pushKV("sigops", nTxSigOps);
|
||||||
entry.pushKV("weight", GetTransactionWeight(tx));
|
entry.pushKV("weight", GetTransactionWeight(tx));
|
||||||
|
|
||||||
if (isCoinbase)
|
transactions.push_back(entry);
|
||||||
result.pushKV("coinbasetxn", entry);
|
|
||||||
else
|
|
||||||
transactions.push_back(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue aux(UniValue::VOBJ);
|
UniValue aux(UniValue::VOBJ);
|
||||||
|
@ -607,10 +572,12 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
|
|
||||||
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
|
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
|
||||||
|
|
||||||
|
UniValue aMutable(UniValue::VARR);
|
||||||
aMutable.push_back("time");
|
aMutable.push_back("time");
|
||||||
aMutable.push_back("transactions");
|
aMutable.push_back("transactions");
|
||||||
aMutable.push_back("prevblock");
|
aMutable.push_back("prevblock");
|
||||||
|
|
||||||
|
UniValue result(UniValue::VOBJ);
|
||||||
result.pushKV("capabilities", aCaps);
|
result.pushKV("capabilities", aCaps);
|
||||||
|
|
||||||
UniValue aRules(UniValue::VARR);
|
UniValue aRules(UniValue::VARR);
|
||||||
|
@ -677,7 +644,6 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
|
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1);
|
||||||
result.pushKV("mutable", aMutable);
|
result.pushKV("mutable", aMutable);
|
||||||
result.pushKV("noncerange", "00000000ffffffff");
|
result.pushKV("noncerange", "00000000ffffffff");
|
||||||
|
|
||||||
int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
|
int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
|
||||||
int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE;
|
int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE;
|
||||||
if (fPreSegWit) {
|
if (fPreSegWit) {
|
||||||
|
|
|
@ -542,7 +542,7 @@ static UniValue echo(const JSONRPCRequest& request)
|
||||||
RPCHelpMan{"echo|echojson ...",
|
RPCHelpMan{"echo|echojson ...",
|
||||||
"\nSimply echo back the input arguments. This command is for testing.\n"
|
"\nSimply echo back the input arguments. This command is for testing.\n"
|
||||||
"\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in "
|
"\nThe difference between echo and echojson is that echojson has argument conversion enabled in the client-side table in "
|
||||||
"lbrycrd-cli and the GUI. There is no server-side difference."
|
"lbrycrd-cli and the GUI. There is no server-side difference.",
|
||||||
{},
|
{},
|
||||||
RPCResults{},
|
RPCResults{},
|
||||||
RPCExamples{""},
|
RPCExamples{""},
|
||||||
|
|
|
@ -332,15 +332,6 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Duplicate checking
|
|
||||||
std::set<CTxDestination> destinations;
|
|
||||||
bool has_data{false};
|
|
||||||
|
|
||||||
if (has_data) {
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, duplicate key: data");
|
|
||||||
}
|
|
||||||
has_data = true;
|
|
||||||
static UniValue createrawtransaction(const JSONRPCRequest& request)
|
static UniValue createrawtransaction(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
RPCHelpMan{"createrawtransaction",
|
RPCHelpMan{"createrawtransaction",
|
||||||
|
|
|
@ -439,6 +439,15 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const
|
||||||
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRPCCaller CRPCTable::operator[](const std::string &name) const
|
||||||
|
{
|
||||||
|
auto it = mapCommands.find(name);
|
||||||
|
assert(it != mapCommands.end());
|
||||||
|
auto& cmds = it->second;
|
||||||
|
assert(cmds.size() == 1);
|
||||||
|
return CRPCCaller(cmds[0]->actor);
|
||||||
|
}
|
||||||
|
|
||||||
static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler)
|
static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -115,6 +115,19 @@ public:
|
||||||
intptr_t unique_id;
|
intptr_t unique_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CRPCCaller
|
||||||
|
{
|
||||||
|
const CRPCCommand::Actor& actor;
|
||||||
|
public:
|
||||||
|
explicit CRPCCaller(const CRPCCommand::Actor& actor) : actor(actor) {}
|
||||||
|
UniValue operator()(const JSONRPCRequest& jsonRequest)
|
||||||
|
{
|
||||||
|
UniValue val;
|
||||||
|
assert(actor(jsonRequest, val, true));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bitcoin RPC command dispatcher.
|
* Bitcoin RPC command dispatcher.
|
||||||
*/
|
*/
|
||||||
|
@ -124,6 +137,7 @@ private:
|
||||||
std::map<std::string, std::vector<const CRPCCommand*>> mapCommands;
|
std::map<std::string, std::vector<const CRPCCommand*>> mapCommands;
|
||||||
public:
|
public:
|
||||||
CRPCTable();
|
CRPCTable();
|
||||||
|
CRPCCaller operator[](const std::string& name) const;
|
||||||
std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
|
std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,7 @@ CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stop
|
||||||
|
|
||||||
CScheduler::~CScheduler()
|
CScheduler::~CScheduler()
|
||||||
{
|
{
|
||||||
assert(!AreThreadsServicingQueue());
|
assert(nThreadsServicingQueue == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CScript StripTimelockPrefix(const CScript& script) {
|
static CScript StripTimelockPrefix(const CScript& script)
|
||||||
|
{
|
||||||
auto it = script.begin();
|
auto it = script.begin();
|
||||||
opcodetype op;
|
opcodetype op;
|
||||||
if (!script.GetOp(it, op))
|
if (!script.GetOp(it, op))
|
||||||
|
@ -263,26 +264,6 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
{
|
|
||||||
return !input.final_script_sig.empty() || !input.final_script_witness.IsNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
PSBTInput& input = psbt.inputs.at(index);
|
|
||||||
const CMutableTransaction& tx = *psbt.tx;
|
|
||||||
|
|
||||||
|
|
||||||
// Verify input sanity, which checks that at most one of witness or non-witness utxos is provided.
|
|
||||||
if (!input.IsSane()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If we have a witness signature, use the smaller witness UTXO.
|
|
||||||
if (sigdata.witness) {
|
|
||||||
input.witness_utxo = utxo;
|
|
||||||
input.non_witness_utxo = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SignatureExtractorChecker final : public BaseSignatureChecker
|
class SignatureExtractorChecker final : public BaseSignatureChecker
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -156,9 +156,6 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
|
||||||
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
|
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
|
||||||
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType);
|
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType);
|
||||||
|
|
||||||
/** Checks whether a PSBTInput is already signed. */
|
|
||||||
bool PSBTInputSigned(PSBTInput& input);
|
|
||||||
|
|
||||||
/** Extract signature data from a transaction input, and insert it. */
|
/** Extract signature data from a transaction input, and insert it. */
|
||||||
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout);
|
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout);
|
||||||
void UpdateInput(CTxIn& input, const SignatureData& data);
|
void UpdateInput(CTxIn& input, const SignatureData& data);
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// Copyright (c) 2011-2015 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
//
|
|
||||||
// Unit tests for block-chain checkpoints
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "checkpoints.h"
|
|
||||||
|
|
||||||
#include "uint256.h"
|
|
||||||
#include "test/test_bitcoin.h"
|
|
||||||
#include "chainparams.h"
|
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sanity)
|
|
||||||
{
|
|
||||||
//const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
|
|
||||||
//BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
|
|
@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(takeover_stability_test) {
|
||||||
BOOST_CHECK(fixture.is_best_claim("@bass", tx2));
|
BOOST_CHECK(fixture.is_best_claim("@bass", tx2));
|
||||||
uint160 id; int takeover;
|
uint160 id; int takeover;
|
||||||
BOOST_REQUIRE(fixture.getLastTakeoverForName("@bass", id, takeover));
|
BOOST_REQUIRE(fixture.getLastTakeoverForName("@bass", id, takeover));
|
||||||
auto height = chainActive.Tip()->nHeight;
|
auto height = ::ChainActive().Tip()->nHeight;
|
||||||
BOOST_CHECK_EQUAL(takeover, height);
|
BOOST_CHECK_EQUAL(takeover, height);
|
||||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "@bass", "three", 3);
|
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "@bass", "three", 3);
|
||||||
fixture.Spend(tx3);
|
fixture.Spend(tx3);
|
||||||
|
@ -462,7 +462,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_takeover_test)
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
uint160 cid2;
|
uint160 cid2;
|
||||||
int takeover;
|
int takeover;
|
||||||
int height = chainActive.Tip()->nHeight;
|
int height = ::ChainActive().Tip()->nHeight;
|
||||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||||
BOOST_CHECK_EQUAL(height, takeover);
|
BOOST_CHECK_EQUAL(height, takeover);
|
||||||
CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "a", cid, 4);
|
CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "a", cid, 4);
|
||||||
|
@ -1056,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(insert_update_claim_test)
|
||||||
fixture.IncrementBlocks(5);
|
fixture.IncrementBlocks(5);
|
||||||
|
|
||||||
// put in bad tx10
|
// put in bad tx10
|
||||||
CTransaction root = fixture.GetCoinbase();
|
auto root = fixture.GetCoinbase();
|
||||||
CMutableTransaction tx10 = fixture.MakeUpdate(root, sName1, sValue1, tx1ClaimId, root.vout[0].nValue);
|
CMutableTransaction tx10 = fixture.MakeUpdate(root, sName1, sValue1, tx1ClaimId, root.vout[0].nValue);
|
||||||
COutPoint tx10OutPoint(tx10.GetHash(), 0);
|
COutPoint tx10OutPoint(tx10.GetHash(), 0);
|
||||||
fixture.IncrementBlocks(1, true);
|
fixture.IncrementBlocks(1, true);
|
||||||
|
@ -1198,7 +1198,7 @@ BOOST_AUTO_TEST_CASE(supporting_claims_test)
|
||||||
std::string sValue1("testa");
|
std::string sValue1("testa");
|
||||||
std::string sValue2("testb");
|
std::string sValue2("testb");
|
||||||
|
|
||||||
int initialHeight = chainActive.Height();
|
int initialHeight = ::ChainActive().Height();
|
||||||
|
|
||||||
CClaimValue val;
|
CClaimValue val;
|
||||||
|
|
||||||
|
@ -1220,6 +1220,7 @@ BOOST_AUTO_TEST_CASE(supporting_claims_test)
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
||||||
fixture.IncrementBlocks(1); // 1
|
fixture.IncrementBlocks(1); // 1
|
||||||
|
|
||||||
|
auto* pcoinsTip = &::ChainstateActive().CoinsTip();
|
||||||
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
||||||
BOOST_CHECK(!pclaimTrie->empty());
|
BOOST_CHECK(!pclaimTrie->empty());
|
||||||
BOOST_CHECK(fixture.queueEmpty());
|
BOOST_CHECK(fixture.queueEmpty());
|
||||||
|
@ -1361,7 +1362,7 @@ BOOST_AUTO_TEST_CASE(supporting_claims_test)
|
||||||
|
|
||||||
// roll all the way back
|
// roll all the way back
|
||||||
fixture.DecrementBlocks(22); // 0
|
fixture.DecrementBlocks(22); // 0
|
||||||
BOOST_CHECK_EQUAL(initialHeight, chainActive.Height());
|
BOOST_CHECK_EQUAL(initialHeight, ::ChainActive().Height());
|
||||||
|
|
||||||
// Make sure that when a support in the queue gets spent and then the spend is
|
// Make sure that when a support in the queue gets spent and then the spend is
|
||||||
// undone, it goes back into the queue in the right spot
|
// undone, it goes back into the queue in the right spot
|
||||||
|
@ -1462,6 +1463,7 @@ BOOST_AUTO_TEST_CASE(supporting_claims2_test)
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
||||||
fixture.IncrementBlocks(1); // 1
|
fixture.IncrementBlocks(1); // 1
|
||||||
|
|
||||||
|
auto* pcoinsTip = &::ChainstateActive().CoinsTip();
|
||||||
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
||||||
BOOST_CHECK(!pclaimTrie->empty());
|
BOOST_CHECK(!pclaimTrie->empty());
|
||||||
BOOST_CHECK(fixture.queueEmpty());
|
BOOST_CHECK(fixture.queueEmpty());
|
||||||
|
@ -1839,6 +1841,7 @@ BOOST_AUTO_TEST_CASE(invalid_claimid_test)
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
||||||
fixture.IncrementBlocks(1, true); // 1
|
fixture.IncrementBlocks(1, true); // 1
|
||||||
|
|
||||||
|
auto* pcoinsTip = &::ChainstateActive().CoinsTip();
|
||||||
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
||||||
BOOST_CHECK(!pclaimTrie->empty());
|
BOOST_CHECK(!pclaimTrie->empty());
|
||||||
BOOST_CHECK(fixture.queueEmpty());
|
BOOST_CHECK(fixture.queueEmpty());
|
||||||
|
@ -1947,7 +1950,7 @@ BOOST_AUTO_TEST_CASE(update_on_support2_test)
|
||||||
std::string name = "test";
|
std::string name = "test";
|
||||||
std::string value = "one";
|
std::string value = "one";
|
||||||
|
|
||||||
auto height = chainActive.Height();
|
auto height = ::ChainActive().Height();
|
||||||
|
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), name, value, 3);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), name, value, 3);
|
||||||
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, name, 1);
|
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, name, 1);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
#include <test/claimtriefixture.h>
|
#include <test/claimtriefixture.h>
|
||||||
#include <test/test_bitcoin.h>
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <boost/scope_exit.hpp>
|
#include <boost/scope_exit.hpp>
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(hardfork_support_test)
|
||||||
CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "two", ClaimIdHash(tx1.GetHash(),0), 1);
|
CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "two", ClaimIdHash(tx1.GetHash(),0), 1);
|
||||||
CMutableTransaction u2 = fixture.MakeUpdate(tx2, "test", "two", ClaimIdHash(tx2.GetHash(),0), 2);
|
CMutableTransaction u2 = fixture.MakeUpdate(tx2, "test", "two", ClaimIdHash(tx2.GetHash(),0), 2);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
BOOST_CHECK_EQUAL(Params().GetConsensus().nExtendedClaimExpirationForkHeight, chainActive.Height());
|
BOOST_CHECK_EQUAL(Params().GetConsensus().nExtendedClaimExpirationForkHeight, ::ChainActive().Height());
|
||||||
|
|
||||||
BOOST_CHECK(fixture.is_best_claim("test", u1));
|
BOOST_CHECK(fixture.is_best_claim("test", u1));
|
||||||
BOOST_CHECK(fixture.best_claim_effective_amount_equals("test",3));
|
BOOST_CHECK(fixture.best_claim_effective_amount_equals("test",3));
|
||||||
|
@ -578,6 +578,7 @@ BOOST_AUTO_TEST_CASE(expiring_supports_test)
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
||||||
fixture.IncrementBlocks(1); // 1, expires at 81
|
fixture.IncrementBlocks(1); // 1, expires at 81
|
||||||
|
|
||||||
|
auto* pcoinsTip = &::ChainstateActive().CoinsTip();
|
||||||
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
BOOST_CHECK(pcoinsTip->HaveCoin(COutPoint(tx1.GetHash(), 0)));
|
||||||
BOOST_CHECK(!pclaimTrie->empty());
|
BOOST_CHECK(!pclaimTrie->empty());
|
||||||
BOOST_CHECK(fixture.queueEmpty());
|
BOOST_CHECK(fixture.queueEmpty());
|
||||||
|
@ -696,7 +697,7 @@ BOOST_AUTO_TEST_CASE(expiring_supports_test)
|
||||||
fixture.Spend(tx3);
|
fixture.Spend(tx3);
|
||||||
fixture.IncrementBlocks(1); // 64
|
fixture.IncrementBlocks(1); // 64
|
||||||
|
|
||||||
blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash());
|
blocks_to_invalidate.push_back(::ChainActive().Tip()->GetBlockHash());
|
||||||
|
|
||||||
BOOST_CHECK(!pclaimTrie->empty());
|
BOOST_CHECK(!pclaimTrie->empty());
|
||||||
BOOST_CHECK(fixture.queueEmpty());
|
BOOST_CHECK(fixture.queueEmpty());
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <test/claimtriefixture.h>
|
#include <test/claimtriefixture.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ BOOST_AUTO_TEST_CASE(claimtriefixture_noop)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
CMutableTransaction BuildTransaction(const CTransaction& prev, uint32_t prevout, unsigned int numOutputs, int locktime)
|
CMutableTransaction BuildTransaction(const CMutableTransaction& prev, uint32_t prevout, unsigned int numOutputs, int locktime)
|
||||||
{
|
{
|
||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
tx.nVersion = CTransaction::CURRENT_VERSION;
|
tx.nVersion = CTransaction::CURRENT_VERSION;
|
||||||
|
@ -30,7 +31,7 @@ CMutableTransaction BuildTransaction(const CTransaction& prev, uint32_t prevout,
|
||||||
tx.vin[0].scriptSig = CScript();
|
tx.vin[0].scriptSig = CScript();
|
||||||
if (locktime != 0) {
|
if (locktime != 0) {
|
||||||
// Use a relative locktime for validity X blocks in the future
|
// Use a relative locktime for validity X blocks in the future
|
||||||
tx.nLockTime = chainActive.Height() + locktime;
|
tx.nLockTime = ::ChainActive().Height() + locktime;
|
||||||
tx.vin[0].nSequence = 0xffffffff - 1;
|
tx.vin[0].nSequence = 0xffffffff - 1;
|
||||||
} else {
|
} else {
|
||||||
tx.nLockTime = 1 << 31; // Disable BIP68
|
tx.nLockTime = 1 << 31; // Disable BIP68
|
||||||
|
@ -78,7 +79,7 @@ ClaimTrieChainFixture::ClaimTrieChainFixture() : CClaimTrieCache(pclaimTrie),
|
||||||
minRemovalWorkaroundHeight(-1), maxRemovalWorkaroundHeight(-1)
|
minRemovalWorkaroundHeight(-1), maxRemovalWorkaroundHeight(-1)
|
||||||
{
|
{
|
||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
BOOST_CHECK_EQUAL(nNextHeight, chainActive.Height() + 1);
|
BOOST_CHECK_EQUAL(nNextHeight, ::ChainActive().Height() + 1);
|
||||||
setNormalizationForkHeight(1000000);
|
setNormalizationForkHeight(1000000);
|
||||||
|
|
||||||
gArgs.ForceSetArg("-limitancestorcount", "1000000");
|
gArgs.ForceSetArg("-limitancestorcount", "1000000");
|
||||||
|
@ -97,7 +98,7 @@ ClaimTrieChainFixture::ClaimTrieChainFixture() : CClaimTrieCache(pclaimTrie),
|
||||||
ClaimTrieChainFixture::~ClaimTrieChainFixture()
|
ClaimTrieChainFixture::~ClaimTrieChainFixture()
|
||||||
{
|
{
|
||||||
added_unchecked = false;
|
added_unchecked = false;
|
||||||
DecrementBlocks(chainActive.Height());
|
DecrementBlocks(::ChainActive().Height());
|
||||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||||
if (normalization_original >= 0) {
|
if (normalization_original >= 0) {
|
||||||
consensus.nNormalizedNameForkHeight = normalization_original;
|
consensus.nNormalizedNameForkHeight = normalization_original;
|
||||||
|
@ -124,7 +125,7 @@ ClaimTrieChainFixture::~ClaimTrieChainFixture()
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClaimTrieChainFixture::setRemovalWorkaroundHeight(int targetMinusCurrent, int blocks = 1000) {
|
void ClaimTrieChainFixture::setRemovalWorkaroundHeight(int targetMinusCurrent, int blocks = 1000) {
|
||||||
int target = chainActive.Height() + targetMinusCurrent;
|
int target = ::ChainActive().Height() + targetMinusCurrent;
|
||||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||||
if (minRemovalWorkaroundHeight < 0) {
|
if (minRemovalWorkaroundHeight < 0) {
|
||||||
minRemovalWorkaroundHeight = consensus.nMinRemovalWorkaroundHeight;
|
minRemovalWorkaroundHeight = consensus.nMinRemovalWorkaroundHeight;
|
||||||
|
@ -138,7 +139,7 @@ void ClaimTrieChainFixture::setRemovalWorkaroundHeight(int targetMinusCurrent, i
|
||||||
|
|
||||||
void ClaimTrieChainFixture::setExpirationForkHeight(int targetMinusCurrent, int64_t preForkExpirationTime, int64_t postForkExpirationTime)
|
void ClaimTrieChainFixture::setExpirationForkHeight(int targetMinusCurrent, int64_t preForkExpirationTime, int64_t postForkExpirationTime)
|
||||||
{
|
{
|
||||||
int target = chainActive.Height() + targetMinusCurrent;
|
int target = ::ChainActive().Height() + targetMinusCurrent;
|
||||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||||
if (expirationForkHeight < 0) {
|
if (expirationForkHeight < 0) {
|
||||||
expirationForkHeight = consensus.nExtendedClaimExpirationForkHeight;
|
expirationForkHeight = consensus.nExtendedClaimExpirationForkHeight;
|
||||||
|
@ -155,7 +156,7 @@ void ClaimTrieChainFixture::setExpirationForkHeight(int targetMinusCurrent, int6
|
||||||
|
|
||||||
void ClaimTrieChainFixture::setNormalizationForkHeight(int targetMinusCurrent)
|
void ClaimTrieChainFixture::setNormalizationForkHeight(int targetMinusCurrent)
|
||||||
{
|
{
|
||||||
int target = chainActive.Height() + targetMinusCurrent;
|
int target = ::ChainActive().Height() + targetMinusCurrent;
|
||||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||||
if (normalization_original < 0)
|
if (normalization_original < 0)
|
||||||
normalization_original = consensus.nNormalizedNameForkHeight;
|
normalization_original = consensus.nNormalizedNameForkHeight;
|
||||||
|
@ -165,7 +166,7 @@ void ClaimTrieChainFixture::setNormalizationForkHeight(int targetMinusCurrent)
|
||||||
|
|
||||||
void ClaimTrieChainFixture::setHashForkHeight(int targetMinusCurrent)
|
void ClaimTrieChainFixture::setHashForkHeight(int targetMinusCurrent)
|
||||||
{
|
{
|
||||||
int target = chainActive.Height() + targetMinusCurrent;
|
int target = ::ChainActive().Height() + targetMinusCurrent;
|
||||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||||
if (forkhash_original < 0)
|
if (forkhash_original < 0)
|
||||||
forkhash_original = consensus.nAllClaimsInMerkleForkHeight;
|
forkhash_original = consensus.nAllClaimsInMerkleForkHeight;
|
||||||
|
@ -179,11 +180,11 @@ bool ClaimTrieChainFixture::CreateBlock(const std::unique_ptr<CBlockTemplate>& p
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
pblock->nVersion = 5;
|
pblock->nVersion = 5;
|
||||||
pblock->hashPrevBlock = chainActive.Tip()->GetBlockHash();
|
pblock->hashPrevBlock = ::ChainActive().Tip()->GetBlockHash();
|
||||||
pblock->nTime = chainActive.Tip()->GetBlockTime() + Params().GetConsensus().nPowTargetSpacing;
|
pblock->nTime = ::ChainActive().Tip()->GetBlockTime() + Params().GetConsensus().nPowTargetSpacing;
|
||||||
CMutableTransaction txCoinbase(*pblock->vtx[0]);
|
CMutableTransaction txCoinbase(*pblock->vtx[0]);
|
||||||
txCoinbase.vin[0].scriptSig = CScript() << int(chainActive.Height() + 1) << int(++unique_block_counter);
|
txCoinbase.vin[0].scriptSig = CScript() << int(::ChainActive().Height() + 1) << int(++unique_block_counter);
|
||||||
txCoinbase.vout[0].nValue = GetBlockSubsidy(chainActive.Height() + 1, Params().GetConsensus());
|
txCoinbase.vout[0].nValue = GetBlockSubsidy(::ChainActive().Height() + 1, Params().GetConsensus());
|
||||||
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
||||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||||
for (uint32_t i = 0;; ++i) {
|
for (uint32_t i = 0;; ++i) {
|
||||||
|
@ -193,7 +194,7 @@ bool ClaimTrieChainFixture::CreateBlock(const std::unique_ptr<CBlockTemplate>& p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto success = ProcessNewBlock(Params(), std::make_shared<const CBlock>(*pblock), true, nullptr);
|
auto success = ProcessNewBlock(Params(), std::make_shared<const CBlock>(*pblock), true, nullptr);
|
||||||
return success && pblock->GetHash() == chainActive.Tip()->GetBlockHash();
|
return success && pblock->GetHash() == ::ChainActive().Tip()->GetBlockHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClaimTrieChainFixture::CreateCoinbases(unsigned int num_coinbases, std::vector<CTransaction>& coinbases)
|
bool ClaimTrieChainFixture::CreateCoinbases(unsigned int num_coinbases, std::vector<CTransaction>& coinbases)
|
||||||
|
@ -220,7 +221,7 @@ void ClaimTrieChainFixture::CommitTx(const CMutableTransaction &tx, bool has_loc
|
||||||
added_unchecked = true;
|
added_unchecked = true;
|
||||||
TestMemPoolEntryHelper entry;
|
TestMemPoolEntryHelper entry;
|
||||||
LOCK(mempool.cs);
|
LOCK(mempool.cs);
|
||||||
mempool.addUnchecked(tx.GetHash(), entry.Fee(0).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
mempool.addUnchecked(entry.Fee(0).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||||
} else {
|
} else {
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
CAmount txFeeRate = CAmount(0);
|
CAmount txFeeRate = CAmount(0);
|
||||||
|
@ -230,7 +231,7 @@ void ClaimTrieChainFixture::CommitTx(const CMutableTransaction &tx, bool has_loc
|
||||||
}
|
}
|
||||||
|
|
||||||
// spend a bid into some non claimtrie related unspent
|
// spend a bid into some non claimtrie related unspent
|
||||||
CMutableTransaction ClaimTrieChainFixture::Spend(const CTransaction &prev)
|
CMutableTransaction ClaimTrieChainFixture::Spend(const CMutableTransaction &prev)
|
||||||
{
|
{
|
||||||
CMutableTransaction tx = BuildTransaction(prev, 0);
|
CMutableTransaction tx = BuildTransaction(prev, 0);
|
||||||
tx.vout[0].scriptPubKey = CScript() << OP_TRUE;
|
tx.vout[0].scriptPubKey = CScript() << OP_TRUE;
|
||||||
|
@ -241,7 +242,7 @@ CMutableTransaction ClaimTrieChainFixture::Spend(const CTransaction &prev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make claim at the current block
|
// make claim at the current block
|
||||||
CMutableTransaction ClaimTrieChainFixture::MakeClaim(const CTransaction& prev, const std::string& name, const std::string& value, CAmount quantity, int locktime)
|
CMutableTransaction ClaimTrieChainFixture::MakeClaim(const CMutableTransaction& prev, const std::string& name, const std::string& value, CAmount quantity, int locktime)
|
||||||
{
|
{
|
||||||
uint32_t prevout = prev.vout.size() - 1;
|
uint32_t prevout = prev.vout.size() - 1;
|
||||||
while (prevout > 0 && prev.vout[prevout].nValue < quantity)
|
while (prevout > 0 && prev.vout[prevout].nValue < quantity)
|
||||||
|
@ -258,13 +259,13 @@ CMutableTransaction ClaimTrieChainFixture::MakeClaim(const CTransaction& prev, c
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutableTransaction ClaimTrieChainFixture::MakeClaim(const CTransaction& prev, const std::string& name, const std::string& value)
|
CMutableTransaction ClaimTrieChainFixture::MakeClaim(const CMutableTransaction& prev, const std::string& name, const std::string& value)
|
||||||
{
|
{
|
||||||
return MakeClaim(prev, name, value, prev.vout[0].nValue, 0);
|
return MakeClaim(prev, name, value, prev.vout[0].nValue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make support at the current block
|
// make support at the current block
|
||||||
CMutableTransaction ClaimTrieChainFixture::MakeSupport(const CTransaction &prev, const CTransaction &claimtx, const std::string& name, CAmount quantity)
|
CMutableTransaction ClaimTrieChainFixture::MakeSupport(const CMutableTransaction &prev, const CMutableTransaction &claimtx, const std::string& name, CAmount quantity)
|
||||||
{
|
{
|
||||||
uint32_t prevout = prev.vout.size() - 1;
|
uint32_t prevout = prev.vout.size() - 1;
|
||||||
while (prevout > 0 && prev.vout[prevout].nValue < quantity)
|
while (prevout > 0 && prev.vout[prevout].nValue < quantity)
|
||||||
|
@ -283,7 +284,7 @@ CMutableTransaction ClaimTrieChainFixture::MakeSupport(const CTransaction &prev,
|
||||||
}
|
}
|
||||||
|
|
||||||
// make update at the current block
|
// make update at the current block
|
||||||
CMutableTransaction ClaimTrieChainFixture::MakeUpdate(const CTransaction &prev, const std::string& name, const std::string& value, const uint160& claimId, CAmount quantity)
|
CMutableTransaction ClaimTrieChainFixture::MakeUpdate(const CMutableTransaction &prev, const std::string& name, const std::string& value, const uint160& claimId, CAmount quantity)
|
||||||
{
|
{
|
||||||
CMutableTransaction tx = BuildTransaction(prev, 0);
|
CMutableTransaction tx = BuildTransaction(prev, 0);
|
||||||
if (prev.vout[0].nValue < quantity) {
|
if (prev.vout[0].nValue < quantity) {
|
||||||
|
@ -298,28 +299,28 @@ CMutableTransaction ClaimTrieChainFixture::MakeUpdate(const CTransaction &prev,
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTransaction& ClaimTrieChainFixture::GetCoinbase()
|
CMutableTransaction ClaimTrieChainFixture::GetCoinbase()
|
||||||
{
|
{
|
||||||
return coinbase_txs.at(coinbase_txs_used++);
|
return CMutableTransaction(coinbase_txs.at(coinbase_txs_used++));
|
||||||
}
|
}
|
||||||
|
|
||||||
// create i blocks
|
// create i blocks
|
||||||
void ClaimTrieChainFixture::IncrementBlocks(int num_blocks, bool mark)
|
void ClaimTrieChainFixture::IncrementBlocks(int num_blocks, bool mark)
|
||||||
{
|
{
|
||||||
if (mark)
|
if (mark)
|
||||||
marks.push_back(chainActive.Height());
|
marks.push_back(::ChainActive().Height());
|
||||||
|
|
||||||
for (int i = 0; i < num_blocks; ++i) {
|
for (int i = 0; i < num_blocks; ++i) {
|
||||||
CScript coinbase_scriptpubkey;
|
CScript coinbase_scriptpubkey;
|
||||||
coinbase_scriptpubkey << CScriptNum(chainActive.Height());
|
coinbase_scriptpubkey << CScriptNum(::ChainActive().Height());
|
||||||
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest().CreateNewBlock(coinbase_scriptpubkey);
|
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest().CreateNewBlock(coinbase_scriptpubkey);
|
||||||
BOOST_REQUIRE(pblocktemplate != nullptr);
|
BOOST_REQUIRE(pblocktemplate != nullptr);
|
||||||
if (!added_unchecked)
|
if (!added_unchecked)
|
||||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), num_txs_for_next_block + 1);
|
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), num_txs_for_next_block + 1);
|
||||||
BOOST_REQUIRE(CreateBlock(pblocktemplate));
|
BOOST_REQUIRE(CreateBlock(pblocktemplate));
|
||||||
num_txs_for_next_block = 0;
|
num_txs_for_next_block = 0;
|
||||||
expirationHeight = chainActive.Height();
|
expirationHeight = ::ChainActive().Height();
|
||||||
nNextHeight = chainActive.Height() + 1;
|
nNextHeight = ::ChainActive().Height() + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,15 +330,15 @@ void ClaimTrieChainFixture::DecrementBlocks(int num_blocks)
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CBlockIndex* pblockindex = chainActive[chainActive.Height() - num_blocks + 1];
|
CBlockIndex* pblockindex = ::ChainActive()[::ChainActive().Height() - num_blocks + 1];
|
||||||
BOOST_CHECK_EQUAL(InvalidateBlock(state, Params(), pblockindex), true);
|
BOOST_CHECK_EQUAL(InvalidateBlock(state, Params(), pblockindex), true);
|
||||||
}
|
}
|
||||||
BOOST_CHECK_EQUAL(state.IsValid(), true);
|
BOOST_CHECK_EQUAL(state.IsValid(), true);
|
||||||
BOOST_CHECK_EQUAL(ActivateBestChain(state, Params()), true);
|
BOOST_CHECK_EQUAL(ActivateBestChain(state, Params()), true);
|
||||||
mempool.clear();
|
mempool.clear();
|
||||||
num_txs_for_next_block = 0;
|
num_txs_for_next_block = 0;
|
||||||
expirationHeight = chainActive.Height();
|
expirationHeight = ::ChainActive().Height();
|
||||||
nNextHeight = chainActive.Height() + 1;
|
nNextHeight = ::ChainActive().Height() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrement back to last mark
|
// decrement back to last mark
|
||||||
|
@ -345,7 +346,7 @@ void ClaimTrieChainFixture::DecrementBlocks()
|
||||||
{
|
{
|
||||||
int mark = marks.back();
|
int mark = marks.back();
|
||||||
marks.pop_back();
|
marks.pop_back();
|
||||||
DecrementBlocks(chainActive.Height() - mark);
|
DecrementBlocks(::ChainActive().Height() - mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClaimTrieChainFixture::queueEmpty() const
|
bool ClaimTrieChainFixture::queueEmpty() const
|
||||||
|
@ -396,7 +397,7 @@ boost::test_tools::predicate_result negativeResult(const std::string& message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// is a claim in queue
|
// is a claim in queue
|
||||||
boost::test_tools::predicate_result ClaimTrieChainFixture::is_claim_in_queue(const std::string& name, const CTransaction &tx)
|
boost::test_tools::predicate_result ClaimTrieChainFixture::is_claim_in_queue(const std::string& name, const CMutableTransaction &tx)
|
||||||
{
|
{
|
||||||
COutPoint outPoint(tx.GetHash(), 0);
|
COutPoint outPoint(tx.GetHash(), 0);
|
||||||
int validAtHeight;
|
int validAtHeight;
|
||||||
|
@ -406,7 +407,7 @@ boost::test_tools::predicate_result ClaimTrieChainFixture::is_claim_in_queue(con
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if tx is best claim based on outpoint
|
// check if tx is best claim based on outpoint
|
||||||
boost::test_tools::predicate_result ClaimTrieChainFixture::is_best_claim(const std::string& name, const CTransaction &tx)
|
boost::test_tools::predicate_result ClaimTrieChainFixture::is_best_claim(const std::string& name, const CMutableTransaction &tx)
|
||||||
{
|
{
|
||||||
CClaimValue val;
|
CClaimValue val;
|
||||||
COutPoint outPoint(tx.GetHash(), 0);
|
COutPoint outPoint(tx.GetHash(), 0);
|
||||||
|
|
|
@ -17,18 +17,16 @@
|
||||||
#include <rpc/claimrpchelp.h>
|
#include <rpc/claimrpchelp.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <test/test_bitcoin.h>
|
#include <test/setup_common.h>
|
||||||
#include <util.h>
|
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
extern ::ArgsManager gArgs;
|
|
||||||
extern std::vector<std::string> random_strings(std::size_t count);
|
extern std::vector<std::string> random_strings(std::size_t count);
|
||||||
|
|
||||||
class CTransaction;
|
class CMutableTransaction;
|
||||||
CMutableTransaction BuildTransaction(const uint256& prevhash);
|
CMutableTransaction BuildTransaction(const uint256& prevhash);
|
||||||
CMutableTransaction BuildTransaction(const CTransaction& prev, uint32_t prevout=0, unsigned int numOutputs=1, int locktime=0);
|
CMutableTransaction BuildTransaction(const CMutableTransaction& prev, uint32_t prevout=0, unsigned int numOutputs=1, int locktime=0);
|
||||||
|
|
||||||
class BlockAssembler;
|
class BlockAssembler;
|
||||||
BlockAssembler AssemblerForTest();
|
BlockAssembler AssemblerForTest();
|
||||||
|
@ -72,20 +70,20 @@ struct ClaimTrieChainFixture: public CClaimTrieCache
|
||||||
void CommitTx(const CMutableTransaction &tx, bool has_locktime=false);
|
void CommitTx(const CMutableTransaction &tx, bool has_locktime=false);
|
||||||
|
|
||||||
// spend a bid into some non claimtrie related unspent
|
// spend a bid into some non claimtrie related unspent
|
||||||
CMutableTransaction Spend(const CTransaction &prev);
|
CMutableTransaction Spend(const CMutableTransaction &prev);
|
||||||
|
|
||||||
// make claim at the current block
|
// make claim at the current block
|
||||||
CMutableTransaction MakeClaim(const CTransaction& prev, const std::string& name, const std::string& value, CAmount quantity, int locktime=0);
|
CMutableTransaction MakeClaim(const CMutableTransaction& prev, const std::string& name, const std::string& value, CAmount quantity, int locktime=0);
|
||||||
|
|
||||||
CMutableTransaction MakeClaim(const CTransaction& prev, const std::string& name, const std::string& value);
|
CMutableTransaction MakeClaim(const CMutableTransaction& prev, const std::string& name, const std::string& value);
|
||||||
|
|
||||||
// make support at the current block
|
// make support at the current block
|
||||||
CMutableTransaction MakeSupport(const CTransaction &prev, const CTransaction &claimtx, const std::string& name, CAmount quantity);
|
CMutableTransaction MakeSupport(const CMutableTransaction &prev, const CMutableTransaction &claimtx, const std::string& name, CAmount quantity);
|
||||||
|
|
||||||
// make update at the current block
|
// make update at the current block
|
||||||
CMutableTransaction MakeUpdate(const CTransaction &prev, const std::string& name, const std::string& value, const uint160& claimId, CAmount quantity);
|
CMutableTransaction MakeUpdate(const CMutableTransaction &prev, const std::string& name, const std::string& value, const uint160& claimId, CAmount quantity);
|
||||||
|
|
||||||
CTransaction& GetCoinbase();
|
CMutableTransaction GetCoinbase();
|
||||||
|
|
||||||
// create i blocks
|
// create i blocks
|
||||||
void IncrementBlocks(int num_blocks, bool mark = false);
|
void IncrementBlocks(int num_blocks, bool mark = false);
|
||||||
|
@ -111,10 +109,10 @@ struct ClaimTrieChainFixture: public CClaimTrieCache
|
||||||
int64_t nodeCount() const;
|
int64_t nodeCount() const;
|
||||||
|
|
||||||
// is a claim in queue
|
// is a claim in queue
|
||||||
boost::test_tools::predicate_result is_claim_in_queue(const std::string& name, const CTransaction &tx);
|
boost::test_tools::predicate_result is_claim_in_queue(const std::string& name, const CMutableTransaction &tx);
|
||||||
|
|
||||||
// check if tx is best claim based on outpoint
|
// check if tx is best claim based on outpoint
|
||||||
boost::test_tools::predicate_result is_best_claim(const std::string& name, const CTransaction &tx);
|
boost::test_tools::predicate_result is_best_claim(const std::string& name, const CMutableTransaction &tx);
|
||||||
|
|
||||||
// check effective quantity of best claim
|
// check effective quantity of best claim
|
||||||
boost::test_tools::predicate_result best_claim_effective_amount_equals(const std::string& name, CAmount amount);
|
boost::test_tools::predicate_result best_claim_effective_amount_equals(const std::string& name, CAmount amount);
|
||||||
|
|
|
@ -156,11 +156,11 @@ BOOST_AUTO_TEST_CASE(hash_claims_children_fuzzer_test)
|
||||||
auto names = random_strings(300);
|
auto names = random_strings(300);
|
||||||
auto lastTx = MakeTransactionRef(fixture.GetCoinbase());
|
auto lastTx = MakeTransactionRef(fixture.GetCoinbase());
|
||||||
for (const auto& name : names) {
|
for (const auto& name : names) {
|
||||||
auto tx = fixture.MakeClaim(*lastTx, name, "one", 1);
|
auto tx = fixture.MakeClaim(CMutableTransaction(*lastTx), name, "one", 1);
|
||||||
lastTx = MakeTransactionRef(std::move(tx));
|
lastTx = MakeTransactionRef(std::move(tx));
|
||||||
if (++i % 5 == 0)
|
if (++i % 5 == 0)
|
||||||
for (std::size_t j = 0; j < (i / 5); ++j) {
|
for (std::size_t j = 0; j < (i / 5); ++j) {
|
||||||
auto tx = fixture.MakeClaim(*lastTx, name, "one", 1);
|
auto tx = fixture.MakeClaim(CMutableTransaction(*lastTx), name, "one", 1);
|
||||||
lastTx = MakeTransactionRef(std::move(tx));
|
lastTx = MakeTransactionRef(std::move(tx));
|
||||||
}
|
}
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
@ -302,31 +302,31 @@ BOOST_AUTO_TEST_CASE(value_proof_test)
|
||||||
CClaimTrieProof proof;
|
CClaimTrieProof proof;
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName1, ClaimIdHash(tx1.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName1, ClaimIdHash(tx1.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName1));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName1));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx1OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx1OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName2, ClaimIdHash(tx2.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName2, ClaimIdHash(tx2.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName2));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName2));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx2OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx2OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName3, ClaimIdHash(tx3.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName3, ClaimIdHash(tx3.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName3));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName3));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx3OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx3OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName4, ClaimIdHash(tx4.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName4, ClaimIdHash(tx4.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName4));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName4));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx4OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx4OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName5, ClaimIdHash(tx1.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName5, ClaimIdHash(tx1.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName5));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName5));
|
||||||
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName6, ClaimIdHash({}, 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName6, ClaimIdHash({}, 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName6));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName6));
|
||||||
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName7, ClaimIdHash(uint256(fixture.getMerkleHash()), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName7, ClaimIdHash(uint256(fixture.getMerkleHash()), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName7));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName7));
|
||||||
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
||||||
|
|
||||||
CMutableTransaction tx5 = fixture.MakeClaim(fixture.GetCoinbase(), sName7, sValue4);
|
CMutableTransaction tx5 = fixture.MakeClaim(fixture.GetCoinbase(), sName7, sValue4);
|
||||||
|
@ -338,23 +338,23 @@ BOOST_AUTO_TEST_CASE(value_proof_test)
|
||||||
BOOST_CHECK_EQUAL(val.outPoint, tx5OutPoint);
|
BOOST_CHECK_EQUAL(val.outPoint, tx5OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName1, ClaimIdHash(tx1.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName1, ClaimIdHash(tx1.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName1));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName1));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx1OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx1OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName2, ClaimIdHash(tx2.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName2, ClaimIdHash(tx2.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName2));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName2));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx2OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx2OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName3, ClaimIdHash(tx3.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName3, ClaimIdHash(tx3.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName3));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName3));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx3OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx3OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName4, ClaimIdHash(tx4.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName4, ClaimIdHash(tx4.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName4));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName4));
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, tx4OutPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, tx4OutPoint);
|
||||||
|
|
||||||
BOOST_CHECK(fixture.getProofForName(sName5, ClaimIdHash(tx5.GetHash(), 0), proof));
|
BOOST_CHECK(fixture.getProofForName(sName5, ClaimIdHash(tx5.GetHash(), 0), proof));
|
||||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName5));
|
BOOST_CHECK(verify_proof(proof, ::ChainActive().Tip()->hashClaimTrie, sName5));
|
||||||
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
||||||
|
|
||||||
fixture.DecrementBlocks();
|
fixture.DecrementBlocks();
|
||||||
|
@ -369,18 +369,18 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
|
||||||
std::string sName("test");
|
std::string sName("test");
|
||||||
std::string sValue1("test");
|
std::string sValue1("test");
|
||||||
|
|
||||||
int orig_chain_height = chainActive.Height();
|
int orig_chain_height = ::ChainActive().Height();
|
||||||
|
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue1, 1);
|
||||||
|
|
||||||
std::unique_ptr<CBlockTemplate> pblockTemp;
|
std::unique_ptr<CBlockTemplate> pblockTemp;
|
||||||
BOOST_CHECK(pblockTemp = AssemblerForTest().CreateNewBlock(tx1.vout[0].scriptPubKey));
|
BOOST_CHECK(pblockTemp = AssemblerForTest().CreateNewBlock(tx1.vout[0].scriptPubKey));
|
||||||
pblockTemp->block.hashPrevBlock = chainActive.Tip()->GetBlockHash();
|
pblockTemp->block.hashPrevBlock = ::ChainActive().Tip()->GetBlockHash();
|
||||||
pblockTemp->block.nVersion = 5;
|
pblockTemp->block.nVersion = 5;
|
||||||
pblockTemp->block.nTime = chainActive.Tip()->GetBlockTime() + Params().GetConsensus().nPowTargetSpacing;
|
pblockTemp->block.nTime = ::ChainActive().Tip()->GetBlockTime() + Params().GetConsensus().nPowTargetSpacing;
|
||||||
CMutableTransaction txCoinbase(*pblockTemp->block.vtx[0]);
|
CMutableTransaction txCoinbase(*pblockTemp->block.vtx[0]);
|
||||||
txCoinbase.vin[0].scriptSig = CScript() << int(chainActive.Height() + 1) << 1;
|
txCoinbase.vin[0].scriptSig = CScript() << int(::ChainActive().Height() + 1) << 1;
|
||||||
txCoinbase.vout[0].nValue = GetBlockSubsidy(chainActive.Height() + 1, Params().GetConsensus());
|
txCoinbase.vout[0].nValue = GetBlockSubsidy(::ChainActive().Height() + 1, Params().GetConsensus());
|
||||||
pblockTemp->block.vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
pblockTemp->block.vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
||||||
pblockTemp->block.hashMerkleRoot = BlockMerkleRoot(pblockTemp->block);
|
pblockTemp->block.hashMerkleRoot = BlockMerkleRoot(pblockTemp->block);
|
||||||
//create bogus hash
|
//create bogus hash
|
||||||
|
@ -398,8 +398,8 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
|
||||||
bool success = ProcessNewBlock(Params(), std::make_shared<const CBlock>(pblockTemp->block), true, nullptr);
|
bool success = ProcessNewBlock(Params(), std::make_shared<const CBlock>(pblockTemp->block), true, nullptr);
|
||||||
// will process , but will not be connected
|
// will process , but will not be connected
|
||||||
BOOST_CHECK(success);
|
BOOST_CHECK(success);
|
||||||
BOOST_CHECK(pblockTemp->block.GetHash() != chainActive.Tip()->GetBlockHash());
|
BOOST_CHECK(pblockTemp->block.GetHash() != ::ChainActive().Tip()->GetBlockHash());
|
||||||
BOOST_CHECK_EQUAL(orig_chain_height, chainActive.Height());
|
BOOST_CHECK_EQUAL(orig_chain_height, ::ChainActive().Height());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MAC_OSX // can't find a random number generator that produces the same sequence on OSX
|
#ifndef MAC_OSX // can't find a random number generator that produces the same sequence on OSX
|
||||||
|
@ -420,7 +420,7 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
|
||||||
std::vector<CMutableTransaction> existingSupports;
|
std::vector<CMutableTransaction> existingSupports;
|
||||||
std::string value(1024, 'c');
|
std::string value(1024, 'c');
|
||||||
|
|
||||||
std::vector<CTransaction> cb {fixture.GetCoinbase()};
|
std::vector<CMutableTransaction> cb {fixture.GetCoinbase()};
|
||||||
for (int i = 0; i < blocks; ++i) {
|
for (int i = 0; i < blocks; ++i) {
|
||||||
for (int j = 0; j < claimsPerBlock; ++j) {
|
for (int j = 0; j < claimsPerBlock; ++j) {
|
||||||
auto name = names[i * claimsPerBlock + j];
|
auto name = names[i * claimsPerBlock + j];
|
||||||
|
@ -455,7 +455,8 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
|
||||||
fixture.Spend(tx);
|
fixture.Spend(tx);
|
||||||
existingSupports.erase(existingSupports.begin() + tidx);
|
existingSupports.erase(existingSupports.begin() + tidx);
|
||||||
}
|
}
|
||||||
if (cb.back().GetValueOut() < 10 || cb.size() > 40000) {
|
auto tx = CTransaction(cb.back());
|
||||||
|
if (tx.GetValueOut() < 10 || cb.size() > 40000) {
|
||||||
cb.clear();
|
cb.clear();
|
||||||
cb.push_back(fixture.GetCoinbase());
|
cb.push_back(fixture.GetCoinbase());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include <test/claimtriefixture.h>
|
#include <test/claimtriefixture.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
extern ::CChainState g_chainstate;
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(claimtrienormalization_tests, RegTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(claimtrienormalization_tests, RegTestingSetup)
|
||||||
|
@ -159,7 +157,7 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_normalization)
|
||||||
|
|
||||||
// Roll forward to fork height again and check again that we're normalized
|
// Roll forward to fork height again and check again that we're normalized
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
BOOST_CHECK(chainActive.Height() == Params().GetConsensus().nNormalizedNameForkHeight);
|
BOOST_CHECK(::ChainActive().Height() == Params().GetConsensus().nNormalizedNameForkHeight);
|
||||||
BOOST_CHECK(fixture.is_best_claim("normalizetest", tx1)); // collapsed tx2
|
BOOST_CHECK(fixture.is_best_claim("normalizetest", tx1)); // collapsed tx2
|
||||||
BOOST_CHECK(fixture.is_best_claim(invalidUtf8, tx10));
|
BOOST_CHECK(fixture.is_best_claim(invalidUtf8, tx10));
|
||||||
|
|
||||||
|
@ -170,7 +168,7 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_normalization)
|
||||||
|
|
||||||
// Roll forward to fork height again and check again that we're normalized
|
// Roll forward to fork height again and check again that we're normalized
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
BOOST_CHECK(chainActive.Height() == Params().GetConsensus().nNormalizedNameForkHeight);
|
BOOST_CHECK(::ChainActive().Height() == Params().GetConsensus().nNormalizedNameForkHeight);
|
||||||
BOOST_CHECK(fixture.is_best_claim("normalizetest", tx1)); // collapsed tx2
|
BOOST_CHECK(fixture.is_best_claim("normalizetest", tx1)); // collapsed tx2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +201,7 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
|
||||||
// cache), flattening all previously existing name clashes due to
|
// cache), flattening all previously existing name clashes due to
|
||||||
// the normalization
|
// the normalization
|
||||||
fixture.setNormalizationForkHeight(1);
|
fixture.setNormalizationForkHeight(1);
|
||||||
int currentHeight = chainActive.Height();
|
int currentHeight = ::ChainActive().Height();
|
||||||
|
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
// Ok normalization fix the name problem
|
// Ok normalization fix the name problem
|
||||||
|
@ -211,15 +209,16 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
|
||||||
BOOST_CHECK(nval1.nHeight == currentHeight);
|
BOOST_CHECK(nval1.nHeight == currentHeight);
|
||||||
BOOST_CHECK(lookupClaim == nval1);
|
BOOST_CHECK(lookupClaim == nval1);
|
||||||
|
|
||||||
CCoinsViewCache coins(pcoinsTip.get());
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
CBlockIndex* pindex = chainActive.Tip();
|
CBlockIndex* pindex = ::ChainActive().Tip();
|
||||||
|
CCoinsViewCache coins(&::ChainstateActive().CoinsTip());
|
||||||
|
|
||||||
CBlock block;
|
CBlock block;
|
||||||
int amelieValidHeight;
|
int amelieValidHeight;
|
||||||
std::string removed;
|
std::string removed;
|
||||||
BOOST_CHECK(trieCache.shouldNormalize());
|
BOOST_CHECK(trieCache.shouldNormalize());
|
||||||
BOOST_CHECK(ReadBlockFromDisk(block, pindex, Params().GetConsensus()));
|
BOOST_CHECK(ReadBlockFromDisk(block, pindex, Params().GetConsensus()));
|
||||||
BOOST_CHECK(g_chainstate.DisconnectBlock(block, pindex, coins, trieCache) == DisconnectResult::DISCONNECT_OK);
|
BOOST_CHECK(::ChainstateActive().DisconnectBlock(block, pindex, coins, trieCache) == DisconnectResult::DISCONNECT_OK);
|
||||||
BOOST_CHECK(!trieCache.shouldNormalize());
|
BOOST_CHECK(!trieCache.shouldNormalize());
|
||||||
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), removed, amelieValidHeight));
|
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), removed, amelieValidHeight));
|
||||||
|
|
||||||
|
@ -301,7 +300,7 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
||||||
CMutableTransaction sx2 = fixture.MakeSupport(fixture.GetCoinbase(), tx2, "Ab", 1);
|
CMutableTransaction sx2 = fixture.MakeSupport(fixture.GetCoinbase(), tx2, "Ab", 1);
|
||||||
|
|
||||||
CClaimTrieCache cache(pclaimTrie);
|
CClaimTrieCache cache(pclaimTrie);
|
||||||
int height = chainActive.Height() + 1;
|
int height = ::ChainActive().Height() + 1;
|
||||||
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height);
|
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height);
|
||||||
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height);
|
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height);
|
||||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height);
|
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// file COPYING or http://opensource.org/licenses/mit-license.php
|
// file COPYING or http://opensource.org/licenses/mit-license.php
|
||||||
|
|
||||||
#include <test/claimtriefixture.h>
|
#include <test/claimtriefixture.h>
|
||||||
#include <utilstrencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -18,12 +18,12 @@ BOOST_AUTO_TEST_CASE(getnamesintrie_test)
|
||||||
std::string sName1("test");
|
std::string sName1("test");
|
||||||
std::string sValue1("test");
|
std::string sValue1("test");
|
||||||
|
|
||||||
uint256 blockHash = chainActive.Tip()->GetBlockHash();
|
uint256 blockHash = ::ChainActive().Tip()->GetBlockHash();
|
||||||
|
|
||||||
fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 42);
|
fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 42);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
rpcfn_type getnamesintrie = tableRPC["getnamesintrie"]->actor;
|
auto getnamesintrie = tableRPC["getnamesintrie"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
|
||||||
|
@ -45,12 +45,12 @@ BOOST_AUTO_TEST_CASE(getvalueforname_test)
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 2);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 2);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
uint256 blockHash = chainActive.Tip()->GetBlockHash();
|
uint256 blockHash = ::ChainActive().Tip()->GetBlockHash();
|
||||||
|
|
||||||
fixture.MakeSupport(fixture.GetCoinbase(), tx1, sName1, 3);
|
fixture.MakeSupport(fixture.GetCoinbase(), tx1, sName1, 3);
|
||||||
fixture.IncrementBlocks(10);
|
fixture.IncrementBlocks(10);
|
||||||
|
|
||||||
rpcfn_type getvalueforname = tableRPC["getvalueforname"]->actor;
|
auto getvalueforname = tableRPC["getvalueforname"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(sName1));
|
req.params.push_back(UniValue(sName1));
|
||||||
|
@ -74,17 +74,17 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test)
|
||||||
std::string sValue1("test1");
|
std::string sValue1("test1");
|
||||||
std::string sValue2("test2");
|
std::string sValue2("test2");
|
||||||
|
|
||||||
int height = chainActive.Height();
|
int height = ::ChainActive().Height();
|
||||||
|
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 2);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 2);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
uint256 blockHash = chainActive.Tip()->GetBlockHash();
|
uint256 blockHash = ::ChainActive().Tip()->GetBlockHash();
|
||||||
|
|
||||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 3);
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 3);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor;
|
auto getclaimsforname = tableRPC["getclaimsforname"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(sName1));
|
req.params.push_back(UniValue(sName1));
|
||||||
|
@ -124,20 +124,20 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback2_test)
|
||||||
std::string sValue1("test1");
|
std::string sValue1("test1");
|
||||||
std::string sValue2("test2");
|
std::string sValue2("test2");
|
||||||
|
|
||||||
int height = chainActive.Height();
|
int height = ::ChainActive().Height();
|
||||||
|
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 1);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 1);
|
||||||
fixture.IncrementBlocks(2);
|
fixture.IncrementBlocks(2);
|
||||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2);
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2);
|
||||||
fixture.IncrementBlocks(3);
|
fixture.IncrementBlocks(3);
|
||||||
|
|
||||||
uint256 blockHash = chainActive.Tip()->GetBlockHash();
|
uint256 blockHash = ::ChainActive().Tip()->GetBlockHash();
|
||||||
|
|
||||||
CMutableTransaction tx3 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, sValue1, 3);
|
CMutableTransaction tx3 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, sValue1, 3);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor;
|
auto getclaimsforname = tableRPC["getclaimsforname"];
|
||||||
rpcfn_type getvalueforname = tableRPC["getvalueforname"]->actor;
|
auto getvalueforname = tableRPC["getvalueforname"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(sName1));
|
req.params.push_back(UniValue(sName1));
|
||||||
|
@ -160,26 +160,26 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback3_test)
|
||||||
std::string sValue1("test1");
|
std::string sValue1("test1");
|
||||||
std::string sValue2("test2");
|
std::string sValue2("test2");
|
||||||
|
|
||||||
int height = chainActive.Height();
|
int height = ::ChainActive().Height();
|
||||||
|
|
||||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 3);
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 3);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2);
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2);
|
||||||
fixture.IncrementBlocks(2);
|
fixture.IncrementBlocks(2);
|
||||||
|
|
||||||
uint256 blockHash = chainActive.Tip()->GetBlockHash();
|
uint256 blockHash = ::ChainActive().Tip()->GetBlockHash();
|
||||||
|
|
||||||
CMutableTransaction tx3 = fixture.Spend(tx1); // abandon the claim
|
CMutableTransaction tx3 = fixture.Spend(tx1); // abandon the claim
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor;
|
auto getclaimsforname = tableRPC["getclaimsforname"];
|
||||||
rpcfn_type getvalueforname = tableRPC["getvalueforname"]->actor;
|
auto getvalueforname = tableRPC["getvalueforname"];
|
||||||
rpcfn_type getblocktemplate = tableRPC["getblocktemplate"]->actor;
|
auto getblocktemplate = tableRPC["getblocktemplate"];
|
||||||
|
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
UniValue templateResults = getblocktemplate(req);
|
UniValue templateResults = getblocktemplate(req);
|
||||||
BOOST_CHECK_EQUAL(templateResults["claimtrie"].get_str(), chainActive.Tip()->hashClaimTrie.GetHex());
|
BOOST_CHECK_EQUAL(templateResults["claimtrie"].get_str(), ::ChainActive().Tip()->hashClaimTrie.GetHex());
|
||||||
|
|
||||||
req.params.push_back(UniValue(sName1));
|
req.params.push_back(UniValue(sName1));
|
||||||
req.params.push_back(blockHash.GetHex());
|
req.params.push_back(blockHash.GetHex());
|
||||||
|
@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
auto tx3 = fixture.MakeClaim(fixture.GetCoinbase(), name, value4, 4);
|
auto tx3 = fixture.MakeClaim(fixture.GetCoinbase(), name, value4, 4);
|
||||||
fixture.IncrementBlocks(1);
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
int height = chainActive.Height();
|
int height = ::ChainActive().Height();
|
||||||
|
|
||||||
auto claimId1 = ClaimIdHash(tx1.GetHash(), 0);
|
auto claimId1 = ClaimIdHash(tx1.GetHash(), 0);
|
||||||
auto claimId2 = ClaimIdHash(tx2.GetHash(), 0);
|
auto claimId2 = ClaimIdHash(tx2.GetHash(), 0);
|
||||||
|
@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
int claim3bid = 2, claim3seq = 2;
|
int claim3bid = 2, claim3seq = 2;
|
||||||
int claim4bid = 0, claim4seq = 3;
|
int claim4bid = 0, claim4seq = 3;
|
||||||
|
|
||||||
auto getclaimsforname = tableRPC["getclaimsforname"]->actor;
|
auto getclaimsforname = tableRPC["getclaimsforname"];
|
||||||
|
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
BOOST_CHECK_EQUAL(claims[3][T_SEQUENCE].get_int(), claim1seq);
|
BOOST_CHECK_EQUAL(claims[3][T_SEQUENCE].get_int(), claim1seq);
|
||||||
BOOST_CHECK_EQUAL(claims[3][T_CLAIMID].get_str(), claimId1.GetHex());
|
BOOST_CHECK_EQUAL(claims[3][T_CLAIMID].get_str(), claimId1.GetHex());
|
||||||
|
|
||||||
auto getclaimbybid = tableRPC["getclaimbybid"]->actor;
|
auto getclaimbybid = tableRPC["getclaimbybid"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(name));
|
req.params.push_back(UniValue(name));
|
||||||
req.params.push_back(UniValue(claim3bid));
|
req.params.push_back(UniValue(claim3bid));
|
||||||
|
@ -281,7 +281,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim3seq);
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim3seq);
|
||||||
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId3.GetHex());
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId3.GetHex());
|
||||||
|
|
||||||
auto getclaimbyseq = tableRPC["getclaimbyseq"]->actor;
|
auto getclaimbyseq = tableRPC["getclaimbyseq"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(name));
|
req.params.push_back(UniValue(name));
|
||||||
req.params.push_back(UniValue(claim2seq));
|
req.params.push_back(UniValue(claim2seq));
|
||||||
|
@ -293,7 +293,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim2seq);
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim2seq);
|
||||||
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId2.GetHex());
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId2.GetHex());
|
||||||
|
|
||||||
auto getclaimbyid = tableRPC["getclaimbyid"]->actor;
|
auto getclaimbyid = tableRPC["getclaimbyid"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(claimId1.GetHex()));
|
req.params.push_back(UniValue(claimId1.GetHex()));
|
||||||
|
|
||||||
|
@ -315,9 +315,9 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim3seq);
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim3seq);
|
||||||
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId3.GetHex());
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId3.GetHex());
|
||||||
|
|
||||||
auto blockhash = chainActive.Tip()->GetBlockHash();
|
auto blockhash = ::ChainActive().Tip()->GetBlockHash();
|
||||||
|
|
||||||
auto getnameproof = tableRPC["getnameproof"]->actor;
|
auto getnameproof = tableRPC["getnameproof"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(name));
|
req.params.push_back(UniValue(name));
|
||||||
req.params.push_back(UniValue(blockhash.GetHex()));
|
req.params.push_back(UniValue(blockhash.GetHex()));
|
||||||
|
@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
claimHash = getValueHash(COutPoint(tx2.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
claimHash = getValueHash(COutPoint(tx2.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
auto getclaimproofbybid = tableRPC["getclaimproofbybid"]->actor;
|
auto getclaimproofbybid = tableRPC["getclaimproofbybid"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(name));
|
req.params.push_back(UniValue(name));
|
||||||
req.params.push_back(UniValue(claim1bid));
|
req.params.push_back(UniValue(claim1bid));
|
||||||
|
@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
claimHash = getValueHash(COutPoint(tx1.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
claimHash = getValueHash(COutPoint(tx1.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
auto getclaimproofbyseq = tableRPC["getclaimproofbyseq"]->actor;
|
auto getclaimproofbyseq = tableRPC["getclaimproofbyseq"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(name));
|
req.params.push_back(UniValue(name));
|
||||||
req.params.push_back(UniValue(claim4seq));
|
req.params.push_back(UniValue(claim4seq));
|
||||||
|
@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
claimHash = getValueHash(COutPoint(tx3.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
claimHash = getValueHash(COutPoint(tx3.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
auto getchangesinblock = tableRPC["getchangesinblock"]->actor;
|
auto getchangesinblock = tableRPC["getchangesinblock"];
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back(UniValue(blockhash.GetHex()));
|
req.params.push_back(UniValue(blockhash.GetHex()));
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ BOOST_AUTO_TEST_CASE(claim_rpc_pending_amount_test)
|
||||||
std::string sValue1("test1");
|
std::string sValue1("test1");
|
||||||
std::string sValue2("test2");
|
std::string sValue2("test2");
|
||||||
|
|
||||||
rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor;
|
auto getclaimsforname = tableRPC["getclaimsforname"];
|
||||||
|
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <attributes.h>
|
#include <attributes.h>
|
||||||
|
#include <claimtrie/forks.h>
|
||||||
#include <clientversion.h>
|
#include <clientversion.h>
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
#include <script/standard.h>
|
#include <script/standard.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <test/setup_common.h>
|
#include <test/setup_common.h>
|
||||||
|
#include <validation.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
#include <undo.h>
|
#include <undo.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <clientversion.h>
|
#include <clientversion.h>
|
||||||
#include <crypto/siphash.h>
|
#include <crypto/siphash.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <test/setup_common.h>
|
#include <test/setup_common.h>
|
||||||
|
|
||||||
|
|
|
@ -223,11 +223,11 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(!pblock->hashClaimTrie.IsNull());
|
BOOST_CHECK(!pblock->hashClaimTrie.IsNull());
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
pblock->hashPrevBlock = chainActive.Tip()->GetBlockHash();
|
pblock->hashPrevBlock = ::ChainActive().Tip()->GetBlockHash();
|
||||||
pblock->nVersion = 5;
|
pblock->nVersion = 5;
|
||||||
pblock->nTime = chainActive.Tip()->GetBlockTime() + chainparams.GetConsensus().nPowTargetSpacing;
|
pblock->nTime = ::ChainActive().Tip()->GetBlockTime() + chainparams.GetConsensus().nPowTargetSpacing;
|
||||||
CMutableTransaction txCoinbase(*pblock->vtx[0]);
|
CMutableTransaction txCoinbase(*pblock->vtx[0]);
|
||||||
txCoinbase.vin[0].scriptSig = CScript() << int(chainActive.Height() + 1) << i;
|
txCoinbase.vin[0].scriptSig = CScript() << int(::ChainActive().Height() + 1) << i;
|
||||||
txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
|
txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
|
||||||
txCoinbase.vout[0].scriptPubKey = CScript();
|
txCoinbase.vout[0].scriptPubKey = CScript();
|
||||||
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
||||||
|
@ -373,8 +373,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
// subsidy changing
|
// subsidy changing
|
||||||
int nHeight = ::ChainActive().Height();
|
int nHeight = ::ChainActive().Height();
|
||||||
// Create an actual 209999-long block chain (without valid blocks).
|
// Create an actual 209999-long block chain (without valid blocks).
|
||||||
while (chainActive.Tip()->nHeight < 209999) {
|
while (::ChainActive().Tip()->nHeight < 209999) {
|
||||||
CBlockIndex* prev = chainActive.Tip();
|
CBlockIndex* prev = ::ChainActive().Tip();
|
||||||
CBlockIndex* next = new CBlockIndex();
|
CBlockIndex* next = new CBlockIndex();
|
||||||
next->phashBlock = new uint256(InsecureRand256());
|
next->phashBlock = new uint256(InsecureRand256());
|
||||||
next->hashClaimTrie = pblocktemplate->block.hashClaimTrie;
|
next->hashClaimTrie = pblocktemplate->block.hashClaimTrie;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <test/test_bitcoin.h>
|
#include <test/setup_common.h>
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(nameclaim_tests, BasicTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(nameclaim_tests, BasicTestingSetup)
|
||||||
|
|
||||||
|
|
1665
src/test/script_tests.1cpp
Normal file
1665
src/test/script_tests.1cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1317,7 +1317,7 @@ BOOST_AUTO_TEST_CASE(script_claimScript)
|
||||||
// Spend normal tx to make claim
|
// Spend normal tx to make claim
|
||||||
// Spend claim to update claim
|
// Spend claim to update claim
|
||||||
// Spend updated claim to abandon name
|
// Spend updated claim to abandon name
|
||||||
CBasicKeyStore keystore;
|
FillableSigningProvider keystore;
|
||||||
std::vector<CKey> keys;
|
std::vector<CKey> keys;
|
||||||
std::vector<CPubKey> pubkeys;
|
std::vector<CPubKey> pubkeys;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
|
@ -1336,23 +1336,23 @@ BOOST_AUTO_TEST_CASE(script_claimScript)
|
||||||
std::vector<unsigned char> vchName(sName.begin(), sName.end());
|
std::vector<unsigned char> vchName(sName.begin(), sName.end());
|
||||||
std::vector<unsigned char> vchValue(sValue.begin(), sValue.end());
|
std::vector<unsigned char> vchValue(sValue.begin(), sValue.end());
|
||||||
|
|
||||||
CMutableTransaction txOrig = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID()));
|
CMutableTransaction txOrig = BuildCreditingTransaction(GetScriptForDestination(PKHash(keys[0].GetPubKey())));
|
||||||
|
|
||||||
CMutableTransaction txClaim0 = BuildSpendingTransaction(CScript(), wit, txOrig);
|
CMutableTransaction txClaim0 = BuildSpendingTransaction(CScript(), wit, CTransaction(txOrig));
|
||||||
CScript txClaimOut0 = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
CScript txClaimOut0 = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
||||||
txClaimOut0 = txClaimOut0 + GetScriptForDestination(keys[1].GetPubKey().GetID());
|
txClaimOut0 = txClaimOut0 + GetScriptForDestination(PKHash(keys[1].GetPubKey()));
|
||||||
txClaim0.vout[0].scriptPubKey = txClaimOut0;
|
txClaim0.vout[0].scriptPubKey = txClaimOut0;
|
||||||
SignSignature(keystore, txOrig, txClaim0, 0, SIGHASH_ALL);
|
SignSignature(keystore, CTransaction(txOrig), txClaim0, 0, SIGHASH_ALL);
|
||||||
|
|
||||||
CMutableTransaction txClaim1 = BuildSpendingTransaction(CScript(), wit, txClaim0);
|
CMutableTransaction txClaim1 = BuildSpendingTransaction(CScript(), wit, CTransaction(txClaim0));
|
||||||
CScript txClaimOut1 = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
CScript txClaimOut1 = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
||||||
txClaimOut1 = txClaimOut1 + GetScriptForDestination(keys[2].GetPubKey().GetID());
|
txClaimOut1 = txClaimOut1 + GetScriptForDestination(PKHash(keys[2].GetPubKey()));
|
||||||
txClaim1.vout[0].scriptPubKey = txClaimOut1;
|
txClaim1.vout[0].scriptPubKey = txClaimOut1;
|
||||||
SignSignature(keystore, txClaim0, txClaim1, 0, SIGHASH_ALL);
|
SignSignature(keystore, CTransaction(txClaim0), txClaim1, 0, SIGHASH_ALL);
|
||||||
|
|
||||||
CMutableTransaction txFinal = BuildSpendingTransaction(CScript(), wit, txClaim1);
|
CMutableTransaction txFinal = BuildSpendingTransaction(CScript(), wit, CTransaction(txClaim1));
|
||||||
txFinal.vout[0].scriptPubKey = GetScriptForDestination(keys[3].GetPubKey().GetID());
|
txFinal.vout[0].scriptPubKey = GetScriptForDestination(PKHash(keys[3].GetPubKey()));
|
||||||
SignSignature(keystore, txClaim1, txFinal, 0, SIGHASH_ALL);
|
SignSignature(keystore, CTransaction(txClaim1), txFinal, 0, SIGHASH_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(script_standard_push)
|
BOOST_AUTO_TEST_CASE(script_standard_push)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <serialize.h>
|
#include <serialize.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
#include <test/setup_common.h>
|
#include <test/setup_common.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <miner.h>
|
#include <miner.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <noui.h>
|
#include <noui.h>
|
||||||
|
#include <policy/policy.h>
|
||||||
#include <pow.h>
|
#include <pow.h>
|
||||||
#include <rpc/register.h>
|
#include <rpc/register.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
|
@ -31,9 +32,6 @@
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#include <boost/test/unit_test_parameters.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
|
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// 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 <coins.h>
|
||||||
#include <consensus/consensus.h>
|
#include <consensus/consensus.h>
|
||||||
#include <consensus/tx_verify.h>
|
#include <consensus/tx_verify.h>
|
||||||
#include <pubkey.h>
|
#include <pubkey.h>
|
||||||
|
|
22
src/txdb.cpp
22
src/txdb.cpp
|
@ -23,8 +23,8 @@ static const sqlite::sqlite_config sharedConfig {
|
||||||
nullptr, sqlite::Encoding::UTF8
|
nullptr, sqlite::Encoding::UTF8
|
||||||
};
|
};
|
||||||
|
|
||||||
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe)
|
CCoinsViewDB::CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory, bool fWipe)
|
||||||
: db(fMemory ? ":memory:" : (GetDataDir() / "coins.sqlite").string(), sharedConfig)
|
: db(fMemory ? ":memory:" : (ldb_path / "coins.sqlite").string(), sharedConfig)
|
||||||
{
|
{
|
||||||
db << "PRAGMA cache_size=-" + std::to_string(nCacheSize >> 10); // in -KB
|
db << "PRAGMA cache_size=-" + std::to_string(nCacheSize >> 10); // in -KB
|
||||||
db << "PRAGMA synchronous=OFF"; // don't disk sync after transaction commit
|
db << "PRAGMA synchronous=OFF"; // don't disk sync after transaction commit
|
||||||
|
@ -62,9 +62,7 @@ bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
|
||||||
bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
|
bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
|
||||||
auto query = db << "SELECT 1 FROM coin "
|
auto query = db << "SELECT 1 FROM coin "
|
||||||
"WHERE txID = ? and txN = ?" << outpoint.hash << outpoint.n;
|
"WHERE txID = ? and txN = ?" << outpoint.hash << outpoint.n;
|
||||||
for (auto&& row: query)
|
return query.begin() != query.end();
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 CCoinsViewDB::GetBestBlock() const {
|
uint256 CCoinsViewDB::GetBestBlock() const {
|
||||||
|
@ -380,12 +378,13 @@ bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos>> &list) {
|
bool CBlockTreeDB::WriteTxIndex(const FlatFilePos& file, const std::vector<std::pair<uint256, uint32_t>>& txOffsets)
|
||||||
if (list.empty()) return true;
|
{
|
||||||
|
if (txOffsets.empty()) return true;
|
||||||
db << "begin";
|
db << "begin";
|
||||||
auto query = db << "INSERT OR REPLACE INTO tx_to_block VALUES(?,?,?,?)";
|
auto query = db << "INSERT OR REPLACE INTO tx_to_block VALUES(?,?,?,?)";
|
||||||
for (auto& kvp: list) {
|
for (auto& kvp: txOffsets) {
|
||||||
query << kvp.first << kvp.second.nFile << kvp.second.nPos << kvp.second.nTxOffset;
|
query << kvp.first << file.nFile << file.nPos << kvp.second;
|
||||||
query++;
|
query++;
|
||||||
}
|
}
|
||||||
query.used(true);
|
query.used(true);
|
||||||
|
@ -397,10 +396,11 @@ bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos>
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
|
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, FlatFilePos &file, uint32_t& offset)
|
||||||
|
{
|
||||||
auto query = db << "SELECT file, blockPos, txPos FROM tx_to_block WHERE txID = ?" << txid;
|
auto query = db << "SELECT file, blockPos, txPos FROM tx_to_block WHERE txID = ?" << txid;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
row >> pos.nFile >> pos.nPos >> pos.nTxOffset;
|
row >> file.nFile >> file.nPos >> offset;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
31
src/txdb.h
31
src/txdb.h
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
|
#include <flatfile.h>
|
||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -64,32 +65,6 @@ static const int64_t max_filter_index_cache = 1024;
|
||||||
//! Max memory allocated to coin DB specific cache (MiB)
|
//! Max memory allocated to coin DB specific cache (MiB)
|
||||||
static const int64_t nMaxCoinsDBCache = 40;
|
static const int64_t nMaxCoinsDBCache = 40;
|
||||||
|
|
||||||
|
|
||||||
struct CDiskTxPos : public CDiskBlockPos
|
|
||||||
{
|
|
||||||
unsigned int nTxOffset; // after header
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
||||||
READWRITEAS(CDiskBlockPos, *this);
|
|
||||||
READWRITE(VARINT(nTxOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
CDiskTxPos(const CDiskBlockPos &blockIn, unsigned int nTxOffsetIn) : CDiskBlockPos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) {
|
|
||||||
}
|
|
||||||
|
|
||||||
CDiskTxPos() {
|
|
||||||
SetNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetNull() {
|
|
||||||
CDiskBlockPos::SetNull();
|
|
||||||
nTxOffset = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** CCoinsView backed by the coin database (chainstate/) */
|
/** CCoinsView backed by the coin database (chainstate/) */
|
||||||
class CCoinsViewDB final : public CCoinsView
|
class CCoinsViewDB final : public CCoinsView
|
||||||
{
|
{
|
||||||
|
@ -145,10 +120,10 @@ public:
|
||||||
bool ReadLastBlockFile(int &nFile);
|
bool ReadLastBlockFile(int &nFile);
|
||||||
bool WriteReindexing(bool fReindexing);
|
bool WriteReindexing(bool fReindexing);
|
||||||
void ReadReindexing(bool &fReindexing);
|
void ReadReindexing(bool &fReindexing);
|
||||||
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
|
|
||||||
bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos>> &list);
|
|
||||||
bool WriteFlag(const std::string &name, bool fValue);
|
bool WriteFlag(const std::string &name, bool fValue);
|
||||||
bool ReadFlag(const std::string &name, bool &fValue);
|
bool ReadFlag(const std::string &name, bool &fValue);
|
||||||
|
bool ReadTxIndex(const uint256 &txid, FlatFilePos &file, uint32_t& offset);
|
||||||
|
bool WriteTxIndex(const FlatFilePos& file, const std::vector<std::pair<uint256, uint32_t>>& txOffsets);
|
||||||
bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex);
|
bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
111
src/undo.h
111
src/undo.h
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
// Copyright (c) 2009-2018 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.
|
||||||
|
|
||||||
|
@ -8,65 +8,96 @@
|
||||||
|
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
#include <compressor.h>
|
#include <compressor.h>
|
||||||
|
#include <consensus/consensus.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <serialize.h>
|
#include <serialize.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
|
|
||||||
/** Undo information for a CTxIn
|
/** Undo information for a CTxIn
|
||||||
*
|
*
|
||||||
* Contains the prevout's CTxOut being spent, and if this was the
|
* Contains the prevout's CTxOut being spent, and its metadata as well
|
||||||
* last output of the affected transaction, its metadata as well
|
* (coinbase or not, height). The serialization contains a dummy value of
|
||||||
* (coinbase or not, height, transaction version)
|
* zero. This is compatible with older versions which expect to see
|
||||||
|
* the transaction version there.
|
||||||
*/
|
*/
|
||||||
class CTxInUndo
|
class TxInUndoSerializer
|
||||||
{
|
{
|
||||||
uint32_t nDeprecated1 = 0; // if the outpoint was the last unspent: its version
|
const Coin* txout;
|
||||||
bool fDeprecated2 = false; // whether the outpoint was the last unspent
|
|
||||||
public:
|
public:
|
||||||
CTxOut txout; // the txout data before being spent
|
template<typename Stream>
|
||||||
bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase
|
void Serialize(Stream &s) const {
|
||||||
uint32_t nHeight; // if the outpoint was the last unspent: its height
|
::Serialize(s, VARINT(txout->nHeight * 2 + (txout->fCoinBase ? 1u : 0u)));
|
||||||
uint32_t nClaimValidHeight; // If the outpoint was a claim or support, the height at which the claim or support should be inserted into the trie
|
if (txout->nHeight > 0) {
|
||||||
bool fIsClaim; // if the outpoint was a claim or support
|
// Required to maintain compatibility with older undo format.
|
||||||
|
::Serialize(s, (unsigned char)0);
|
||||||
CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nClaimValidHeight(0), fIsClaim(false) {}
|
|
||||||
CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, uint32_t nHeightIn = 0) :
|
|
||||||
txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nClaimValidHeight(0), fIsClaim(false) {}
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
|
||||||
if (ser_action.ForRead()) {
|
|
||||||
uint32_t nCode = 0;
|
|
||||||
READWRITE(VARINT(nCode)); // VARINT in this method is for legacy compatibility
|
|
||||||
nHeight = nCode >> 2U;
|
|
||||||
fCoinBase = nCode & 2U;
|
|
||||||
fDeprecated2 = nCode & 1U;
|
|
||||||
} else {
|
|
||||||
uint32_t nCode = (nHeight << 2U) | (fCoinBase ? 2U : 0U) | (fDeprecated2 ? 1U: 0U);
|
|
||||||
READWRITE(VARINT(nCode));
|
|
||||||
}
|
}
|
||||||
if (fDeprecated2)
|
::Serialize(s, CTxOutCompressor(REF(txout->out)));
|
||||||
READWRITE(VARINT(nDeprecated1));
|
|
||||||
READWRITE(REF(CTxOutCompressor(REF(txout))));
|
|
||||||
READWRITE(VARINT(nClaimValidHeight));
|
|
||||||
READWRITE(fIsClaim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit TxInUndoSerializer(const Coin* coin) : txout(coin) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TxInUndoDeserializer
|
||||||
|
{
|
||||||
|
Coin* txout;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename Stream>
|
||||||
|
void Unserialize(Stream &s) {
|
||||||
|
unsigned int nCode = 0;
|
||||||
|
::Unserialize(s, VARINT(nCode));
|
||||||
|
txout->nHeight = nCode / 2;
|
||||||
|
txout->fCoinBase = nCode & 1;
|
||||||
|
if (txout->nHeight > 0) {
|
||||||
|
// Old versions stored the version number for the last spend of
|
||||||
|
// a transaction's outputs. Non-final spends were indicated with
|
||||||
|
// height = 0.
|
||||||
|
unsigned int nVersionDummy;
|
||||||
|
::Unserialize(s, VARINT(nVersionDummy));
|
||||||
|
}
|
||||||
|
::Unserialize(s, CTxOutCompressor(REF(txout->out)));
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t MIN_TRANSACTION_INPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxIn(), PROTOCOL_VERSION);
|
||||||
|
static const size_t MAX_INPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_INPUT_WEIGHT;
|
||||||
|
|
||||||
/** Undo information for a CTransaction */
|
/** Undo information for a CTransaction */
|
||||||
class CTxUndo
|
class CTxUndo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// undo information for all txins
|
// undo information for all txins
|
||||||
std::vector<CTxInUndo> vprevout;
|
std::vector<Coin> vprevout;
|
||||||
|
// tx index to claim valid height
|
||||||
|
std::map<int, int> claimHeights;
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
template <typename Stream>
|
||||||
|
void Serialize(Stream& s) const {
|
||||||
|
// TODO: avoid reimplementing vector serializer
|
||||||
|
uint64_t count = vprevout.size();
|
||||||
|
::Serialize(s, COMPACTSIZE(REF(count)));
|
||||||
|
for (const auto& prevout : vprevout) {
|
||||||
|
::Serialize(s, TxInUndoSerializer(&prevout));
|
||||||
|
}
|
||||||
|
::Serialize(s, claimHeights);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
template <typename Stream>
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
void Unserialize(Stream& s) {
|
||||||
READWRITE(vprevout);
|
// TODO: avoid reimplementing vector deserializer
|
||||||
|
uint64_t count = 0;
|
||||||
|
::Unserialize(s, COMPACTSIZE(count));
|
||||||
|
if (count > MAX_INPUTS_PER_BLOCK) {
|
||||||
|
throw std::ios_base::failure("Too many input undo records");
|
||||||
|
}
|
||||||
|
vprevout.resize(count);
|
||||||
|
for (auto& prevout : vprevout) {
|
||||||
|
::Unserialize(s, TxInUndoDeserializer(&prevout));
|
||||||
|
}
|
||||||
|
::Unserialize(s, claimHeights);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1090,15 +1090,16 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||||
return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, pfMissingInputs, GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee, test_accept);
|
return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, pfMissingInputs, GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee, test_accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FillTx(const uint256& tx_hash, const CDiskTxPos& postx, uint256& block_hash, CTransactionRef& tx) {
|
bool FillTx(const uint256& tx_hash, const FlatFilePos& pos, uint32_t offset, uint256& block_hash, CTransactionRef& tx)
|
||||||
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
|
{
|
||||||
|
CAutoFile file(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
|
||||||
if (file.IsNull()) {
|
if (file.IsNull()) {
|
||||||
return error("%s: OpenBlockFile failed", __func__);
|
return error("%s: OpenBlockFile failed", __func__);
|
||||||
}
|
}
|
||||||
CBlockHeader header;
|
CBlockHeader header;
|
||||||
try {
|
try {
|
||||||
file >> header;
|
file >> header;
|
||||||
if (fseek(file.Get(), postx.nTxOffset, SEEK_CUR)) {
|
if (fseek(file.Get(), offset, SEEK_CUR)) {
|
||||||
return error("%s: fseek(...) failed", __func__);
|
return error("%s: fseek(...) failed", __func__);
|
||||||
}
|
}
|
||||||
file >> tx;
|
file >> tx;
|
||||||
|
@ -1120,15 +1121,16 @@ bool GetTransaction(const uint256& hash, CTransactionRef& txOut, const Consensus
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
if (!block_index) {
|
if (!blockIndex) {
|
||||||
CTransactionRef ptx = mempool.get(hash);
|
CTransactionRef ptx = mempool.get(hash);
|
||||||
if (ptx) {
|
if (ptx) {
|
||||||
txOut = ptx;
|
txOut = ptx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (pblocktree) {
|
if (pblocktree) {
|
||||||
CDiskTxPos pos;
|
uint32_t offset;
|
||||||
if (pblocktree->ReadTxIndex(hash, pos) && FillTx(hash, pos, hashBlock, ptx)) {
|
FlatFilePos pos;
|
||||||
|
if (pblocktree->ReadTxIndex(hash, pos, offset) && FillTx(hash, pos, offset, hashBlock, ptx)) {
|
||||||
txOut = ptx;
|
txOut = ptx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1141,7 @@ bool GetTransaction(const uint256& hash, CTransactionRef& txOut, const Consensus
|
||||||
for (const auto& tx : block.vtx) {
|
for (const auto& tx : block.vtx) {
|
||||||
if (tx->GetHash() == hash) {
|
if (tx->GetHash() == hash) {
|
||||||
txOut = tx;
|
txOut = tx;
|
||||||
hashBlock = block_index->GetBlockHash();
|
hashBlock = blockIndex->GetBlockHash();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1149,11 +1151,6 @@ bool GetTransaction(const uint256& hash, CTransactionRef& txOut, const Consensus
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// CBlock and CBlockIndex
|
// CBlock and CBlockIndex
|
||||||
|
@ -1750,19 +1747,20 @@ int ApplyTxInUndo(unsigned int index, CTxUndo& txUndo, CCoinsViewCache& view, CC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore claim if applicable
|
if (!undo.out.scriptPubKey.empty()) {
|
||||||
if (undo.fIsClaim && !undo.txout.scriptPubKey.empty()) {
|
auto it = txUndo.claimHeights.find(index);
|
||||||
auto nValidHeight = undo.nClaimValidHeight;
|
// restore claim if applicable
|
||||||
CClaimScriptUndoSpendOp undoSpend(COutPoint(out.hash, out.n), undo.txout.nValue, undo.nHeight, nValidHeight);
|
if (it != txUndo.claimHeights.end()) {
|
||||||
ProcessClaim(undoSpend, trieCache, undo.txout.scriptPubKey);
|
CClaimScriptUndoSpendOp undoSpend(out, undo.out.nValue, undo.nHeight, it->second);
|
||||||
|
ProcessClaim(undoSpend, trieCache, undo.out.scriptPubKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The potential_overwrite parameter to AddCoin is only allowed to be false if we know for
|
// The potential_overwrite parameter to AddCoin is only allowed to be false if we know for
|
||||||
// sure that the coin did not already exist in the cache. As we have queried for that above
|
// sure that the coin did not already exist in the cache. As we have queried for that above
|
||||||
// using HaveCoin, we don't need to guess. When fClean is false, a coin already existed and
|
// using HaveCoin, we don't need to guess. When fClean is false, a coin already existed and
|
||||||
// it is an overwrite.
|
// it is an overwrite.
|
||||||
Coin coin(undo.txout, int(undo.nHeight), undo.fCoinBase);
|
view.AddCoin(out, std::move(undo), !fClean);
|
||||||
view.AddCoin(out, std::move(coin), !fClean);
|
|
||||||
|
|
||||||
return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
|
return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
|
||||||
}
|
}
|
||||||
|
@ -2213,9 +2211,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
CAmount nFees = 0;
|
CAmount nFees = 0;
|
||||||
int nInputs = 0;
|
int nInputs = 0;
|
||||||
int64_t nSigOpsCost = 0;
|
int64_t nSigOpsCost = 0;
|
||||||
CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
|
std::vector<std::pair<uint256, uint32_t>> txOffsets;
|
||||||
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
uint32_t offset = ::GetSizeOfCompactSize(block.vtx.size());
|
||||||
vPos.reserve(block.vtx.size());
|
txOffsets.reserve(block.vtx.size());
|
||||||
blockundo.vtxundo.reserve(block.vtx.size() - 1);
|
blockundo.vtxundo.reserve(block.vtx.size() - 1);
|
||||||
std::vector<PrecomputedTransactionData> txdata;
|
std::vector<PrecomputedTransactionData> txdata;
|
||||||
txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
|
txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated
|
||||||
|
@ -2303,14 +2301,10 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
blockundo.vtxundo.push_back(CTxUndo());
|
blockundo.vtxundo.push_back(CTxUndo());
|
||||||
}
|
}
|
||||||
UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
|
UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
|
||||||
if (i > 0 && !mClaimUndoHeights.empty())
|
if (i > 0 && !mClaimUndoHeights.empty()) {
|
||||||
{
|
auto& claimsHeights = blockundo.vtxundo.back().claimHeights;
|
||||||
auto& txinUndos = blockundo.vtxundo.back().vprevout;
|
|
||||||
for (auto itHeight = mClaimUndoHeights.begin(); itHeight != mClaimUndoHeights.end(); ++itHeight)
|
for (auto itHeight = mClaimUndoHeights.begin(); itHeight != mClaimUndoHeights.end(); ++itHeight)
|
||||||
{
|
claimsHeights[itHeight->first] = itHeight->second;
|
||||||
txinUndos[itHeight->first].nClaimValidHeight = itHeight->second;
|
|
||||||
txinUndos[itHeight->first].fIsClaim = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The CTxUndo vector contains the heights at which claims should be put into the trie.
|
// The CTxUndo vector contains the heights at which claims should be put into the trie.
|
||||||
|
@ -2324,17 +2318,18 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
// in. Some OP_UPDATE_CLAIM's, for example, may be invalid, and so may never have been
|
// in. Some OP_UPDATE_CLAIM's, for example, may be invalid, and so may never have been
|
||||||
// inserted into the trie in the first place.
|
// inserted into the trie in the first place.
|
||||||
|
|
||||||
vPos.push_back(std::make_pair(tx.GetHash(), pos));
|
offset += ::GetSerializeSize(tx, CLIENT_VERSION);
|
||||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
txOffsets.push_back(std::make_pair(tx.GetHash(), offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: if the "just check" flag is set, we should reduce the work done here. Incrementing blocks twice per mine is not efficient.
|
// TODO: if the "just check" flag is set, we should reduce the work done here. Incrementing blocks twice per mine is not efficient.
|
||||||
assert(trieCache.incrementBlock());
|
assert(trieCache.incrementBlock());
|
||||||
|
|
||||||
if (trieCache.getMerkleHash() != block.hashClaimTrie) {
|
if (trieCache.getMerkleHash() != block.hashClaimTrie) {
|
||||||
return state.DoS(100, error("ConnectBlock() : the merkle root of the claim trie does not match "
|
return state.Invalid(ValidationInvalidReason::CLAIMTRIE_HASH,
|
||||||
"(actual=%s vs block=%s on height=%d)", trieCache.getMerkleHash().GetHex(),
|
error("ConnectBlock() : the merkle root of the claim trie does not match "
|
||||||
block.hashClaimTrie.GetHex(), pindex->nHeight), REJECT_INVALID, "bad-claim-merkle-hash");
|
"(actual=%s vs block=%s on height=%d)", trieCache.getMerkleHash().GetHex(),
|
||||||
|
block.hashClaimTrie.GetHex(), pindex->nHeight), REJECT_INVALID, "bad-claim-merkle-hash");
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
|
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
|
||||||
|
@ -2355,12 +2350,10 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
if (fJustCheck)
|
if (fJustCheck)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (pindex->pprev != nullptr) {
|
if (pindex->pprev && !WriteUndoDataForBlock(blockundo, state, pindex, chainparams))
|
||||||
if (!WriteUndoDataForBlock(blockundo, state, pindex, chainparams))
|
return false;
|
||||||
return error("Unable to write to the Undo data block");
|
if (!pblocktree->WriteTxIndex(pindex->GetBlockPos(), txOffsets))
|
||||||
if (!pblocktree->WriteTxIndex(vPos))
|
return false;
|
||||||
return error("Unable to write to the TX Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
|
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
|
||||||
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
|
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
|
||||||
|
@ -2576,12 +2569,13 @@ void static UpdateTip(const CBlockIndex* pindexNew, const CChainParams& chainPar
|
||||||
auto currentTime = GetAdjustedTime();
|
auto currentTime = GetAdjustedTime();
|
||||||
if (!warningMessages.empty() || !isInitialBlockDownload || lastBlockPrintTime < currentTime - 15 || LogAcceptCategory(BCLog::CLAIMS)) {
|
if (!warningMessages.empty() || !isInitialBlockDownload || lastBlockPrintTime < currentTime - 15 || LogAcceptCategory(BCLog::CLAIMS)) {
|
||||||
lastBlockPrintTime = currentTime;
|
lastBlockPrintTime = currentTime;
|
||||||
|
auto& cache = ::ChainstateActive().CoinsTip();
|
||||||
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g txb=%lu tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s",
|
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%.8g txb=%lu tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s",
|
||||||
__func__, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
|
__func__, pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
|
||||||
std::log(pindexNew->nChainWork.getdouble()) / std::log(2.0), (unsigned long) pindexNew->nTx,
|
std::log(pindexNew->nChainWork.getdouble()) / std::log(2.0), (unsigned long) pindexNew->nTx,
|
||||||
(unsigned long) pindexNew->nChainTx, FormatISO8601DateTime(pindexNew->GetBlockTime()),
|
(unsigned long) pindexNew->nChainTx, FormatISO8601DateTime(pindexNew->GetBlockTime()),
|
||||||
GuessVerificationProgress(chainParams.TxData(), pindexNew),
|
GuessVerificationProgress(chainParams.TxData(), pindexNew),
|
||||||
pcoinsTip->DynamicMemoryUsage() * (1.0 / (1U << 20U)), pcoinsTip->GetCacheSize(),
|
cache.DynamicMemoryUsage() * (1.0 / (1U << 20U)), cache.GetCacheSize(),
|
||||||
isInitialBlockDownload ? " IBD" : "");
|
isInitialBlockDownload ? " IBD" : "");
|
||||||
if (!warningMessages.empty())
|
if (!warningMessages.empty())
|
||||||
LogPrintf(" warning='%s'", warningMessages); /* Continued */
|
LogPrintf(" warning='%s'", warningMessages); /* Continued */
|
||||||
|
|
|
@ -689,9 +689,8 @@ public:
|
||||||
bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
// Block (dis)connection on a given view:
|
// Block (dis)connection on a given view:
|
||||||
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view);
|
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view, CClaimTrieCache& trieCache);
|
||||||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex,
|
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, CClaimTrieCache& trieCache, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
|
||||||
|
|
||||||
// Apply the effects of a block disconnection on the UTXO set.
|
// Apply the effects of a block disconnection on the UTXO set.
|
||||||
bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
|
bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
|
||||||
|
|
|
@ -187,12 +187,6 @@ public:
|
||||||
|
|
||||||
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
|
ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
|
||||||
{
|
{
|
||||||
// Check if we've past a hardfork state for segwit.
|
|
||||||
if (pos == Consensus::DEPLOYMENT_SEGWIT) {
|
|
||||||
return pindexPrev != nullptr && pindexPrev->nHeight + 1 >= params.nWitnessForkHeight ?
|
|
||||||
ThresholdState::ACTIVE : ThresholdState::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
|
return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,17 +77,6 @@ bool IsWalletLoaded(const fs::path& wallet_path)
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
auto env = g_dbenvs.find(env_directory.string());
|
auto env = g_dbenvs.find(env_directory.string());
|
||||||
if (env == g_dbenvs.end()) return false;
|
if (env == g_dbenvs.end()) return false;
|
||||||
auto db = env->second.m_databases.find(database_filename);
|
|
||||||
return db != env->second.m_databases.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<BerkeleyEnvironment> GetWalletEnv(const fs::path& wallet_path, std::string& database_filename)
|
|
||||||
{
|
|
||||||
fs::path env_directory;
|
|
||||||
SplitWalletPath(wallet_path, env_directory, database_filename);
|
|
||||||
LOCK(cs_db);
|
|
||||||
auto env = g_dbenvs.find(env_directory.string());
|
|
||||||
if (env == g_dbenvs.end()) return false;
|
|
||||||
auto database = env->second.lock();
|
auto database = env->second.lock();
|
||||||
return database && database->IsDatabaseLoaded(database_filename);
|
return database && database->IsDatabaseLoaded(database_filename);
|
||||||
}
|
}
|
||||||
|
@ -619,7 +608,6 @@ void BerkeleyBatch::Flush()
|
||||||
if (env && env->dbenv) { // env is nullptr for dummy databases (i.e. in tests). Don't actually flush if env is nullptr so we don't segfault
|
if (env && env->dbenv) { // env is nullptr for dummy databases (i.e. in tests). Don't actually flush if env is nullptr so we don't segfault
|
||||||
env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
|
env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BerkeleyDatabase::IncrementUpdateCounter()
|
void BerkeleyDatabase::IncrementUpdateCounter()
|
||||||
|
@ -687,32 +675,6 @@ void BerkeleyEnvironment::ReloadDbEnv()
|
||||||
Open(true);
|
Open(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BerkeleyEnvironment::ReloadDbEnv()
|
|
||||||
{
|
|
||||||
// Make sure that no Db's are in use
|
|
||||||
AssertLockNotHeld(cs_db);
|
|
||||||
std::unique_lock<CCriticalSection> lock(cs_db);
|
|
||||||
m_db_in_use.wait(lock, [this](){
|
|
||||||
for (auto& count : mapFileUseCount) {
|
|
||||||
if (count.second > 0) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<std::string> filenames;
|
|
||||||
for (auto it : mapDb) {
|
|
||||||
filenames.push_back(it.first);
|
|
||||||
}
|
|
||||||
// Close the individual Db's
|
|
||||||
for (const std::string& filename : filenames) {
|
|
||||||
CloseDb(filename);
|
|
||||||
}
|
|
||||||
// Reset the environment
|
|
||||||
Flush(true); // This will flush and close the environment
|
|
||||||
Reset();
|
|
||||||
Open(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
|
bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
|
||||||
{
|
{
|
||||||
if (database.IsDummy()) {
|
if (database.IsDummy()) {
|
||||||
|
|
|
@ -169,8 +169,6 @@ public:
|
||||||
|
|
||||||
void ReloadDbEnv();
|
void ReloadDbEnv();
|
||||||
|
|
||||||
void ReloadDbEnv();
|
|
||||||
|
|
||||||
std::atomic<unsigned int> nUpdateCounter;
|
std::atomic<unsigned int> nUpdateCounter;
|
||||||
unsigned int nLastSeen;
|
unsigned int nLastSeen;
|
||||||
unsigned int nLastFlushed;
|
unsigned int nLastFlushed;
|
||||||
|
|
|
@ -141,4 +141,5 @@ void WalletInit::Construct(InitInterfaces& interfaces) const
|
||||||
wallets.pop_back();
|
wallets.pop_back();
|
||||||
RemoveWallet(wallet);
|
RemoveWallet(wallet);
|
||||||
UnloadWallet(std::move(wallet));
|
UnloadWallet(std::move(wallet));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,12 @@ enum isminetype : unsigned int
|
||||||
ISMINE_NO = 0,
|
ISMINE_NO = 0,
|
||||||
ISMINE_WATCH_ONLY = 1 << 0,
|
ISMINE_WATCH_ONLY = 1 << 0,
|
||||||
ISMINE_SPENDABLE = 1 << 1,
|
ISMINE_SPENDABLE = 1 << 1,
|
||||||
ISMINE_USED = 1 << 2,
|
ISMINE_CLAIM = 1 << 2,
|
||||||
|
ISMINE_SUPPORT = 1 << 3,
|
||||||
|
ISMINE_USED = 1 << 4,
|
||||||
|
ISMINE_STAKE = ISMINE_CLAIM | ISMINE_SUPPORT,
|
||||||
ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE,
|
ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE,
|
||||||
ISMINE_ALL_USED = ISMINE_ALL | ISMINE_USED,
|
ISMINE_ALL_USED = ISMINE_ALL | ISMINE_USED | ISMINE_STAKE,
|
||||||
ISMINE_ENUM_ELEMENTS,
|
ISMINE_ENUM_ELEMENTS,
|
||||||
};
|
};
|
||||||
/** used for bitflags of isminetype */
|
/** used for bitflags of isminetype */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
|
#include <nameclaim.h>
|
||||||
#include <node/transaction.h>
|
#include <node/transaction.h>
|
||||||
#include <outputtype.h>
|
#include <outputtype.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
#include <script/descriptor.h>
|
#include <script/descriptor.h>
|
||||||
#include <script/sign.h>
|
#include <script/sign.h>
|
||||||
|
#include <validation.h>
|
||||||
#include <util/bip32.h>
|
#include <util/bip32.h>
|
||||||
#include <util/fees.h>
|
#include <util/fees.h>
|
||||||
#include <util/moneystr.h>
|
#include <util/moneystr.h>
|
||||||
|
@ -385,6 +387,8 @@ thoritative as long as it remains unspent and there are no other greater unspent
|
||||||
CScript claimScript = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
CScript claimScript = CScript() << OP_CLAIM_NAME << vchName << vchValue << OP_2DROP << OP_DROP;
|
||||||
|
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
|
auto locked_chain = pwallet->chain().lock();
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
EnsureWalletIsUnlocked(pwallet);
|
EnsureWalletIsUnlocked(pwallet);
|
||||||
|
|
||||||
//Get new address
|
//Get new address
|
||||||
|
@ -398,7 +402,7 @@ thoritative as long as it remains unspent and there are no other greater unspent
|
||||||
|
|
||||||
CCoinControl cc;
|
CCoinControl cc;
|
||||||
cc.m_change_type = pwallet->m_default_change_type;
|
cc.m_change_type = pwallet->m_default_change_type;
|
||||||
auto tx = SendMoney(pwallet, dest, nAmount, false, cc, {}, {}, claimScript);
|
auto tx = SendMoney(*locked_chain, pwallet, dest, nAmount, false, cc, {}, claimScript);
|
||||||
return tx->GetHash().GetHex();
|
return tx->GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +438,8 @@ UniValue updateclaim(const JSONRPCRequest& request)
|
||||||
CAmount nAmount = AmountFromValue(request.params[2]);
|
CAmount nAmount = AmountFromValue(request.params[2]);
|
||||||
|
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
LOCK2(cs_main, pwallet->cs_wallet);
|
auto locked_chain = pwallet->chain().lock();
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
auto it = pwallet->mapWallet.find(hash);
|
auto it = pwallet->mapWallet.find(hash);
|
||||||
if (it == pwallet->mapWallet.end()) {
|
if (it == pwallet->mapWallet.end()) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
||||||
|
@ -480,7 +485,7 @@ UniValue updateclaim(const JSONRPCRequest& request)
|
||||||
cc.m_change_type = pwallet->m_default_change_type;
|
cc.m_change_type = pwallet->m_default_change_type;
|
||||||
cc.Select(COutPoint(wtx.tx->GetHash(), i));
|
cc.Select(COutPoint(wtx.tx->GetHash(), i));
|
||||||
cc.fAllowOtherInputs = true; // when selecting a coin, that's the only one used without this flag (and we need to cover the fee)
|
cc.fAllowOtherInputs = true; // when selecting a coin, that's the only one used without this flag (and we need to cover the fee)
|
||||||
wtxNew = SendMoney(pwallet, dest, nAmount, false, cc, {}, {}, updateScript);
|
wtxNew = SendMoney(*locked_chain, pwallet, dest, nAmount, false, cc, {}, updateScript);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,7 +521,8 @@ UniValue abandonclaim(const JSONRPCRequest& request)
|
||||||
CTxDestination address = DecodeDestination(request.params[1].get_str());
|
CTxDestination address = DecodeDestination(request.params[1].get_str());
|
||||||
|
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
LOCK2(cs_main, pwallet->cs_wallet);
|
auto locked_chain = pwallet->chain().lock();
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
auto it = pwallet->mapWallet.find(hash);
|
auto it = pwallet->mapWallet.find(hash);
|
||||||
if (it == pwallet->mapWallet.end()) {
|
if (it == pwallet->mapWallet.end()) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
||||||
|
@ -533,7 +539,7 @@ UniValue abandonclaim(const JSONRPCRequest& request)
|
||||||
CCoinControl cc;
|
CCoinControl cc;
|
||||||
cc.m_change_type = pwallet->m_default_change_type;
|
cc.m_change_type = pwallet->m_default_change_type;
|
||||||
cc.Select(COutPoint(wtx.tx->GetHash(), i));
|
cc.Select(COutPoint(wtx.tx->GetHash(), i));
|
||||||
wtxNew = SendMoney(pwallet, address, wtx.tx->vout[i].nValue, true, cc, {}, {});
|
wtxNew = SendMoney(*locked_chain, pwallet, address, wtx.tx->vout[i].nValue, true, cc, {});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,7 +552,7 @@ static void MaybePushAddress(UniValue& entry, const CTxDestination &dest);
|
||||||
|
|
||||||
extern std::string escapeNonUtf8(const std::string&);
|
extern std::string escapeNonUtf8(const std::string&);
|
||||||
|
|
||||||
void ListNameClaims(const CWalletTx& wtx, CWallet* const pwallet, const std::string& strAccount, int nMinDepth,
|
void ListNameClaims(interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx, CWallet* const pwallet, int nMinDepth,
|
||||||
UniValue& ret, const bool include_supports, bool list_spent)
|
UniValue& ret, const bool include_supports, bool list_spent)
|
||||||
{
|
{
|
||||||
CAmount nFee;
|
CAmount nFee;
|
||||||
|
@ -554,15 +560,11 @@ void ListNameClaims(const CWalletTx& wtx, CWallet* const pwallet, const std::str
|
||||||
std::list<COutputEntry> listSent;
|
std::list<COutputEntry> listSent;
|
||||||
std::list<COutputEntry> listReceived;
|
std::list<COutputEntry> listReceived;
|
||||||
|
|
||||||
wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, isminetype::ISMINE_ALL);
|
wtx.GetAmounts(listReceived, listSent, nFee, isminetype::ISMINE_ALL);
|
||||||
|
|
||||||
bool fAllAccounts = (strAccount == std::string("*"));
|
|
||||||
if (!fAllAccounts && wtx.strFromAccount != strAccount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (const auto& s: listSent)
|
for (const auto& s: listSent)
|
||||||
{
|
{
|
||||||
if (!list_spent && pwallet->IsSpent(wtx.GetHash(), s.vout))
|
if (!list_spent && pwallet->IsSpent(locked_chain, wtx.GetHash(), s.vout))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
UniValue entry(UniValue::VOBJ);
|
UniValue entry(UniValue::VOBJ);
|
||||||
|
@ -611,27 +613,20 @@ void ListNameClaims(const CWalletTx& wtx, CWallet* const pwallet, const std::str
|
||||||
|
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
|
||||||
auto it = mapBlockIndex.find(wtx.hashBlock);
|
if (auto pindex = LookupBlockIndex(wtx.m_confirm.hashBlock))
|
||||||
if (it != mapBlockIndex.end())
|
|
||||||
{
|
{
|
||||||
CBlockIndex* pindex = it->second;
|
entry.pushKV("height", pindex->nHeight);
|
||||||
if (pindex)
|
entry.pushKV("expiration height", pindex->nHeight + trieCache.expirationTime());
|
||||||
{
|
if (pindex->nHeight + trieCache.expirationTime() > ::ChainActive().Height()) {
|
||||||
entry.pushKV("height", pindex->nHeight);
|
entry.pushKV("expired", false);
|
||||||
entry.pushKV("expiration height", pindex->nHeight + trieCache.expirationTime());
|
entry.pushKV("blocks to expiration", pindex->nHeight + trieCache.expirationTime() - ::ChainActive().Height());
|
||||||
if (pindex->nHeight + trieCache.expirationTime() > chainActive.Height())
|
}
|
||||||
{
|
else {
|
||||||
entry.pushKV("expired", false);
|
entry.pushKV("expired", true);
|
||||||
entry.pushKV("blocks to expiration", pindex->nHeight + trieCache.expirationTime() - chainActive.Height());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry.pushKV("expired", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry.pushKV("confirmations", wtx.GetDepthInMainChain());
|
entry.pushKV("confirmations", wtx.GetDepthInMainChain(locked_chain));
|
||||||
entry.pushKV("is spent", pwallet->IsSpent(wtx.GetHash(), s.vout));
|
entry.pushKV("is spent", pwallet->IsSpent(locked_chain, wtx.GetHash(), s.vout));
|
||||||
if (op == OP_CLAIM_NAME)
|
if (op == OP_CLAIM_NAME)
|
||||||
{
|
{
|
||||||
entry.pushKV("is in name trie", trieCache.haveClaim(sName, COutPoint(wtx.GetHash(), s.vout)));
|
entry.pushKV("is in name trie", trieCache.haveClaim(sName, COutPoint(wtx.GetHash(), s.vout)));
|
||||||
|
@ -686,8 +681,6 @@ UniValue listnameclaims(const JSONRPCRequest& request)
|
||||||
" }\n"
|
" }\n"
|
||||||
"]\n");
|
"]\n");
|
||||||
|
|
||||||
std::string strAccount = "*";
|
|
||||||
|
|
||||||
auto include_supports = request.params.size() < 1 || request.params[0].get_bool();
|
auto include_supports = request.params.size() < 1 || request.params[0].get_bool();
|
||||||
bool fListSpent = request.params.size() > 1 && !request.params[1].get_bool();
|
bool fListSpent = request.params.size() > 1 && !request.params[1].get_bool();
|
||||||
|
|
||||||
|
@ -698,14 +691,15 @@ UniValue listnameclaims(const JSONRPCRequest& request)
|
||||||
|
|
||||||
UniValue ret(UniValue::VARR);
|
UniValue ret(UniValue::VARR);
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
|
auto locked_chain = pwallet->chain().lock();
|
||||||
LOCK2(cs_main, pwallet->cs_wallet);
|
LOCK2(cs_main, pwallet->cs_wallet);
|
||||||
const auto& txOrdered = pwallet->wtxOrdered;
|
const auto& txOrdered = pwallet->wtxOrdered;
|
||||||
|
|
||||||
for (auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
|
for (auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
|
||||||
{
|
{
|
||||||
auto *const pwtx = (*it).second.first;
|
auto *const pwtx = (*it).second;
|
||||||
if (pwtx != nullptr && pwtx->GetDepthInMainChain() >= nMinDepth)
|
if (pwtx != nullptr && pwtx->GetDepthInMainChain(*locked_chain) >= nMinDepth)
|
||||||
ListNameClaims(*pwtx, pwallet, strAccount, 0, ret, include_supports, fListSpent);
|
ListNameClaims(*locked_chain, *pwtx, pwallet, 0, ret, include_supports, fListSpent);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto arrTmp = ret.getValues();
|
auto arrTmp = ret.getValues();
|
||||||
|
@ -759,6 +753,7 @@ UniValue supportclaim(const JSONRPCRequest& request)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("claimid must be maximum of length %d", claimLength));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("claimid must be maximum of length %d", claimLength));
|
||||||
|
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
|
auto locked_chain = pwallet->chain().lock();
|
||||||
LOCK2(cs_main, pwallet->cs_wallet);
|
LOCK2(cs_main, pwallet->cs_wallet);
|
||||||
EnsureWalletIsUnlocked(pwallet);
|
EnsureWalletIsUnlocked(pwallet);
|
||||||
|
|
||||||
|
@ -799,7 +794,7 @@ UniValue supportclaim(const JSONRPCRequest& request)
|
||||||
if (isTip) {
|
if (isTip) {
|
||||||
CTransactionRef ref;
|
CTransactionRef ref;
|
||||||
uint256 block;
|
uint256 block;
|
||||||
if (!GetTransaction(uint256(claimNsupports.claim.outPoint.hash), ref, Params().GetConsensus(), block, true))
|
if (!GetTransaction(uint256(claimNsupports.claim.outPoint.hash), ref, Params().GetConsensus(), block))
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to locate the TX with the claim's output.");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to locate the TX with the claim's output.");
|
||||||
if (!ExtractDestination(ref->vout[claimNsupports.claim.outPoint.n].scriptPubKey, dest))
|
if (!ExtractDestination(ref->vout[claimNsupports.claim.outPoint.n].scriptPubKey, dest))
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to extract the destination from the chosen claim.");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to extract the destination from the chosen claim.");
|
||||||
|
@ -816,7 +811,7 @@ UniValue supportclaim(const JSONRPCRequest& request)
|
||||||
|
|
||||||
CCoinControl cc;
|
CCoinControl cc;
|
||||||
cc.m_change_type = pwallet->m_default_change_type;
|
cc.m_change_type = pwallet->m_default_change_type;
|
||||||
auto tx = SendMoney(pwallet, dest, nAmount, false, cc, {}, {}, supportScript);
|
auto tx = SendMoney(*locked_chain, pwallet, dest, nAmount, false, cc, {}, supportScript);
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
result.pushKV("txId", tx->GetHash().GetHex());
|
result.pushKV("txId", tx->GetHash().GetHex());
|
||||||
|
@ -850,7 +845,8 @@ UniValue abandonsupport(const JSONRPCRequest& request)
|
||||||
CTxDestination address = DecodeDestination(request.params[1].get_str());
|
CTxDestination address = DecodeDestination(request.params[1].get_str());
|
||||||
|
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
LOCK2(cs_main, pwallet->cs_wallet);
|
auto locked_chain = pwallet->chain().lock();
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
auto it = pwallet->mapWallet.find(hash);
|
auto it = pwallet->mapWallet.find(hash);
|
||||||
if (it == pwallet->mapWallet.end()) {
|
if (it == pwallet->mapWallet.end()) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
||||||
|
@ -867,7 +863,7 @@ UniValue abandonsupport(const JSONRPCRequest& request)
|
||||||
CCoinControl cc;
|
CCoinControl cc;
|
||||||
cc.m_change_type = pwallet->m_default_change_type;
|
cc.m_change_type = pwallet->m_default_change_type;
|
||||||
cc.Select(COutPoint(wtx.tx->GetHash(), i));
|
cc.Select(COutPoint(wtx.tx->GetHash(), i));
|
||||||
wtxNew = SendMoney(pwallet, address, wtx.tx->vout[i].nValue, true, cc, {}, {});
|
wtxNew = SendMoney(*locked_chain, pwallet, address, wtx.tx->vout[i].nValue, true, cc, {});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1574,7 +1570,7 @@ static UniValue addtimelockedaddress(const JSONRPCRequest& request)
|
||||||
if (!request.params[2].isNull())
|
if (!request.params[2].isNull())
|
||||||
label = LabelFromValue(request.params[2]);
|
label = LabelFromValue(request.params[2]);
|
||||||
|
|
||||||
LOCK2(cs_main, pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
|
|
||||||
auto address = request.params[1].get_str();
|
auto address = request.params[1].get_str();
|
||||||
CTxDestination destination = DecodeDestination(address);
|
CTxDestination destination = DecodeDestination(address);
|
||||||
|
@ -1881,12 +1877,6 @@ static void ListTransactions(interfaces::Chain::Lock& locked_chain, CWallet* con
|
||||||
|
|
||||||
bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
|
bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
|
||||||
|
|
||||||
bool list_sent = fAllAccounts;
|
|
||||||
|
|
||||||
if (IsDeprecatedRPCEnabled("accounts")) {
|
|
||||||
list_sent |= strAccount == strSentAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sent
|
// Sent
|
||||||
if (!filter_label)
|
if (!filter_label)
|
||||||
{
|
{
|
||||||
|
@ -3059,8 +3049,8 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
|
||||||
auto supports = pwallet->GetBalance(ISMINE_SUPPORT);
|
auto supports = pwallet->GetBalance(ISMINE_SUPPORT);
|
||||||
obj.pushKV("balance", ValueFromAmount(balance.m_mine_trusted));
|
obj.pushKV("balance", ValueFromAmount(balance.m_mine_trusted));
|
||||||
obj.pushKV("available_balance", ValueFromAmount(balance.m_mine_trusted - claims.m_mine_trusted - supports.m_mine_trusted));
|
obj.pushKV("available_balance", ValueFromAmount(balance.m_mine_trusted - claims.m_mine_trusted - supports.m_mine_trusted));
|
||||||
obj.pushKV("staked_claim_balance", ValueFromAmount(claims));
|
obj.pushKV("staked_claim_balance", ValueFromAmount(claims.m_mine_trusted));
|
||||||
obj.pushKV("staked_support_balance", ValueFromAmount(supports));
|
obj.pushKV("staked_support_balance", ValueFromAmount(supports.m_mine_trusted));
|
||||||
obj.pushKV("unconfirmed_balance", ValueFromAmount(balance.m_mine_untrusted_pending));
|
obj.pushKV("unconfirmed_balance", ValueFromAmount(balance.m_mine_untrusted_pending));
|
||||||
obj.pushKV("immature_balance", ValueFromAmount(balance.m_mine_immature));
|
obj.pushKV("immature_balance", ValueFromAmount(balance.m_mine_immature));
|
||||||
obj.pushKV("txcount", (int)pwallet->mapWallet.size());
|
obj.pushKV("txcount", (int)pwallet->mapWallet.size());
|
||||||
|
@ -3176,7 +3166,6 @@ static UniValue loadwallet(const JSONRPCRequest& request)
|
||||||
+ HelpExampleRpc("loadwallet", "\"test.dat\"")
|
+ HelpExampleRpc("loadwallet", "\"test.dat\"")
|
||||||
},
|
},
|
||||||
}.Check(request);
|
}.Check(request);
|
||||||
WalletLocation location(request.params[0].get_str());
|
|
||||||
|
|
||||||
WalletLocation location(request.params[0].get_str());
|
WalletLocation location(request.params[0].get_str());
|
||||||
|
|
||||||
|
@ -4587,23 +4576,6 @@ UniValue sethdseed(const JSONRPCRequest& request)
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify input looks sane. This will check that we have at most one uxto, witness or non-witness.
|
|
||||||
if (!input.IsSane()) {
|
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "PSBT input is not sane.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have no utxo, grab it from the wallet.
|
|
||||||
if (!input.non_witness_utxo && input.witness_utxo.IsNull()) {
|
|
||||||
if (sigdata.witness) {
|
|
||||||
// Convert the non-witness utxo to witness
|
|
||||||
if (input.witness_utxo.IsNull() && input.non_witness_utxo) {
|
|
||||||
input.witness_utxo = input.non_witness_utxo->vout[txin.prevout.n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UniValue walletprocesspsbt(const JSONRPCRequest& request)
|
UniValue walletprocesspsbt(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||||
|
|
|
@ -9,21 +9,20 @@
|
||||||
#include <consensus/validation.h>
|
#include <consensus/validation.h>
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
|
#include <psbt.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <test/test_bitcoin.h>
|
#include <test/setup_common.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <wallet/coincontrol.h>
|
#include <wallet/coincontrol.h>
|
||||||
#include <wallet/test/wallet_test_fixture.h>
|
#include <wallet/test/init_test_fixture.h>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
struct CatchWalletTestSetup: public TestingSetup {
|
struct CatchWalletTestSetup: public InitWalletDirTestingSetup {
|
||||||
CatchWalletTestSetup() : TestingSetup(CBaseChainParams::REGTEST) {
|
CatchWalletTestSetup() : InitWalletDirTestingSetup(CBaseChainParams::REGTEST) {
|
||||||
RegisterWalletRPCCommands(tableRPC);
|
auto rpc_method = tableRPC["createwallet"];
|
||||||
|
|
||||||
rpcfn_type rpc_method = tableRPC["createwallet"]->actor;
|
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
req.params.push_back("tester_wallet");
|
req.params.push_back("tester_wallet");
|
||||||
|
@ -31,7 +30,7 @@ struct CatchWalletTestSetup: public TestingSetup {
|
||||||
BOOST_CHECK_EQUAL(results["name"].get_str(), "tester_wallet");
|
BOOST_CHECK_EQUAL(results["name"].get_str(), "tester_wallet");
|
||||||
}
|
}
|
||||||
~CatchWalletTestSetup() override {
|
~CatchWalletTestSetup() override {
|
||||||
rpcfn_type rpc_method = tableRPC["unloadwallet"]->actor;
|
auto rpc_method = tableRPC["unloadwallet"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -42,7 +41,7 @@ struct CatchWalletTestSetup: public TestingSetup {
|
||||||
BOOST_FIXTURE_TEST_SUITE(claim_rpc_tests, CatchWalletTestSetup)
|
BOOST_FIXTURE_TEST_SUITE(claim_rpc_tests, CatchWalletTestSetup)
|
||||||
|
|
||||||
double AvailableBalance() {
|
double AvailableBalance() {
|
||||||
rpcfn_type rpc_method = tableRPC["getbalance"]->actor;
|
auto rpc_method = tableRPC["getbalance"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -52,7 +51,7 @@ double AvailableBalance() {
|
||||||
|
|
||||||
uint256 ClaimAName(const std::string& name, const std::string& data, const std::string& price, bool isUpdate = false) {
|
uint256 ClaimAName(const std::string& name, const std::string& data, const std::string& price, bool isUpdate = false) {
|
||||||
// pass a txid as name for update
|
// pass a txid as name for update
|
||||||
rpcfn_type rpc_method = tableRPC[isUpdate ? "updateclaim" : "claimname"]->actor;
|
auto rpc_method = tableRPC[isUpdate ? "updateclaim" : "claimname"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -73,7 +72,7 @@ uint256 ClaimAName(const std::string& name, const std::string& data, const std::
|
||||||
|
|
||||||
uint256 SupportAName(const std::string& name, const std::string& claimId, const std::string& price) {
|
uint256 SupportAName(const std::string& name, const std::string& claimId, const std::string& price) {
|
||||||
// pass a txid as name for update
|
// pass a txid as name for update
|
||||||
rpcfn_type rpc_method = tableRPC["supportclaim"]->actor;
|
auto rpc_method = tableRPC["supportclaim"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -89,7 +88,7 @@ uint256 SupportAName(const std::string& name, const std::string& claimId, const
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue LookupAllNames() {
|
UniValue LookupAllNames() {
|
||||||
rpcfn_type rpc_method = tableRPC["listnameclaims"]->actor;
|
auto rpc_method = tableRPC["listnameclaims"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -97,7 +96,7 @@ UniValue LookupAllNames() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint256> generateBlock(int blocks = 1) {
|
std::vector<uint256> generateBlock(int blocks = 1) {
|
||||||
rpcfn_type rpc_method = tableRPC["generate"]->actor;
|
auto rpc_method = tableRPC["generate"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -115,7 +114,7 @@ std::vector<uint256> generateBlock(int blocks = 1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void rollbackBlock(const std::vector<uint256>& ids) {
|
void rollbackBlock(const std::vector<uint256>& ids) {
|
||||||
rpcfn_type rpc_method = tableRPC["invalidateblock"]->actor;
|
auto rpc_method = tableRPC["invalidateblock"];
|
||||||
for (auto it = ids.rbegin(); it != ids.rend(); ++it) {
|
for (auto it = ids.rbegin(); it != ids.rend(); ++it) {
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
|
@ -129,7 +128,7 @@ void rollbackBlock(const std::vector<uint256>& ids) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 AbandonAClaim(const uint256& txid, bool isSupport = false) {
|
uint256 AbandonAClaim(const uint256& txid, bool isSupport = false) {
|
||||||
rpcfn_type pre_rpc_method = tableRPC["getrawchangeaddress"]->actor;
|
auto pre_rpc_method = tableRPC["getrawchangeaddress"];
|
||||||
JSONRPCRequest pre_req;
|
JSONRPCRequest pre_req;
|
||||||
pre_req.URI = "/wallet/tester_wallet";
|
pre_req.URI = "/wallet/tester_wallet";
|
||||||
pre_req.params = UniValue(UniValue::VARR);
|
pre_req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -137,7 +136,7 @@ uint256 AbandonAClaim(const uint256& txid, bool isSupport = false) {
|
||||||
UniValue adr_hash = pre_rpc_method(pre_req);
|
UniValue adr_hash = pre_rpc_method(pre_req);
|
||||||
|
|
||||||
// pass a txid as name for update
|
// pass a txid as name for update
|
||||||
rpcfn_type rpc_method = tableRPC[isSupport ? "abandonsupport" : "abandonclaim"]->actor;
|
auto rpc_method = tableRPC[isSupport ? "abandonsupport" : "abandonclaim"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -156,7 +155,7 @@ uint256 AbandonAClaim(const uint256& txid, bool isSupport = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidateBalance(double claims, double supports) {
|
void ValidateBalance(double claims, double supports) {
|
||||||
rpcfn_type rpc_method = tableRPC["getwalletinfo"]->actor;
|
auto rpc_method = tableRPC["getwalletinfo"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -295,7 +294,7 @@ BOOST_AUTO_TEST_CASE(claim_op_runthrough_bech32)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<COutPoint> SpendableCoins() {
|
std::vector<COutPoint> SpendableCoins() {
|
||||||
rpcfn_type rpc_method = tableRPC["listunspent"]->actor;
|
auto rpc_method = tableRPC["listunspent"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -307,7 +306,7 @@ std::vector<COutPoint> SpendableCoins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxDestination NewAddress(OutputType t) {
|
CTxDestination NewAddress(OutputType t) {
|
||||||
rpcfn_type rpc_method = tableRPC["getnewaddress"]->actor;
|
auto rpc_method = tableRPC["getnewaddress"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -318,7 +317,7 @@ CTxDestination NewAddress(OutputType t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SignRawTransaction(const std::string& tx) {
|
std::string SignRawTransaction(const std::string& tx) {
|
||||||
rpcfn_type rpc_method = tableRPC["signrawtransactionwithwallet"]->actor;
|
auto rpc_method = tableRPC["signrawtransactionwithwallet"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -332,7 +331,7 @@ std::string SignRawTransaction(const std::string& tx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SendRawTransaction(const std::string& tx) {
|
std::string SendRawTransaction(const std::string& tx) {
|
||||||
rpcfn_type rpc_method = tableRPC["sendrawtransaction"]->actor;
|
auto rpc_method = tableRPC["sendrawtransaction"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -343,7 +342,7 @@ std::string SendRawTransaction(const std::string& tx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FundRawTransaction(const std::string& tx) {
|
std::string FundRawTransaction(const std::string& tx) {
|
||||||
rpcfn_type rpc_method = tableRPC["fundrawtransaction"]->actor;
|
auto rpc_method = tableRPC["fundrawtransaction"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -354,7 +353,7 @@ std::string FundRawTransaction(const std::string& tx) {
|
||||||
|
|
||||||
std::string ProcessPsbt(const PartiallySignedTransaction& pst) {
|
std::string ProcessPsbt(const PartiallySignedTransaction& pst) {
|
||||||
BOOST_CHECK(pst.IsSane());
|
BOOST_CHECK(pst.IsSane());
|
||||||
rpcfn_type rpc_method = tableRPC["walletprocesspsbt"]->actor;
|
auto rpc_method = tableRPC["walletprocesspsbt"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -369,7 +368,7 @@ std::string ProcessPsbt(const PartiallySignedTransaction& pst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FinalizePsbt(const std::string& pst) {
|
std::string FinalizePsbt(const std::string& pst) {
|
||||||
rpcfn_type rpc_method = tableRPC["finalizepsbt"]->actor;
|
auto rpc_method = tableRPC["finalizepsbt"];
|
||||||
JSONRPCRequest req;
|
JSONRPCRequest req;
|
||||||
req.URI = "/wallet/tester_wallet";
|
req.URI = "/wallet/tester_wallet";
|
||||||
req.params = UniValue(UniValue::VARR);
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
@ -397,7 +396,7 @@ BOOST_AUTO_TEST_CASE(can_sign_all_addr)
|
||||||
+ GetScriptForDestination(destination);
|
+ GetScriptForDestination(destination);
|
||||||
CTxOut out(100000, scriptPubKey);
|
CTxOut out(100000, scriptPubKey);
|
||||||
claimTx.vout.push_back(out);
|
claimTx.vout.push_back(out);
|
||||||
auto hex = EncodeHexTx(claimTx);
|
auto hex = EncodeHexTx(CTransaction(claimTx));
|
||||||
hex = SignRawTransaction(hex);
|
hex = SignRawTransaction(hex);
|
||||||
txids.push_back(SendRawTransaction(hex));
|
txids.push_back(SendRawTransaction(hex));
|
||||||
CTxIn spendIn(uint256S(txids.back()), 0);
|
CTxIn spendIn(uint256S(txids.back()), 0);
|
||||||
|
@ -405,7 +404,7 @@ BOOST_AUTO_TEST_CASE(can_sign_all_addr)
|
||||||
CTxOut spendOut(90000, GetScriptForDestination(destination2));
|
CTxOut spendOut(90000, GetScriptForDestination(destination2));
|
||||||
spendTx.vin.push_back(spendIn);
|
spendTx.vin.push_back(spendIn);
|
||||||
spendTx.vout.push_back(spendOut);
|
spendTx.vout.push_back(spendOut);
|
||||||
hex = EncodeHexTx(spendTx);
|
hex = EncodeHexTx(CTransaction(spendTx));
|
||||||
spends.push_back(hex);
|
spends.push_back(hex);
|
||||||
}
|
}
|
||||||
generateBlock(1);
|
generateBlock(1);
|
||||||
|
|
|
@ -244,7 +244,7 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
|
||||||
auto chain = interfaces::MakeChain();
|
auto chain = interfaces::MakeChain();
|
||||||
|
|
||||||
CWallet wallet(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
|
CWallet wallet(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
|
||||||
CWalletTx wtx(&wallet, m_coinbase_txns.back());
|
CWalletTx wtx(&wallet, MakeTransactionRef(m_coinbase_txns.back()));
|
||||||
|
|
||||||
auto locked_chain = chain->lock();
|
auto locked_chain = chain->lock();
|
||||||
LockAssertion lock(::cs_main);
|
LockAssertion lock(::cs_main);
|
||||||
|
@ -516,47 +516,4 @@ BOOST_FIXTURE_TEST_CASE(dummy_input_size_test, TestChain100Setup)
|
||||||
BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(true), DUMMY_NESTED_P2WPKH_INPUT_SIZE);
|
BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(true), DUMMY_NESTED_P2WPKH_INPUT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit calculation which is used to test the wallet constant
|
|
||||||
// We get the same virtual size due to rounding(weight/4) for both use_max_sig values
|
|
||||||
static size_t CalculateNestedKeyhashInputSize(bool use_max_sig)
|
|
||||||
{
|
|
||||||
// Generate ephemeral valid pubkey
|
|
||||||
CKey key;
|
|
||||||
key.MakeNewKey(true);
|
|
||||||
CPubKey pubkey = key.GetPubKey();
|
|
||||||
|
|
||||||
// Generate pubkey hash
|
|
||||||
uint160 key_hash(Hash160(pubkey.begin(), pubkey.end()));
|
|
||||||
|
|
||||||
// Create inner-script to enter into keystore. Key hash can't be 0...
|
|
||||||
CScript inner_script = CScript() << OP_0 << std::vector<unsigned char>(key_hash.begin(), key_hash.end());
|
|
||||||
|
|
||||||
// Create outer P2SH script for the output
|
|
||||||
uint160 script_id(Hash160(inner_script.begin(), inner_script.end()));
|
|
||||||
CScript script_pubkey = CScript() << OP_HASH160 << std::vector<unsigned char>(script_id.begin(), script_id.end()) << OP_EQUAL;
|
|
||||||
|
|
||||||
// Add inner-script to key store and key to watchonly
|
|
||||||
CBasicKeyStore keystore;
|
|
||||||
keystore.AddCScript(inner_script);
|
|
||||||
keystore.AddKeyPubKey(key, pubkey);
|
|
||||||
|
|
||||||
// Fill in dummy signatures for fee calculation.
|
|
||||||
SignatureData sig_data;
|
|
||||||
|
|
||||||
if (!ProduceSignature(keystore, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, script_pubkey, sig_data)) {
|
|
||||||
// We're hand-feeding it correct arguments; shouldn't happen
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CTxIn tx_in;
|
|
||||||
UpdateInput(tx_in, sig_data);
|
|
||||||
return (size_t)GetVirtualTransactionInputSize(tx_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(dummy_input_size_test, TestChain100Setup)
|
|
||||||
{
|
|
||||||
BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(false), DUMMY_NESTED_P2WPKH_INPUT_SIZE);
|
|
||||||
BOOST_CHECK_EQUAL(CalculateNestedKeyhashInputSize(true), DUMMY_NESTED_P2WPKH_INPUT_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
@ -126,29 +126,6 @@ static void ReleaseWallet(CWallet* wallet)
|
||||||
g_wallet_release_cv.notify_all();
|
g_wallet_release_cv.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
|
||||||
{
|
|
||||||
// Mark wallet for unloading.
|
|
||||||
CWallet* pwallet = wallet.get();
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(g_wallet_release_mutex);
|
|
||||||
auto it = g_unloading_wallet_set.insert(pwallet);
|
|
||||||
assert(it.second);
|
|
||||||
}
|
|
||||||
// The wallet can be in use so it's not possible to explicitly unload here.
|
|
||||||
// Notify the unload intent so that all remaining shared pointers are
|
|
||||||
// released.
|
|
||||||
pwallet->NotifyUnload();
|
|
||||||
// Time to ditch our shared_ptr and wait for ReleaseWallet call.
|
|
||||||
wallet.reset();
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(g_wallet_release_mutex);
|
|
||||||
while (g_unloading_wallet_set.count(pwallet) == 1) {
|
|
||||||
g_wallet_release_cv.wait(lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
||||||
{
|
{
|
||||||
// Mark wallet for unloading.
|
// Mark wallet for unloading.
|
||||||
|
|
|
@ -95,9 +95,6 @@ constexpr CAmount HIGH_MAX_TX_FEE{100 * HIGH_TX_FEE_PER_KB};
|
||||||
//! Pre-calculated constants for input size estimation in *virtual size*
|
//! Pre-calculated constants for input size estimation in *virtual size*
|
||||||
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE = 91;
|
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE = 91;
|
||||||
|
|
||||||
//! Pre-calculated constants for input size estimation in *virtual size*
|
|
||||||
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE = 91;
|
|
||||||
|
|
||||||
class CCoinControl;
|
class CCoinControl;
|
||||||
class COutput;
|
class COutput;
|
||||||
class CScript;
|
class CScript;
|
||||||
|
@ -885,10 +882,10 @@ private:
|
||||||
*/
|
*/
|
||||||
uint256 m_last_block_processed GUARDED_BY(cs_wallet);
|
uint256 m_last_block_processed GUARDED_BY(cs_wallet);
|
||||||
|
|
||||||
|
public:
|
||||||
//! Fetches a key from the keypool
|
//! Fetches a key from the keypool
|
||||||
bool GetKeyFromPool(CPubKey &key, bool internal = false);
|
bool GetKeyFromPool(CPubKey &key, bool internal = false);
|
||||||
|
|
||||||
public:
|
|
||||||
/*
|
/*
|
||||||
* Main wallet lock.
|
* Main wallet lock.
|
||||||
* This lock protects all the fields added by CWallet.
|
* This lock protects all the fields added by CWallet.
|
||||||
|
@ -913,8 +910,6 @@ public:
|
||||||
|
|
||||||
const WalletLocation& GetLocation() const { return m_location; }
|
const WalletLocation& GetLocation() const { return m_location; }
|
||||||
|
|
||||||
const WalletLocation& GetLocation() const { return m_location; }
|
|
||||||
|
|
||||||
/** Get a name for this wallet for logging/debugging purposes.
|
/** Get a name for this wallet for logging/debugging purposes.
|
||||||
*/
|
*/
|
||||||
const std::string& GetName() const { return m_location.GetName(); }
|
const std::string& GetName() const { return m_location.GetName(); }
|
||||||
|
|
|
@ -102,14 +102,3 @@ bool WalletLocation::Exists() const
|
||||||
{
|
{
|
||||||
return fs::symlink_status(m_path).type() != fs::file_not_found;
|
return fs::symlink_status(m_path).type() != fs::file_not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletLocation::WalletLocation(const std::string& name)
|
|
||||||
: m_name(name)
|
|
||||||
, m_path(fs::absolute(name, GetWalletDir()))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WalletLocation::Exists() const
|
|
||||||
{
|
|
||||||
return fs::symlink_status(m_path).type() != fs::file_not_found;
|
|
||||||
}
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue